PERFORCE change 31003 for review
Peter Wemm
peter at FreeBSD.org
Mon May 12 02:22:27 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=31003
Change 31003 by peter at 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), at 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, at 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, at 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;
More information about the p4-projects
mailing list