From 73e2418107dd10274464a3938a87997e827fe29d Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 23 Mar 2010 15:27:40 -0700 Subject: [PATCH] vkernel64 - Add missing bits from later kernel work in the main tree * Add missing virtual kernel intercept in 64-bit real kernel trap.c code. * Add td_ucred caching to userenter() in vkernel64 trap.c code. * Set PG_RW, PG_U, PG_V in pcb_cr3. It is unclear whether these are necessary. * Remove debugging. --- sys/platform/pc64/x86_64/pmap.c | 1 + sys/platform/pc64/x86_64/trap.c | 10 ++++++++ sys/platform/vkernel64/x86_64/exception.c | 2 +- sys/platform/vkernel64/x86_64/trap.c | 29 +++++++++++++++++------ 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/sys/platform/pc64/x86_64/pmap.c b/sys/platform/pc64/x86_64/pmap.c index cd343dbfb7..7c45c0d6ce 100644 --- a/sys/platform/pc64/x86_64/pmap.c +++ b/sys/platform/pc64/x86_64/pmap.c @@ -3764,6 +3764,7 @@ pmap_setlwpvm(struct lwp *lp, struct vmspace *newvm) tlb_flush_count++; #endif curthread->td_pcb->pcb_cr3 = vtophys(pmap->pm_pml4); + curthread->td_pcb->pcb_cr3 |= PG_RW | PG_U | PG_V; load_cr3(curthread->td_pcb->pcb_cr3); pmap = vmspace_pmap(oldvm); #if defined(SMP) diff --git a/sys/platform/pc64/x86_64/trap.c b/sys/platform/pc64/x86_64/trap.c index ecdcdd9582..b394da5852 100644 --- a/sys/platform/pc64/x86_64/trap.c +++ b/sys/platform/pc64/x86_64/trap.c @@ -747,6 +747,16 @@ trap(struct trapframe *frame) } MAKEMPSAFE(have_mplock); trap_fatal(frame, 0); + goto out2; + } + + /* + * Virtual kernel intercept - if the fault is directly related to a + * VM context managed by a virtual kernel then let the virtual kernel + * handle it. + */ + if (lp->lwp_vkernel && lp->lwp_vkernel->ve) { + vkernel_trap(lp, frame); goto out; } diff --git a/sys/platform/vkernel64/x86_64/exception.c b/sys/platform/vkernel64/x86_64/exception.c index 28afac21c6..6236a2effa 100644 --- a/sys/platform/vkernel64/x86_64/exception.c +++ b/sys/platform/vkernel64/x86_64/exception.c @@ -181,7 +181,7 @@ exc_segfault(int signo, siginfo_t *info, void *ctxp) { ucontext_t *ctx = ctxp; -#if 1 +#if 0 kprintf("CAUGHT SIG %d RIP %08lx ERR %08lx TRAPNO %ld " "err %ld addr %08lx\n", signo, diff --git a/sys/platform/vkernel64/x86_64/trap.c b/sys/platform/vkernel64/x86_64/trap.c index 431daa54d7..ff8ae75f91 100644 --- a/sys/platform/vkernel64/x86_64/trap.c +++ b/sys/platform/vkernel64/x86_64/trap.c @@ -184,15 +184,30 @@ MALLOC_DEFINE(M_SYSMSG, "sysmsg", "sysmsg structure"); extern int max_sysmsg; /* - * userenter() passively intercepts the thread switch function to increase - * the thread priority from a user priority to a kernel priority, reducing + * Passively intercepts the thread switch function to increase the thread + * priority from a user priority to a kernel priority, reducing * syscall and trap overhead for the case where no switch occurs. + * + * Synchronizes td_ucred with p_ucred. This is used by system calls, + * signal handling, faults, AST traps, and anything else that enters the + * kernel from userland and provides the kernel with a stable read-only + * copy of the process ucred. */ - static __inline void -userenter(struct thread *curtd) +userenter(struct thread *curtd, struct proc *curp) { + struct ucred *ocred; + struct ucred *ncred; + curtd->td_release = lwkt_passive_release; + + if (curtd->td_ucred != curp->p_ucred) { + ncred = crhold(curp->p_ucred); + ocred = curtd->td_ucred; + curtd->td_ucred = ncred; + if (ocred) + crfree(ocred); + } } /* @@ -419,7 +434,7 @@ restart: type = frame->tf_trapno; code = frame->tf_err; - userenter(td); + userenter(td, p); sticks = (int)td->td_sticks; lp->lwp_md.md_regs = frame; @@ -1148,7 +1163,7 @@ syscall2(struct trapframe *frame) if (syscall_mpsafe == 0) MAKEMPSAFE(have_mplock); #endif - userenter(td); /* lazy raise our priority */ + userenter(td, p); /* lazy raise our priority */ reg = 0; regcnt = 6; @@ -1387,7 +1402,7 @@ generic_lwp_return(struct lwp *lp, struct trapframe *frame) * released when the thread goes to sleep. */ lwkt_setpri_self(TDPRI_USER_NORM); - userenter(lp->lwp_thread); + userenter(lp->lwp_thread, p); userret(lp, frame, 0); #ifdef KTRACE if (KTRPOINT(lp->lwp_thread, KTR_SYSRET)) -- 2.41.0