trap.c (114952) | trap.c (114987) |
---|---|
1/*- 2 * Copyright (C) 1994, David Greenman 3 * Copyright (c) 1990, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the University of Utah, and William Jolitz. 8 * --- 21 unchanged lines hidden (view full) --- 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 | 1/*- 2 * Copyright (C) 1994, David Greenman 3 * Copyright (c) 1990, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the University of Utah, and William Jolitz. 8 * --- 21 unchanged lines hidden (view full) --- 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 |
38 * $FreeBSD: head/sys/amd64/amd64/trap.c 114952 2003-05-12 18:33:19Z peter $ | 38 * $FreeBSD: head/sys/amd64/amd64/trap.c 114987 2003-05-14 04:10:49Z peter $ |
39 */ 40 41/* 42 * 386 Trap and System call handling 43 */ 44 45#include "opt_clock.h" 46#include "opt_cpu.h" --- 39 unchanged lines hidden (view full) --- 86 87#include <ddb/ddb.h> 88 89#include <sys/sysctl.h> 90 91extern void trap(struct trapframe frame); 92extern void syscall(struct trapframe frame); 93 | 39 */ 40 41/* 42 * 386 Trap and System call handling 43 */ 44 45#include "opt_clock.h" 46#include "opt_cpu.h" --- 39 unchanged lines hidden (view full) --- 86 87#include <ddb/ddb.h> 88 89#include <sys/sysctl.h> 90 91extern void trap(struct trapframe frame); 92extern void syscall(struct trapframe frame); 93 |
94static int trap_pfault(struct trapframe *, int, vm_offset_t); | 94static int trap_pfault(struct trapframe *, int); |
95static void trap_fatal(struct trapframe *, vm_offset_t); 96void dblfault_handler(void); 97 98#define MAX_TRAP_MSG 28 99static char *trap_msg[] = { 100 "", /* 0 unused */ 101 "privileged instruction fault", /* 1 T_PRIVINFLT */ 102 "", /* 2 unused */ --- 53 unchanged lines hidden (view full) --- 156void 157trap(frame) 158 struct trapframe frame; 159{ 160 struct thread *td = curthread; 161 struct proc *p = td->td_proc; 162 u_int sticks = 0; 163 int i = 0, ucode = 0, type, code; | 95static void trap_fatal(struct trapframe *, vm_offset_t); 96void dblfault_handler(void); 97 98#define MAX_TRAP_MSG 28 99static char *trap_msg[] = { 100 "", /* 0 unused */ 101 "privileged instruction fault", /* 1 T_PRIVINFLT */ 102 "", /* 2 unused */ --- 53 unchanged lines hidden (view full) --- 156void 157trap(frame) 158 struct trapframe frame; 159{ 160 struct thread *td = curthread; 161 struct proc *p = td->td_proc; 162 u_int sticks = 0; 163 int i = 0, ucode = 0, type, code; |
164 vm_offset_t eva; | |
165 166 atomic_add_int(&cnt.v_trap, 1); 167 type = frame.tf_trapno; 168 169#ifdef DDB 170 if (db_active) { | 164 165 atomic_add_int(&cnt.v_trap, 1); 166 type = frame.tf_trapno; 167 168#ifdef DDB 169 if (db_active) { |
170 vm_offset_t eva; |
|
171 eva = (type == T_PAGEFLT ? frame.tf_addr : 0); 172 trap_fatal(&frame, eva); 173 goto out; 174 } 175#endif 176 177 if ((frame.tf_rflags & PSL_I) == 0) { 178 /* --- 18 unchanged lines hidden (view full) --- 197 * We shouldn't enable interrupts while holding a 198 * spin lock. 199 */ 200 if (PCPU_GET(spinlocks) == NULL) 201 enable_intr(); 202 } 203 } 204 | 171 eva = (type == T_PAGEFLT ? frame.tf_addr : 0); 172 trap_fatal(&frame, eva); 173 goto out; 174 } 175#endif 176 177 if ((frame.tf_rflags & PSL_I) == 0) { 178 /* --- 18 unchanged lines hidden (view full) --- 197 * We shouldn't enable interrupts while holding a 198 * spin lock. 199 */ 200 if (PCPU_GET(spinlocks) == NULL) 201 enable_intr(); 202 } 203 } 204 |
205 eva = 0; | |
206 code = frame.tf_err; 207 if (type == T_PAGEFLT) { 208 /* 209 * If we get a page fault while holding a spin lock, then 210 * it is most likely a fatal kernel page fault. The kernel 211 * is already going to panic trying to get a sleep lock to 212 * do the VM lookup, so just consider it a fatal trap so the 213 * kernel can print out a useful trap message and even get 214 * to the debugger. 215 */ | 205 code = frame.tf_err; 206 if (type == T_PAGEFLT) { 207 /* 208 * If we get a page fault while holding a spin lock, then 209 * it is most likely a fatal kernel page fault. The kernel 210 * is already going to panic trying to get a sleep lock to 211 * do the VM lookup, so just consider it a fatal trap so the 212 * kernel can print out a useful trap message and even get 213 * to the debugger. 214 */ |
216 eva = frame.tf_addr; | |
217 if (PCPU_GET(spinlocks) != NULL) | 215 if (PCPU_GET(spinlocks) != NULL) |
218 trap_fatal(&frame, eva); | 216 trap_fatal(&frame, frame.tf_addr); |
219 } 220 221#ifdef DEVICE_POLLING 222 if (poll_in_trap) 223 ether_poll(poll_in_trap); 224#endif /* DEVICE_POLLING */ 225 226 if (ISPL(frame.tf_cs) == SEL_UPL) { --- 29 unchanged lines hidden (view full) --- 256 case T_TSSFLT: /* invalid TSS fault */ 257 case T_DOUBLEFLT: /* double fault */ 258 default: 259 ucode = code + BUS_SEGM_FAULT ; 260 i = SIGBUS; 261 break; 262 263 case T_PAGEFLT: /* page fault */ | 217 } 218 219#ifdef DEVICE_POLLING 220 if (poll_in_trap) 221 ether_poll(poll_in_trap); 222#endif /* DEVICE_POLLING */ 223 224 if (ISPL(frame.tf_cs) == SEL_UPL) { --- 29 unchanged lines hidden (view full) --- 254 case T_TSSFLT: /* invalid TSS fault */ 255 case T_DOUBLEFLT: /* double fault */ 256 default: 257 ucode = code + BUS_SEGM_FAULT ; 258 i = SIGBUS; 259 break; 260 261 case T_PAGEFLT: /* page fault */ |
264 i = trap_pfault(&frame, TRUE, eva); | 262 i = trap_pfault(&frame, TRUE); |
265 if (i == -1) 266 goto userout; 267 if (i == 0) 268 goto user; 269 270 ucode = T_PAGEFLT; 271 break; 272 --- 53 unchanged lines hidden (view full) --- 326 } 327 } else { 328 /* kernel trap */ 329 330 KASSERT(cold || td->td_ucred != NULL, 331 ("kernel trap doesn't have ucred")); 332 switch (type) { 333 case T_PAGEFLT: /* page fault */ | 263 if (i == -1) 264 goto userout; 265 if (i == 0) 266 goto user; 267 268 ucode = T_PAGEFLT; 269 break; 270 --- 53 unchanged lines hidden (view full) --- 324 } 325 } else { 326 /* kernel trap */ 327 328 KASSERT(cold || td->td_ucred != NULL, 329 ("kernel trap doesn't have ucred")); 330 switch (type) { 331 case T_PAGEFLT: /* page fault */ |
334 (void) trap_pfault(&frame, FALSE, eva); | 332 (void) trap_pfault(&frame, FALSE); |
335 goto out; 336 337 case T_DNA: 338 /* 339 * The kernel is apparently using npx for copying. 340 * XXX this should be fatal unless the kernel has 341 * registered such use. 342 */ --- 82 unchanged lines hidden (view full) --- 425#endif /* DDB */ 426 goto out; 427 } else if (panic_on_nmi == 0) 428 goto out; 429 /* FALLTHROUGH */ 430#endif /* DEV_ISA */ 431 } 432 | 333 goto out; 334 335 case T_DNA: 336 /* 337 * The kernel is apparently using npx for copying. 338 * XXX this should be fatal unless the kernel has 339 * registered such use. 340 */ --- 82 unchanged lines hidden (view full) --- 423#endif /* DDB */ 424 goto out; 425 } else if (panic_on_nmi == 0) 426 goto out; 427 /* FALLTHROUGH */ 428#endif /* DEV_ISA */ 429 } 430 |
433 trap_fatal(&frame, eva); | 431 trap_fatal(&frame, 0); |
434 goto out; 435 } 436 437 /* Translate fault for emulators (e.g. Linux) */ 438 if (*p->p_sysent->sv_transtrap) 439 i = (*p->p_sysent->sv_transtrap)(i, type); 440 441 trapsignal(td, i, ucode); 442 443#ifdef DEBUG 444 if (type <= MAX_TRAP_MSG) { 445 uprintf("fatal process exception: %s", 446 trap_msg[type]); 447 if ((type == T_PAGEFLT) || (type == T_PROTFLT)) | 432 goto out; 433 } 434 435 /* Translate fault for emulators (e.g. Linux) */ 436 if (*p->p_sysent->sv_transtrap) 437 i = (*p->p_sysent->sv_transtrap)(i, type); 438 439 trapsignal(td, i, ucode); 440 441#ifdef DEBUG 442 if (type <= MAX_TRAP_MSG) { 443 uprintf("fatal process exception: %s", 444 trap_msg[type]); 445 if ((type == T_PAGEFLT) || (type == T_PROTFLT)) |
448 uprintf(", fault VA = 0x%lx", eva); | 446 uprintf(", fault VA = 0x%lx", frame.tf_addr); |
449 uprintf("\n"); 450 } 451#endif 452 453user: 454 userret(td, &frame, sticks); 455 mtx_assert(&Giant, MA_NOTOWNED); 456userout: 457#ifdef DIAGNOSTIC 458 cred_free_thread(td); 459#endif 460out: 461 return; 462} 463 464static int | 447 uprintf("\n"); 448 } 449#endif 450 451user: 452 userret(td, &frame, sticks); 453 mtx_assert(&Giant, MA_NOTOWNED); 454userout: 455#ifdef DIAGNOSTIC 456 cred_free_thread(td); 457#endif 458out: 459 return; 460} 461 462static int |
465trap_pfault(frame, usermode, eva) | 463trap_pfault(frame, usermode) |
466 struct trapframe *frame; 467 int usermode; | 464 struct trapframe *frame; 465 int usermode; |
468 vm_offset_t eva; | |
469{ 470 vm_offset_t va; 471 struct vmspace *vm = NULL; 472 vm_map_t map = 0; 473 int rv = 0; 474 vm_prot_t ftype; 475 struct thread *td = curthread; 476 struct proc *p = td->td_proc; | 466{ 467 vm_offset_t va; 468 struct vmspace *vm = NULL; 469 vm_map_t map = 0; 470 int rv = 0; 471 vm_prot_t ftype; 472 struct thread *td = curthread; 473 struct proc *p = td->td_proc; |
474 vm_offset_t eva = frame->tf_addr; |
|
477 478 va = trunc_page(eva); 479 if (va >= KERNBASE) { 480 /* 481 * Don't allow user-mode faults in kernel address space. 482 */ 483 if (usermode) 484 goto nogo; --- 323 unchanged lines hidden (view full) --- 808#ifdef DIAGNOSTIC 809 cred_free_thread(td); 810#endif 811 WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning", 812 (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"); 813 mtx_assert(&sched_lock, MA_NOTOWNED); 814 mtx_assert(&Giant, MA_NOTOWNED); 815} | 475 476 va = trunc_page(eva); 477 if (va >= KERNBASE) { 478 /* 479 * Don't allow user-mode faults in kernel address space. 480 */ 481 if (usermode) 482 goto nogo; --- 323 unchanged lines hidden (view full) --- 806#ifdef DIAGNOSTIC 807 cred_free_thread(td); 808#endif 809 WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning", 810 (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"); 811 mtx_assert(&sched_lock, MA_NOTOWNED); 812 mtx_assert(&Giant, MA_NOTOWNED); 813} |
816 | |