ia64/xen-unstable

changeset 3695:ff48344d34df

bitkeeper revision 1.1159.212.110 (42079080u5EKN2Dp7MbOEM7lnEs4gg)

Various bug fixes, and NMI/DF improvements for x86_64.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author kaf24@scramble.cl.cam.ac.uk
date Mon Feb 07 16:00:00 2005 +0000 (2005-02-07)
parents 75266d5ca7ca
children aa3214cefa34
files xen/arch/x86/boot/x86_32.S xen/arch/x86/boot/x86_64.S xen/arch/x86/setup.c xen/arch/x86/smpboot.c xen/arch/x86/traps.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/entry.S xen/arch/x86/x86_64/traps.c xen/include/asm-x86/config.h
line diff
     1.1 --- a/xen/arch/x86/boot/x86_32.S	Mon Feb 07 15:51:42 2005 +0000
     1.2 +++ b/xen/arch/x86/boot/x86_32.S	Mon Feb 07 16:00:00 2005 +0000
     1.3 @@ -214,7 +214,7 @@ ENTRY(gdt_table)
     1.4          .org 0x1000
     1.5  ENTRY(idle_pg_table) # Initial page directory is 4kB
     1.6          .org 0x2000
     1.7 -ENTRY(cpu0_stack)    # Initial stack is 8kB
     1.8 -        .org 0x4000
     1.9 +ENTRY(cpu0_stack)
    1.10 +        .org 0x2000 + STACK_SIZE
    1.11  ENTRY(stext)
    1.12  ENTRY(_stext)
     2.1 --- a/xen/arch/x86/boot/x86_64.S	Mon Feb 07 15:51:42 2005 +0000
     2.2 +++ b/xen/arch/x86/boot/x86_64.S	Mon Feb 07 16:00:00 2005 +0000
     2.3 @@ -243,8 +243,8 @@ ENTRY(idle_pg_table_l2)
     2.4          identmap /* Too orangey for crows :-) */
     2.5  
     2.6          .org 0x4000
     2.7 -ENTRY(cpu0_stack)    # Initial stack is 8kB
     2.8 +ENTRY(cpu0_stack)
     2.9  
    2.10 -        .org 0x6000
    2.11 +        .org 0x4000 + STACK_SIZE
    2.12  ENTRY(stext)
    2.13  ENTRY(_stext)
     3.1 --- a/xen/arch/x86/setup.c	Mon Feb 07 15:51:42 2005 +0000
     3.2 +++ b/xen/arch/x86/setup.c	Mon Feb 07 16:00:00 2005 +0000
     3.3 @@ -298,19 +298,21 @@ void __init identify_cpu(struct cpuinfo_
     3.4  unsigned long cpu_initialized;
     3.5  void __init cpu_init(void)
     3.6  {
     3.7 -    extern void percpu_traps_init(void);
     3.8      int nr = smp_processor_id();
     3.9      struct tss_struct *t = &init_tss[nr];
    3.10 +    unsigned char idt_load[10];
    3.11  
    3.12      if ( test_and_set_bit(nr, &cpu_initialized) )
    3.13          panic("CPU#%d already initialized!!!\n", nr);
    3.14      printk("Initializing CPU#%d\n", nr);
    3.15  
    3.16 -    /* Set up GDT and IDT. */
    3.17      SET_GDT_ENTRIES(current, DEFAULT_GDT_ENTRIES);
    3.18      SET_GDT_ADDRESS(current, DEFAULT_GDT_ADDRESS);
    3.19      __asm__ __volatile__ ( "lgdt %0" : "=m" (*current->arch.gdt) );
    3.20 -    __asm__ __volatile__ ( "lidt %0" : "=m" (idt_descr) );
    3.21 +
    3.22 +    *(unsigned short *)(&idt_load[0]) = (IDT_ENTRIES*sizeof(idt_entry_t))-1;
    3.23 +    *(unsigned long  *)(&idt_load[2]) = (unsigned long)idt_tables[nr];
    3.24 +    __asm__ __volatile__ ( "lidt %0" : "=m" (idt_load) );
    3.25  
    3.26      /* No nested task. */
    3.27      __asm__ __volatile__ ( "pushf ; andw $0xbfff,(%"__OP"sp) ; popf" );
    3.28 @@ -336,8 +338,6 @@ void __init cpu_init(void)
    3.29      CD(0); CD(1); CD(2); CD(3); /* no db4 and db5 */; CD(6); CD(7);
    3.30  #undef CD
    3.31  
    3.32 -    percpu_traps_init();
    3.33 -
    3.34      /* Install correct page table. */
    3.35      write_ptbase(current);
    3.36  
     4.1 --- a/xen/arch/x86/smpboot.c	Mon Feb 07 15:51:42 2005 +0000
     4.2 +++ b/xen/arch/x86/smpboot.c	Mon Feb 07 16:00:00 2005 +0000
     4.3 @@ -388,33 +388,27 @@ static int cpucount;
     4.4  void __init start_secondary(void)
     4.5  {
     4.6      unsigned int cpu = cpucount;
     4.7 -    /* 6 bytes suitable for passing to LIDT instruction. */
     4.8 -    unsigned char idt_load[6];
     4.9  
    4.10 +    extern void percpu_traps_init(void);
    4.11      extern void cpu_init(void);
    4.12  
    4.13      set_current(idle_task[cpu]);
    4.14  
    4.15      /*
    4.16 -     * Dont put anything before smp_callin(), SMP
    4.17 -     * booting is too fragile that we want to limit the
    4.18 -     * things done here to the most necessary things.
    4.19 -     */
    4.20 -    cpu_init();
    4.21 -    smp_callin();
    4.22 -
    4.23 -    while (!atomic_read(&smp_commenced))
    4.24 -        rep_nop();
    4.25 -
    4.26 -    /*
    4.27       * At this point, boot CPU has fully initialised the IDT. It is
    4.28       * now safe to make ourselves a private copy.
    4.29       */
    4.30      idt_tables[cpu] = xmalloc_array(idt_entry_t, IDT_ENTRIES);
    4.31      memcpy(idt_tables[cpu], idt_table, IDT_ENTRIES*sizeof(idt_entry_t));
    4.32 -    *(unsigned short *)(&idt_load[0]) = (IDT_ENTRIES*sizeof(idt_entry_t))-1;
    4.33 -    *(unsigned long  *)(&idt_load[2]) = (unsigned long)idt_tables[cpu];
    4.34 -    __asm__ __volatile__ ( "lidt %0" : "=m" (idt_load) );
    4.35 +
    4.36 +    percpu_traps_init();
    4.37 +
    4.38 +    cpu_init();
    4.39 +
    4.40 +    smp_callin();
    4.41 +
    4.42 +    while (!atomic_read(&smp_commenced))
    4.43 +        rep_nop();
    4.44  
    4.45      /*
    4.46       * low-memory mappings have been cleared, flush them from the local TLBs 
     5.1 --- a/xen/arch/x86/traps.c	Mon Feb 07 15:51:42 2005 +0000
     5.2 +++ b/xen/arch/x86/traps.c	Mon Feb 07 16:00:00 2005 +0000
     5.3 @@ -553,19 +553,55 @@ asmlinkage int do_general_protection(str
     5.4      return 0;
     5.5  }
     5.6  
     5.7 +unsigned long nmi_softirq_reason;
     5.8 +static void nmi_softirq(void)
     5.9 +{
    5.10 +    if ( dom0 == NULL )
    5.11 +        return;
    5.12 +
    5.13 +    if ( test_and_clear_bit(0, &nmi_softirq_reason) )
    5.14 +        send_guest_virq(dom0->exec_domain[0], VIRQ_PARITY_ERR);
    5.15 +
    5.16 +    if ( test_and_clear_bit(1, &nmi_softirq_reason) )
    5.17 +        send_guest_virq(dom0->exec_domain[0], VIRQ_IO_ERR);
    5.18 +}
    5.19 +
    5.20  asmlinkage void mem_parity_error(struct xen_regs *regs)
    5.21  {
    5.22 -    console_force_unlock();
    5.23 -    printk("\n\nNMI - MEMORY ERROR\n");
    5.24 -    fatal_trap(TRAP_nmi, regs);
    5.25 +    /* Clear and disable the parity-error line. */
    5.26 +    outb((inb(0x61)&15)|4,0x61);
    5.27 +
    5.28 +    switch ( opt_nmi[0] )
    5.29 +    {
    5.30 +    case 'd': /* 'dom0' */
    5.31 +        set_bit(0, &nmi_softirq_reason);
    5.32 +        raise_softirq(NMI_SOFTIRQ);
    5.33 +    case 'i': /* 'ignore' */
    5.34 +        break;
    5.35 +    default:  /* 'fatal' */
    5.36 +        console_force_unlock();
    5.37 +        printk("\n\nNMI - MEMORY ERROR\n");
    5.38 +        fatal_trap(TRAP_nmi, regs);
    5.39 +    }
    5.40  }
    5.41  
    5.42  asmlinkage void io_check_error(struct xen_regs *regs)
    5.43  {
    5.44 -    console_force_unlock();
    5.45 +    /* Clear and disable the I/O-error line. */
    5.46 +    outb((inb(0x61)&15)|8,0x61);
    5.47  
    5.48 -    printk("\n\nNMI - I/O ERROR\n");
    5.49 -    fatal_trap(TRAP_nmi, regs);
    5.50 +    switch ( opt_nmi[0] )
    5.51 +    {
    5.52 +    case 'd': /* 'dom0' */
    5.53 +        set_bit(0, &nmi_softirq_reason);
    5.54 +        raise_softirq(NMI_SOFTIRQ);
    5.55 +    case 'i': /* 'ignore' */
    5.56 +        break;
    5.57 +    default:  /* 'fatal' */
    5.58 +        console_force_unlock();
    5.59 +        printk("\n\nNMI - I/O ERROR\n");
    5.60 +        fatal_trap(TRAP_nmi, regs);
    5.61 +    }
    5.62  }
    5.63  
    5.64  static void unknown_nmi_error(unsigned char reason)
    5.65 @@ -579,27 +615,17 @@ asmlinkage void do_nmi(struct xen_regs *
    5.66  {
    5.67      ++nmi_count(smp_processor_id());
    5.68  
    5.69 -#if CONFIG_X86_LOCAL_APIC
    5.70      if ( nmi_watchdog )
    5.71          nmi_watchdog_tick(regs);
    5.72 -    else
    5.73 -#endif
    5.74 +
    5.75 +    if ( reason & 0x80 )
    5.76 +        mem_parity_error(regs);
    5.77 +    else if ( reason & 0x40 )
    5.78 +        io_check_error(regs);
    5.79 +    else if ( !nmi_watchdog )
    5.80          unknown_nmi_error((unsigned char)(reason&0xff));
    5.81  }
    5.82  
    5.83 -unsigned long nmi_softirq_reason;
    5.84 -static void nmi_softirq(void)
    5.85 -{
    5.86 -    if ( dom0 == NULL )
    5.87 -        return;
    5.88 -
    5.89 -    if ( test_and_clear_bit(0, &nmi_softirq_reason) )
    5.90 -        send_guest_virq(dom0->exec_domain[0], VIRQ_PARITY_ERR);
    5.91 -
    5.92 -    if ( test_and_clear_bit(1, &nmi_softirq_reason) )
    5.93 -        send_guest_virq(dom0->exec_domain[0], VIRQ_IO_ERR);
    5.94 -}
    5.95 -
    5.96  asmlinkage int math_state_restore(struct xen_regs *regs)
    5.97  {
    5.98      /* Prevent recursion. */
    5.99 @@ -706,8 +732,8 @@ void set_tss_desc(unsigned int n, void *
   5.100  
   5.101  void __init trap_init(void)
   5.102  {
   5.103 -    extern void doublefault_init(void);
   5.104 -    doublefault_init();
   5.105 +    extern void percpu_traps_init(void);
   5.106 +    extern void cpu_init(void);
   5.107  
   5.108      /*
   5.109       * Note that interrupt gates are always used, rather than trap gates. We 
   5.110 @@ -745,13 +771,9 @@ void __init trap_init(void)
   5.111      /* CPU0 uses the master IDT. */
   5.112      idt_tables[0] = idt_table;
   5.113  
   5.114 -    /*
   5.115 -     * Should be a barrier for any external CPU state.
   5.116 -     */
   5.117 -    {
   5.118 -        extern void cpu_init(void);
   5.119 -        cpu_init();
   5.120 -    }
   5.121 +    percpu_traps_init();
   5.122 +
   5.123 +    cpu_init();
   5.124  
   5.125      open_softirq(NMI_SOFTIRQ, nmi_softirq);
   5.126  }
     6.1 --- a/xen/arch/x86/x86_32/entry.S	Mon Feb 07 15:51:42 2005 +0000
     6.2 +++ b/xen/arch/x86/x86_32/entry.S	Mon Feb 07 16:00:00 2005 +0000
     6.3 @@ -596,7 +596,7 @@ ENTRY(nmi)
     6.4          # Okay, its almost a normal NMI tick. We can only process it if:
     6.5          #  A. We are the outermost Xen activation (in which case we have
     6.6          #     the selectors safely saved on our stack)
     6.7 -        #  B. DS-GS all contain sane Xen values.
     6.8 +        #  B. DS and ES contain sane Xen values.
     6.9          # In all other cases we bail without touching DS-GS, as we have
    6.10          # interrupted an enclosing Xen activation in tricky prologue or
    6.11          # epilogue code.
    6.12 @@ -644,11 +644,11 @@ nmi_parity_err:
    6.13          orb  $0x4,%al
    6.14          outb %al,$0x61
    6.15          cmpb $'i',%ss:SYMBOL_NAME(opt_nmi) # nmi=ignore
    6.16 -        je   restore_all_xen
    6.17 +        je   nmi_out
    6.18          bts  $0,%ss:SYMBOL_NAME(nmi_softirq_reason)
    6.19          bts  $NMI_SOFTIRQ,%ss:SYMBOL_NAME(irq_stat)
    6.20          cmpb $'d',%ss:SYMBOL_NAME(opt_nmi) # nmi=dom0
    6.21 -        je   restore_all_xen
    6.22 +        je   nmi_out
    6.23          movl $(__HYPERVISOR_DS),%edx       # nmi=fatal
    6.24          movl %edx,%ds
    6.25          movl %edx,%es
    6.26 @@ -656,7 +656,15 @@ nmi_parity_err:
    6.27          push %edx
    6.28          call SYMBOL_NAME(mem_parity_error)
    6.29          addl $4,%esp
    6.30 -        jmp  ret_from_intr
    6.31 +nmi_out:movl  %ss:XREGS_eflags(%esp),%eax
    6.32 +        movb  %ss:XREGS_cs(%esp),%al
    6.33 +        testl $(3|X86_EFLAGS_VM),%eax
    6.34 +	jz    restore_all_xen
    6.35 +        movl  $(__HYPERVISOR_DS),%edx
    6.36 +        movl  %edx,%ds
    6.37 +        movl  %edx,%es
    6.38 +        GET_CURRENT(%ebx)
    6.39 +        jmp   test_all_events
    6.40                  
    6.41  nmi_io_err: 
    6.42          # Clear and disable the I/O-error line
    6.43 @@ -664,11 +672,11 @@ nmi_io_err:
    6.44          orb  $0x8,%al
    6.45          outb %al,$0x61
    6.46          cmpb $'i',%ss:SYMBOL_NAME(opt_nmi) # nmi=ignore
    6.47 -        je   restore_all_xen
    6.48 +        je   nmi_out
    6.49          bts  $1,%ss:SYMBOL_NAME(nmi_softirq_reason)
    6.50          bts  $NMI_SOFTIRQ,%ss:SYMBOL_NAME(irq_stat)
    6.51          cmpb $'d',%ss:SYMBOL_NAME(opt_nmi) # nmi=dom0
    6.52 -        je   restore_all_xen
    6.53 +        je   nmi_out
    6.54          movl $(__HYPERVISOR_DS),%edx       # nmi=fatal
    6.55          movl %edx,%ds
    6.56          movl %edx,%es
    6.57 @@ -676,7 +684,7 @@ nmi_io_err:
    6.58          push %edx
    6.59          call SYMBOL_NAME(io_check_error)                        
    6.60          addl $4,%esp
    6.61 -        jmp  ret_from_intr
    6.62 +        jmp  nmi_out
    6.63  
    6.64  
    6.65  ENTRY(setup_vm86_frame)
     7.1 --- a/xen/arch/x86/x86_32/traps.c	Mon Feb 07 15:51:42 2005 +0000
     7.2 +++ b/xen/arch/x86/x86_32/traps.c	Mon Feb 07 16:00:00 2005 +0000
     7.3 @@ -175,34 +175,33 @@ asmlinkage void do_double_fault(void)
     7.4          __asm__ __volatile__ ( "hlt" );
     7.5  }
     7.6  
     7.7 -void __init doublefault_init(void)
     7.8 +void __init percpu_traps_init(void)
     7.9  {
    7.10 -    /*
    7.11 -     * Make a separate task for double faults. This will get us debug output if
    7.12 -     * we blow the kernel stack.
    7.13 -     */
    7.14 -    struct tss_struct *tss = &doublefault_tss;
    7.15 -    memset(tss, 0, sizeof(*tss));
    7.16 -    tss->ds     = __HYPERVISOR_DS;
    7.17 -    tss->es     = __HYPERVISOR_DS;
    7.18 -    tss->ss     = __HYPERVISOR_DS;
    7.19 -    tss->esp    = (unsigned long)
    7.20 -        &doublefault_stack[DOUBLEFAULT_STACK_SIZE];
    7.21 -    tss->__cr3  = __pa(idle_pg_table);
    7.22 -    tss->cs     = __HYPERVISOR_CS;
    7.23 -    tss->eip    = (unsigned long)do_double_fault;
    7.24 -    tss->eflags = 2;
    7.25 -    tss->bitmap = IOBMP_INVALID_OFFSET;
    7.26 -    _set_tssldt_desc(gdt_table+__DOUBLEFAULT_TSS_ENTRY,
    7.27 -                     (unsigned long)tss, 235, 9);
    7.28 +    if ( smp_processor_id() == 0 )
    7.29 +    {
    7.30 +        /*
    7.31 +         * Make a separate task for double faults. This will get us debug
    7.32 +         * output if we blow the kernel stack.
    7.33 +         */
    7.34 +        struct tss_struct *tss = &doublefault_tss;
    7.35 +        memset(tss, 0, sizeof(*tss));
    7.36 +        tss->ds     = __HYPERVISOR_DS;
    7.37 +        tss->es     = __HYPERVISOR_DS;
    7.38 +        tss->ss     = __HYPERVISOR_DS;
    7.39 +        tss->esp    = (unsigned long)
    7.40 +            &doublefault_stack[DOUBLEFAULT_STACK_SIZE];
    7.41 +        tss->__cr3  = __pa(idle_pg_table);
    7.42 +        tss->cs     = __HYPERVISOR_CS;
    7.43 +        tss->eip    = (unsigned long)do_double_fault;
    7.44 +        tss->eflags = 2;
    7.45 +        tss->bitmap = IOBMP_INVALID_OFFSET;
    7.46 +        _set_tssldt_desc(gdt_table+__DOUBLEFAULT_TSS_ENTRY,
    7.47 +                         (unsigned long)tss, 235, 9);
    7.48 +    }
    7.49  
    7.50      set_task_gate(TRAP_double_fault, __DOUBLEFAULT_TSS_ENTRY<<3);
    7.51  }
    7.52  
    7.53 -void __init percpu_traps_init(void)
    7.54 -{
    7.55 -}
    7.56 -
    7.57  long set_fast_trap(struct exec_domain *p, int idx)
    7.58  {
    7.59      trap_info_t *ti;
     8.1 --- a/xen/arch/x86/x86_64/entry.S	Mon Feb 07 15:51:42 2005 +0000
     8.2 +++ b/xen/arch/x86/x86_64/entry.S	Mon Feb 07 16:00:00 2005 +0000
     8.3 @@ -12,9 +12,9 @@
     8.4  #include <public/xen.h>
     8.5  
     8.6  ENTRY(hypercall)
     8.7 -        movl  $0x0833,8(%rsp)
     8.8 +        movl  $__GUEST_SS,8(%rsp)
     8.9          pushq %r11
    8.10 -        pushq $0x082b
    8.11 +        pushq $__GUEST_CS
    8.12          pushq %rcx
    8.13          pushq $0
    8.14          SAVE_ALL
    8.15 @@ -133,7 +133,13 @@ ENTRY(double_fault)
    8.16          jmp   error_code
    8.17  
    8.18  ENTRY(nmi)
    8.19 -        iretq
    8.20 +        pushq $0
    8.21 +        SAVE_ALL
    8.22 +        inb   $0x61,%al
    8.23 +        movl  %eax,%esi # reason
    8.24 +        movl  %esp,%edi # regs
    8.25 +        call  SYMBOL_NAME(do_nmi)
    8.26 +	jmp   restore_all_xen
    8.27  
    8.28  .data
    8.29  
     9.1 --- a/xen/arch/x86/x86_64/traps.c	Mon Feb 07 15:51:42 2005 +0000
     9.2 +++ b/xen/arch/x86/x86_64/traps.c	Mon Feb 07 16:00:00 2005 +0000
     9.3 @@ -129,10 +129,7 @@ void show_page_walk(unsigned long addr)
     9.4      printk("    L1 = %p\n", page);
     9.5  }
     9.6  
     9.7 -#define DOUBLEFAULT_STACK_SIZE 1024
     9.8 -static unsigned char doublefault_stack[DOUBLEFAULT_STACK_SIZE];
     9.9  asmlinkage void double_fault(void);
    9.10 -
    9.11  asmlinkage void do_double_fault(struct xen_regs *regs)
    9.12  {
    9.13      /* Disable the NMI watchdog. It's useless now. */
    9.14 @@ -142,19 +139,9 @@ asmlinkage void do_double_fault(struct x
    9.15  
    9.16      /* Find information saved during fault and dump it to the console. */
    9.17      printk("************************************\n");
    9.18 -    printk("EIP:    %04lx:[<%p>]      \nEFLAGS: %p\n",
    9.19 -           0xffff & regs->cs, regs->rip, regs->eflags);
    9.20 -    printk("rax: %p   rbx: %p   rcx: %p   rdx: %p\n",
    9.21 -           regs->rax, regs->rbx, regs->rcx, regs->rdx);
    9.22 -    printk("rsi: %p   rdi: %p   rbp: %p   rsp: %p\n",
    9.23 -           regs->rsi, regs->rdi, regs->rbp, regs->rsp);
    9.24 -    printk("r8:  %p   r9:  %p   r10: %p   r11: %p\n",
    9.25 -           regs->r8,  regs->r9,  regs->r10, regs->r11);
    9.26 -    printk("r12: %p   r13: %p   r14: %p   r15: %p\n",
    9.27 -           regs->r12, regs->r13, regs->r14, regs->r15);
    9.28 +    show_registers(regs);
    9.29      printk("************************************\n");
    9.30 -    printk("CPU%d DOUBLE FAULT -- system shutdown\n",
    9.31 -           logical_smp_processor_id());
    9.32 +    printk("CPU%d DOUBLE FAULT -- system shutdown\n", smp_processor_id());
    9.33      printk("System needs manual reset.\n");
    9.34      printk("************************************\n");
    9.35  
    9.36 @@ -166,25 +153,29 @@ asmlinkage void do_double_fault(struct x
    9.37          __asm__ __volatile__ ( "hlt" );
    9.38  }
    9.39  
    9.40 -void __init doublefault_init(void)
    9.41 -{
    9.42 -    int i;
    9.43 -
    9.44 -    /* Initialise IST1 for each CPU. Note the handler is non-reentrant. */
    9.45 -    for ( i = 0; i < NR_CPUS; i++ )
    9.46 -        init_tss[i].ist[0] = (unsigned long)
    9.47 -            &doublefault_stack[DOUBLEFAULT_STACK_SIZE];
    9.48 -
    9.49 -    /* Set interrupt gate for double faults, specifying IST1. */
    9.50 -    set_intr_gate(TRAP_double_fault, &double_fault);
    9.51 -    idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */
    9.52 -}
    9.53 -
    9.54  asmlinkage void hypercall(void);
    9.55  void __init percpu_traps_init(void)
    9.56  {
    9.57      char *stack_top = (char *)get_stack_top();
    9.58      char *stack     = (char *)((unsigned long)stack_top & ~(STACK_SIZE - 1));
    9.59 +    int   cpu       = smp_processor_id();
    9.60 +
    9.61 +    /* Double-fault handler has its own per-CPU 1kB stack. */
    9.62 +    init_tss[cpu].ist[0] = (unsigned long)&stack[1024];
    9.63 +    set_intr_gate(TRAP_double_fault, &double_fault);
    9.64 +    idt_tables[cpu][TRAP_double_fault].a |= 1UL << 32; /* IST1 */
    9.65 +
    9.66 +    /* NMI handler has its own per-CPU 1kB stack. */
    9.67 +    init_tss[cpu].ist[1] = (unsigned long)&stack[2048];
    9.68 +    idt_tables[cpu][TRAP_nmi].a          |= 2UL << 32; /* IST2 */
    9.69 +
    9.70 +    /*
    9.71 +     * Trampoline for SYSCALL entry from long mode.
    9.72 +     */
    9.73 +
    9.74 +    /* Skip the NMI and DF stacks. */
    9.75 +    stack = &stack[2048];
    9.76 +    wrmsr(MSR_LSTAR, (unsigned long)stack, ((unsigned long)stack>>32)); 
    9.77  
    9.78      /* movq %rsp, saversp(%rip) */
    9.79      stack[0] = 0x48;
    9.80 @@ -202,9 +193,36 @@ void __init percpu_traps_init(void)
    9.81      stack[14] = 0xe9;
    9.82      *(u32 *)&stack[15] = (char *)hypercall - &stack[19];
    9.83  
    9.84 +    /*
    9.85 +     * Trampoline for SYSCALL entry from compatibility mode.
    9.86 +     */
    9.87 +
    9.88 +    /* Skip the long-mode entry trampoline. */
    9.89 +    stack = &stack[19];
    9.90 +    wrmsr(MSR_CSTAR, (unsigned long)stack, ((unsigned long)stack>>32)); 
    9.91 +
    9.92 +    /* movq %rsp, saversp(%rip) */
    9.93 +    stack[0] = 0x48;
    9.94 +    stack[1] = 0x89;
    9.95 +    stack[2] = 0x25;
    9.96 +    *(u32 *)&stack[3] = (stack_top - &stack[7]) - 16;
    9.97 +
    9.98 +    /* leaq saversp(%rip), %rsp */
    9.99 +    stack[7] = 0x48;
   9.100 +    stack[8] = 0x8d;
   9.101 +    stack[9] = 0x25;
   9.102 +    *(u32 *)&stack[10] = (stack_top - &stack[14]) - 16;
   9.103 +
   9.104 +    /* jmp hypercall */
   9.105 +    stack[14] = 0xe9;
   9.106 +    *(u32 *)&stack[15] = (char *)hypercall - &stack[19];
   9.107 +
   9.108 +    /*
   9.109 +     * Common SYSCALL parameters.
   9.110 +     */
   9.111 +
   9.112      wrmsr(MSR_STAR,  0, (FLAT_RING3_CS64<<16) | __HYPERVISOR_CS); 
   9.113 -    wrmsr(MSR_LSTAR, (unsigned long)stack, ((unsigned long)stack>>32)); 
   9.114 -    wrmsr(MSR_SYSCALL_MASK, 0xFFFFFFFFU, 0U);
   9.115 +    wrmsr(MSR_SYSCALL_MASK, ~EF_IE, 0U); /* disable interrupts */
   9.116  }
   9.117  
   9.118  void *decode_reg(struct xen_regs *regs, u8 b)
    10.1 --- a/xen/include/asm-x86/config.h	Mon Feb 07 15:51:42 2005 +0000
    10.2 +++ b/xen/include/asm-x86/config.h	Mon Feb 07 16:00:00 2005 +0000
    10.3 @@ -191,6 +191,10 @@ extern void __out_of_line_bug(int line) 
    10.4  #define __HYPERVISOR_DS32 0x0818
    10.5  #define __HYPERVISOR_DS   __HYPERVISOR_DS64
    10.6  
    10.7 +#define __GUEST_CS        0x082b
    10.8 +#define __GUEST_DS        0x0000
    10.9 +#define __GUEST_SS        0x0833
   10.10 +
   10.11  /* For generic assembly code: use macros to define operation/operand sizes. */
   10.12  #define __OS "q"  /* Operation Suffix */
   10.13  #define __OP "r"  /* Operand Prefix */