From 7680ffd381bc44e39ab56d7f5fbaf77b376b7207 Mon Sep 17 00:00:00 2001 From: kettenis Date: Sat, 27 Aug 2016 14:22:35 +0000 Subject: [PATCH] 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@ --- sys/arch/arm/arm/pmap7.c | 16 +++++++++++++--- 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 $ */ /* @@ -302,6 +302,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 */ @@ -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 */ -- 2.20.1