ARM: domains: keep vectors in separate domain
authorRussell King <rmk+kernel@arm.linux.org.uk>
Fri, 21 Aug 2015 08:38:31 +0000 (09:38 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Fri, 21 Aug 2015 12:55:53 +0000 (13:55 +0100)
Keep the machine vectors in its own domain to avoid software based
user access control from making the vector code inaccessible, and
thereby deadlocking the machine.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/include/asm/domain.h
arch/arm/include/asm/pgtable-2level-hwdef.h
arch/arm/mm/mmu.c
arch/arm/mm/pgd.c

index 08b601e..396a12e 100644 (file)
@@ -43,6 +43,7 @@
 #define DOMAIN_USER    1
 #define DOMAIN_IO      0
 #endif
+#define DOMAIN_VECTORS 3
 
 /*
  * Domain types
@@ -62,7 +63,8 @@
        (domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
         domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
         domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
-        domain_val(DOMAIN_IO, DOMAIN_CLIENT))
+        domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
+        domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
 
 #ifndef __ASSEMBLY__
 
index 5e68278..d0131ee 100644 (file)
@@ -23,6 +23,7 @@
 #define PMD_PXNTABLE           (_AT(pmdval_t, 1) << 2)     /* v7 */
 #define PMD_BIT4               (_AT(pmdval_t, 1) << 4)
 #define PMD_DOMAIN(x)          (_AT(pmdval_t, (x)) << 5)
+#define PMD_DOMAIN_MASK                PMD_DOMAIN(0x0f)
 #define PMD_PROTECTION         (_AT(pmdval_t, 1) << 9)         /* v5 */
 /*
  *   - section
index 6ca7d9a..a016de2 100644 (file)
@@ -291,13 +291,13 @@ static struct mem_type mem_types[] = {
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
                                L_PTE_RDONLY,
                .prot_l1   = PMD_TYPE_TABLE,
-               .domain    = DOMAIN_USER,
+               .domain    = DOMAIN_VECTORS,
        },
        [MT_HIGH_VECTORS] = {
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
                                L_PTE_USER | L_PTE_RDONLY,
                .prot_l1   = PMD_TYPE_TABLE,
-               .domain    = DOMAIN_USER,
+               .domain    = DOMAIN_VECTORS,
        },
        [MT_MEMORY_RWX] = {
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
index a3681f1..e683db1 100644 (file)
@@ -84,6 +84,16 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
                if (!new_pte)
                        goto no_pte;
 
+#ifndef CONFIG_ARM_LPAE
+               /*
+                * Modify the PTE pointer to have the correct domain.  This
+                * needs to be the vectors domain to avoid the low vectors
+                * being unmapped.
+                */
+               pmd_val(*new_pmd) &= ~PMD_DOMAIN_MASK;
+               pmd_val(*new_pmd) |= PMD_DOMAIN(DOMAIN_VECTORS);
+#endif
+
                init_pud = pud_offset(init_pgd, 0);
                init_pmd = pmd_offset(init_pud, 0);
                init_pte = pte_offset_map(init_pmd, 0);