git: e9ab9910fa12 - main - arm64: Clean up enabling in-kernel BTI
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 27 Mar 2025 13:47:47 UTC
The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=e9ab9910fa12ce7b042a83a25dfaf5efdb631a32 commit e9ab9910fa12ce7b042a83a25dfaf5efdb631a32 Author: Andrew Turner <andrew@FreeBSD.org> AuthorDate: 2025-03-27 13:47:28 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2025-03-27 13:47:28 +0000 arm64: Clean up enabling in-kernel BTI Some hypervisors incorrectly use the Guarded Page (GP) bit from the last level page table as part of the output address. This causes them to raise an address size exception as the calculated physical address is too large. Only set the GP bit in the page table when BTI is present. Reviewed by: alc, kib, markj Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D49154 --- sys/arm64/arm64/locore.S | 22 +++++++++++++++++++--- sys/arm64/arm64/pmap.c | 3 ++- sys/arm64/include/pte.h | 3 ++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S index 88193b6c93f7..9cf23fcf13a1 100644 --- a/sys/arm64/arm64/locore.S +++ b/sys/arm64/arm64/locore.S @@ -87,6 +87,7 @@ ENTRY(_start) * x26 = Kernel L1 table * x24 = TTBR1 table * x22 = PTE shareability attributes + * x21 = BTI guarded page attribute if supported */ /* Enable the mmu */ @@ -136,9 +137,13 @@ virtdone: str x27, [x0, #BP_KERN_TTBR0] str x23, [x0, #BP_BOOT_EL] - /* Set this before it's used in kasan_init_early */ + /* Set these before they are used in kasan_init_early */ adrp x1, pmap_sh_attr str x22, [x1, :lo12:pmap_sh_attr] +#ifdef __ARM_FEATURE_BTI_DEFAULT + adrp x1, pmap_gp_attr + str x21, [x1, :lo12:pmap_gp_attr] +#endif #ifdef KASAN /* Save bootparams */ @@ -487,6 +492,17 @@ LENTRY(create_pagetables) cmp x6, x27 b.lo 1b +#ifdef __ARM_FEATURE_BTI_DEFAULT + /* + * Check if the CPU supports BTI + */ + mrs x6, id_aa64pfr1_el1 /* Read the ID register */ + and x6, x6, ID_AA64PFR1_BT_MASK /* Mask the field we need */ + cmp x6, xzr /* Check it's non-zero */ + cset x6, ne /* x6 is set if non-zero */ + lsl x21, x6, ATTR_S1_GP_SHIFT /* Shift to the correct bit */ +#endif + /* * Find the shareability attribute we should use. If FEAT_LPA2 is * enabled then the shareability field is moved from the page table @@ -785,7 +801,7 @@ LENTRY(build_l2_block_pagetable) orr x12, x12, #(ATTR_AF) orr x12, x12, #(ATTR_S1_UXN) #ifdef __ARM_FEATURE_BTI_DEFAULT - orr x12, x12, #(ATTR_S1_GP) + orr x12, x12, x21 #endif /* Set the shareability attribute */ orr x12, x12, x22 @@ -863,7 +879,7 @@ LENTRY(build_l3_page_pagetable) orr x12, x12, #(ATTR_AF) orr x12, x12, #(ATTR_S1_UXN) #ifdef __ARM_FEATURE_BTI_DEFAULT - orr x12, x12, #(ATTR_S1_GP) + orr x12, x12, x21 #endif /* Set the shareability attribute */ orr x12, x12, x22 diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 5a3dbbf00203..14ef7dd0169c 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -182,7 +182,8 @@ #define pmap_l2_pindex(v) ((v) >> L2_SHIFT) #ifdef __ARM_FEATURE_BTI_DEFAULT -#define ATTR_KERN_GP ATTR_S1_GP +pt_entry_t __read_mostly pmap_gp_attr; +#define ATTR_KERN_GP pmap_gp_attr #else #define ATTR_KERN_GP 0 #endif diff --git a/sys/arm64/include/pte.h b/sys/arm64/include/pte.h index ae6a8694f6c4..464d8c941c56 100644 --- a/sys/arm64/include/pte.h +++ b/sys/arm64/include/pte.h @@ -73,7 +73,8 @@ typedef uint64_t pt_entry_t; /* page table entry */ #define ATTR_CONTIGUOUS (1UL << 52) #define ATTR_DBM (1UL << 51) -#define ATTR_S1_GP (1UL << 50) +#define ATTR_S1_GP_SHIFT 50 +#define ATTR_S1_GP (1UL << ATTR_S1_GP_SHIFT) /* * Largest possible output address field for a level 3 page. Block