Skip to content

Commit 181ce6b

Browse files
author
Marc Zyngier
committed
Merge branch kvm-arm64/misc-6.18 into kvmarm-master/next
* kvm-arm64/misc-6.18: : . : . : Misc improvements and bug fixes: : : - Fix XN handling in the S2 page table dumper : (20250809135356.1003520-1-r09922117@csie.ntu.edu.tw) : : - Fix sanitity checks for huge mapping with pKVM running np guests : (20250815162655.121108-1-ben.horgan@arm.com) : : - Fix use of TRBE when KVM is disabled, and Linux running under : a lesser hypervisor (2025090-etm_crash-v2-1-aa9713a7306b@oss.qualcomm.com) : : - Fix out of date MTE-related comments (20250915155234.196288-1-alexandru.elisei@arm.com) : : - Fix PSCI BE support when running a NV guest (20250916161103.1040727-1-maz@kernel.org) : : - Fix page reference leak when refusing to map a page due to mismatched attributes : (20250917130737.2139403-1-tabba@google.com) : : - Add trap handling for PMSDSFR_EL1 : (20250901-james-perf-feat_spe_eft-v8-7-2e2738f24559@linaro.org) : : - Add advertisement from FEAT_LSFE (Large System Float Extension) : (20250918-arm64-lsfe-v4-1-0abc712101c7@kernel.org) : . KVM: arm64: Expose FEAT_LSFE to guests KVM: arm64: Add trap configs for PMSDSFR_EL1 KVM: arm64: Fix page leak in user_mem_abort() KVM: arm64: Fix kvm_vcpu_{set,is}_be() to deal with EL2 state KVM: arm64: Update stale comment for sanitise_mte_tags() KVM: arm64: Return early from trace helpers when KVM isn't available KVM: arm64: Fix debug checking for np-guests using huge mappings KVM: arm64: ptdump: Don't test PTE_VALID alongside other attributes Signed-off-by: Marc Zyngier <maz@kernel.org>
2 parents 47f1574 + 5d20605 commit 181ce6b

8 files changed

Lines changed: 57 additions & 38 deletions

File tree

arch/arm64/include/asm/kvm_emulate.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -525,21 +525,29 @@ static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu)
525525
if (vcpu_mode_is_32bit(vcpu)) {
526526
*vcpu_cpsr(vcpu) |= PSR_AA32_E_BIT;
527527
} else {
528-
u64 sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1);
528+
enum vcpu_sysreg r;
529+
u64 sctlr;
530+
531+
r = vcpu_has_nv(vcpu) ? SCTLR_EL2 : SCTLR_EL1;
532+
533+
sctlr = vcpu_read_sys_reg(vcpu, r);
529534
sctlr |= SCTLR_ELx_EE;
530-
vcpu_write_sys_reg(vcpu, sctlr, SCTLR_EL1);
535+
vcpu_write_sys_reg(vcpu, sctlr, r);
531536
}
532537
}
533538

534539
static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu)
535540
{
541+
enum vcpu_sysreg r;
542+
u64 bit;
543+
536544
if (vcpu_mode_is_32bit(vcpu))
537545
return !!(*vcpu_cpsr(vcpu) & PSR_AA32_E_BIT);
538546

539-
if (vcpu_mode_priv(vcpu))
540-
return !!(vcpu_read_sys_reg(vcpu, SCTLR_EL1) & SCTLR_ELx_EE);
541-
else
542-
return !!(vcpu_read_sys_reg(vcpu, SCTLR_EL1) & SCTLR_EL1_E0E);
547+
r = is_hyp_ctxt(vcpu) ? SCTLR_EL2 : SCTLR_EL1;
548+
bit = vcpu_mode_priv(vcpu) ? SCTLR_ELx_EE : SCTLR_EL1_E0E;
549+
550+
return vcpu_read_sys_reg(vcpu, r) & bit;
543551
}
544552

545553
static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu,

arch/arm64/include/asm/vncr_mapping.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@
9494
#define VNCR_PMSICR_EL1 0x838
9595
#define VNCR_PMSIRR_EL1 0x840
9696
#define VNCR_PMSLATFR_EL1 0x848
97+
#define VNCR_PMSNEVFR_EL1 0x850
98+
#define VNCR_PMSDSFR_EL1 0x858
9799
#define VNCR_TRFCR_EL1 0x880
98100
#define VNCR_MPAM1_EL1 0x900
99101
#define VNCR_MPAMHCR_EL2 0x930

