same bugs in the two files (uml-linux-2.4.26-3):
arch/um/drivers/line.c
int line_write(struct line *lines, struct tty_struct *tty, int from_user,
        const char *buf, int len)
{
 struct line *line;
 char *new;
 unsigned long flags;
 int n, err, i, ret = 0;
 
 if(tty->stopped) return 0;
 
 if(from_user){
  new = kmalloc(len, GFP_KERNEL);
  if(new == NULL)
   return(0);
  n = copy_from_user(new, buf, len);
  buf = new;
  if(n == len){
   len = -EFAULT;
   goto out_free;
  }
 
  len -= n;
 }
 
 i = minor(tty->device) - tty->driver.minor_start;
 line = &lines[i];
 
 down(&line->sem);  ========================> may cause shedule in interrrupt
 if(line->head != line->tail){
  local_irq_save(flags);
  ret += buffer_data(line, buf, len);
  err = flush_buffer(line);
  local_irq_restore(flags);
  if(err <= 0)
   goto out_up;
 }
 
 
in arch/um/drivers/stdio_console.c
static void console_write(struct console *console, const char *string,
     unsigned len)
{
 struct line *line = &vts[console->index];
 
 if(con_init_done)
  down(&line->sem);  ========================> may cause shedule in interrrupt
 console_write_chan(&line->chan_list, string, len);
 if(con_init_done)
  up(&line->sem);
}
 
my fix is change
[w4760c@w4760c-x3 drivers]$ diff -Nru line.c line.c.old
--- line.c      2005-04-28 09:22:29.000000000 +0800
+++ line.c.old  2005-04-26 09:38:18.000000000 +0800
@@ -134,9 +134,7 @@
        i = minor(tty->device) - tty->driver.minor_start;
        line = &lines[i];
 
-       if(!in_interrupt())
-               down(&line->sem);
-
+       down(&line->sem);
        if(line->head != line->tail){
                local_irq_save(flags);
                ret += buffer_data(line, buf, len);
@@ -159,8 +157,7 @@
                        ret += buffer_data(line, buf + n, len);
        }
  out_up:
-       if(!in_interrupt())
-               up(&line->sem);
+       up(&line->sem);
 
  out_free:
        if(from_user)
 
--- stdio_console.c     2005-04-26 14:41:05.000000000 +0800
+++ stdio_console.c.bak 2005-04-26 14:33:30.000000000 +0800
@@ -188,10 +188,10 @@
 {
        struct line *line = &vts[console->index];
 
-       if(con_init_done && !in_interrupt())
+       if(con_init_done)
                down(&line->sem);
        console_write_chan(&line->chan_list, string, len);
-       if(con_init_done && !in_interrupt())
+       if(con_init_done)
                up(&line->sem);
 }
 
 
please help to confirm if it's correct?
 
best regards
Yu Dong
 
Tel: 010-65642141
Email:  w4760c@motorola.com
PCS Beijing Design Center
Motorola(China) Electronics Ltd.