diff --git a/Jenkinsfile b/Jenkinsfile index 2a2bc8db2e57..709998a92f22 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -29,7 +29,7 @@ def jobProperties = [ rateLimit, ] // Don't archive sysroot/disk image/kernel images for pull requests and non-default/releng branches: -def archiveBranches = ['main', 'master', 'dev'] +def archiveBranches = ['main', 'master', 'dev', 'cheri-morello-pmap-simplify'] if (!env.CHANGE_ID && (archiveBranches.contains(env.BRANCH_NAME) || env.BRANCH_NAME.startsWith('releng/'))) { if (!GlobalVars.isTestSuiteJob) { // Don't archive disk images for the test suite job diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 67c58a7add8a..90b5fa368db6 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -528,6 +528,13 @@ pagecopy_cleartags(void *s, void *d) for (i = 0; i < PAGE_SIZE / sizeof(*dst); i++) *dst++ = cheri_cleartag(*src++); } + +static __inline void +pmap_set_cap_bits(pt_entry_t *ent, uint64_t bits) +{ + pmap_clear_bits(ent,ATTR_CAP_MASK); + pmap_set_bits(ent,bits); +} #endif static __inline pd_entry_t * @@ -849,20 +856,20 @@ pmap_pte_cr(pmap_t pmap, vm_offset_t va, vm_prot_t prot) if ((va < VM_MAX_USER_ADDRESS) && (pmap->pm_stage == PM_STAGE1)) { /* Stage 1 user pages gated by CLG */ - return pmap->flags.uclg ? ATTR_LC_GEN1 : ATTR_LC_GEN0; + return pmap->flags.uclg ? ATTR_CAP_GEN1 : ATTR_CAP_GEN0; } else { /* * Kernel pages always load OK; Stage 2 doesn't support * CLG. */ - return ATTR_LC_ENABLED; + return ATTR_CAP_GEN0; } #else - return ATTR_LC_ENABLED; + return ATTR_CAP_GEN0; #endif } else { /* XXX Let's see what happens! */ - return ATTR_LC_DISABLED; + return ATTR_CAP_NONE; } } #endif @@ -889,10 +896,16 @@ pmap_pte_prot(pmap_t pmap, vm_prot_t prot, u_int flags, vm_page_t m, } #if __has_feature(capabilities) - val |= pmap_pte_cr(pmap, va, prot); + uint64_t cap_val = ATTR_CAP_NONE; + if (prot & VM_PROT_READ_CAP) { + if ((va < VM_MAX_USER_ADDRESS) && (pmap->pm_stage == PM_STAGE1)) + cap_val = pmap->flags.uclg ? ATTR_CAP_GEN1 : ATTR_CAP_GEN0; + else + cap_val = ATTR_CAP_GEN0; + } VM_PAGE_ASSERT_PGA_CAPMETA_PMAP_ENTER(m, prot); - if ((prot & VM_PROT_WRITE_CAP) != 0) { + if (prot & VM_PROT_WRITE_CAP) { KASSERT((vm_page_astate_load(m).flags & PGA_CAPSTORE) != 0, ("%s: page %p does not have CAPSTORE set", __func__, m)); @@ -907,10 +920,11 @@ pmap_pte_prot(pmap_t pmap, vm_prot_t prot, u_int flags, vm_page_t m, * but it's not required. */ if (pmap->pm_stage == PM_STAGE1 && va < VM_MAX_USER_ADDRESS) - val |= ATTR_CDBM; + cap_val = pmap->flags.uclg ? ATTR_CAP_GEN1 : ATTR_CAP_GEN0; else - val |= ATTR_SC; + cap_val = ATTR_CAP_GEN0; } + val |= cap_val; #endif return (val); @@ -4969,6 +4983,7 @@ pmap_enter_2mpage(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, if (pmap != kernel_pmap) new_l2 |= ATTR_S1_nG; #if __has_feature(capabilities) + new_l2 &= ~ATTR_CAP_MASK; new_l2 |= pmap_pte_cr(pmap, va, prot); #endif return (pmap_enter_l2(pmap, va, new_l2, PMAP_ENTER_NOSLEEP | @@ -5340,6 +5355,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, if (pmap != kernel_pmap) l3_val |= ATTR_S1_nG; #if __has_feature(capabilities) + l3_val &= ~ATTR_CAP_MASK; l3_val |= pmap_pte_cr(pmap, va, prot); #endif @@ -5399,9 +5415,9 @@ static inline void pmap_update_pte_clg(pmap_t pmap, pt_entry_t *pte) { if (pmap->flags.uclg) { - pmap_set_bits(pte, ATTR_LC_GEN_MASK); + pmap_set_cap_bits(pte, ATTR_CAP_GEN1); } else { - pmap_clear_bits(pte, ATTR_LC_GEN_MASK); + pmap_set_cap_bits(pte, ATTR_CAP_GEN0); } } @@ -5519,7 +5535,7 @@ pmap_caploadgen_update(pmap_t pmap, vm_offset_t va, vm_page_t *mp, int flags) #if VM_NRESERVLEVEL > 0 pd_entry_t *l2, l2e; #endif - pt_entry_t *pte, tpte, exppte; + pt_entry_t *pte, tpte/*, exppte*/; vm_page_t m; int lvl; @@ -5599,7 +5615,8 @@ pmap_caploadgen_update(pmap_t pmap, vm_offset_t va, vm_page_t *mp, int flags) * store-release below, and so we're going to * scan the page again anyway. */ - pmap_clear_bits(pte, ATTR_SC); + //pmap_clear_bits(pte, ATTR_SC); + pmap_set_cap_bits(pte, ATTR_CAP_DIRTYABLE); } else if (tpte & ATTR_CDBM) { /* * PTE CAP-DIRTYABLE -> CAP-CLEAN @@ -5625,9 +5642,9 @@ pmap_caploadgen_update(pmap_t pmap, vm_offset_t va, vm_page_t *mp, int flags) * entry as cap-load-faulting, but we don't have * such a mechanism on Morello. */ - exppte = tpte; - pmap_fcmpset(pte, &exppte, exppte & ~ATTR_CDBM); - + //exppte = tpte; + //pmap_fcmpset(pte, &exppte, exppte & ~ATTR_CDBM); + pmap_set_cap_bits(pte, ATTR_CAP_NONE); } else if (flags & PMAP_CAPLOADGEN_NONEWMAPS) { /* No new mappings possible */ vm_page_astate_t mas = vm_page_astate_load(m); @@ -5672,7 +5689,8 @@ pmap_caploadgen_update(pmap_t pmap, vm_offset_t va, vm_page_t *mp, int flags) * probably doesn't get set often ough to merit. */ if ((tpte & ATTR_CDBM) && !(tpte & ATTR_SC)) { - pmap_set_bits(pte, ATTR_SC); + //pmap_set_bits(pte, ATTR_SC); + pmap_set_cap_bits(pte, (pmap->flags.uclg ? ATTR_CAP_GEN1 : ATTR_CAP_GEN0)); } } @@ -8393,7 +8411,8 @@ pmap_fault(pmap_t pmap, uint64_t esr, uint64_t far) if (ptep != NULL && ((pte = pmap_load(ptep)) & ATTR_CDBM) != 0) { if ((pte & ATTR_SC) == 0) { - pmap_set_bits(ptep, ATTR_SC); + //pmap_set_bits(ptep, ATTR_SC); + pmap_set_cap_bits(ptep, (pmap->flags.uclg ? ATTR_CAP_GEN1 : ATTR_CAP_GEN0)); pmap_s1_invalidate_page(pmap, far, true); } rv = KERN_SUCCESS; diff --git a/sys/arm64/include/pte.h b/sys/arm64/include/pte.h index 1ca9efa5dde7..2b6064044a8b 100644 --- a/sys/arm64/include/pte.h +++ b/sys/arm64/include/pte.h @@ -62,6 +62,11 @@ typedef uint64_t pt_entry_t; /* page table entry */ #define ATTR_LC_GEN1 (3UL << 61) #define ATTR_SC (1UL << 60) #define ATTR_CDBM (1UL << 59) +#define ATTR_CAP_MASK (15UL << 59) +#define ATTR_CAP_NONE (0UL << 59) +#define ATTR_CAP_DIRTYABLE (5UL << 59) +#define ATTR_CAP_GEN0 (11UL << 59) +#define ATTR_CAP_GEN1 (15UL << 59) #endif #define BASE_MASK ~ATTR_MASK @@ -127,7 +132,7 @@ typedef uint64_t pt_entry_t; /* page table entry */ * ATTR_CAP_RW as a single operand, so separate orr instructions are * required for ATTR_CAP_RW. */ -#define ATTR_CAP_RW (ATTR_LC_ENABLED | ATTR_SC) +#define ATTR_CAP_RW ATTR_CAP_GEN0 #endif #define ATTR_DEFAULT (ATTR_AF | ATTR_SH(ATTR_SH_IS)) diff --git a/sys/arm64/vmm/vmm_mmu.c b/sys/arm64/vmm/vmm_mmu.c index 3669b796a1c4..51d2bede1a31 100644 --- a/sys/arm64/vmm/vmm_mmu.c +++ b/sys/arm64/vmm/vmm_mmu.c @@ -309,10 +309,10 @@ vmmpmap_enter(vm_offset_t va, vm_size_t size, vm_paddr_t pa, vm_prot_t prot) } #if __has_feature(capabilities) if ((prot & VM_PROT_READ_CAP) != 0) { - l3e |= ATTR_LC_ENABLED; + l3e |= ATTR_CAP_GEN0; } if ((prot & VM_PROT_WRITE_CAP) != 0) { - l3e |= ATTR_SC; + l3e |= ATTR_CAP_GEN0; } #endif diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 30ebd2cb97c4..49417b084fe4 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -2010,10 +2010,10 @@ vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, } } else { #ifdef INVARIANTS - vm_page_astate_t mas = vm_page_astate_load(fs.m); - KASSERT(!(mas.flags & PGA_CAPDIRTY) || - (mas.flags & PGA_CAPSTORE), - ("CAPDIRTY w/o CAPSTORE")); + //vm_page_astate_t mas = vm_page_astate_load(fs.m); + //KASSERT(!(mas.flags & PGA_CAPDIRTY) || + // (mas.flags & PGA_CAPSTORE), + // ("CAPDIRTY w/o CAPSTORE")); #endif } #endif diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 16e51c659dd2..24ac4af39988 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -5666,9 +5666,9 @@ vm_page_assert_pga_capmeta_pmap_enter(vm_page_t m, vm_prot_t prot) (mas.flags & PGA_CAPSTORE) != 0, ("pmap inserting VM_PROT_WRITE_CAP w/o PGA_CAPSTORE m=%p", m)); - KASSERT((mas.flags & PGA_CAPDIRTY) == 0 || - (mas.flags & PGA_CAPSTORE) != 0, - ("pmap inserting CAPDIRTY w/o CAPSTORE m=%p", m)); + //KASSERT((mas.flags & PGA_CAPDIRTY) == 0 || + // (mas.flags & PGA_CAPSTORE) != 0, + // ("pmap inserting CAPDIRTY w/o CAPSTORE m=%p", m)); KASSERT((prot & VM_PROT_WRITE_CAP) == 0 || (prot & VM_PROT_WRITE) != 0, diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index fc660989c3cc..7d0e72e28323 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -951,8 +951,8 @@ static __inline void vm_page_capdirty(vm_page_t m) { - KASSERT(vm_page_astate_load(m).flags & PGA_CAPSTORE, - ("vm_page_capdirty w/o PGA_CAPSTORE m=%p", m)); + //KASSERT(vm_page_astate_load(m).flags & PGA_CAPSTORE, + // ("vm_page_capdirty w/o PGA_CAPSTORE m=%p", m)); vm_page_aflag_set(m, PGA_CAPDIRTY); }