summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2002-07-24 00:55:53 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2002-07-24 00:55:53 +0000
commit74de1996a817c9f7c9f471a6de69e89d30e1adc9 (patch)
treeeca4f0b8ba72afcdcee10ddbfe73aae250555580 /sys
parent5c51485ccc3c55680e4e343ccc56f5dc2948a8bb (diff)
Support for non-exec mappings on sun4m.
- support exec traps and deal with them correctly. - Instead of pretending that the pte permissions are a bit-mask, just make two stupid 8-entry tables (one for kernel, one for userland) that provides translation between VM_PROT* masks and pte permissions. This gives sun4m a non-exec stack.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc/sparc/pmap.c69
-rw-r--r--sys/arch/sparc/sparc/trap.c12
2 files changed, 69 insertions, 12 deletions
diff --git a/sys/arch/sparc/sparc/pmap.c b/sys/arch/sparc/sparc/pmap.c
index 62dbd1a402a..ae9897b5aa5 100644
--- a/sys/arch/sparc/sparc/pmap.c
+++ b/sys/arch/sparc/sparc/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.125 2002/07/09 18:08:18 art Exp $ */
+/* $OpenBSD: pmap.c,v 1.126 2002/07/24 00:55:52 art Exp $ */
/* $NetBSD: pmap.c,v 1.118 1998/05/19 19:00:18 thorpej Exp $ */
/*
@@ -653,6 +653,58 @@ setpte4m(va, pte)
setpgt4m(ptep, pte);
}
+/*
+ * Translation table for kernel vs. PTE protection bits.
+ */
+u_int protection_codes[2][8];
+#define pte_prot4m(pm, prot) (protection_codes[pm == pmap_kernel()?0:1][prot])
+
+static void
+sparc_protection_init4m(void)
+{
+ u_int prot, *kp, *up;
+
+ kp = protection_codes[0];
+ up = protection_codes[1];
+
+ for (prot = 0; prot < 8; prot++) {
+ switch (prot) {
+ case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
+ kp[prot] = PPROT_N_RWX;
+ up[prot] = PPROT_RWX_RWX;
+ break;
+ case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_NONE:
+ kp[prot] = PPROT_N_RWX;
+ up[prot] = PPROT_RW_RW;
+ break;
+ case VM_PROT_READ | VM_PROT_NONE | VM_PROT_EXECUTE:
+ kp[prot] = PPROT_N_RX;
+ up[prot] = PPROT_RX_RX;
+ break;
+ case VM_PROT_READ | VM_PROT_NONE | VM_PROT_NONE:
+ kp[prot] = PPROT_N_RX;
+ up[prot] = PPROT_R_R;
+ break;
+ case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_EXECUTE:
+ kp[prot] = PPROT_N_RWX;
+ up[prot] = PPROT_RWX_RWX;
+ break;
+ case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_NONE:
+ kp[prot] = PPROT_N_RWX;
+ up[prot] = PPROT_RW_RW;
+ break;
+ case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_EXECUTE:
+ kp[prot] = PPROT_N_RX;
+ up[prot] = PPROT_X_X;
+ break;
+ case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_NONE:
+ kp[prot] = PPROT_N_RX;
+ up[prot] = PPROT_R_R;
+ break;
+ }
+ }
+}
+
#endif /* 4m only */
/*----------------------------------------------------------------*/
@@ -3217,6 +3269,7 @@ pmap_bootstrap4m(void)
mmu_install_tables(&cpuinfo);
pmap_page_upload(avail_start);
+ sparc_protection_init4m();
}
void
@@ -4781,10 +4834,7 @@ pmap_changeprot4m(pm, va, prot, wired)
write_user_windows(); /* paranoia */
va = trunc_page(va);
- if (pm == pmap_kernel())
- newprot = prot & VM_PROT_WRITE ? PPROT_N_RWX : PPROT_N_RX;
- else
- newprot = prot & VM_PROT_WRITE ? PPROT_RWX_RWX : PPROT_RX_RX;
+ newprot = pte_prot4m(pm, prot);
pmap_stats.ps_changeprots++;
@@ -5238,8 +5288,7 @@ pmap_enter4m(pm, va, pa, prot, flags)
#endif
pteproto |= PMAP_T2PTE_SRMMU(pa);
- /* Make sure we get a pte with appropriate perms! */
- pteproto |= SRMMU_TEPTE | PPROT_RX_RX;
+ pteproto |= SRMMU_TEPTE;
pa &= ~PMAP_TNC_SRMMU;
/*
@@ -5254,12 +5303,12 @@ pmap_enter4m(pm, va, pa, prot, flags)
pteproto |= (atop(pa) << SRMMU_PPNSHIFT);
- if (prot & VM_PROT_WRITE)
- pteproto |= PPROT_WRITE;
+ /* correct protections */
+ pteproto |= pte_prot4m(pm, prot);
ctx = getcontext4m();
if (pm == pmap_kernel())
- ret = pmap_enk4m(pm, va, prot, flags, pv, pteproto | PPROT_S);
+ ret = pmap_enk4m(pm, va, prot, flags, pv, pteproto);
else
ret = pmap_enu4m(pm, va, prot, flags, pv, pteproto);
#ifdef DIAGNOSTIC
diff --git a/sys/arch/sparc/sparc/trap.c b/sys/arch/sparc/sparc/trap.c
index d0d57e22c43..381fe7c1739 100644
--- a/sys/arch/sparc/sparc/trap.c
+++ b/sys/arch/sparc/sparc/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.38 2002/05/16 21:11:18 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.39 2002/07/24 00:55:52 art Exp $ */
/* $NetBSD: trap.c,v 1.58 1997/09/12 08:55:01 pk Exp $ */
/*
@@ -861,7 +861,15 @@ mem_access_fault4m(type, sfsr, sfva, tf)
if ((sfsr & SFSR_FT) == SFSR_FT_NONE)
goto out; /* No fault. Why were we called? */
- ftype = sfsr & SFSR_AT_STORE ? VM_PROT_WRITE : VM_PROT_READ;
+ if ((sfsr & SFSR_AT_STORE)) {
+ /* stores are never text faults. */
+ ftype = VM_PROT_WRITE;
+ } else {
+ ftype = VM_PROT_READ;
+ if ((sfsr & SFSR_AT_TEXT) || (type == T_TEXTFAULT)) {
+ ftype |= VM_PROT_EXECUTE;
+ }
+ }
/*
* NOTE: the per-CPU fault status register readers (in locore)