diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-08-21 09:38:31 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-08-21 13:55:53 +0100 |
commit | a02d8dfd54cdf3b1b0464ccc2c1c4afe2c003a35 (patch) | |
tree | b760333143b1fa4e3de0b6c22c854c67a1e47c4a /arch/arm/mm | |
parent | 3c2aed5b28819564e1a07b4686bd89802bcc4d6b (diff) | |
download | op-kernel-dev-a02d8dfd54cdf3b1b0464ccc2c1c4afe2c003a35.zip op-kernel-dev-a02d8dfd54cdf3b1b0464ccc2c1c4afe2c003a35.tar.gz |
ARM: domains: keep vectors in separate domain
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>
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/mmu.c | 4 | ||||
-rw-r--r-- | arch/arm/mm/pgd.c | 10 |
2 files changed, 12 insertions, 2 deletions
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 6ca7d9a..a016de2 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -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, diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index a3681f1..e683db1 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c @@ -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); |