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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch kvm-arm64/pkvm-features-6.20 into kvmarm-master/next

* kvm-arm64/pkvm-features-6.20:
: .
: pKVM guest feature trapping fixes, courtesy of Fuad Tabba.
: .
KVM: arm64: Prevent host from managing timer offsets for protected VMs
KVM: arm64: Check whether a VM IOCTL is allowed in pKVM
KVM: arm64: Track KVM IOCTLs and their associated KVM caps
KVM: arm64: Do not allow KVM_CAP_ARM_MTE for any guest in pKVM
KVM: arm64: Include VM type when checking VM capabilities in pKVM
KVM: arm64: Introduce helper to calculate fault IPA offset
KVM: arm64: Fix MTE flag initialization for protected VMs
KVM: arm64: Fix Trace Buffer trap polarity for protected VMs
KVM: arm64: Fix Trace Buffer trapping for protected VMs

Signed-off-by: Marc Zyngier <maz@kernel.org>

+108 -24
+2
arch/arm64/include/asm/kvm_arm.h
··· 316 316 #define PAR_TO_HPFAR(par) \ 317 317 (((par) & GENMASK_ULL(52 - 1, 12)) >> 8) 318 318 319 + #define FAR_TO_FIPA_OFFSET(far) ((far) & GENMASK_ULL(11, 0)) 320 + 319 321 #define ECN(x) { ESR_ELx_EC_##x, #x } 320 322 321 323 #define kvm_arm_exception_class \
+2
arch/arm64/include/asm/kvm_host.h
··· 1656 1656 p; \ 1657 1657 }) 1658 1658 1659 + long kvm_get_cap_for_kvm_ioctl(unsigned int ioctl, long *ext); 1660 + 1659 1661 #endif /* __ARM64_KVM_HOST_H__ */
+28 -4
arch/arm64/include/asm/kvm_pkvm.h
··· 9 9 #include <linux/arm_ffa.h> 10 10 #include <linux/memblock.h> 11 11 #include <linux/scatterlist.h> 12 + #include <asm/kvm_host.h> 12 13 #include <asm/kvm_pgtable.h> 13 14 14 15 /* Maximum number of VMs that can co-exist under pKVM. */ ··· 24 23 int pkvm_create_hyp_vcpu(struct kvm_vcpu *vcpu); 25 24 26 25 /* 27 - * This functions as an allow-list of protected VM capabilities. 28 - * Features not explicitly allowed by this function are denied. 26 + * Check whether the specific capability is allowed in pKVM. 27 + * 28 + * Certain features are allowed only for non-protected VMs in pKVM, which is why 29 + * this takes the VM (kvm) as a parameter. 29 30 */ 30 - static inline bool kvm_pvm_ext_allowed(long ext) 31 + static inline bool kvm_pkvm_ext_allowed(struct kvm *kvm, long ext) 31 32 { 32 33 switch (ext) { 33 34 case KVM_CAP_IRQCHIP: ··· 45 42 case KVM_CAP_ARM_PTRAUTH_ADDRESS: 46 43 case KVM_CAP_ARM_PTRAUTH_GENERIC: 47 44 return true; 48 - default: 45 + case KVM_CAP_ARM_MTE: 49 46 return false; 47 + default: 48 + return !kvm || !kvm_vm_is_protected(kvm); 50 49 } 50 + } 51 + 52 + /* 53 + * Check whether the KVM VM IOCTL is allowed in pKVM. 54 + * 55 + * Certain features are allowed only for non-protected VMs in pKVM, which is why 56 + * this takes the VM (kvm) as a parameter. 57 + */ 58 + static inline bool kvm_pkvm_ioctl_allowed(struct kvm *kvm, unsigned int ioctl) 59 + { 60 + long ext; 61 + int r; 62 + 63 + r = kvm_get_cap_for_kvm_ioctl(ioctl, &ext); 64 + 65 + if (WARN_ON_ONCE(r < 0)) 66 + return false; 67 + 68 + return kvm_pkvm_ext_allowed(kvm, ext); 51 69 } 52 70 53 71 extern struct memblock_region kvm_nvhe_sym(hyp_memory)[];
+13 -5
arch/arm64/kvm/arch_timer.c
··· 1056 1056 1057 1057 ctxt->timer_id = timerid; 1058 1058 1059 - if (timerid == TIMER_VTIMER) 1060 - ctxt->offset.vm_offset = &kvm->arch.timer_data.voffset; 1061 - else 1062 - ctxt->offset.vm_offset = &kvm->arch.timer_data.poffset; 1059 + if (!kvm_vm_is_protected(vcpu->kvm)) { 1060 + if (timerid == TIMER_VTIMER) 1061 + ctxt->offset.vm_offset = &kvm->arch.timer_data.voffset; 1062 + else 1063 + ctxt->offset.vm_offset = &kvm->arch.timer_data.poffset; 1064 + } else { 1065 + ctxt->offset.vm_offset = NULL; 1066 + } 1063 1067 1064 1068 hrtimer_setup(&ctxt->hrtimer, kvm_hrtimer_expire, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD); 1065 1069 ··· 1087 1083 timer_context_init(vcpu, i); 1088 1084 1089 1085 /* Synchronize offsets across timers of a VM if not already provided */ 1090 - if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) { 1086 + if (!vcpu_is_protected(vcpu) && 1087 + !test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) { 1091 1088 timer_set_offset(vcpu_vtimer(vcpu), kvm_phys_timer_read()); 1092 1089 timer_set_offset(vcpu_ptimer(vcpu), 0); 1093 1090 } ··· 1690 1685 int ret = 0; 1691 1686 1692 1687 if (offset->reserved) 1688 + return -EINVAL; 1689 + 1690 + if (kvm_vm_is_protected(kvm)) 1693 1691 return -EINVAL; 1694 1692 1695 1693 mutex_lock(&kvm->lock);
+50 -2
arch/arm64/kvm/arm.c
··· 58 58 static enum kvm_wfx_trap_policy kvm_wfi_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK; 59 59 static enum kvm_wfx_trap_policy kvm_wfe_trap_policy __read_mostly = KVM_WFX_NOTRAP_SINGLE_TASK; 60 60 61 + /* 62 + * Tracks KVM IOCTLs and their associated KVM capabilities. 63 + */ 64 + struct kvm_ioctl_cap_map { 65 + unsigned int ioctl; 66 + long ext; 67 + }; 68 + 69 + /* Make KVM_CAP_NR_VCPUS the reference for features we always supported */ 70 + #define KVM_CAP_ARM_BASIC KVM_CAP_NR_VCPUS 71 + 72 + /* 73 + * Sorted by ioctl to allow for potential binary search, 74 + * though linear scan is sufficient for this size. 75 + */ 76 + static const struct kvm_ioctl_cap_map vm_ioctl_caps[] = { 77 + { KVM_CREATE_IRQCHIP, KVM_CAP_IRQCHIP }, 78 + { KVM_ARM_SET_DEVICE_ADDR, KVM_CAP_ARM_SET_DEVICE_ADDR }, 79 + { KVM_ARM_MTE_COPY_TAGS, KVM_CAP_ARM_MTE }, 80 + { KVM_SET_DEVICE_ATTR, KVM_CAP_DEVICE_CTRL }, 81 + { KVM_GET_DEVICE_ATTR, KVM_CAP_DEVICE_CTRL }, 82 + { KVM_HAS_DEVICE_ATTR, KVM_CAP_DEVICE_CTRL }, 83 + { KVM_ARM_SET_COUNTER_OFFSET, KVM_CAP_COUNTER_OFFSET }, 84 + { KVM_ARM_GET_REG_WRITABLE_MASKS, KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES }, 85 + { KVM_ARM_PREFERRED_TARGET, KVM_CAP_ARM_BASIC }, 86 + }; 87 + 88 + /* 89 + * Set *ext to the capability. 90 + * Return 0 if found, or -EINVAL if no IOCTL matches. 91 + */ 92 + long kvm_get_cap_for_kvm_ioctl(unsigned int ioctl, long *ext) 93 + { 94 + int i; 95 + 96 + for (i = 0; i < ARRAY_SIZE(vm_ioctl_caps); i++) { 97 + if (vm_ioctl_caps[i].ioctl == ioctl) { 98 + *ext = vm_ioctl_caps[i].ext; 99 + return 0; 100 + } 101 + } 102 + 103 + return -EINVAL; 104 + } 105 + 61 106 DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector); 62 107 63 108 DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_base); ··· 132 87 if (cap->flags) 133 88 return -EINVAL; 134 89 135 - if (kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(cap->cap)) 90 + if (is_protected_kvm_enabled() && !kvm_pkvm_ext_allowed(kvm, cap->cap)) 136 91 return -EINVAL; 137 92 138 93 switch (cap->cap) { ··· 348 303 { 349 304 int r; 350 305 351 - if (kvm && kvm_vm_is_protected(kvm) && !kvm_pvm_ext_allowed(ext)) 306 + if (is_protected_kvm_enabled() && !kvm_pkvm_ext_allowed(kvm, ext)) 352 307 return 0; 353 308 354 309 switch (ext) { ··· 1938 1893 struct kvm *kvm = filp->private_data; 1939 1894 void __user *argp = (void __user *)arg; 1940 1895 struct kvm_device_attr attr; 1896 + 1897 + if (is_protected_kvm_enabled() && !kvm_pkvm_ioctl_allowed(kvm, ioctl)) 1898 + return -EINVAL; 1941 1899 1942 1900 switch (ioctl) { 1943 1901 case KVM_CREATE_IRQCHIP: {
+9 -9
arch/arm64/kvm/hyp/nvhe/pkvm.c
··· 117 117 if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceFilt, IMP)) 118 118 val |= MDCR_EL2_TTRF; 119 119 120 - if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, ExtTrcBuff, IMP)) 121 - val |= MDCR_EL2_E2TB_MASK; 120 + if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP)) 121 + val &= ~MDCR_EL2_E2TB_MASK; 122 122 123 123 /* Trap Debug Communications Channel registers */ 124 124 if (!kvm_has_feat(kvm, ID_AA64MMFR0_EL1, FGT, IMP)) ··· 339 339 /* Preserve the vgic model so that GICv3 emulation works */ 340 340 hyp_vm->kvm.arch.vgic.vgic_model = host_kvm->arch.vgic.vgic_model; 341 341 342 - if (test_bit(KVM_ARCH_FLAG_MTE_ENABLED, &host_kvm->arch.flags)) 343 - set_bit(KVM_ARCH_FLAG_MTE_ENABLED, &kvm->arch.flags); 344 - 345 342 /* No restrictions for non-protected VMs. */ 346 343 if (!kvm_vm_is_protected(kvm)) { 347 344 hyp_vm->kvm.arch.flags = host_arch_flags; ··· 353 356 return; 354 357 } 355 358 359 + if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_MTE)) 360 + kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_MTE_ENABLED); 361 + 356 362 bitmap_zero(allowed_features, KVM_VCPU_MAX_FEATURES); 357 363 358 364 set_bit(KVM_ARM_VCPU_PSCI_0_2, allowed_features); 359 365 360 - if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PMU_V3)) 366 + if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_PMU_V3)) 361 367 set_bit(KVM_ARM_VCPU_PMU_V3, allowed_features); 362 368 363 - if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_ADDRESS)) 369 + if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_PTRAUTH_ADDRESS)) 364 370 set_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, allowed_features); 365 371 366 - if (kvm_pvm_ext_allowed(KVM_CAP_ARM_PTRAUTH_GENERIC)) 372 + if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_PTRAUTH_GENERIC)) 367 373 set_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, allowed_features); 368 374 369 - if (kvm_pvm_ext_allowed(KVM_CAP_ARM_SVE)) { 375 + if (kvm_pkvm_ext_allowed(kvm, KVM_CAP_ARM_SVE)) { 370 376 set_bit(KVM_ARM_VCPU_SVE, allowed_features); 371 377 kvm->arch.flags |= host_arch_flags & BIT(KVM_ARCH_FLAG_GUEST_HAS_SVE); 372 378 }
+1 -1
arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c
··· 44 44 45 45 /* Build the full address */ 46 46 fault_ipa = kvm_vcpu_get_fault_ipa(vcpu); 47 - fault_ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0); 47 + fault_ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu)); 48 48 49 49 /* If not for GICV, move on */ 50 50 if (fault_ipa < vgic->vgic_cpu_base ||
+1 -1
arch/arm64/kvm/inject_fault.c
··· 296 296 unsigned long addr, esr; 297 297 298 298 addr = kvm_vcpu_get_fault_ipa(vcpu); 299 - addr |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0); 299 + addr |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu)); 300 300 301 301 __kvm_inject_sea(vcpu, kvm_vcpu_trap_is_iabt(vcpu), addr); 302 302
+2 -2
arch/arm64/kvm/mmu.c
··· 2079 2079 2080 2080 /* Falls between the IPA range and the PARange? */ 2081 2081 if (fault_ipa >= BIT_ULL(VTCR_EL2_IPA(vcpu->arch.hw_mmu->vtcr))) { 2082 - fault_ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0); 2082 + fault_ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu)); 2083 2083 2084 2084 return kvm_inject_sea(vcpu, is_iabt, fault_ipa); 2085 2085 } ··· 2185 2185 * faulting VA. This is always 12 bits, irrespective 2186 2186 * of the page size. 2187 2187 */ 2188 - ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0); 2188 + ipa |= FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu)); 2189 2189 ret = io_mem_abort(vcpu, ipa); 2190 2190 goto out_unlock; 2191 2191 }