arch/arm64/kvm/debug.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -233,29 +233,29 @@ void kvm_debug_handle_oslar(struct kvm_vcpu *vcpu, u64 val)
233233
preempt_enable();
234234
}
235235

236-
void kvm_enable_trbe(void)
236+
static bool skip_trbe_access(bool skip_condition)
237237
{
238-
if (has_vhe() || is_protected_kvm_enabled() ||
239-
WARN_ON_ONCE(preemptible()))
240-
return;
238+
return (WARN_ON_ONCE(preemptible()) || skip_condition ||
239+
is_protected_kvm_enabled() || !is_kvm_arm_initialised());
240+
}
241241

242-
host_data_set_flag(TRBE_ENABLED);
242+
void kvm_enable_trbe(void)
243+
{
244+
if (!skip_trbe_access(has_vhe()))
245+
host_data_set_flag(TRBE_ENABLED);
243246
}
244247
EXPORT_SYMBOL_GPL(kvm_enable_trbe);
245248

246249
void kvm_disable_trbe(void)
247250
{
248-
if (has_vhe() || is_protected_kvm_enabled() ||
249-
WARN_ON_ONCE(preemptible()))
250-
return;
251-
252-
host_data_clear_flag(TRBE_ENABLED);
251+
if (!skip_trbe_access(has_vhe()))
252+
host_data_clear_flag(TRBE_ENABLED);
253253
}
254254
EXPORT_SYMBOL_GPL(kvm_disable_trbe);
255255

