Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 (20250902-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>

+57 -38
+14 -6
arch/arm64/include/asm/kvm_emulate.h
··· 525 525 if (vcpu_mode_is_32bit(vcpu)) { 526 526 *vcpu_cpsr(vcpu) |= PSR_AA32_E_BIT; 527 527 } 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); 529 534 sctlr |= SCTLR_ELx_EE; 530 - vcpu_write_sys_reg(vcpu, sctlr, SCTLR_EL1); 535 + vcpu_write_sys_reg(vcpu, sctlr, r); 531 536 } 532 537 } 533 538 534 539 static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu) 535 540 { 541 + enum vcpu_sysreg r; 542 + u64 bit; 543 + 536 544 if (vcpu_mode_is_32bit(vcpu)) 537 545 return !!(*vcpu_cpsr(vcpu) & PSR_AA32_E_BIT); 538 546 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; 543 551 } 544 552 545 553 static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu,
+2
arch/arm64/include/asm/vncr_mapping.h
··· 94 94 #define VNCR_PMSICR_EL1 0x838 95 95 #define VNCR_PMSIRR_EL1 0x840 96 96 #define VNCR_PMSLATFR_EL1 0x848 97 + #define VNCR_PMSNEVFR_EL1 0x850 98 + #define VNCR_PMSDSFR_EL1 0x858 97 99 #define VNCR_TRFCR_EL1 0x880 98 100 #define VNCR_MPAM1_EL1 0x900 99 101 #define VNCR_MPAMHCR_EL2 0x930
+11 -11
arch/arm64/kvm/debug.c
··· 233 233 preempt_enable(); 234 234 } 235 235 236 + static bool skip_trbe_access(bool skip_condition) 237 + { 238 + return (WARN_ON_ONCE(preemptible()) || skip_condition || 239 + is_protected_kvm_enabled() || !is_kvm_arm_initialised()); 240 + } 241 + 236 242 void kvm_enable_trbe(void) 237 243 { 238 - if (has_vhe() || is_protected_kvm_enabled() || 239 - WARN_ON_ONCE(preemptible())) 240 - return; 241 - 242 - host_data_set_flag(TRBE_ENABLED); 244 + if (!skip_trbe_access(has_vhe())) 245 + host_data_set_flag(TRBE_ENABLED); 243 246 } 244 247 EXPORT_SYMBOL_GPL(kvm_enable_trbe); 245 248 246 249 void kvm_disable_trbe(void) 247 250 { 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); 253 253 } 254 254 EXPORT_SYMBOL_GPL(kvm_disable_trbe); 255 255 256 256 void kvm_tracing_set_el1_configuration(u64 trfcr_while_in_guest) 257 257 { 258 - if (is_protected_kvm_enabled() || WARN_ON_ONCE(preemptible())) 258 + if (skip_trbe_access(false)) 259 259 return; 260 260 261 261 if (has_vhe()) {
+1
arch/arm64/kvm/emulate-nested.c
··· 1185 1185 SR_TRAP(SYS_PMSIRR_EL1, CGT_MDCR_TPMS), 1186 1186 SR_TRAP(SYS_PMSLATFR_EL1, CGT_MDCR_TPMS), 1187 1187 SR_TRAP(SYS_PMSNEVFR_EL1, CGT_MDCR_TPMS), 1188 + SR_TRAP(SYS_PMSDSFR_EL1, CGT_MDCR_TPMS), 1188 1189 SR_TRAP(SYS_TRFCR_EL1, CGT_MDCR_TTRF), 1189 1190 SR_TRAP(SYS_TRBBASER_EL1, CGT_MDCR_E2TB), 1190 1191 SR_TRAP(SYS_TRBLIMITR_EL1, CGT_MDCR_E2TB),
+6 -3
arch/arm64/kvm/hyp/nvhe/mem_protect.c
··· 1010 1010 return ret; 1011 1011 if (!kvm_pte_valid(pte)) 1012 1012 return -ENOENT; 1013 - if (kvm_granule_size(level) != size) 1013 + if (size && kvm_granule_size(level) != size) 1014 1014 return -E2BIG; 1015 + 1016 + if (!size) 1017 + size = kvm_granule_size(level); 1015 1018 1016 1019 state = guest_get_page_state(pte, ipa); 1017 1020 if (state != PKVM_PAGE_SHARED_BORROWED) ··· 1103 1100 if (prot & ~KVM_PGTABLE_PROT_RWX) 1104 1101 return -EINVAL; 1105 1102 1106 - assert_host_shared_guest(vm, ipa, PAGE_SIZE); 1103 + assert_host_shared_guest(vm, ipa, 0); 1107 1104 guest_lock_component(vm); 1108 1105 ret = kvm_pgtable_stage2_relax_perms(&vm->pgt, ipa, prot, 0); 1109 1106 guest_unlock_component(vm); ··· 1159 1156 if (pkvm_hyp_vm_is_protected(vm)) 1160 1157 return -EPERM; 1161 1158 1162 - assert_host_shared_guest(vm, ipa, PAGE_SIZE); 1159 + assert_host_shared_guest(vm, ipa, 0); 1163 1160 guest_lock_component(vm); 1164 1161 kvm_pgtable_stage2_mkyoung(&vm->pgt, ipa, 0); 1165 1162 guest_unlock_component(vm);
+9 -7
arch/arm64/kvm/mmu.c
··· 1459 1459 * able to see the page's tags and therefore they must be initialised first. If 1460 1460 * PG_mte_tagged is set, tags have already been initialised. 1461 1461 * 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. 1467 1464 */ 1468 1465 static void sanitise_mte_tags(struct kvm *kvm, kvm_pfn_t pfn, 1469 1466 unsigned long size) ··· 1703 1706 * cache maintenance. 1704 1707 */ 1705 1708 if (!kvm_supports_cacheable_pfnmap()) 1706 - return -EFAULT; 1709 + ret = -EFAULT; 1707 1710 } else { 1708 1711 /* 1709 1712 * If the page was identified as device early by looking at ··· 1726 1729 } 1727 1730 1728 1731 if (exec_fault && s2_force_noncacheable) 1729 - return -ENOEXEC; 1732 + ret = -ENOEXEC; 1733 + 1734 + if (ret) { 1735 + kvm_release_page_unused(page); 1736 + return ret; 1737 + } 1730 1738 1731 1739 /* 1732 1740 * Potentially reduce shadow S2 permissions to match the guest's own
+10 -10
arch/arm64/kvm/ptdump.c
··· 32 32 .set = " ", 33 33 .clear = "F", 34 34 }, { 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, 37 37 .set = "R", 38 38 .clear = " ", 39 39 }, { 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, 42 42 .set = "W", 43 43 .clear = " ", 44 44 }, { 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 ", 49 49 }, { 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, 52 52 .set = "AF", 53 53 .clear = " ", 54 54 }, {
+4 -1
arch/arm64/kvm/sys_regs.c
··· 1757 1757 val &= ~ID_AA64ISAR2_EL1_WFxT; 1758 1758 break; 1759 1759 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; 1761 1762 break; 1762 1763 case SYS_ID_AA64MMFR2_EL1: 1763 1764 val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK; ··· 3180 3179 ID_AA64ISAR2_EL1_APA3 | 3181 3180 ID_AA64ISAR2_EL1_GPA3)), 3182 3181 ID_WRITABLE(ID_AA64ISAR3_EL1, (ID_AA64ISAR3_EL1_FPRCVT | 3182 + ID_AA64ISAR3_EL1_LSFE | 3183 3183 ID_AA64ISAR3_EL1_FAMINMAX)), 3184 3184 ID_UNALLOCATED(6,4), 3185 3185 ID_UNALLOCATED(6,5), ··· 3276 3274 { SYS_DESC(SYS_PMBLIMITR_EL1), undef_access }, 3277 3275 { SYS_DESC(SYS_PMBPTR_EL1), undef_access }, 3278 3276 { SYS_DESC(SYS_PMBSR_EL1), undef_access }, 3277 + { SYS_DESC(SYS_PMSDSFR_EL1), undef_access }, 3279 3278 /* PMBIDR_EL1 is not trapped */ 3280 3279 3281 3280 { PMU_SYS_REG(PMINTENSET_EL1),