diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-08-27 14:22:36 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-08-27 14:22:36 +0000 |
commit | 4d04abefd34b749258076f5b38200af9b37215a2 (patch) | |
tree | d2352a354448369aaf8c9a69138f6695a75f7249 /sys | |
parent | 20d23896dc245f50f5dab2b4695f7c291e674e92 (diff) |
Add support for the PXN bit in level 1 translation table descriptors and
enable it on CPUs that support it. When enabled, this prevents the kernel
from executing userland code.
ok jsg@, tom@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/arm/arm/pmap7.c | 16 | ||||
-rw-r--r-- | sys/arch/arm/include/pte.h | 6 |
2 files changed, 17 insertions, 5 deletions
diff --git a/sys/arch/arm/arm/pmap7.c b/sys/arch/arm/arm/pmap7.c index 0889e549205..4997cea003b 100644 --- a/sys/arch/arm/arm/pmap7.c +++ b/sys/arch/arm/arm/pmap7.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap7.c,v 1.49 2016/08/26 16:02:33 kettenis Exp $ */ +/* $OpenBSD: pmap7.c,v 1.50 2016/08/27 14:22:35 kettenis Exp $ */ /* $NetBSD: pmap.c,v 1.147 2004/01/18 13:03:50 scw Exp $ */ /* @@ -303,6 +303,11 @@ struct l1_ttable { #define L1_IDX(va) (((vaddr_t)(va)) >> L1_S_SHIFT) /* + * Set if the PXN bit is supported. + */ +pd_entry_t l1_c_pxn; + +/* * A list of all L1 tables */ TAILQ_HEAD(, l1_ttable) l1_list; @@ -1267,7 +1272,7 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags) pd_entry_t *pl1pd, l1pd; pl1pd = &pm->pm_l1->l1_kva[L1_IDX(va)]; - l1pd = L1_C_PROTO | l2b->l2b_phys; + l1pd = L1_C_PROTO | l2b->l2b_phys | l1_c_pxn; if (*pl1pd != l1pd) { *pl1pd = l1pd; PTE_SYNC(pl1pd); @@ -2861,7 +2866,7 @@ void (*pmap_zero_page_func)(struct vm_page *); void pmap_pte_init_armv7(void) { - uint32_t id_mmfr3; + uint32_t id_mmfr0, id_mmfr3; /* * XXX We want to use proper TEX settings eventually. @@ -2910,6 +2915,11 @@ pmap_pte_init_armv7(void) pmap_copy_page_func = pmap_copy_page_generic; pmap_zero_page_func = pmap_zero_page_generic; + /* Check if the PXN bit is supported. */ + __asm volatile("mrc p15, 0, %0, c0, c1, 4" : "=r"(id_mmfr0)); + if ((id_mmfr0 & ID_MMFR0_VMSA_MASK) >= VMSA_V7_PXN) + l1_c_pxn = L1_C_V7_PXN; + /* Check for coherent walk. */ __asm volatile("mrc p15, 0, %0, c0, c1, 7" : "=r"(id_mmfr3)); if ((id_mmfr3 & 0x00f00000) == 0x00100000) diff --git a/sys/arch/arm/include/pte.h b/sys/arch/arm/include/pte.h index 059e2812576..4dc2638fa2b 100644 --- a/sys/arch/arm/include/pte.h +++ b/sys/arch/arm/include/pte.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pte.h,v 1.7 2016/08/18 09:28:22 kettenis Exp $ */ +/* $OpenBSD: pte.h,v 1.8 2016/08/27 14:22:35 kettenis Exp $ */ /* $NetBSD: pte.h,v 1.6 2003/04/18 11:08:28 scw Exp $ */ /* @@ -159,6 +159,7 @@ typedef uint32_t pt_entry_t; /* L2 table entry */ #define L1_S_V7_AF 0x00000400 /* Access Flag */ #define L1_S_V7_IMP 0x00000200 /* implementation defined */ #define L1_S_V7_XN 0x00000010 /* eXecute Never */ +#define L1_S_V7_PXN 0x00000001 /* Privileged eXecute Never */ /* L1 Coarse Descriptor */ #define L1_C_IMP0 0x00000004 /* implementation defined */ @@ -170,8 +171,9 @@ typedef uint32_t pt_entry_t; /* L2 table entry */ #define L1_C_XSCALE_P 0x00000200 /* ECC enable for this section */ -#define L1_C_V7_NS 0x00000008 /* Non-secure */ #define L1_C_V7_IMP 0x00000200 /* implementation defined */ +#define L1_C_V7_NS 0x00000008 /* Non-secure */ +#define L1_C_V7_PXN 0x00000004 /* Privileged eXecute Never */ /* L1 Fine Descriptor */ #define L1_F_IMP0 0x00000004 /* implementation defined */ |