Skip to content

Commit b53d4a2

Browse files
misalehoupton
authored andcommitted
KVM: arm64: Use BTI for nvhe
CONFIG_ARM64_BTI_KERNEL compiles the kernel to support ARMv8.5-BTI. However, the nvhe code doesn't make use of it as it doesn't map any pages with Guarded Page(GP) bit. kvm pgtable code is modified to map executable pages with GP bit if BTI is enabled for the kernel. At hyp init, SCTLR_EL2.BT is set to 1 to match EL1 configuration (SCTLR_EL1.BT1) set in bti_enable(). One difference between kernel and nvhe code, is that the kernel maps .text with GP while nvhe maps all the executable pages, this makes nvhe code need to deal with special initialization code coming from other executable sections (.idmap.text). For this we need to add bti instruction at the beginning of __kvm_handle_stub_hvc as it can be called by __host_hvc through branch instruction(br) and unlike SYM_FUNC_START, SYM_CODE_START doesn’t add bti instruction at the beginning, and it can’t be modified to add it as it is used with vector tables. Another solution which is more intrusive is to convert __kvm_handle_stub_hvc to a function and inject “bti jc” instead of “bti c” in SYM_FUNC_START Signed-off-by: Mostafa Saleh <smostafa@google.com> Link: https://lore.kernel.org/r/20230530150845.2856828-1-smostafa@google.com Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
1 parent c876c3f commit b53d4a2

3 files changed

Lines changed: 19 additions & 1 deletion

File tree

arch/arm64/include/asm/sysreg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@
558558
(BIT(18)) | (BIT(22)) | (BIT(23)) | (BIT(28)) | \
559559
(BIT(29)))
560560

561+
#define SCTLR_EL2_BT (BIT(36))
561562
#ifdef CONFIG_CPU_BIG_ENDIAN
562563
#define ENDIAN_SET_EL2 SCTLR_ELx_EE
563564
#else

arch/arm64/kvm/hyp/nvhe/hyp-init.S

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ alternative_if ARM64_HAS_ADDRESS_AUTH
128128
SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
129129
orr x0, x0, x1
130130
alternative_else_nop_endif
131+
132+
#ifdef CONFIG_ARM64_BTI_KERNEL
133+
alternative_if ARM64_BTI
134+
orr x0, x0, #SCTLR_EL2_BT
135+
alternative_else_nop_endif
136+
#endif /* CONFIG_ARM64_BTI_KERNEL */
137+
131138
msr sctlr_el2, x0
132139
isb
133140

@@ -196,6 +203,11 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu)
196203
SYM_CODE_END(__kvm_hyp_init_cpu)
197204

198205
SYM_CODE_START(__kvm_handle_stub_hvc)
206+
/*
207+
* __kvm_handle_stub_hvc called from __host_hvc through branch instruction(br) so
208+
* we need bti j at beginning.
209+
*/
210+
bti j
199211
cmp x0, #HVC_SOFT_RESTART
200212
b.ne 1f
201213

arch/arm64/kvm/hyp/pgtable.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,16 @@
3434
#define KVM_PTE_LEAF_ATTR_LO_S2_SH_IS 3
3535
#define KVM_PTE_LEAF_ATTR_LO_S2_AF BIT(10)
3636

37-
#define KVM_PTE_LEAF_ATTR_HI GENMASK(63, 51)
37+
#define KVM_PTE_LEAF_ATTR_HI GENMASK(63, 50)
3838

3939
#define KVM_PTE_LEAF_ATTR_HI_SW GENMASK(58, 55)
4040

4141
#define KVM_PTE_LEAF_ATTR_HI_S1_XN BIT(54)
4242

4343
#define KVM_PTE_LEAF_ATTR_HI_S2_XN BIT(54)
4444

45+
#define KVM_PTE_LEAF_ATTR_HI_S1_GP BIT(50)
46+
4547
#define KVM_PTE_LEAF_ATTR_S2_PERMS (KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | \
4648
KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
4749
KVM_PTE_LEAF_ATTR_HI_S2_XN)
@@ -371,6 +373,9 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep)
371373

372374
if (device)
373375
return -EINVAL;
376+
377+
if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) && system_supports_bti())
378+
attr |= KVM_PTE_LEAF_ATTR_HI_S1_GP;
374379
} else {
375380
attr |= KVM_PTE_LEAF_ATTR_HI_S1_XN;
376381
}

0 commit comments

Comments
 (0)