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.
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