256256
void kvm_tracing_set_el1_configuration(u64 trfcr_while_in_guest)
257257
{
258-
if (is_protected_kvm_enabled() || WARN_ON_ONCE(preemptible()))
258+
if (skip_trbe_access(false))
259259
return;
260260

261261
if (has_vhe()) {

arch/arm64/kvm/emulate-nested.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,7 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
11851185
SR_TRAP(SYS_PMSIRR_EL1, CGT_MDCR_TPMS),
11861186
SR_TRAP(SYS_PMSLATFR_EL1, CGT_MDCR_TPMS),
11871187
SR_TRAP(SYS_PMSNEVFR_EL1, CGT_MDCR_TPMS),
1188+
SR_TRAP(SYS_PMSDSFR_EL1, CGT_MDCR_TPMS),
11881189
SR_TRAP(SYS_TRFCR_EL1, CGT_MDCR_TTRF),
11891190
SR_TRAP(SYS_TRBBASER_EL1, CGT_MDCR_E2TB),
11901191
SR_TRAP(SYS_TRBLIMITR_EL1, CGT_MDCR_E2TB),

arch/arm64/kvm/hyp/nvhe/mem_protect.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,9 +1010,12 @@ static int __check_host_shared_guest(struct pkvm_hyp_vm *vm, u64 *__phys, u64 ip
10101010
return ret;
10111011
if (!kvm_pte_valid(pte))
10121012
return -ENOENT;
1013-
if (kvm_granule_size(level) != size)
1013+
if (size && kvm_granule_size(level) != size)
10141014
return -E2BIG;
10151015

1016+
if (!size)
1017+
size = kvm_granule_size(level);
1018+
10161019
state = guest_get_page_state(pte, ipa);
10171020
if (state != PKVM_PAGE_SHARED_BORROWED)
10181021
return -EPERM;
@@ -1100,7 +1103,7 @@ int __pkvm_host_relax_perms_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu, enum kvm_
11001103
if (prot & ~KVM_PGTABLE_PROT_RWX)
11011104
return -EINVAL;
11021105

1103-
assert_host_shared_guest(vm, ipa, PAGE_SIZE);
1106+
assert_host_shared_guest(vm, ipa, 0);
11041107
guest_lock_component(vm);
11051108
ret = kvm_pgtable_stage2_relax_perms(&vm->pgt, ipa, prot, 0);
11061109
guest_unlock_component(vm);
@@ -1156,7 +1159,7 @@ int __pkvm_host_mkyoung_guest(u64 gfn, struct pkvm_hyp_vcpu *vcpu)
11561159
if (pkvm_hyp_vm_is_protected(vm))
11571160
return -EPERM;
11581161

1159-
assert_host_shared_guest(vm, ipa, PAGE_SIZE);
1162+
assert_host_shared_guest(vm, ipa, 0);
11601163
guest_lock_component(vm);
11611164
kvm_pgtable_stage2_mkyoung(&vm->pgt, ipa, 0);
11621165
guest_unlock_component(vm);

arch/arm64/kvm/mmu.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,11 +1459,8 @@ static int get_vma_page_shift(struct vm_area_struct *vma, unsigned long hva)
14591459
* able to see the page's tags and therefore they must be initialised first. If
14601460
* PG_mte_tagged is set, tags have already been initialised.
14611461
*
1462-
* The race in the test/set of the PG_mte_tagged flag is handled by:
1463-
* - preventing VM_SHARED mappings in a memslot with MTE preventing two VMs
1464-
* racing to santise the same page
1465-
* - mmap_lock protects between a VM faulting a page in and the VMM performing
1466-
* an mprotect() to add VM_MTE
1462+
* Must be called with kvm->mmu_lock held to ensure the memory remains mapped
1463+
* while the tags are zeroed.
14671464
*/
14681465
static void sanitise_mte_tags(struct kvm *kvm, kvm_pfn_t pfn,
14691466
unsigned long size)
@@ -1706,7 +1703,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
17061703
* cache maintenance.
17071704
*/
17081705
if (!kvm_supports_cacheable_pfnmap())
1709-
return -EFAULT;
1706+
ret = -EFAULT;
17101707
} else {
17111708
/*
17121709
* If the page was identified as device early by looking at
@@ -1729,7 +1726,12 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
17291726
}
17301727

17311728
if (exec_fault && s2_force_noncacheable)
1732-
return -ENOEXEC;
1729+
ret = -ENOEXEC;
1730+
1731+
if (ret) {
1732+
kvm_release_page_unused(page);
1733+
return ret;
1734+
}
17331735

17341736
/*
17351737
* Potentially reduce shadow S2 permissions to match the guest's own

arch/arm64/kvm/ptdump.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,23 @@ static const struct ptdump_prot_bits stage2_pte_bits[] = {
3232
.set = " ",
3333
.clear = "F",
3434
}, {
35-
.mask = KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
36-
.val = KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
35+
.mask = KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R,
36+
.val = KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R,
3737
.set = "R",
3838
.clear = " ",
3939
}, {
40-
.mask = KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
41-
.val = KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
40+
.mask = KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W,
41+
.val = KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W,
4242
.set = "W",
4343
.clear = " ",
4444
}, {
45-
.mask = KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
46-
.val = PTE_VALID,
47-
.set = " ",
48-
.clear = "X",
45+
.mask = KVM_PTE_LEAF_ATTR_HI_S2_XN,
46+
.val = KVM_PTE_LEAF_ATTR_HI_S2_XN,
47+
.set = "NX",
48+
.clear = "x ",
4949
}, {
50-
.mask = KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
51-
.val = KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
50+
.mask = KVM_PTE_LEAF_ATTR_LO_S2_AF,
51+
.val = KVM_PTE_LEAF_ATTR_LO_S2_AF,
5252
.set = "AF",
5353
.clear = " ",
5454
}, {

arch/arm64/kvm/sys_regs.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1757,7 +1757,8 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
17571757
val &= ~ID_AA64ISAR2_EL1_WFxT;
17581758
break;
17591759
case SYS_ID_AA64ISAR3_EL1:
1760-
val &= ID_AA64ISAR3_EL1_FPRCVT | ID_AA64ISAR3_EL1_FAMINMAX;
1760+
val &= ID_AA64ISAR3_EL1_FPRCVT | ID_AA64ISAR3_EL1_LSFE |
1761+
ID_AA64ISAR3_EL1_FAMINMAX;
17611762
break;
17621763
case SYS_ID_AA64MMFR2_EL1:
17631764
val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK;
@@ -3179,6 +3180,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
31793180
ID_AA64ISAR2_EL1_APA3 |
31803181
ID_AA64ISAR2_EL1_GPA3)),
31813182
ID_WRITABLE(ID_AA64ISAR3_EL1, (ID_AA64ISAR3_EL1_FPRCVT |
3183+
ID_AA64ISAR3_EL1_LSFE |
31823184
ID_AA64ISAR3_EL1_FAMINMAX)),
31833185
ID_UNALLOCATED(6,4),
31843186
ID_UNALLOCATED(6,5),
@@ -3274,6 +3276,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
32743276
{ SYS_DESC(SYS_PMBLIMITR_EL1), undef_access },
32753277
{ SYS_DESC(SYS_PMBPTR_EL1), undef_access },
32763278
{ SYS_DESC(SYS_PMBSR_EL1), undef_access },
3279+
{ SYS_DESC(SYS_PMSDSFR_EL1), undef_access },
32773280
/* PMBIDR_EL1 is not trapped */
32783281

32793282
{ PMU_SYS_REG(PMINTENSET_EL1),

0 commit comments

Comments
 (0)