diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S --- a/sys/arm64/arm64/locore.S +++ b/sys/arm64/arm64/locore.S @@ -552,6 +552,7 @@ /* Build the L0 block entry */ mov x12, #L0_TABLE + orr x12, x12, #(TATTR_UXN_TABLE | TATTR_AP_TABLE_NO_EL0) /* Only use the output address bits */ lsr x9, x9, #PAGE_SHIFT diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -789,7 +789,8 @@ freemempos += PAGE_SIZE; pmap_store(&pagetable_dmap[l1_slot], - (l2_pa & ~Ln_TABLE_MASK) | L1_TABLE); + (l2_pa & ~Ln_TABLE_MASK) | + TATTR_PXN_TABLE | L1_TABLE); memset(l2, 0, PAGE_SIZE); } @@ -1873,14 +1874,26 @@ */ if (ptepindex >= (NUL2E + NUL1E)) { - pd_entry_t *l0; + pd_entry_t *l0p, l0e; vm_pindex_t l0index; l0index = ptepindex - (NUL2E + NUL1E); - l0 = &pmap->pm_l0[l0index]; - KASSERT((pmap_load(l0) & ATTR_DESCR_VALID) == 0, - ("%s: L0 entry %#lx is valid", __func__, pmap_load(l0))); - pmap_store(l0, VM_PAGE_TO_PHYS(m) | L0_TABLE); + l0p = &pmap->pm_l0[l0index]; + KASSERT((pmap_load(l0p) & ATTR_DESCR_VALID) == 0, + ("%s: L0 entry %#lx is valid", __func__, pmap_load(l0p))); + l0e = VM_PAGE_TO_PHYS(m) | L0_TABLE; + + /* + * Mark all kernel memory as not accessible from userspace + * and userspace memory as not executable from the kernel. + * This has been done for the bootstrap L0 entries in + * locore.S. + */ + if (pmap == kernel_pmap) + l0e |= TATTR_UXN_TABLE | TATTR_AP_TABLE_NO_EL0; + else + l0e |= TATTR_PXN_TABLE; + pmap_store(l0p, l0e); } else if (ptepindex >= NUL2E) { vm_pindex_t l0index, l1index; pd_entry_t *l0, *l1; diff --git a/sys/arm64/include/pte.h b/sys/arm64/include/pte.h --- a/sys/arm64/include/pte.h +++ b/sys/arm64/include/pte.h @@ -38,6 +38,15 @@ typedef uint64_t pt_entry_t; /* page table entry */ #endif +/* Table attributes */ +#define TATTR_MASK UINT64_C(0xfff8000000000000) +#define TATTR_AP_TABLE_MASK (3UL << 61) +#define TATTR_AP_TABLE_RO (2UL << 61) +#define TATTR_AP_TABLE_NO_EL0 (1UL << 61) +#define TATTR_UXN_TABLE (1UL << 60) +#define TATTR_PXN_TABLE (1UL << 59) +/* Bits 58:51 are ignored */ + /* Block and Page attributes */ #define ATTR_MASK_H UINT64_C(0xfffc000000000000) #define ATTR_MASK_L UINT64_C(0x0000000000000fff)