Ok, are all the panics fixed now?
Tor Egge
Tor.Egge at cvsup.no.freebsd.org
Thu Aug 28 13:21:06 PDT 2003
>
> Hi,
> Forgive the naive question, but is this an easy issue to solve ?
> Or is it just scratching the surface of a larger more complex problem not
> easily resolved by a simple patch or two ?
I'm enclosed a patch that introduces PADDR2/PMAP2 which is to be used
by pmap_pte() (should not be called from interrupts on noncurrent
pmaps) while pmap_pte_quick() (should not be called without splvm()
protection) will use PADDR1/PMAP1.
The patch also backs out revision 1.250.2.20 of
src/sys/i386/i386/pmap.c.
- Tor Egge
-------------- next part --------------
Index: sys/i386/i386/mp_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/mp_machdep.c,v
retrieving revision 1.115.2.17
diff -u -r1.115.2.17 mp_machdep.c
--- sys/i386/i386/mp_machdep.c 9 Aug 2003 16:21:18 -0000 1.115.2.17
+++ sys/i386/i386/mp_machdep.c 28 Aug 2003 20:05:38 -0000
@@ -2133,13 +2133,14 @@
/* allocate and set up an idle stack data page */
stack = (char *)kmem_alloc(kernel_map, UPAGES*PAGE_SIZE);
for (i = 0; i < UPAGES; i++)
- SMPpt[pg + 5 + i] = (pt_entry_t)
+ SMPpt[pg + 6 + i] = (pt_entry_t)
(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack));
SMPpt[pg + 1] = 0; /* *prv_CMAP1 */
SMPpt[pg + 2] = 0; /* *prv_CMAP2 */
SMPpt[pg + 3] = 0; /* *prv_CMAP3 */
SMPpt[pg + 4] = 0; /* *prv_PMAP1 */
+ SMPpt[pg + 5] = 0; /* *prv_PMAP2 */
/* prime data page for it to use */
gd->gd_cpuid = x;
@@ -2148,10 +2149,12 @@
gd->gd_prv_CMAP2 = &SMPpt[pg + 2];
gd->gd_prv_CMAP3 = &SMPpt[pg + 3];
gd->gd_prv_PMAP1 = (pd_entry_t *)&SMPpt[pg + 4];
+ gd->gd_prv_PMAP2 = (pd_entry_t *)&SMPpt[pg + 5];
gd->gd_prv_CADDR1 = SMP_prvspace[x].CPAGE1;
gd->gd_prv_CADDR2 = SMP_prvspace[x].CPAGE2;
gd->gd_prv_CADDR3 = SMP_prvspace[x].CPAGE3;
gd->gd_prv_PADDR1 = (pt_entry_t *)SMP_prvspace[x].PPAGE1;
+ gd->gd_prv_PADDR2 = (pt_entry_t *)SMP_prvspace[x].PPAGE2;
/* setup a vector to our boot code */
*((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
@@ -2205,7 +2208,7 @@
/* Allocate and setup BSP idle stack */
stack = (char *)kmem_alloc(kernel_map, UPAGES * PAGE_SIZE);
for (i = 0; i < UPAGES; i++)
- SMPpt[5 + i] = (pt_entry_t)
+ SMPpt[6 + i] = (pt_entry_t)
(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack));
for (x = 0; x < NKPT; x++)
Index: sys/i386/i386/genassym.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/genassym.c,v
retrieving revision 1.86.2.4
diff -u -r1.86.2.4 genassym.c
--- sys/i386/i386/genassym.c 9 Aug 2003 16:21:17 -0000 1.86.2.4
+++ sys/i386/i386/genassym.c 28 Aug 2003 20:05:38 -0000
@@ -198,10 +198,12 @@
ASSYM(GD_PRV_CMAP2, offsetof(struct globaldata, gd_prv_CMAP2));
ASSYM(GD_PRV_CMAP3, offsetof(struct globaldata, gd_prv_CMAP3));
ASSYM(GD_PRV_PMAP1, offsetof(struct globaldata, gd_prv_PMAP1));
+ASSYM(GD_PRV_PMAP2, offsetof(struct globaldata, gd_prv_PMAP2));
ASSYM(GD_PRV_CADDR1, offsetof(struct globaldata, gd_prv_CADDR1));
ASSYM(GD_PRV_CADDR2, offsetof(struct globaldata, gd_prv_CADDR2));
ASSYM(GD_PRV_CADDR3, offsetof(struct globaldata, gd_prv_CADDR3));
ASSYM(GD_PRV_PADDR1, offsetof(struct globaldata, gd_prv_PADDR1));
+ASSYM(GD_PRV_PADDR2, offsetof(struct globaldata, gd_prv_PADDR2));
ASSYM(PS_IDLESTACK, offsetof(struct privatespace, idlestack));
ASSYM(PS_IDLESTACK_TOP, sizeof(struct privatespace));
#endif
Index: sys/i386/i386/globals.s
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/Attic/globals.s,v
retrieving revision 1.13.2.1
diff -u -r1.13.2.1 globals.s
--- sys/i386/i386/globals.s 16 May 2000 06:58:06 -0000 1.13.2.1
+++ sys/i386/i386/globals.s 28 Aug 2003 20:05:38 -0000
@@ -109,7 +109,9 @@
.globl gd_cpuid, gd_cpu_lockid, gd_other_cpus
.globl gd_ss_eflags, gd_inside_intr
.globl gd_prv_CMAP1, gd_prv_CMAP2, gd_prv_CMAP3, gd_prv_PMAP1
+ .globl gd_prv_PMAP2
.globl gd_prv_CADDR1, gd_prv_CADDR2, gd_prv_CADDR3, gd_prv_PADDR1
+ .globl gd_prv_PADDR2
.set gd_cpuid,globaldata + GD_CPUID
.set gd_cpu_lockid,globaldata + GD_CPU_LOCKID
@@ -120,10 +122,12 @@
.set gd_prv_CMAP2,globaldata + GD_PRV_CMAP2
.set gd_prv_CMAP3,globaldata + GD_PRV_CMAP3
.set gd_prv_PMAP1,globaldata + GD_PRV_PMAP1
+ .set gd_prv_PMAP2,globaldata + GD_PRV_PMAP2
.set gd_prv_CADDR1,globaldata + GD_PRV_CADDR1
.set gd_prv_CADDR2,globaldata + GD_PRV_CADDR2
.set gd_prv_CADDR3,globaldata + GD_PRV_CADDR3
.set gd_prv_PADDR1,globaldata + GD_PRV_PADDR1
+ .set gd_prv_PADDR2,globaldata + GD_PRV_PADDR2
#endif
#if defined(SMP) || defined(APIC_IO)
Index: sys/i386/i386/pmap.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/pmap.c,v
retrieving revision 1.250.2.20
diff -u -r1.250.2.20 pmap.c
--- sys/i386/i386/pmap.c 26 Aug 2003 05:35:00 -0000 1.250.2.20
+++ sys/i386/i386/pmap.c 28 Aug 2003 20:05:38 -0000
@@ -114,6 +114,8 @@
#include <sys/mman.h>
#include <sys/malloc.h>
+#include <machine/cpu.h>
+#include <machine/ipl.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <sys/sysctl.h>
@@ -215,15 +217,19 @@
#define CMAP2 prv_CMAP2
#define CMAP3 prv_CMAP3
#define PMAP1 prv_PMAP1
+#define PMAP2 prv_PMAP2
#define CADDR1 prv_CADDR1
#define CADDR2 prv_CADDR2
#define CADDR3 prv_CADDR3
#define PADDR1 prv_PADDR1
+#define PADDR2 prv_PADDR2
#else
static pt_entry_t *CMAP1, *CMAP2, *CMAP3;
static caddr_t CADDR1, CADDR2, CADDR3;
static pd_entry_t *PMAP1;
static pt_entry_t *PADDR1;
+static pd_entry_t *PMAP2;
+static pt_entry_t *PADDR2;
#endif
static pt_entry_t *ptmmap;
@@ -257,6 +263,7 @@
static vm_page_t pmap_allocpte __P((pmap_t pmap, vm_offset_t va));
static vm_page_t _pmap_allocpte __P((pmap_t pmap, unsigned ptepindex));
+static pt_entry_t *pmap_pte_quick __P((pmap_t pmap, vm_offset_t va));
static vm_page_t pmap_page_lookup __P((vm_object_t object, vm_pindex_t pindex));
static int pmap_unuse_pt __P((pmap_t, vm_offset_t, vm_page_t));
static vm_offset_t pmap_kmem_choose(vm_offset_t addr);
@@ -364,6 +371,7 @@
* ptemap is used for pmap_pte
*/
SYSMAP(pd_entry_t *, PMAP1, PADDR1, 1);
+ SYSMAP(pd_entry_t *, PMAP2, PADDR2, 1);
#endif
/*
@@ -454,10 +462,12 @@
gd->gd_prv_CMAP2 = &SMPpt[2];
gd->gd_prv_CMAP3 = &SMPpt[3];
gd->gd_prv_PMAP1 = &SMPpt[4];
+ gd->gd_prv_PMAP2 = &SMPpt[5];
gd->gd_prv_CADDR1 = SMP_prvspace[0].CPAGE1;
gd->gd_prv_CADDR2 = SMP_prvspace[0].CPAGE2;
gd->gd_prv_CADDR3 = SMP_prvspace[0].CPAGE3;
gd->gd_prv_PADDR1 = (pt_entry_t *)SMP_prvspace[0].PPAGE1;
+ gd->gd_prv_PADDR2 = (pt_entry_t *)SMP_prvspace[0].PPAGE2;
#endif
invltlb();
@@ -663,13 +673,18 @@
* Function:
* Extract the page table entry associated
* with the given map/virtual_address pair.
+ * Note: Must be protected by splvm()
*/
-pt_entry_t *
-pmap_pte(pmap_t pmap, vm_offset_t va)
+static pt_entry_t *
+pmap_pte_quick(pmap_t pmap, vm_offset_t va)
{
pd_entry_t *pde, newpf;
+#ifdef INVARIANTS
+ if (~cpl & (net_imask | bio_imask | cam_imask))
+ panic("pmap_pte_quick not protected by splvm()");
+#endif
pde = pmap_pde(pmap, va);
if (*pde & PG_V) {
if (*pde & PG_PS)
@@ -691,6 +706,44 @@
}
/*
+ * Routine: pmap_pte
+ * Function:
+ * Extract the page table entry associated
+ * with the given map/virtual_address pair.
+ * Note: Must not be called from interrupts on non-current pmap
+ */
+
+pt_entry_t *
+pmap_pte(pmap_t pmap, vm_offset_t va)
+{
+ pd_entry_t *pde, newpf;
+
+ pde = pmap_pde(pmap, va);
+ if (*pde & PG_V) {
+ if (*pde & PG_PS)
+ return (pt_entry_t *)pde;
+ if (pmap_is_current(pmap))
+ return vtopte(va);
+#ifdef INVARIANTS
+ if (intr_nesting_level != 0) {
+ panic("pmap_pte called from interrupt");
+ }
+#endif
+ newpf = *pde & PG_FRAME;
+ if ((*PMAP2 & PG_FRAME) != newpf) {
+ *PMAP2 = newpf | PG_RW | PG_V;
+#ifdef SMP
+ cpu_invlpg(PADDR2);
+#else
+ invltlb_1pg((vm_offset_t) PADDR2);
+#endif
+ }
+ return PADDR2 + (i386_btop(va) & (NPTEPG - 1));
+ }
+ return (0);
+}
+
+/*
* Routine: pmap_extract
* Function:
* Extract the physical page address associated
@@ -1635,8 +1688,8 @@
if (nva > eva)
nva = eva;
- for (; sva < nva; sva += PAGE_SIZE) {
- pte = pmap_pte(pmap, sva);
+ pte = pmap_pte(pmap, sva);
+ for (; sva < nva; sva += PAGE_SIZE, pte++) {
if ((*pte & PG_V) == 0)
continue;
@@ -1684,7 +1737,7 @@
while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
pv->pv_pmap->pm_stats.resident_count--;
- pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+ pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
tpte = pte_store(pte, 0);
if (tpte & PG_W)
@@ -2681,7 +2734,7 @@
#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
pte = vtopte(pv->pv_va);
#else
- pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+ pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
#endif
tpte = *pte;
@@ -2762,7 +2815,7 @@
continue;
}
#endif
- pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+ pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
if (*pte & bit) {
splx(s);
return TRUE;
@@ -2807,7 +2860,7 @@
}
#endif
- pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+ pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
if (setem) {
*pte |= bit;
@@ -2893,7 +2946,7 @@
if (!pmap_track_modified(pv->pv_va))
continue;
- pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+ pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
if (pte && (*pte & PG_A)) {
*pte &= ~PG_A;
@@ -3180,6 +3233,7 @@
struct proc *p;
int npte = 0;
int index;
+ int s;
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_pid != pid)
continue;
@@ -3195,6 +3249,7 @@
pde = &pmap->pm_pdir[i];
if (pde && pmap_pde_v(pde)) {
+ s = splvm();
for(j=0;j<1024;j++) {
unsigned va = base + (j << PAGE_SHIFT);
if (va >= (vm_offset_t) VM_MIN_KERNEL_ADDRESS) {
@@ -3202,9 +3257,10 @@
index = 0;
printf("\n");
}
+ splx(s);
return npte;
}
- pte = pmap_pte( pmap, va);
+ pte = pmap_pte_quick(pmap, va);
if (pte && pmap_pte_v(pte)) {
vm_offset_t pa;
vm_page_t m;
@@ -3222,6 +3278,7 @@
}
}
}
+ splx(s);
}
}
}
@@ -3242,9 +3299,11 @@
{
unsigned va, i, j;
unsigned *ptep;
+ int s;
if (pm == kernel_pmap)
return;
+ s = splvm();
for (i = 0; i < 1024; i++)
if (pm->pm_pdir[i])
for (j = 0; j < 1024; j++) {
@@ -3253,10 +3312,11 @@
continue;
if (pm != kernel_pmap && va > UPT_MAX_ADDRESS)
continue;
- ptep = pmap_pte(pm, va);
+ ptep = pmap_pte_quick(pm, va);
if (pmap_pte_v(ptep))
printf("%x:%x ", va, *(int *) ptep);
};
+ splx(s);
}
Index: sys/i386/include/globaldata.h
===================================================================
RCS file: /home/ncvs/src/sys/i386/include/Attic/globaldata.h,v
retrieving revision 1.11.2.2
diff -u -r1.11.2.2 globaldata.h
--- sys/i386/include/globaldata.h 9 Aug 2003 16:21:19 -0000 1.11.2.2
+++ sys/i386/include/globaldata.h 28 Aug 2003 20:05:38 -0000
@@ -61,10 +61,12 @@
pt_entry_t *gd_prv_CMAP2;
pt_entry_t *gd_prv_CMAP3;
pd_entry_t *gd_prv_PMAP1;
+ pd_entry_t *gd_prv_PMAP2;
caddr_t gd_prv_CADDR1;
caddr_t gd_prv_CADDR2;
caddr_t gd_prv_CADDR3;
pt_entry_t *gd_prv_PADDR1;
+ pt_entry_t *gd_prv_PADDR2;
#endif
u_int gd_astpending;
};
@@ -80,13 +82,14 @@
struct globaldata globaldata;
char __filler0[PAGE_SIZE - sizeof(struct globaldata)];
- /* page 1..4 - CPAGE1,CPAGE2,CPAGE3,PPAGE1 */
+ /* page 1..5 - CPAGE1,CPAGE2,CPAGE3,PPAGE1,PPAGE2 */
char CPAGE1[PAGE_SIZE];
char CPAGE2[PAGE_SIZE];
char CPAGE3[PAGE_SIZE];
char PPAGE1[PAGE_SIZE];
+ char PPAGE2[PAGE_SIZE];
- /* page 5..4+UPAGES - idle stack (UPAGES pages) */
+ /* page 6..5+UPAGES - idle stack (UPAGES pages) */
char idlestack[UPAGES * PAGE_SIZE];
};
Index: sys/i386/include/globals.h
===================================================================
RCS file: /home/ncvs/src/sys/i386/include/Attic/globals.h,v
retrieving revision 1.5.2.2
diff -u -r1.5.2.2 globals.h
--- sys/i386/include/globals.h 9 Aug 2003 16:21:19 -0000 1.5.2.2
+++ sys/i386/include/globals.h 28 Aug 2003 20:05:38 -0000
@@ -104,10 +104,12 @@
#define prv_CMAP2 GLOBAL_LVALUE(prv_CMAP2, pt_entry_t *)
#define prv_CMAP3 GLOBAL_LVALUE(prv_CMAP3, pt_entry_t *)
#define prv_PMAP1 GLOBAL_LVALUE(prv_PMAP1, pd_entry_t *)
+#define prv_PMAP2 GLOBAL_LVALUE(prv_PMAP2, pd_entry_t *)
#define prv_CADDR1 GLOBAL_RVALUE(prv_CADDR1, caddr_t)
#define prv_CADDR2 GLOBAL_RVALUE(prv_CADDR2, caddr_t)
#define prv_CADDR3 GLOBAL_RVALUE(prv_CADDR3, caddr_t)
#define prv_PADDR1 GLOBAL_RVALUE(prv_PADDR1, pt_entry_t *)
+#define prv_PADDR2 GLOBAL_RVALUE(prv_PADDR2, pt_entry_t *)
#endif
#endif /*UP kernel*/
@@ -134,10 +136,12 @@
GLOBAL_FUNC(prv_CMAP2)
GLOBAL_FUNC(prv_CMAP3)
GLOBAL_FUNC(prv_PMAP1)
+GLOBAL_FUNC(prv_PMAP2)
GLOBAL_FUNC(prv_CADDR1)
GLOBAL_FUNC(prv_CADDR2)
GLOBAL_FUNC(prv_CADDR3)
GLOBAL_FUNC(prv_PADDR1)
+GLOBAL_FUNC(prv_PADDR2)
#endif
#define SET_CURPROC(x) (_global_curproc_set_nv((int)x))
More information about the freebsd-stable
mailing list