The branch main has been updated by andrew:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=e9ab9910fa12ce7b042a83a25dfaf5efdb631a32

commit e9ab9910fa12ce7b042a83a25dfaf5efdb631a32
Author:     Andrew Turner <and...@freebsd.org>
AuthorDate: 2025-03-27 13:47:28 +0000
Commit:     Andrew Turner <and...@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

Reply via email to