Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/i386/i386 - keep cr3 register and its copy in TSS s...



details:   https://anonhg.NetBSD.org/src/rev/627ebac0dbdc
branches:  trunk
changeset: 565564:627ebac0dbdc
user:      yamt <yamt%NetBSD.org@localhost>
date:      Mon Apr 12 13:17:46 2004 +0000

description:
- keep cr3 register and its copy in TSS synchronized.
  otherwise an interrupt vector using a task gate (ie. ddbipi) messes it up.
- defer LDTR loading as well as cr3.
- tweak comments to make three copies of switching code more synchronized.

diffstat:

 sys/arch/i386/i386/locore.S |  13 +++++++++----
 sys/arch/i386/i386/pmap.c   |  28 ++++++++++++++++++++--------
 2 files changed, 29 insertions(+), 12 deletions(-)

diffs (135 lines):

diff -r 49771032e231 -r 627ebac0dbdc sys/arch/i386/i386/locore.S
--- a/sys/arch/i386/i386/locore.S       Mon Apr 12 12:52:42 2004 +0000
+++ b/sys/arch/i386/i386/locore.S       Mon Apr 12 13:17:46 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore.S,v 1.25 2004/03/26 19:05:33 drochner Exp $     */
+/*     $NetBSD: locore.S,v 1.26 2004/04/12 13:17:46 yamt Exp $ */
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -1775,6 +1775,8 @@
        movl    PCB_EBP(%edi),%ebp
 
        /* Switch TSS. Reset "task busy" flag before loading. */
+       movl    %cr3,%eax
+       movl    %eax,PCB_CR3(%edi)
 #ifdef MULTIPROCESSOR
        movl    CPUVAR(GDT),%eax
 #else
@@ -1925,6 +1927,9 @@
        jnz     switch_restored
 #endif
 
+       /* Switch TSS. Reset "task busy" flag before loading. */
+       movl    %cr3,%eax
+       movl    %eax,PCB_CR3(%esi) /* XXX should be done by pmap_activate? */
 #ifdef MULTIPROCESSOR
        movl    CPUVAR(GDT),%eax
 #else  
@@ -1933,7 +1938,6 @@
 #endif
        movl    L_MD_TSS_SEL(%edi),%edx
 
-       /* Switch TSS. Reset "task busy" flag before loading. */
        andl    $~0x0200,4(%eax,%edx, 1)
        ltr     %dx
 
@@ -2078,7 +2082,9 @@
        movl    PCB_ESP(%esi),%esp
        movl    PCB_EBP(%esi),%ebp
 
-       /* Load TSS info. */
+       /* Switch TSS. Reset "task busy" flag before loading. */
+       movl    %cr3,%eax
+       movl    %eax,PCB_CR3(%esi)
 #ifdef MULTIPROCESSOR
        movl    CPUVAR(GDT),%eax
 #else  
@@ -2086,7 +2092,6 @@
        movl    _C_LABEL(gdt),%eax
 #endif
 
-       /* Switch TSS. */
        andl    $~0x0200,4-SEL_KPL(%eax,%edx,1)
        ltr     %dx
 
diff -r 49771032e231 -r 627ebac0dbdc sys/arch/i386/i386/pmap.c
--- a/sys/arch/i386/i386/pmap.c Mon Apr 12 12:52:42 2004 +0000
+++ b/sys/arch/i386/i386/pmap.c Mon Apr 12 13:17:46 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.171 2004/02/20 17:35:01 yamt Exp $  */
+/*     $NetBSD: pmap.c,v 1.172 2004/04/12 13:17:46 yamt Exp $  */
 
 /*
  *
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.171 2004/02/20 17:35:01 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.172 2004/04/12 13:17:46 yamt Exp $");
 
 #include "opt_cputype.h"
 #include "opt_user_ldt.h"
@@ -1939,12 +1939,11 @@
        struct lwp *l;
 {
        struct cpu_info *ci = curcpu();
-       struct pcb *pcb = &l->l_addr->u_pcb;
        struct pmap *pmap = vm_map_pmap(&l->l_proc->p_vmspace->vm_map);
 
-       pcb->pcb_ldt_sel = pmap->pm_ldt_sel;
-       pcb->pcb_cr3 = pmap->pm_pdirpa;
        if (l == ci->ci_curlwp) {
+               struct pcb *pcb;
+
                KASSERT(ci->ci_want_pmapload == 0);
                KASSERT(ci->ci_tlbstate != TLBSTATE_VALID);
 #ifdef KSTACK_CHECK_DR0
@@ -1967,6 +1966,9 @@
                        return;
                }
 
+               pcb = &l->l_addr->u_pcb;
+               pcb->pcb_ldt_sel = pmap->pm_ldt_sel;
+
                ci->ci_want_pmapload = 1;
        }
 }
@@ -2021,6 +2023,7 @@
        struct pmap *pmap;
        struct pmap *oldpmap;
        struct lwp *l;
+       struct pcb *pcb;
        int s;
 
        KASSERT(ci->ci_want_pmapload);
@@ -2031,8 +2034,10 @@
        KASSERT(pmap != pmap_kernel());
        oldpmap = ci->ci_pmap;
 
-       KASSERT(pmap->pm_ldt_sel == l->l_addr->u_pcb.pcb_ldt_sel);
-       lldt(pmap->pm_ldt_sel);
+       pcb = ci->ci_curpcb;
+       KASSERT(pcb == &l->l_addr->u_pcb);
+       /* loaded by pmap_activate */
+       KASSERT(pcb->pcb_ldt_sel == pmap->pm_ldt_sel);
 
        if (pmap == oldpmap) {
                if (!pmap_reactivate(pmap)) {
@@ -2071,7 +2076,14 @@
        ci->ci_pmap = pmap;
        ci->ci_tlbstate = TLBSTATE_VALID;
        splx(s);
-       lcr3(pmap->pm_pdirpa);
+
+       /*
+        * update tss and load corresponding registers.
+        */
+
+       lldt(pcb->pcb_ldt_sel);
+       pcb->pcb_cr3 = pmap->pm_pdirpa;
+       lcr3(pcb->pcb_cr3);
 
        ci->ci_want_pmapload = 0;
 



Home | Main Index | Thread Index | Old Index