svn commit: r250297 - in head/sys/arm: arm include
Grzegorz Bernacki
gber at FreeBSD.org
Mon May 6 15:30:35 UTC 2013
Author: gber
Date: Mon May 6 15:30:34 2013
New Revision: 250297
URL: http://svnweb.freebsd.org/changeset/base/250297
Log:
Fix L2 PTE access permissions management.
Keep following access permissions:
APX AP Kernel User
1 01 R N
1 10 R R
0 01 R/W N
0 11 R/W R/W
Avoid using reserved in ARMv6 APX|AP settings:
- In case of unprivileged (user) access without permission to write,
the access permission bits were being set to reserved for ARMv6
(but valid for ARMv7) value of APX|AP = 111.
Fix-up faulting userland accesses properly:
- Wrong condition statement in pmap_fault_fixup() caused that
any genuine, unprivileged access was being fixed-up instead of
just skip doing anything and return. Staring from now we ensure
proper reaction for illicit user accesses.
L2_S_PROT_R and L2_S_PROT_U names might be misleading as they do not
reflect real permission levels. It will be clarified in following
patches (switch to AP[2:1] permissions model).
Obtained from: Semihalf
Modified:
head/sys/arm/arm/pmap-v6.c
head/sys/arm/include/pmap.h
Modified: head/sys/arm/arm/pmap-v6.c
==============================================================================
--- head/sys/arm/arm/pmap-v6.c Mon May 6 14:57:02 2013 (r250296)
+++ head/sys/arm/arm/pmap-v6.c Mon May 6 15:30:34 2013 (r250297)
@@ -983,6 +983,7 @@ pmap_set_prot(pt_entry_t *ptep, vm_prot_
if (!(prot & VM_PROT_EXECUTE))
*ptep |= L2_XN;
+ *ptep |= L2_APX;
*ptep |= L2_S_PROT_R;
if (user)
@@ -990,6 +991,8 @@ pmap_set_prot(pt_entry_t *ptep, vm_prot_
if (prot & VM_PROT_WRITE)
*ptep &= ~(L2_APX);
+ else if (user)
+ *ptep &= ~(L2_S_PROT_R);
}
/*
@@ -1216,7 +1219,7 @@ pmap_fault_fixup(pmap_t pm, vm_offset_t
/*
* Catch a userland access to the vector page mapped at 0x0
*/
- if (user && ((pte & L2_S_PROT_MASK) == L2_S_PROT_U))
+ if (user && !(pte & L2_S_PROT_U))
goto out;
if (va == vector_page)
goto out;
@@ -2649,7 +2652,10 @@ do_l2b_alloc:
npte |= L2_TYPE_INV;
}
+ npte |= L2_APX;
npte |= L2_S_PROT_R;
+ if (user)
+ npte |= L2_S_PROT_U;
if (prot & VM_PROT_WRITE) {
npte &= ~(L2_APX);
@@ -2657,11 +2663,8 @@ do_l2b_alloc:
if (m != NULL &&
(m->oflags & VPO_UNMANAGED) == 0)
vm_page_aflag_set(m, PGA_WRITEABLE);
- }
-
- if (user)
- npte |= L2_S_PROT_U;
-
+ } else if (user)
+ npte &= ~(L2_S_PROT_R);
if (!(prot & VM_PROT_EXECUTE) && m)
npte |= L2_XN;
Modified: head/sys/arm/include/pmap.h
==============================================================================
--- head/sys/arm/include/pmap.h Mon May 6 14:57:02 2013 (r250296)
+++ head/sys/arm/include/pmap.h Mon May 6 15:30:34 2013 (r250297)
@@ -352,7 +352,7 @@ extern int pmap_needs_pte_sync;
#elif (ARM_MMU_V6 + ARM_MMU_V7) != 0
#define L2_S_PROT_U (L2_AP0(2)) /* user access */
-#define L2_S_PROT_R (L2_APX|L2_AP0(1)) /* read access */
+#define L2_S_PROT_R (L2_AP0(1)) /* read access */
#define L2_S_PROT_MASK (L2_S_PROT_U|L2_S_PROT_R)
#define L2_S_WRITABLE(pte) (!(pte & L2_APX))
More information about the svn-src-head
mailing list