From owner-p4-projects@FreeBSD.ORG Mon May 12 02:22:27 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3B1DE37B408; Mon, 12 May 2003 02:22:26 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D0B3E37B407 for ; Mon, 12 May 2003 02:22:25 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 480C443FE1 for ; Mon, 12 May 2003 02:22:25 -0700 (PDT) (envelope-from peter@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h4C9MO0U076701 for ; Mon, 12 May 2003 02:22:24 -0700 (PDT) (envelope-from peter@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h4C9MOAT076698 for perforce@freebsd.org; Mon, 12 May 2003 02:22:24 -0700 (PDT) Date: Mon, 12 May 2003 02:22:24 -0700 (PDT) Message-Id: <200305120922.h4C9MOAT076698@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to peter@freebsd.org using -f From: Peter Wemm To: Perforce Change Reviews Subject: PERFORCE change 31003 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 May 2003 09:22:27 -0000 http://perforce.freebsd.org/chv.cgi?CH=31003 Change 31003 by peter@peter_hammer on 2003/05/12 02:21:50 create tf_addr in trapframe to store the fault address. This avoids having to run the page fault handler with interrupts disabled for so long. Adjust exception.S to enable this. Affected files ... .. //depot/projects/hammer/sys/amd64/amd64/exception.S#8 edit .. //depot/projects/hammer/sys/amd64/amd64/genassym.c#10 edit .. //depot/projects/hammer/sys/amd64/amd64/machdep.c#26 edit .. //depot/projects/hammer/sys/amd64/amd64/trap.c#12 edit .. //depot/projects/hammer/sys/amd64/include/frame.h#6 edit .. //depot/projects/hammer/sys/amd64/include/ucontext.h#6 edit Differences ... ==== //depot/projects/hammer/sys/amd64/amd64/exception.S#8 (text+ko) ==== @@ -74,50 +74,63 @@ */ #define IDTVEC(name) ALIGN_TEXT; .globl __CONCAT(X,name); \ .type __CONCAT(X,name),@function; __CONCAT(X,name): -#define TRAP(a) pushq $(a) ; jmp alltraps -#define TRAP_NOEN(a) pushq $(a) ; jmp alltraps_noen MCOUNT_LABEL(user) MCOUNT_LABEL(btrap) +/* Traps that we leave interrupts disabled for.. */ +#define TRAP_NOEN(a) \ + subq $TF_RIP,%rsp; \ + movq $(a),TF_TRAPNO(%rsp) ; \ + jmp alltraps_noen +IDTVEC(dbg) + TRAP_NOEN(T_TRCTRAP) +IDTVEC(bpt) + TRAP_NOEN(T_BPTFLT) + +/* Regular traps */ +#define TRAP(a) \ + subq $TF_RIP,%rsp; \ + movq $(a),TF_TRAPNO(%rsp) ; \ + jmp alltraps IDTVEC(div) - pushq $0; TRAP(T_DIVIDE) -IDTVEC(dbg) - pushq $0; TRAP_NOEN(T_TRCTRAP) + TRAP(T_DIVIDE) IDTVEC(nmi) - pushq $0; TRAP(T_NMI) -IDTVEC(bpt) - pushq $0; TRAP_NOEN(T_BPTFLT) + TRAP(T_NMI) IDTVEC(ofl) - pushq $0; TRAP(T_OFLOW) + TRAP(T_OFLOW) IDTVEC(bnd) - pushq $0; TRAP(T_BOUND) + TRAP(T_BOUND) IDTVEC(ill) - pushq $0; TRAP(T_PRIVINFLT) + TRAP(T_PRIVINFLT) IDTVEC(dna) - pushq $0; TRAP(T_DNA) + TRAP(T_DNA) IDTVEC(fpusegm) - pushq $0; TRAP(T_FPOPFLT) + TRAP(T_FPOPFLT) +IDTVEC(mchk) + TRAP(T_MCHK) +IDTVEC(rsvd) + TRAP(T_RESERVED) +IDTVEC(fpu) + TRAP(T_ARITHTRAP) +IDTVEC(xmm) + TRAP(T_XMMFLT) + +/* This group of traps have tf_err already pushed by the cpu */ +#define TRAP_ERR(a) \ + subq $TF_ERR,%rsp; \ + movq $(a),TF_TRAPNO(%rsp) ; \ + jmp alltraps_noen IDTVEC(tss) - TRAP(T_TSSFLT) + TRAP_ERR(T_TSSFLT) IDTVEC(missing) - TRAP(T_SEGNPFLT) + TRAP_ERR(T_SEGNPFLT) IDTVEC(stk) - TRAP(T_STKFLT) + TRAP_ERR(T_STKFLT) IDTVEC(prot) - TRAP(T_PROTFLT) -IDTVEC(page) - TRAP_NOEN(T_PAGEFLT) -IDTVEC(mchk) - pushq $0; TRAP(T_MCHK) -IDTVEC(rsvd) - pushq $0; TRAP(T_RESERVED) -IDTVEC(fpu) - pushq $0; TRAP(T_ARITHTRAP) + TRAP_ERR(T_PROTFLT) IDTVEC(align) - TRAP(T_ALIGNFLT) -IDTVEC(xmm) - pushq $0; TRAP(T_XMMFLT) + TRAP_ERR(T_ALIGNFLT) /* * alltraps entry point. Use swapgs if this is the first time in the @@ -129,7 +142,6 @@ .globl alltraps .type alltraps,@function alltraps: - subq $TF_TRAPNO,%rsp /* tf_err and tf_trapno already pushed */ testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */ jz alltraps_testi /* already running with kernel GS.base */ swapgs @@ -139,6 +151,7 @@ sti alltraps_pushregs: movq %rdi,TF_RDI(%rsp) +alltraps_pushregs_no_rdi: movq %rsi,TF_RSI(%rsp) movq %rdx,TF_RDX(%rsp) movq %rcx,TF_RCX(%rsp) @@ -170,15 +183,14 @@ .globl alltraps_noen .type alltraps_noen,@function alltraps_noen: - subq $TF_TRAPNO,%rsp /* tf_err and tf_trapno already pushed */ testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */ jz alltraps_pushregs /* already running with kernel GS.base */ swapgs jmp alltraps_pushregs IDTVEC(dblfault) - pushq $T_DOUBLEFLT - subq $TF_TRAPNO,%rsp /* tf_err and tf_trapno already pushed */ + subq $TF_ERR,%rsp + movq $T_DOUBLEFLT,TF_TRAPNO(%rsp) testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */ jz 1f /* already running with kernel GS.base */ swapgs @@ -186,6 +198,20 @@ 2: hlt jmp 2b +IDTVEC(page) + subq $TF_ERR,%rsp + movq $T_PAGEFLT,TF_TRAPNO(%rsp) + testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */ + jz 1f /* already running with kernel GS.base */ + swapgs +1: movq %rdi,TF_RDI(%rsp) + movq %cr2,%rdi + movq %rdi,TF_ADDR(%rsp) + testl $PSL_I,TF_RFLAGS(%rsp) + jz alltraps_pushregs_no_rdi + sti + jmp alltraps_pushregs_no_rdi + /* * Call gate entry for FreeBSD ELF and Linux/NetBSD syscall (int 0x80) * ==== //depot/projects/hammer/sys/amd64/amd64/genassym.c#10 (text+ko) ==== @@ -152,6 +152,7 @@ ASSYM(TF_RCX, offsetof(struct trapframe, tf_rcx)); ASSYM(TF_RAX, offsetof(struct trapframe, tf_rax)); ASSYM(TF_TRAPNO, offsetof(struct trapframe, tf_trapno)); +ASSYM(TF_ADDR, offsetof(struct trapframe, tf_addr)); ASSYM(TF_ERR, offsetof(struct trapframe, tf_err)); ASSYM(TF_RIP, offsetof(struct trapframe, tf_rip)); ASSYM(TF_CS, offsetof(struct trapframe, tf_cs)); ==== //depot/projects/hammer/sys/amd64/amd64/machdep.c#26 (text+ko) ==== @@ -245,7 +245,7 @@ sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK) ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; - bcopy(regs, &sf.sf_uc.uc_mcontext.mc_r15, sizeof(*regs)); + bcopy(regs, &sf.sf_uc.uc_mcontext.mc_rdi, sizeof(*regs)); sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); /* magic */ get_fpcontext(td, &sf.sf_uc.uc_mcontext); fpstate_drop(td); @@ -280,11 +280,11 @@ /* Fill in POSIX parts */ sf.sf_si.si_signo = sig; sf.sf_si.si_code = code; - regs->tf_rcx = regs->tf_err; /* arg 4 in %rcx */ + regs->tf_rcx = regs->tf_addr; /* arg 4 in %rcx */ } else { /* Old FreeBSD-style arguments. */ regs->tf_rsi = code; /* arg 2 in %rsi */ - regs->tf_rcx = regs->tf_err; /* arg 4 in %rcx */ + regs->tf_rcx = regs->tf_addr; /* arg 4 in %rcx */ sf.sf_ahu.sf_handler = catcher; } PROC_UNLOCK(p); @@ -371,7 +371,7 @@ ret = set_fpcontext(td, &ucp->uc_mcontext); if (ret != 0) return (ret); - bcopy(&ucp->uc_mcontext.mc_r15, regs, sizeof(*regs)); + bcopy(&ucp->uc_mcontext.mc_rdi, regs, sizeof(*regs)); PROC_LOCK(p); #if defined(COMPAT_43) || defined(COMPAT_SUNOS) ==== //depot/projects/hammer/sys/amd64/amd64/trap.c#12 (text+ko) ==== @@ -168,7 +168,7 @@ #ifdef DDB if (db_active) { - eva = (type == T_PAGEFLT ? rcr2() : 0); + eva = (type == T_PAGEFLT ? frame.tf_addr : 0); trap_fatal(&frame, eva); goto out; } @@ -194,11 +194,10 @@ printf("kernel trap %d with interrupts disabled\n", type); /* - * Page faults need interrupts diasabled until later, - * and we shouldn't enable interrupts while holding a + * We shouldn't enable interrupts while holding a * spin lock. */ - if (type != T_PAGEFLT && PCPU_GET(spinlocks) == NULL) + if (PCPU_GET(spinlocks) == NULL) enable_intr(); } } @@ -213,17 +212,9 @@ * do the VM lookup, so just consider it a fatal trap so the * kernel can print out a useful trap message and even get * to the debugger. - * - * Note that T_PAGEFLT is registered as an interrupt gate. This - * is just like a trap gate, except interrupts are disabled. This - * happens to be critically important, because we could otherwise - * preempt and run another process that may cause %cr2 to be - * clobbered for something else. */ - eva = rcr2(); - if (PCPU_GET(spinlocks) == NULL) - enable_intr(); - else + eva = frame.tf_addr; + if (PCPU_GET(spinlocks) != NULL) trap_fatal(&frame, eva); } @@ -454,7 +445,7 @@ uprintf("fatal process exception: %s", trap_msg[type]); if ((type == T_PAGEFLT) || (type == T_PROTFLT)) - uprintf(", fault VA = 0x%lx", (u_long)eva); + uprintf(", fault VA = 0x%lx", eva); uprintf("\n"); } #endif @@ -556,8 +547,6 @@ frame->tf_err & PGEX_W ? "write" : "read", frame->tf_err & PGEX_P ? "protection violation" : "page not present", (void *)eva, (void *)frame->tf_rip, (void *)frame->tf_rax, (void *)frame->tf_rbx, (void *)frame->tf_rcx, (void *)frame->tf_rdx, (void *)frame->tf_rsp, (void *)frame->tf_rbp, (void *)frame->tf_rsi, (void *)frame->tf_rdi); - /* kludge to pass faulting virtual address to sendsig */ - frame->tf_err = eva; return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV); } ==== //depot/projects/hammer/sys/amd64/include/frame.h#6 (text+ko) ==== @@ -68,6 +68,7 @@ register_t tf_r14; register_t tf_r15; register_t tf_trapno; + register_t tf_addr; /* below portion defined in hardware */ register_t tf_err; register_t tf_rip; @@ -96,6 +97,7 @@ register_t if_r14; register_t if_r15; register_t :64; /* compat with trap frame - trapno */ + register_t :64; /* compat with trap frame - addr */ register_t :64; /* compat with trap frame - err */ /* below portion defined in hardware */ register_t if_rip; @@ -124,6 +126,7 @@ register_t cf_r14; register_t cf_r15; register_t :64; /* compat with trap frame - trapno */ + register_t :64; /* compat with trap frame - addr */ register_t :64; /* compat with trap frame - err */ /* below portion defined in hardware */ register_t cf_rip; ==== //depot/projects/hammer/sys/amd64/include/ucontext.h#6 (text+ko) ==== @@ -38,22 +38,24 @@ * and ucontext_t at the same time. */ register_t mc_onstack; /* XXX - sigcontext compat. */ - register_t mc_r15; /* machine state (struct trapframe) */ - register_t mc_r14; - register_t mc_r13; - register_t mc_r12; - register_t mc_r11; - register_t mc_r10; - register_t mc_r9; - register_t mc_r8; - register_t mc_rdi; + + register_t mc_rdi; /* machine state (struct trapframe) */ register_t mc_rsi; - register_t mc_rbp; - register_t mc_rbx; register_t mc_rdx; register_t mc_rcx; + register_t mc_r8; + register_t mc_r9; register_t mc_rax; + register_t mc_rbx; + register_t mc_rbp; + register_t mc_r10; + register_t mc_r11; + register_t mc_r12; + register_t mc_r13; + register_t mc_r14; + register_t mc_r15; register_t mc_trapno; + register_t mc_addr; register_t mc_err; register_t mc_rip; register_t mc_cs;