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