ia64/xen-unstable

changeset 2973:d0353c3d3ebd

bitkeeper revision 1.1159.1.417 (41966eb4oNbZp-QqXdzTAzmhv6s-QQ)

sync w/ head
author cl349@freefall.cl.cam.ac.uk
date Sat Nov 13 20:29:40 2004 +0000 (2004-11-13)
parents e2675067dd05 3c505be01ff1
children 912f55644225
files .rootkeys linux-2.6.9-xen-sparse/drivers/xen/netback/netback.c xen/arch/x86/pdb-stub.c xen/arch/x86/traps.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_32/mm.c xen/common/ac_timer.c xen/common/keyhandler.c xen/common/schedule.c xen/include/asm-x86/debugger.h xen/include/asm-x86/pdb.h xen/include/xen/debugger_hooks.h xen/include/xen/keyhandler.h
line diff
     1.1 --- a/.rootkeys	Sat Nov 13 10:11:50 2004 +0000
     1.2 +++ b/.rootkeys	Sat Nov 13 20:29:40 2004 +0000
     1.3 @@ -708,6 +708,7 @@ 3ddb79c3KhTI0F_Iw_hRL9QEyOVK-g xen/inclu
     1.4  404f1b920OQVnrbnXnySS-WxrH9Wzw xen/include/asm-x86/config.h
     1.5  3ddb79c2LLt11EQHjrd6sB7FUqvFfA xen/include/asm-x86/cpufeature.h
     1.6  40cf1596ajIU1KJfF22XD-tSLfH6XA xen/include/asm-x86/current.h
     1.7 +4194efbdvxUXjCLobbopgLOojisO4Q xen/include/asm-x86/debugger.h
     1.8  3ddb79c2jFkPAZTDmU35L6IUssYMgQ xen/include/asm-x86/debugreg.h
     1.9  3ddb79c3r9-31dIsewPV3P3i8HALsQ xen/include/asm-x86/delay.h
    1.10  3ddb79c34BFiXjBJ_cCKB0aCsV1IDw xen/include/asm-x86/desc.h
    1.11 @@ -772,7 +773,6 @@ 3f840f12CkbYSlwMrY2S11Mpyxg7Nw xen/inclu
    1.12  3ddb79c259jh8hE7vre_8NuE7nwNSA xen/include/xen/config.h
    1.13  3eb165e0eawr3R-p2ZQtSdLWtLRN_A xen/include/xen/console.h
    1.14  3ddb79c1V44RD26YqCUm-kqIupM37A xen/include/xen/ctype.h
    1.15 -4194efbdvxUXjCLobbopgLOojisO4Q xen/include/xen/debugger_hooks.h
    1.16  3ddb79c05DdHQ0UxX_jKsXdR4QlMCA xen/include/xen/delay.h
    1.17  3ddb79c2O729EttZTYu1c8LcsUO_GQ xen/include/xen/elf.h
    1.18  3ddb79c0HIghfBF8zFUdmXhOU8i6hA xen/include/xen/errno.h
     2.1 --- a/linux-2.6.9-xen-sparse/drivers/xen/netback/netback.c	Sat Nov 13 10:11:50 2004 +0000
     2.2 +++ b/linux-2.6.9-xen-sparse/drivers/xen/netback/netback.c	Sat Nov 13 20:29:40 2004 +0000
     2.3 @@ -42,7 +42,6 @@ static unsigned char rx_notify[NR_EVENT_
     2.4  static unsigned long mmap_vstart;
     2.5  #define MMAP_VADDR(_req) (mmap_vstart + ((_req) * PAGE_SIZE))
     2.6  
     2.7 -#define PKT_MIN_LEN (ETH_HLEN + 20)
     2.8  #define PKT_PROT_LEN 64
     2.9  
    2.10  static struct {
    2.11 @@ -501,7 +500,7 @@ static void net_tx_action(unsigned long 
    2.12  
    2.13          netif_schedule_work(netif);
    2.14  
    2.15 -        if ( unlikely(txreq.size <= PKT_MIN_LEN) || 
    2.16 +        if ( unlikely(txreq.size < ETH_HLEN) || 
    2.17               unlikely(txreq.size > ETH_FRAME_LEN) )
    2.18          {
    2.19              DPRINTK("Bad packet size: %d\n", txreq.size);
     3.1 --- a/xen/arch/x86/pdb-stub.c	Sat Nov 13 10:11:50 2004 +0000
     3.2 +++ b/xen/arch/x86/pdb-stub.c	Sat Nov 13 20:29:40 2004 +0000
     3.3 @@ -1214,6 +1214,27 @@ void pdb_key_pressed(unsigned char key)
     3.4      pdb_handle_exception(KEYPRESS_EXCEPTION, regs);
     3.5  }
     3.6  
     3.7 +void pdb_handle_debug_trap(struct xen_regs *regs, long error_code)
     3.8 +{
     3.9 +    unsigned int condition;
    3.10 +    struct domain *tsk = current;
    3.11 +    struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
    3.12 +
    3.13 +    __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
    3.14 +    if ( (condition & (1 << 14)) != (1 << 14) )
    3.15 +        printk("\nwarning: debug trap w/o BS bit [0x%x]\n\n", condition);
    3.16 +    __asm__("movl %0,%%db6" : : "r" (0));
    3.17 +
    3.18 +    if ( pdb_handle_exception(1, regs) != 0 )
    3.19 +    {
    3.20 +        tsk->thread.debugreg[6] = condition;
    3.21 +
    3.22 +        gtb->flags = GTBF_TRAP_NOCODE;
    3.23 +        gtb->cs    = tsk->thread.traps[1].cs;
    3.24 +        gtb->eip   = tsk->thread.traps[1].address;
    3.25 +    }
    3.26 +}
    3.27 +
    3.28  void initialize_pdb()
    3.29  {
    3.30      extern char opt_pdb[];
    3.31 @@ -1244,7 +1265,7 @@ void initialize_pdb()
    3.32      /* Acknowledge any spurious GDB packets. */
    3.33      pdb_put_char('+');
    3.34  
    3.35 -    add_key_handler('D', pdb_key_pressed, "enter pervasive debugger");
    3.36 +    register_keyhandler('D', pdb_key_pressed, "enter pervasive debugger");
    3.37  
    3.38      pdb_initialized = 1;
    3.39  }
     4.1 --- a/xen/arch/x86/traps.c	Sat Nov 13 10:11:50 2004 +0000
     4.2 +++ b/xen/arch/x86/traps.c	Sat Nov 13 20:29:40 2004 +0000
     4.3 @@ -50,8 +50,7 @@
     4.4  #include <asm/flushtlb.h>
     4.5  #include <asm/uaccess.h>
     4.6  #include <asm/i387.h>
     4.7 -#include <asm/pdb.h>
     4.8 -#include <xen/debugger_hooks.h>
     4.9 +#include <asm/debugger.h>
    4.10  
    4.11  extern char opt_nmi[];
    4.12  
    4.13 @@ -223,7 +222,9 @@ static inline void do_trap(int trapnr, c
    4.14      trap_info_t *ti;
    4.15      unsigned long fixup;
    4.16  
    4.17 -    if (!(regs->cs & 3))
    4.18 +    DEBUGGER_trap_entry(trapnr, regs, error_code);
    4.19 +
    4.20 +    if ( !(regs->cs & 3) )
    4.21          goto xen_fault;
    4.22  
    4.23      ti = current->thread.traps + trapnr;
    4.24 @@ -244,8 +245,7 @@ static inline void do_trap(int trapnr, c
    4.25          return;
    4.26      }
    4.27  
    4.28 -    if (debugger_trap(trapnr, regs))
    4.29 -	return;
    4.30 +    DEBUGGER_trap_fatal(trapnr, regs, error_code);
    4.31  
    4.32      show_registers(regs);
    4.33      panic("CPU%d FATAL TRAP: vector = %d (%s)\n"
    4.34 @@ -284,18 +284,15 @@ asmlinkage void do_int3(struct xen_regs 
    4.35      struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
    4.36      trap_info_t *ti;
    4.37  
    4.38 -    if (debugger_trap(3, regs))
    4.39 -        return;
    4.40 +    DEBUGGER_trap_entry(TRAP_int3, regs, error_code);
    4.41  
    4.42 -    if ( (regs->cs & 3) != 3 )
    4.43 +    if ( unlikely((regs->cs & 3) == 0) )
    4.44      {
    4.45 -        if ( unlikely((regs->cs & 3) == 0) )
    4.46 -        {
    4.47 -            show_registers(regs);
    4.48 -            panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n"
    4.49 -                  "[error_code=%08x]\n",
    4.50 -                  smp_processor_id(), error_code);
    4.51 -        }
    4.52 +        DEBUGGER_trap_fatal(TRAP_int3, regs, error_code);
    4.53 +        show_registers(regs);
    4.54 +        panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n"
    4.55 +              "[error_code=%08x]\n",
    4.56 +              smp_processor_id(), error_code);
    4.57      }
    4.58  
    4.59      ti = current->thread.traps + 3;
    4.60 @@ -331,7 +328,7 @@ asmlinkage void do_double_fault(void)
    4.61      printk("System needs manual reset.\n");
    4.62      printk("************************************\n");
    4.63  
    4.64 -    debugger_trap(8, NULL);
    4.65 +    DEBUGGER_trap_fatal(TRAP_double_fault, NULL, 0);
    4.66  
    4.67      /* Lock up the console to prevent spurious output from other CPUs. */
    4.68      console_force_lock();
    4.69 @@ -352,6 +349,8 @@ asmlinkage void do_page_fault(struct xen
    4.70  
    4.71      __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (addr) : );
    4.72  
    4.73 +    DEBUGGER_trap_entry(TRAP_page_fault, regs, error_code);
    4.74 +
    4.75      perfc_incrc(page_faults);
    4.76  
    4.77      if ( likely(VM_ASSIST(d, VMASST_TYPE_writable_pagetables)) )
    4.78 @@ -411,8 +410,7 @@ asmlinkage void do_page_fault(struct xen
    4.79          return;
    4.80      }
    4.81  
    4.82 -    if (debugger_trap(14, regs))
    4.83 -	return;
    4.84 +    DEBUGGER_trap_fatal(TRAP_page_fault, regs, error_code);
    4.85  
    4.86      if ( addr >= PAGE_OFFSET )
    4.87      {
    4.88 @@ -446,6 +444,8 @@ asmlinkage void do_general_protection(st
    4.89      trap_info_t *ti;
    4.90      unsigned long fixup;
    4.91  
    4.92 +    DEBUGGER_trap_entry(TRAP_gp_fault, regs, error_code);
    4.93 +    
    4.94      /* Badness if error in ring 0, or result of an interrupt. */
    4.95      if ( !(regs->cs & 3) || (error_code & 1) )
    4.96          goto gp_in_kernel;
    4.97 @@ -476,15 +476,6 @@ asmlinkage void do_general_protection(st
    4.98          ti = current->thread.traps + (error_code>>3);
    4.99          if ( TI_GET_DPL(ti) >= (regs->cs & 3) )
   4.100          {
   4.101 -#ifdef XEN_DEBUGGER
   4.102 -            if ( pdb_initialized && (pdb_ctx.system_call != 0) )
   4.103 -            {
   4.104 -                unsigned long cr3 = read_cr3();
   4.105 -                if ( cr3 == pdb_ctx.ptbr )
   4.106 -                    pdb_linux_syscall_enter_bkpt(regs, error_code, ti);
   4.107 -            }
   4.108 -#endif
   4.109 -
   4.110              gtb->flags = GTBF_TRAP_NOCODE;
   4.111              regs->eip += 2;
   4.112              goto finish_propagation;
   4.113 @@ -497,7 +488,7 @@ asmlinkage void do_general_protection(st
   4.114           gpf_emulate_4gb(regs) )
   4.115          return;
   4.116  #endif
   4.117 -    
   4.118 +
   4.119      /* Pass on GPF as is. */
   4.120      ti = current->thread.traps + 13;
   4.121      gtb->flags      = GTBF_TRAP;
   4.122 @@ -518,8 +509,7 @@ asmlinkage void do_general_protection(st
   4.123          return;
   4.124      }
   4.125  
   4.126 -    if (debugger_trap(13, regs))
   4.127 -	return;
   4.128 +    DEBUGGER_trap_fatal(TRAP_gp_fault, regs, error_code);
   4.129  
   4.130      die("general protection fault", regs, error_code);
   4.131  }
   4.132 @@ -566,8 +556,7 @@ asmlinkage void io_check_error(struct xe
   4.133  
   4.134  static void unknown_nmi_error(unsigned char reason, struct xen_regs * regs)
   4.135  {
   4.136 -    if (debugger_trap(2, regs))
   4.137 -	return;
   4.138 +    DEBUGGER_trap_entry(TRAP_nmi, regs, 0);
   4.139  
   4.140      printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
   4.141      printk("Dazed and confused, but trying to continue\n");
   4.142 @@ -622,39 +611,13 @@ asmlinkage void math_state_restore(struc
   4.143      }
   4.144  }
   4.145  
   4.146 -#ifdef XEN_DEBUGGER
   4.147 -asmlinkage void do_pdb_debug(struct xen_regs *regs, long error_code)
   4.148 -{
   4.149 -    unsigned int condition;
   4.150 -    struct domain *tsk = current;
   4.151 -    struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
   4.152 -
   4.153 -    __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
   4.154 -    if ( (condition & (1 << 14)) != (1 << 14) )
   4.155 -        printk("\nwarning: debug trap w/o BS bit [0x%x]\n\n", condition);
   4.156 -    __asm__("movl %0,%%db6" : : "r" (0));
   4.157 -
   4.158 -    if ( pdb_handle_exception(1, regs) != 0 )
   4.159 -    {
   4.160 -        tsk->thread.debugreg[6] = condition;
   4.161 -
   4.162 -        gtb->flags = GTBF_TRAP_NOCODE;
   4.163 -        gtb->cs    = tsk->thread.traps[1].cs;
   4.164 -        gtb->eip   = tsk->thread.traps[1].address;
   4.165 -    }
   4.166 -}
   4.167 -#endif
   4.168 -
   4.169  asmlinkage void do_debug(struct xen_regs *regs, long error_code)
   4.170  {
   4.171      unsigned int condition;
   4.172      struct exec_domain *tsk = current;
   4.173      struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
   4.174  
   4.175 -#ifdef XEN_DEBUGGER
   4.176 -    if ( pdb_initialized )
   4.177 -        return do_pdb_debug(regs, error_code);
   4.178 -#endif
   4.179 +    DEBUGGER_trap_entry(TRAP_debug, regs, error_code);
   4.180  
   4.181      __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
   4.182  
     5.1 --- a/xen/arch/x86/x86_32/entry.S	Sat Nov 13 10:11:50 2004 +0000
     5.2 +++ b/xen/arch/x86/x86_32/entry.S	Sat Nov 13 20:29:40 2004 +0000
     5.3 @@ -63,7 +63,7 @@
     5.4  #include <public/xen.h>
     5.5  
     5.6  #define GET_CURRENT(reg)   \
     5.7 -        movl $4096-4, reg; \
     5.8 +        movl $8192-4, reg; \
     5.9          orl  %esp, reg;    \
    5.10          andl $~3,reg;      \
    5.11          movl (reg),reg;
     6.1 --- a/xen/arch/x86/x86_32/mm.c	Sat Nov 13 10:11:50 2004 +0000
     6.2 +++ b/xen/arch/x86/x86_32/mm.c	Sat Nov 13 20:29:40 2004 +0000
     6.3 @@ -54,32 +54,8 @@ void __set_fixmap(enum fixed_addresses i
     6.4  }
     6.5  
     6.6  
     6.7 -static void __init fixrange_init(unsigned long start, 
     6.8 -                                 unsigned long end, 
     6.9 -                                 l2_pgentry_t *pg_base)
    6.10 -{
    6.11 -    l2_pgentry_t *l2e;
    6.12 -    int i;
    6.13 -    unsigned long vaddr, page;
    6.14 -
    6.15 -    vaddr = start;
    6.16 -    i = l2_table_offset(vaddr);
    6.17 -    l2e = pg_base + i;
    6.18 -
    6.19 -    for ( ; (i < ENTRIES_PER_L2_PAGETABLE) && (vaddr != end); l2e++, i++ ) 
    6.20 -    {
    6.21 -        if ( l2_pgentry_val(*l2e) != 0 )
    6.22 -            continue;
    6.23 -        page = (unsigned long)alloc_xenheap_page();
    6.24 -        clear_page(page);
    6.25 -        *l2e = mk_l2_pgentry(__pa(page) | __PAGE_HYPERVISOR);
    6.26 -        vaddr += 1 << L2_PAGETABLE_SHIFT;
    6.27 -    }
    6.28 -}
    6.29 -
    6.30  void __init paging_init(void)
    6.31  {
    6.32 -    unsigned long addr;
    6.33      void *ioremap_pt;
    6.34      int i;
    6.35  
    6.36 @@ -89,13 +65,6 @@ void __init paging_init(void)
    6.37              mk_l2_pgentry((i << L2_PAGETABLE_SHIFT) | 
    6.38                            __PAGE_HYPERVISOR | _PAGE_PSE);
    6.39  
    6.40 -    /*
    6.41 -     * Fixed mappings, only the page table structure has to be
    6.42 -     * created - mappings will be set by set_fixmap():
    6.43 -     */
    6.44 -    addr = FIXADDR_START & ~((1<<L2_PAGETABLE_SHIFT)-1);
    6.45 -    fixrange_init(addr, 0, idle_pg_table);
    6.46 -
    6.47      /* Create page table for ioremap(). */
    6.48      ioremap_pt = (void *)alloc_xenheap_page();
    6.49      clear_page(ioremap_pt);
     7.1 --- a/xen/common/ac_timer.c	Sat Nov 13 10:11:50 2004 +0000
     7.2 +++ b/xen/common/ac_timer.c	Sat Nov 13 20:29:40 2004 +0000
     7.3 @@ -286,5 +286,5 @@ void __init ac_timer_init(void)
     7.4          spin_lock_init(&ac_timers[i].lock);
     7.5      }
     7.6  
     7.7 -    add_key_handler('a', dump_timerq, "dump ac_timer queues");
     7.8 +    register_keyhandler('a', dump_timerq, "dump ac_timer queues");
     7.9  }
     8.1 --- a/xen/common/keyhandler.c	Sat Nov 13 10:11:50 2004 +0000
     8.2 +++ b/xen/common/keyhandler.c	Sat Nov 13 20:29:40 2004 +0000
     8.3 @@ -1,3 +1,6 @@
     8.4 +/******************************************************************************
     8.5 + * keyhandler.c
     8.6 + */
     8.7  
     8.8  #include <xen/keyhandler.h> 
     8.9  #include <xen/reboot.h>
    8.10 @@ -10,49 +13,61 @@
    8.11  #define KEY_MAX 256
    8.12  #define STR_MAX  64
    8.13  
    8.14 -static struct { 
    8.15 -    key_handler *handler;
    8.16 -    int          flags;
    8.17 +static struct {
    8.18 +    union {
    8.19 +        keyhandler_t     *handler;
    8.20 +        irq_keyhandler_t *irq_handler;
    8.21 +    } u;
    8.22 +    unsigned int flags;
    8.23      char         desc[STR_MAX]; 
    8.24  } key_table[KEY_MAX]; 
    8.25  
    8.26 -#define KEYHANDLER_NO_DEFER 0x1
    8.27 +#define KEYHANDLER_IRQ_CALLBACK 0x1
    8.28  
    8.29  static unsigned char keypress_key;
    8.30  
    8.31  void keypress_softirq(void)
    8.32  {
    8.33 -    key_handler  *h;
    8.34 +    keyhandler_t *h;
    8.35      unsigned char key = keypress_key;
    8.36 -    if ( (h = key_table[key].handler) != NULL )
    8.37 +    if ( (h = key_table[key].u.handler) != NULL )
    8.38          (*h)(key);
    8.39  }
    8.40  
    8.41  void handle_keypress(unsigned char key, struct xen_regs *regs)
    8.42  {
    8.43 -    key_handler  *h;
    8.44 +    irq_keyhandler_t *h;
    8.45  
    8.46 -    keypress_key = key;
    8.47 -    if ( (key_table[key].flags & KEYHANDLER_NO_DEFER) &&
    8.48 -         ((h = key_table[key].handler) != NULL) )
    8.49 -        ((void (*)(unsigned char, struct xen_regs *))*h)(key, regs);
    8.50 +    if ( key_table[key].flags & KEYHANDLER_IRQ_CALLBACK )
    8.51 +    {
    8.52 +        if ( (h = key_table[key].u.irq_handler) != NULL )
    8.53 +            (*h)(key, regs);
    8.54 +    }
    8.55      else
    8.56 +    {
    8.57 +        keypress_key = key;
    8.58          raise_softirq(KEYPRESS_SOFTIRQ);
    8.59 +    }
    8.60  }
    8.61  
    8.62 -void add_key_handler(unsigned char key, key_handler *handler, char *desc)
    8.63 +void register_keyhandler(
    8.64 +    unsigned char key, keyhandler_t *handler, char *desc)
    8.65  {
    8.66 -    key_table[key].handler = handler;
    8.67 -    key_table[key].flags = 0;
    8.68 +    ASSERT(key_table[key].u.handler == NULL);
    8.69 +    key_table[key].u.handler = handler;
    8.70 +    key_table[key].flags     = 0;
    8.71      strncpy(key_table[key].desc, desc, STR_MAX);
    8.72      key_table[key].desc[STR_MAX-1] = '\0'; 
    8.73  }
    8.74  
    8.75 -void add_key_handler_no_defer(unsigned char key, key_handler *handler,
    8.76 -                              char *desc)
    8.77 +void register_irq_keyhandler(
    8.78 +    unsigned char key, irq_keyhandler_t *handler, char *desc)
    8.79  {
    8.80 -    add_key_handler(key, handler, desc);
    8.81 -    key_table[key].flags |= KEYHANDLER_NO_DEFER;
    8.82 +    ASSERT(key_table[key].u.irq_handler == NULL);
    8.83 +    key_table[key].u.irq_handler = handler;
    8.84 +    key_table[key].flags         = KEYHANDLER_IRQ_CALLBACK;
    8.85 +    strncpy(key_table[key].desc, desc, STR_MAX);
    8.86 +    key_table[key].desc[STR_MAX-1] = '\0'; 
    8.87  }
    8.88  
    8.89  static void show_handlers(unsigned char key)
    8.90 @@ -60,16 +75,15 @@ static void show_handlers(unsigned char 
    8.91      int i; 
    8.92      printk("'%c' pressed -> showing installed handlers\n", key);
    8.93      for ( i = 0; i < KEY_MAX; i++ ) 
    8.94 -        if ( key_table[i].handler != NULL ) 
    8.95 +        if ( key_table[i].u.handler != NULL ) 
    8.96              printk(" key '%c' (ascii '%02x') => %s\n", 
    8.97                     (i<33 || i>126)?(' '):(i),i,
    8.98                     key_table[i].desc);
    8.99  }
   8.100  
   8.101  
   8.102 -static void dump_registers(unsigned char key)
   8.103 +static void dump_registers(unsigned char key, struct xen_regs *regs)
   8.104  {
   8.105 -    struct xen_regs *regs = (struct xen_regs *)get_execution_context();
   8.106      extern void show_registers(struct xen_regs *regs); 
   8.107      printk("'%c' pressed -> dumping registers\n", key); 
   8.108      show_registers(regs); 
   8.109 @@ -153,20 +167,30 @@ void initialize_keytable(void)
   8.110  {
   8.111      open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq);
   8.112  
   8.113 -    add_key_handler('d', dump_registers, "dump registers"); 
   8.114 -    add_key_handler('h', show_handlers, "show this message");
   8.115 -    add_key_handler('l', print_sched_histo, "print sched latency histogram");
   8.116 -    add_key_handler('L', reset_sched_histo, "reset sched latency histogram");
   8.117 -    add_key_handler('q', do_task_queues, "dump task queues + guest state");
   8.118 -    add_key_handler('r', dump_runq,      "dump run queues");
   8.119 -    add_key_handler('R', halt_machine,   "reboot machine"); 
   8.120 +    register_irq_keyhandler(
   8.121 +        'd', dump_registers, "dump registers"); 
   8.122 +    register_keyhandler(
   8.123 +        'h', show_handlers, "show this message");
   8.124 +    register_keyhandler(
   8.125 +        'l', print_sched_histo, "print sched latency histogram");
   8.126 +    register_keyhandler(
   8.127 +        'L', reset_sched_histo, "reset sched latency histogram");
   8.128 +    register_keyhandler(
   8.129 +        'q', do_task_queues, "dump task queues + guest state");
   8.130 +    register_keyhandler(
   8.131 +        'r', dump_runq,      "dump run queues");
   8.132 +    register_keyhandler(
   8.133 +        'R', halt_machine,   "reboot machine"); 
   8.134  
   8.135  #ifndef NDEBUG
   8.136 -    add_key_handler('o', audit_domains_key,  "audit domains >0 EXPERIMENTAL"); 
   8.137 +    register_keyhandler(
   8.138 +        'o', audit_domains_key,  "audit domains >0 EXPERIMENTAL"); 
   8.139  #endif
   8.140  
   8.141  #ifdef PERF_COUNTERS
   8.142 -    add_key_handler('p', perfc_printall, "print performance counters"); 
   8.143 -    add_key_handler('P', perfc_reset,    "reset performance counters"); 
   8.144 +    register_keyhandler(
   8.145 +        'p', perfc_printall, "print performance counters"); 
   8.146 +    register_keyhandler(
   8.147 +        'P', perfc_reset,    "reset performance counters"); 
   8.148  #endif
   8.149  }
     9.1 --- a/xen/common/schedule.c	Sat Nov 13 10:11:50 2004 +0000
     9.2 +++ b/xen/common/schedule.c	Sat Nov 13 20:29:40 2004 +0000
     9.3 @@ -56,13 +56,11 @@
     9.4  #define TRC_SCHED_S_TIMER_FN          0x0001000A
     9.5  #define TRC_SCHED_T_TIMER_FN          0x0001000B
     9.6  #define TRC_SCHED_DOM_TIMER_FN        0x0001000C
     9.7 -#define TRC_SCHED_FALLBACK_TIMER_FN   0x0001000D
     9.8  
     9.9  /* Various timer handlers. */
    9.10  static void s_timer_fn(unsigned long unused);
    9.11  static void t_timer_fn(unsigned long unused);
    9.12  static void dom_timer_fn(unsigned long data);
    9.13 -static void fallback_timer_fn(unsigned long unused);
    9.14  
    9.15  /* This is global for now so that private implementations can reach it */
    9.16  schedule_data_t schedule_data[NR_CPUS];
    9.17 @@ -87,12 +85,6 @@ static struct scheduler ops;
    9.18  /* Per-CPU periodic timer sends an event to the currently-executing domain. */
    9.19  static struct ac_timer t_timer[NR_CPUS]; 
    9.20  
    9.21 -/*
    9.22 - * Per-CPU timer which ensures that even guests with very long quantums get
    9.23 - * their time-of-day state updated often enough to avoid wrapping.
    9.24 - */
    9.25 -static struct ac_timer fallback_timer[NR_CPUS];
    9.26 -
    9.27  extern xmem_cache_t *domain_struct_cachep;
    9.28  extern xmem_cache_t *exec_domain_struct_cachep;
    9.29  
    9.30 @@ -486,7 +478,6 @@ int idle_cpu(int cpu)
    9.31   * - s_timer: per CPU timer for preemption and scheduling decisions
    9.32   * - t_timer: per CPU periodic timer to send timer interrupt to current dom
    9.33   * - dom_timer: per domain timer to specifiy timeout values
    9.34 - * - fallback_timer: safeguard to ensure time is up to date
    9.35   ****************************************************************************/
    9.36  
    9.37  /* The scheduler timer: force a run through the scheduler*/
    9.38 @@ -500,45 +491,31 @@ static void s_timer_fn(unsigned long unu
    9.39  /* Periodic tick timer: send timer event to current domain*/
    9.40  static void t_timer_fn(unsigned long unused)
    9.41  {
    9.42 -    struct exec_domain *p = current;
    9.43 +    struct exec_domain *ed = current;
    9.44 +    struct domain *d = ed->domain;
    9.45  
    9.46      TRACE_0D(TRC_SCHED_T_TIMER_FN);
    9.47  
    9.48 -    if ( !is_idle_task(p->domain) ) {
    9.49 -        update_dom_time(p->domain);
    9.50 -        send_guest_virq(p, VIRQ_TIMER);
    9.51 +    if ( !is_idle_task(d) )
    9.52 +    {
    9.53 +        update_dom_time(d);
    9.54 +        send_guest_virq(ed, VIRQ_TIMER);
    9.55      }
    9.56  
    9.57 -    t_timer[p->processor].expires = NOW() + MILLISECS(10);
    9.58 -    add_ac_timer(&t_timer[p->processor]);
    9.59 +    t_timer[d->processor].expires = NOW() + MILLISECS(10);
    9.60 +    add_ac_timer(&t_timer[d->processor]);
    9.61  }
    9.62  
    9.63  /* Domain timer function, sends a virtual timer interrupt to domain */
    9.64  static void dom_timer_fn(unsigned long data)
    9.65  {
    9.66      struct exec_domain *ed = (struct exec_domain *)data;
    9.67 -    struct domain *d = ed->domain;
    9.68 +
    9.69      TRACE_0D(TRC_SCHED_DOM_TIMER_FN);
    9.70 -    update_dom_time(d);
    9.71 +    update_dom_time(ed->domain);
    9.72      send_guest_virq(ed, VIRQ_TIMER);
    9.73  }
    9.74  
    9.75 -
    9.76 -/* Fallback timer to ensure guests get time updated 'often enough'. */
    9.77 -static void fallback_timer_fn(unsigned long unused)
    9.78 -{
    9.79 -    struct exec_domain *ed = current;
    9.80 -    struct domain *p = ed->domain;
    9.81 -
    9.82 -    TRACE_0D(TRC_SCHED_FALLBACK_TIMER_FN);
    9.83 -
    9.84 -    if ( !is_idle_task(p) )
    9.85 -        update_dom_time(p);
    9.86 -
    9.87 -    fallback_timer[ed->processor].expires = NOW() + MILLISECS(500);
    9.88 -    add_ac_timer(&fallback_timer[ed->processor]);
    9.89 -}
    9.90 -
    9.91  /* Initialise the data structures. */
    9.92  void __init scheduler_init(void)
    9.93  {
    9.94 @@ -560,11 +537,6 @@ void __init scheduler_init(void)
    9.95          t_timer[i].cpu      = i;
    9.96          t_timer[i].data     = 3;
    9.97          t_timer[i].function = &t_timer_fn;
    9.98 -
    9.99 -        init_ac_timer(&fallback_timer[i]);
   9.100 -        fallback_timer[i].cpu      = i;
   9.101 -        fallback_timer[i].data     = 4;
   9.102 -        fallback_timer[i].function = &fallback_timer_fn;
   9.103      }
   9.104  
   9.105      schedule_data[0].idle = &idle0_exec_domain;
   9.106 @@ -598,9 +570,6 @@ void schedulers_start(void)
   9.107  
   9.108      t_timer_fn(0);
   9.109      smp_call_function((void *)t_timer_fn, NULL, 1, 1);
   9.110 -
   9.111 -    fallback_timer_fn(0);
   9.112 -    smp_call_function((void *)fallback_timer_fn, NULL, 1, 1);
   9.113  }
   9.114  
   9.115  
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/xen/include/asm-x86/debugger.h	Sat Nov 13 20:29:40 2004 +0000
    10.3 @@ -0,0 +1,137 @@
    10.4 +/******************************************************************************
    10.5 + * asm/debugger.h
    10.6 + * 
    10.7 + * Generic hooks into arch-dependent Xen.
    10.8 + * 
    10.9 + * Each debugger should define two functions here:
   10.10 + * 
   10.11 + * 1. debugger_trap_entry(): 
   10.12 + *  Called at start of any synchronous fault or trap, before any other work
   10.13 + *  is done. The idea is that if your debugger deliberately caused the trap
   10.14 + *  (e.g. to implement breakpoints or data watchpoints) then you can take
   10.15 + *  appropriate action and return a non-zero value to cause early exit from
   10.16 + *  the trap function.
   10.17 + * 
   10.18 + * 2. debugger_trap_fatal():
   10.19 + *  Called when Xen is about to give up and crash. Typically you will use this
   10.20 + *  hook to drop into a debug session. It can also be used to hook off
   10.21 + *  deliberately caused traps (which you then handle and return non-zero)
   10.22 + *  but really these should be hooked off 'debugger_trap_entry'.
   10.23 + */
   10.24 +
   10.25 +#ifndef __X86_DEBUGGER_H__
   10.26 +#define __X86_DEBUGGER_H__
   10.27 +
   10.28 +/* Avoid magic vector numbers by using these semi-sensical names. */
   10.29 +#define TRAP_divide_error     0
   10.30 +#define TRAP_debug            1
   10.31 +#define TRAP_nmi              2
   10.32 +#define TRAP_int3             3
   10.33 +#define TRAP_overflow         4
   10.34 +#define TRAP_bounds           5
   10.35 +#define TRAP_invalid_op       6
   10.36 +#define TRAP_no_device        7
   10.37 +#define TRAP_double_fault     8
   10.38 +#define TRAP_copro_seg        9
   10.39 +#define TRAP_invalid_tss     10
   10.40 +#define TRAP_no_segment      11
   10.41 +#define TRAP_stack_error     12
   10.42 +#define TRAP_gp_fault        13
   10.43 +#define TRAP_page_fault      14
   10.44 +#define TRAP_spurious_int    15
   10.45 +#define TRAP_copro_error     16
   10.46 +#define TRAP_alignment_check 17
   10.47 +#define TRAP_machine_check   18
   10.48 +#define TRAP_simd_error      19
   10.49 +
   10.50 +/* The main trap handlers use these helper macros which include early bail. */
   10.51 +#define DEBUGGER_trap_entry(_v, _r, _e) \
   10.52 +    if ( debugger_trap_entry(_v, _r, _e) ) return;
   10.53 +#define DEBUGGER_trap_fatal(_v, _r, _e) \
   10.54 +    if ( debugger_trap_fatal(_v, _r, _e) ) return;
   10.55 +
   10.56 +#ifdef XEN_DEBUGGER
   10.57 +
   10.58 +#include <asm/pdb.h>
   10.59 +
   10.60 +static inline int debugger_trap_entry(
   10.61 +    unsigned int vector, struct xen_regs *regs, unsigned int error_code)
   10.62 +{
   10.63 +    int ret = 0;
   10.64 +
   10.65 +    switch ( vector )
   10.66 +    {
   10.67 +    case TRAP_debug:
   10.68 +        if ( pdb_initialized )
   10.69 +        {
   10.70 +            pdb_handle_debug_trap(regs, (long)error_code);
   10.71 +            ret = 1; /* early exit */
   10.72 +        }
   10.73 +        break;
   10.74 +
   10.75 +    case TRAP_int3:
   10.76 +        if ( pdb_initialized && (pdb_handle_exception(vector, regs) == 0) )
   10.77 +            ret = 1; /* early exit */
   10.78 +        break;
   10.79 +
   10.80 +    case TRAP_gp_fault:        
   10.81 +        if ( ((regs->cs & 3) != 0) && ((error_code & 3) == 2) &&
   10.82 +             pdb_initialized && (pdb_ctx.system_call != 0) )
   10.83 +        {
   10.84 +            unsigned long cr3 = read_cr3();
   10.85 +            if ( cr3 == pdb_ctx.ptbr )
   10.86 +                pdb_linux_syscall_enter_bkpt(
   10.87 +                    regs, error_code, current->thread.traps + (error_code>>3));
   10.88 +        }
   10.89 +        break;
   10.90 +    }
   10.91 +
   10.92 +    return ret;
   10.93 +}
   10.94 +
   10.95 +static inline int debugger_trap_fatal(
   10.96 +    unsigned int vector, struct xen_regs *regs, unsigned int error_code)
   10.97 +{
   10.98 +    int ret = 0;
   10.99 +
  10.100 +    switch ( vector )
  10.101 +    {
  10.102 +    case TRAP_page_fault:
  10.103 +        if ( pdb_page_fault_possible )
  10.104 +        {
  10.105 +            pdb_page_fault = 1;
  10.106 +            /* make eax & edx valid to complete the instruction */
  10.107 +            regs->eax = (long)&pdb_page_fault_scratch;
  10.108 +            regs->edx = (long)&pdb_page_fault_scratch;
  10.109 +            ret = 1; /* exit - do not crash! */
  10.110 +        }
  10.111 +        break;
  10.112 +    }
  10.113 +
  10.114 +    return ret;
  10.115 +}
  10.116 +
  10.117 +#elif 0
  10.118 +
  10.119 +extern int kdb_trap(int, int, struct xen_regs *);
  10.120 +
  10.121 +static inline int debugger_trap_entry(
  10.122 +    unsigned int vector, struct xen_regs *regs, unsigned int error_code)
  10.123 +{
  10.124 +    return 0;
  10.125 +}
  10.126 +
  10.127 +static inline int debugger_trap_fatal(
  10.128 +    unsigned int vector, struct xen_regs *regs, unsigned int error_code)
  10.129 +{
  10.130 +    return kdb_trap(vector, 0, regs);
  10.131 +}
  10.132 +
  10.133 +#else
  10.134 +
  10.135 +#define debugger_trap_entry(_v, _r, _e) (0)
  10.136 +#define debugger_trap_fatal(_v, _r, _e) (0)
  10.137 +
  10.138 +#endif
  10.139 +
  10.140 +#endif /* __X86_DEBUGGER_H__ */
    11.1 --- a/xen/include/asm-x86/pdb.h	Sat Nov 13 10:11:50 2004 +0000
    11.2 +++ b/xen/include/asm-x86/pdb.h	Sat Nov 13 20:29:40 2004 +0000
    11.3 @@ -84,4 +84,6 @@ void pdb_linux_syscall_enter_bkpt (struc
    11.4  void pdb_linux_syscall_exit_bkpt (struct xen_regs *regs, 
    11.5  				  struct pdb_context *pdb_ctx);
    11.6  
    11.7 +void pdb_handle_debug_trap(struct xen_regs *regs, long error_code);
    11.8 +
    11.9  #endif  /* __PDB_H__ */
    12.1 --- a/xen/include/xen/debugger_hooks.h	Sat Nov 13 10:11:50 2004 +0000
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,37 +0,0 @@
    12.4 -
    12.5 -#ifndef __DEBUGGER_HOOKS_H__
    12.6 -#define __DEBUGGER_HOOKS_H__
    12.7 -
    12.8 -static inline int debugger_trap(int type, struct xen_regs *regs)
    12.9 -{
   12.10 -    int ret = 0;
   12.11 -
   12.12 -#ifdef XEN_DEBUGGER
   12.13 -    switch (type) {
   12.14 -    case 3:
   12.15 -        if ( pdb_initialized && pdb_handle_exception(type, regs) == 0 )
   12.16 -            return 1;
   12.17 -        break;
   12.18 -    case 14:
   12.19 -        if ( pdb_page_fault_possible )
   12.20 -        {
   12.21 -            pdb_page_fault = 1;
   12.22 -            /* make eax & edx valid to complete the instruction */
   12.23 -            regs->eax = (long)&pdb_page_fault_scratch;
   12.24 -            regs->edx = (long)&pdb_page_fault_scratch;
   12.25 -            return 1;
   12.26 -        }
   12.27 -        break;
   12.28 -    }
   12.29 -#endif
   12.30 -
   12.31 -#if 0
   12.32 -    extern int kdb_trap(int, int, struct xen_regs *);
   12.33 -    if ((ret = kdb_trap(type, 0, regs)))
   12.34 -        return ret;
   12.35 -#endif
   12.36 -
   12.37 -    return ret;
   12.38 -}
   12.39 -
   12.40 -#endif /* __DEBUGGER_HOOKS_H__ */
    13.1 --- a/xen/include/xen/keyhandler.h	Sat Nov 13 10:11:50 2004 +0000
    13.2 +++ b/xen/include/xen/keyhandler.h	Sat Nov 13 20:29:40 2004 +0000
    13.3 @@ -1,16 +1,35 @@
    13.4 -/* 
    13.5 -** We keep an array of 'handlers' for each key code between 0 and 255; 
    13.6 -** this is intended to allow very simple debugging routines (toggle 
    13.7 -** debug flag, dump registers, reboot, etc) to be hooked in in a slightly
    13.8 -** nicer fashion than just editing the serial/keyboard drivers. 
    13.9 -*/
   13.10 -struct xen_regs;
   13.11 +/******************************************************************************
   13.12 + * keyhandler.h
   13.13 + * 
   13.14 + * We keep an array of 'handlers' for each key code between 0 and 255; 
   13.15 + * this is intended to allow very simple debugging routines (toggle 
   13.16 + * debug flag, dump registers, reboot, etc) to be hooked in in a slightly
   13.17 + * nicer fashion than just editing the serial/keyboard drivers. 
   13.18 + */
   13.19 +
   13.20 +#ifndef __XEN_KEYHANDLER_H__
   13.21 +#define __XEN_KEYHANDLER_H__
   13.22 +
   13.23 +#include <asm/regs.h>
   13.24  
   13.25 -typedef void key_handler(unsigned char key);
   13.26 +/*
   13.27 + * Register a callback function for key @key. The callback occurs in
   13.28 + * softirq context with no locks held and interrupts enabled.
   13.29 + */
   13.30 +typedef void keyhandler_t(unsigned char key);
   13.31 +extern void register_keyhandler(
   13.32 +    unsigned char key, keyhandler_t *handler, char *desc); 
   13.33  
   13.34 -extern void add_key_handler(unsigned char key, 
   13.35 -			    key_handler *handler, char *desc); 
   13.36 -extern void add_key_handler_no_defer(unsigned char key, 
   13.37 -                                     key_handler *handler, char *desc); 
   13.38 +/*
   13.39 + * Register an IRQ callback function for key @key. The callback occurs
   13.40 + * synchronously in hard-IRQ context with interrupts disabled. The @regs
   13.41 + * callback parameter points at the interrupted register context.
   13.42 + */
   13.43 +typedef void irq_keyhandler_t(unsigned char key, struct xen_regs *regs);
   13.44 +extern void register_irq_keyhandler(
   13.45 +    unsigned char key, irq_keyhandler_t *handler, char *desc); 
   13.46  
   13.47 +/* Inject a keypress into the key-handling subsystem. */
   13.48  extern void handle_keypress(unsigned char key, struct xen_regs *regs);
   13.49 +
   13.50 +#endif /* __XEN_KEYHANDLER_H__ */