ia64/xen-unstable

changeset 3052:7a5f9d08bfa1

bitkeeper revision 1.1159.180.2 (419dc71eHwyXT3BVHFdxBKRp1BPxFw)

Add return codes to exception handlers to indicate if a fault was fixed
up and so instruction replay ought to work.
author kaf24@scramble.cl.cam.ac.uk
date Fri Nov 19 10:12:46 2004 +0000 (2004-11-19)
parents ef0abb9f8b5d
children c74e9fdfcab7
files xen/arch/x86/memory.c xen/arch/x86/shadow.c xen/arch/x86/traps.c xen/include/asm-x86/debugger.h xen/include/asm-x86/processor.h
line diff
     1.1 --- a/xen/arch/x86/memory.c	Fri Nov 19 09:20:24 2004 +0000
     1.2 +++ b/xen/arch/x86/memory.c	Fri Nov 19 10:12:46 2004 +0000
     1.3 @@ -1809,8 +1809,7 @@ int ptwr_do_page_fault(unsigned long add
     1.4          domain_crash();
     1.5      }
     1.6      
     1.7 -    /* Maybe fall through to shadow mode to propagate writable L1. */
     1.8 -    return !current->mm.shadow_mode;
     1.9 +    return EXCRET_fault_fixed;
    1.10  }
    1.11  
    1.12  static __init int ptwr_init(void)
     2.1 --- a/xen/arch/x86/shadow.c	Fri Nov 19 09:20:24 2004 +0000
     2.2 +++ b/xen/arch/x86/shadow.c	Fri Nov 19 10:12:46 2004 +0000
     2.3 @@ -636,7 +636,7 @@ int shadow_fault(unsigned long va, long 
     2.4      shadow_unlock(m);
     2.5  
     2.6      check_pagetable(m, current->mm.pagetable, "post-sf");
     2.7 -    return 1;
     2.8 +    return EXCRET_fault_fixed;
     2.9  }
    2.10  
    2.11  
     3.1 --- a/xen/arch/x86/traps.c	Fri Nov 19 09:20:24 2004 +0000
     3.2 +++ b/xen/arch/x86/traps.c	Fri Nov 19 10:12:46 2004 +0000
     3.3 @@ -228,7 +228,7 @@ asmlinkage void fatal_trap(int trapnr, s
     3.4          __asm__ __volatile__ ( "hlt" );
     3.5  }
     3.6  
     3.7 -static inline void do_trap(int trapnr, char *str,
     3.8 +static inline int do_trap(int trapnr, char *str,
     3.9                             struct xen_regs *regs, 
    3.10                             long error_code, int use_error_code)
    3.11  {
    3.12 @@ -249,7 +249,7 @@ static inline void do_trap(int trapnr, c
    3.13      tb->eip        = ti->address;
    3.14      if ( TI_GET_IF(ti) )
    3.15          d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
    3.16 -    return; 
    3.17 +    return 0;
    3.18  
    3.19   xen_fault:
    3.20  
    3.21 @@ -257,7 +257,7 @@ static inline void do_trap(int trapnr, c
    3.22      {
    3.23          DPRINTK("Trap %d: %08lx -> %08lx\n", trapnr, regs->eip, fixup);
    3.24          regs->eip = fixup;
    3.25 -        return;
    3.26 +        return 0;
    3.27      }
    3.28  
    3.29      DEBUGGER_trap_fatal(trapnr, regs, error_code);
    3.30 @@ -266,18 +266,19 @@ static inline void do_trap(int trapnr, c
    3.31      panic("CPU%d FATAL TRAP: vector = %d (%s)\n"
    3.32            "[error_code=%08x]\n",
    3.33            smp_processor_id(), trapnr, str, error_code);
    3.34 +    return 0;
    3.35  }
    3.36  
    3.37  #define DO_ERROR_NOCODE(trapnr, str, name) \
    3.38 -asmlinkage void do_##name(struct xen_regs * regs, long error_code) \
    3.39 +asmlinkage int do_##name(struct xen_regs * regs, long error_code) \
    3.40  { \
    3.41 -    do_trap(trapnr, str, regs, error_code, 0); \
    3.42 +    return do_trap(trapnr, str, regs, error_code, 0); \
    3.43  }
    3.44  
    3.45  #define DO_ERROR(trapnr, str, name) \
    3.46 -asmlinkage void do_##name(struct xen_regs * regs, long error_code) \
    3.47 +asmlinkage int do_##name(struct xen_regs * regs, long error_code) \
    3.48  { \
    3.49 -    do_trap(trapnr, str, regs, error_code, 1); \
    3.50 +    return do_trap(trapnr, str, regs, error_code, 1); \
    3.51  }
    3.52  
    3.53  DO_ERROR_NOCODE( 0, "divide error", divide_error)
    3.54 @@ -292,7 +293,7 @@ DO_ERROR_NOCODE(16, "fpu error", coproce
    3.55  DO_ERROR(17, "alignment check", alignment_check)
    3.56  DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error)
    3.57  
    3.58 -asmlinkage void do_int3(struct xen_regs *regs, long error_code)
    3.59 +asmlinkage int do_int3(struct xen_regs *regs, long error_code)
    3.60  {
    3.61      struct domain *d = current;
    3.62      struct trap_bounce *tb = &d->thread.trap_bounce;
    3.63 @@ -316,6 +317,8 @@ asmlinkage void do_int3(struct xen_regs 
    3.64      tb->eip        = ti->address;
    3.65      if ( TI_GET_IF(ti) )
    3.66          d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
    3.67 +
    3.68 +    return 0;
    3.69  }
    3.70  
    3.71  asmlinkage void do_double_fault(void)
    3.72 @@ -355,7 +358,7 @@ asmlinkage void do_machine_check(struct 
    3.73      fatal_trap(TRAP_machine_check, regs, error_code);
    3.74  }
    3.75  
    3.76 -asmlinkage void do_page_fault(struct xen_regs *regs, long error_code)
    3.77 +asmlinkage int do_page_fault(struct xen_regs *regs, long error_code)
    3.78  {
    3.79      trap_info_t *ti;
    3.80      unsigned long off, addr, fixup;
    3.81 @@ -377,18 +380,22 @@ asmlinkage void do_page_fault(struct xen
    3.82                        ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l2_idx) )
    3.83          {
    3.84              ptwr_flush(PTWR_PT_ACTIVE);
    3.85 -            return;
    3.86 +            return EXCRET_fault_fixed;
    3.87          }
    3.88  
    3.89          if ( (addr < PAGE_OFFSET) &&
    3.90               ((error_code & 3) == 3) && /* write-protection fault */
    3.91               ptwr_do_page_fault(addr) )
    3.92 -            return;
    3.93 +        {
    3.94 +            if ( unlikely(d->mm.shadow_mode) )
    3.95 +                (void)shadow_fault(addr, error_code);
    3.96 +            return EXCRET_fault_fixed;
    3.97 +        }
    3.98      }
    3.99  
   3.100      if ( unlikely(d->mm.shadow_mode) && 
   3.101           (addr < PAGE_OFFSET) && shadow_fault(addr, error_code) )
   3.102 -        return; /* Returns TRUE if fault was handled. */
   3.103 +        return EXCRET_fault_fixed;
   3.104  
   3.105      if ( unlikely(addr >= LDT_VIRT_START) && 
   3.106           (addr < (LDT_VIRT_START + (d->mm.ldt_ents*LDT_ENTRY_SIZE))) )
   3.107 @@ -400,7 +407,7 @@ asmlinkage void do_page_fault(struct xen
   3.108          off  = addr - LDT_VIRT_START;
   3.109          addr = d->mm.ldt_base + off;
   3.110          if ( likely(map_ldt_shadow_page(off >> PAGE_SHIFT)) )
   3.111 -            return; /* successfully copied the mapping */
   3.112 +            return EXCRET_fault_fixed; /* successfully copied the mapping */
   3.113      }
   3.114  
   3.115      if ( unlikely(!(regs->cs & 3)) )
   3.116 @@ -414,7 +421,7 @@ asmlinkage void do_page_fault(struct xen
   3.117      tb->eip        = ti->address;
   3.118      if ( TI_GET_IF(ti) )
   3.119          d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
   3.120 -    return; 
   3.121 +    return 0; 
   3.122  
   3.123   xen_fault:
   3.124  
   3.125 @@ -424,7 +431,7 @@ asmlinkage void do_page_fault(struct xen
   3.126          if ( !d->mm.shadow_mode )
   3.127              DPRINTK("Page fault: %08lx -> %08lx\n", regs->eip, fixup);
   3.128          regs->eip = fixup;
   3.129 -        return;
   3.130 +        return 0;
   3.131      }
   3.132  
   3.133      DEBUGGER_trap_fatal(TRAP_page_fault, regs, error_code);
   3.134 @@ -451,9 +458,10 @@ asmlinkage void do_page_fault(struct xen
   3.135            "[error_code=%08x]\n"
   3.136            "Faulting linear address might be %08lx\n",
   3.137            smp_processor_id(), error_code, addr);
   3.138 +    return 0;
   3.139  }
   3.140  
   3.141 -asmlinkage void do_general_protection(struct xen_regs *regs, long error_code)
   3.142 +asmlinkage int do_general_protection(struct xen_regs *regs, long error_code)
   3.143  {
   3.144      struct domain *d = current;
   3.145      struct trap_bounce *tb = &d->thread.trap_bounce;
   3.146 @@ -502,7 +510,7 @@ asmlinkage void do_general_protection(st
   3.147      if ( VM_ASSIST(d, VMASST_TYPE_4gb_segments) && 
   3.148           (error_code == 0) && 
   3.149           gpf_emulate_4gb(regs) )
   3.150 -        return;
   3.151 +        return 0;
   3.152  #endif
   3.153  
   3.154      /* Pass on GPF as is. */
   3.155 @@ -514,7 +522,7 @@ asmlinkage void do_general_protection(st
   3.156      tb->eip        = ti->address;
   3.157      if ( TI_GET_IF(ti) )
   3.158          d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
   3.159 -    return;
   3.160 +    return 0;
   3.161  
   3.162   gp_in_kernel:
   3.163  
   3.164 @@ -522,7 +530,7 @@ asmlinkage void do_general_protection(st
   3.165      {
   3.166          DPRINTK("GPF (%04lx): %08lx -> %08lx\n", error_code, regs->eip, fixup);
   3.167          regs->eip = fixup;
   3.168 -        return;
   3.169 +        return 0;
   3.170      }
   3.171  
   3.172      DEBUGGER_trap_fatal(TRAP_gp_fault, regs, error_code);
   3.173 @@ -530,6 +538,7 @@ asmlinkage void do_general_protection(st
   3.174      show_registers(regs);
   3.175      panic("CPU%d GENERAL PROTECTION FAULT\n"
   3.176            "[error_code=%08x]\n", smp_processor_id(), error_code);
   3.177 +    return 0;
   3.178  }
   3.179  
   3.180  asmlinkage void mem_parity_error(struct xen_regs *regs)
   3.181 @@ -549,8 +558,6 @@ asmlinkage void io_check_error(struct xe
   3.182  
   3.183  static void unknown_nmi_error(unsigned char reason, struct xen_regs * regs)
   3.184  {
   3.185 -    DEBUGGER_trap_entry(TRAP_nmi, regs, 0);
   3.186 -
   3.187      printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
   3.188      printk("Dazed and confused, but trying to continue\n");
   3.189      printk("Do you have a strange power saving mode enabled?\n");
   3.190 @@ -581,7 +588,7 @@ static void nmi_softirq(void)
   3.191          send_guest_virq(dom0, VIRQ_IO_ERR);
   3.192  }
   3.193  
   3.194 -asmlinkage void math_state_restore(struct xen_regs *regs, long error_code)
   3.195 +asmlinkage int math_state_restore(struct xen_regs *regs, long error_code)
   3.196  {
   3.197      /* Prevent recursion. */
   3.198      clts();
   3.199 @@ -602,9 +609,11 @@ asmlinkage void math_state_restore(struc
   3.200          tb->cs         = current->thread.traps[7].cs;
   3.201          tb->eip        = current->thread.traps[7].address;
   3.202      }
   3.203 +
   3.204 +    return EXCRET_fault_fixed;
   3.205  }
   3.206  
   3.207 -asmlinkage void do_debug(struct xen_regs *regs, long error_code)
   3.208 +asmlinkage int do_debug(struct xen_regs *regs, long error_code)
   3.209  {
   3.210      unsigned int condition;
   3.211      struct domain *d = current;
   3.212 @@ -619,7 +628,7 @@ asmlinkage void do_debug(struct xen_regs
   3.213           (d->thread.debugreg[7] == 0) )
   3.214      {
   3.215          __asm__("movl %0,%%db7" : : "r" (0));
   3.216 -        return;
   3.217 +        goto out;
   3.218      }
   3.219  
   3.220      if ( (regs->cs & 3) == 0 )
   3.221 @@ -632,7 +641,7 @@ asmlinkage void do_debug(struct xen_regs
   3.222           * on it. No need to bump EIP; the only faulting trap is an instruction
   3.223           * breakpoint, which can't happen to us.
   3.224           */
   3.225 -        return;
   3.226 +        goto out;
   3.227      }
   3.228  
   3.229      /* Save debug status register where guest OS can peek at it */
   3.230 @@ -641,13 +650,16 @@ asmlinkage void do_debug(struct xen_regs
   3.231      tb->flags = TBF_TRAP_NOCODE;
   3.232      tb->cs    = d->thread.traps[1].cs;
   3.233      tb->eip   = d->thread.traps[1].address;
   3.234 +
   3.235 + out:
   3.236 +    return EXCRET_not_a_fault;
   3.237  }
   3.238  
   3.239 -
   3.240 -asmlinkage void do_spurious_interrupt_bug(struct xen_regs * regs,
   3.241 -                                          long error_code)
   3.242 -{ /* nothing */ }
   3.243 -
   3.244 +asmlinkage int do_spurious_interrupt_bug(
   3.245 +    struct xen_regs * regs, long error_code)
   3.246 +{
   3.247 +    return EXCRET_not_a_fault;
   3.248 +}
   3.249  
   3.250  #define _set_gate(gate_addr,type,dpl,addr) \
   3.251  do { \
     4.1 --- a/xen/include/asm-x86/debugger.h	Fri Nov 19 09:20:24 2004 +0000
     4.2 +++ b/xen/include/asm-x86/debugger.h	Fri Nov 19 10:12:46 2004 +0000
     4.3 @@ -22,33 +22,13 @@
     4.4  #ifndef __X86_DEBUGGER_H__
     4.5  #define __X86_DEBUGGER_H__
     4.6  
     4.7 -/* Avoid magic vector numbers by using these semi-sensical names. */
     4.8 -#define TRAP_divide_error     0
     4.9 -#define TRAP_debug            1
    4.10 -#define TRAP_nmi              2
    4.11 -#define TRAP_int3             3
    4.12 -#define TRAP_overflow         4
    4.13 -#define TRAP_bounds           5
    4.14 -#define TRAP_invalid_op       6
    4.15 -#define TRAP_no_device        7
    4.16 -#define TRAP_double_fault     8
    4.17 -#define TRAP_copro_seg        9
    4.18 -#define TRAP_invalid_tss     10
    4.19 -#define TRAP_no_segment      11
    4.20 -#define TRAP_stack_error     12
    4.21 -#define TRAP_gp_fault        13
    4.22 -#define TRAP_page_fault      14
    4.23 -#define TRAP_spurious_int    15
    4.24 -#define TRAP_copro_error     16
    4.25 -#define TRAP_alignment_check 17
    4.26 -#define TRAP_machine_check   18
    4.27 -#define TRAP_simd_error      19
    4.28 +#include <asm/processor.h>
    4.29  
    4.30  /* The main trap handlers use these helper macros which include early bail. */
    4.31  #define DEBUGGER_trap_entry(_v, _r, _e) \
    4.32 -    if ( debugger_trap_entry(_v, _r, _e) ) return;
    4.33 +    if ( debugger_trap_entry(_v, _r, _e) ) return EXCRET_fault_fixed;
    4.34  #define DEBUGGER_trap_fatal(_v, _r, _e) \
    4.35 -    if ( debugger_trap_fatal(_v, _r, _e) ) return;
    4.36 +    if ( debugger_trap_fatal(_v, _r, _e) ) return EXCRET_fault_fixed;
    4.37  
    4.38  #ifdef XEN_DEBUGGER
    4.39  
     5.1 --- a/xen/include/asm-x86/processor.h	Fri Nov 19 09:20:24 2004 +0000
     5.2 +++ b/xen/include/asm-x86/processor.h	Fri Nov 19 10:12:46 2004 +0000
     5.3 @@ -85,6 +85,39 @@
     5.4  #define X86_CR4_OSXMMEXCPT	0x0400	/* enable unmasked SSE exceptions */
     5.5  
     5.6  /*
     5.7 + * Trap/fault mnemonics.
     5.8 + */
     5.9 +#define TRAP_divide_error     0
    5.10 +#define TRAP_debug            1
    5.11 +#define TRAP_nmi              2
    5.12 +#define TRAP_int3             3
    5.13 +#define TRAP_overflow         4
    5.14 +#define TRAP_bounds           5
    5.15 +#define TRAP_invalid_op       6
    5.16 +#define TRAP_no_device        7
    5.17 +#define TRAP_double_fault     8
    5.18 +#define TRAP_copro_seg        9
    5.19 +#define TRAP_invalid_tss     10
    5.20 +#define TRAP_no_segment      11
    5.21 +#define TRAP_stack_error     12
    5.22 +#define TRAP_gp_fault        13
    5.23 +#define TRAP_page_fault      14
    5.24 +#define TRAP_spurious_int    15
    5.25 +#define TRAP_copro_error     16
    5.26 +#define TRAP_alignment_check 17
    5.27 +#define TRAP_machine_check   18
    5.28 +#define TRAP_simd_error      19
    5.29 +
    5.30 +/*
    5.31 + * Non-fatal fault/trap handlers return an error code to the caller. If the
    5.32 + * code is non-zero, it means that either the exception was not due to a fault
    5.33 + * (i.e., it was a trap) or that the fault has been fixed up so the instruction
    5.34 + * replay ought to succeed.
    5.35 + */
    5.36 +#define EXCRET_not_a_fault 1 /* It was a trap. No instruction replay needed. */
    5.37 +#define EXCRET_fault_fixed 1 /* It was fault that we fixed: try a replay. */
    5.38 +
    5.39 +/*
    5.40   * 'trap_bounce' flags values.
    5.41   */
    5.42  #define TBF_TRAP        1