git: c553f62a3007 - stable/13 - Add arm64 CnP support
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 19 Jul 2022 07:37:17 UTC
The branch stable/13 has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=c553f62a300735ceaf1c3ca6a9a012e78a69e662 commit c553f62a300735ceaf1c3ca6a9a012e78a69e662 Author: Andrew Turner <andrew@FreeBSD.org> AuthorDate: 2022-05-25 09:55:40 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2022-07-19 07:03:30 +0000 Add arm64 CnP support Set the Common not Private bit in the ttbr registers when supported on arm64. This tells the hardware it can share the translation table entries on multiple CPUs. Reviewed by: alc, kib Sponsored by: The FreeBSD Foundation (cherry picked from commit 9e0716f4610158936c0b9cec1a9930c4ebe924fb) --- sys/arm64/arm64/pmap.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 0c6f3630c42d..a8615b0a3902 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -6845,6 +6845,8 @@ out: mtx_unlock_spin(&set->asid_set_mutex); } +static uint64_t __read_mostly ttbr_flags; + /* * Compute the value that should be stored in ttbr0 to activate the specified * pmap. This value may change from time to time. @@ -6852,10 +6854,70 @@ out: uint64_t pmap_to_ttbr0(pmap_t pmap) { + uint64_t ttbr; + + ttbr = pmap->pm_ttbr; + ttbr |= ASID_TO_OPERAND(COOKIE_TO_ASID(pmap->pm_cookie)); + ttbr |= ttbr_flags; + + return (ttbr); +} + +static void +pmap_set_cnp(void *arg) +{ + uint64_t ttbr0, ttbr1; + u_int cpuid; + + cpuid = *(u_int *)arg; + if (cpuid == curcpu) { + /* + * Set the flags while all CPUs are handling the + * smp_rendezvous so will not call pmap_to_ttbr0. Any calls + * to pmap_to_ttbr0 after this will have the CnP flag set. + * The dsb after invalidating the TLB will act as a barrier + * to ensure all CPUs can observe this change. + */ + ttbr_flags |= TTBR_CnP; + } + + ttbr0 = READ_SPECIALREG(ttbr0_el1); + ttbr0 |= TTBR_CnP; + + ttbr1 = READ_SPECIALREG(ttbr1_el1); + ttbr1 |= TTBR_CnP; + + /* Update ttbr{0,1}_el1 with the CnP flag */ + WRITE_SPECIALREG(ttbr0_el1, ttbr0); + WRITE_SPECIALREG(ttbr1_el1, ttbr1); + isb(); + __asm __volatile("tlbi vmalle1is"); + dsb(ish); + isb(); +} + +/* + * Defer enabling CnP until we have read the ID registers to know if it's + * supported on all CPUs. + */ +static void +pmap_init_cnp(void *dummy __unused) +{ + uint64_t reg; + u_int cpuid; + + if (!get_kernel_reg(ID_AA64MMFR2_EL1, ®)) + return; + + if (ID_AA64MMFR2_CnP_VAL(reg) != ID_AA64MMFR2_CnP_NONE) { + if (bootverbose) + printf("Enabling CnP\n"); + cpuid = curcpu; + smp_rendezvous(NULL, pmap_set_cnp, NULL, &cpuid); + } - return (ASID_TO_OPERAND(COOKIE_TO_ASID(pmap->pm_cookie)) | - pmap->pm_ttbr); } +SYSINIT(pmap_init_cnp, SI_SUB_SMP, SI_ORDER_ANY, pmap_init_cnp, NULL); static bool pmap_activate_int(pmap_t pmap)