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 @@ -87,6 +87,7 @@ * 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 @@ 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 @@ 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 @@ 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 @@ 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 --- 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 --- a/sys/arm64/include/pte.h +++ b/sys/arm64/include/pte.h @@ -73,7 +73,8 @@ #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