From: Greg Kroah-Hartman Date: Mon, 15 Mar 2021 11:31:25 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.4.262~16 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3c93b6ff2ea3c362a961010ff2d9e4c824a157d9;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: kvm-arm64-ensure-i-cache-isolation-between-vcpus-of-a-same-vm.patch kvm-arm64-reject-vm-creation-when-the-default-ipa-size-is-unsupported.patch --- diff --git a/queue-5.4/kvm-arm64-ensure-i-cache-isolation-between-vcpus-of-a-same-vm.patch b/queue-5.4/kvm-arm64-ensure-i-cache-isolation-between-vcpus-of-a-same-vm.patch new file mode 100644 index 00000000000..758f53a5ba4 --- /dev/null +++ b/queue-5.4/kvm-arm64-ensure-i-cache-isolation-between-vcpus-of-a-same-vm.patch @@ -0,0 +1,132 @@ +From foo@baz Mon Mar 15 12:27:33 PM CET 2021 +From: Marc Zyngier +Date: Mon, 15 Mar 2021 11:10:00 +0000 +Subject: KVM: arm64: Ensure I-cache isolation between vcpus of a same VM +To: gregkh@linuxfoundation.org +Cc: kvmarm@lists.cs.columbia.edu, kernel-team@android.com, stable@vger.kernel.org, Will Deacon , Catalin Marinas +Message-ID: <20210315111000.4136196-1-maz@kernel.org> + +From: Marc Zyngier + +Commit 01dc9262ff5797b675c32c0c6bc682777d23de05 upstream. + +It recently became apparent that the ARMv8 architecture has interesting +rules regarding attributes being used when fetching instructions +if the MMU is off at Stage-1. + +In this situation, the CPU is allowed to fetch from the PoC and +allocate into the I-cache (unless the memory is mapped with +the XN attribute at Stage-2). + +If we transpose this to vcpus sharing a single physical CPU, +it is possible for a vcpu running with its MMU off to influence +another vcpu running with its MMU on, as the latter is expected to +fetch from the PoU (and self-patching code doesn't flush below that +level). + +In order to solve this, reuse the vcpu-private TLB invalidation +code to apply the same policy to the I-cache, nuking it every time +the vcpu runs on a physical CPU that ran another vcpu of the same +VM in the past. + +This involve renaming __kvm_tlb_flush_local_vmid() to +__kvm_flush_cpu_context(), and inserting a local i-cache invalidation +there. + +Cc: stable@vger.kernel.org +Signed-off-by: Marc Zyngier +Acked-by: Will Deacon +Acked-by: Catalin Marinas +Link: https://lore.kernel.org/r/20210303164505.68492-1-maz@kernel.org +[maz: added 32bit ARM support] +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/include/asm/kvm_asm.h | 2 +- + arch/arm/kvm/hyp/tlb.c | 3 ++- + arch/arm64/include/asm/kvm_asm.h | 2 +- + arch/arm64/kvm/hyp/tlb.c | 3 ++- + virt/kvm/arm/arm.c | 8 +++++++- + 5 files changed, 13 insertions(+), 5 deletions(-) + +--- a/arch/arm/include/asm/kvm_asm.h ++++ b/arch/arm/include/asm/kvm_asm.h +@@ -56,7 +56,7 @@ extern char __kvm_hyp_init_end[]; + extern void __kvm_flush_vm_context(void); + extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); + extern void __kvm_tlb_flush_vmid(struct kvm *kvm); +-extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu); ++extern void __kvm_flush_cpu_context(struct kvm_vcpu *vcpu); + + extern void __kvm_timer_set_cntvoff(u32 cntvoff_low, u32 cntvoff_high); + +--- a/arch/arm/kvm/hyp/tlb.c ++++ b/arch/arm/kvm/hyp/tlb.c +@@ -45,7 +45,7 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa + __kvm_tlb_flush_vmid(kvm); + } + +-void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu) ++void __hyp_text __kvm_flush_cpu_context(struct kvm_vcpu *vcpu) + { + struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm); + +@@ -54,6 +54,7 @@ void __hyp_text __kvm_tlb_flush_local_vm + isb(); + + write_sysreg(0, TLBIALL); ++ write_sysreg(0, ICIALLU); + dsb(nsh); + isb(); + +--- a/arch/arm64/include/asm/kvm_asm.h ++++ b/arch/arm64/include/asm/kvm_asm.h +@@ -60,7 +60,7 @@ extern char __kvm_hyp_vector[]; + extern void __kvm_flush_vm_context(void); + extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); + extern void __kvm_tlb_flush_vmid(struct kvm *kvm); +-extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu); ++extern void __kvm_flush_cpu_context(struct kvm_vcpu *vcpu); + + extern void __kvm_timer_set_cntvoff(u32 cntvoff_low, u32 cntvoff_high); + +--- a/arch/arm64/kvm/hyp/tlb.c ++++ b/arch/arm64/kvm/hyp/tlb.c +@@ -182,7 +182,7 @@ void __hyp_text __kvm_tlb_flush_vmid(str + __tlb_switch_to_host(kvm, &cxt); + } + +-void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu) ++void __hyp_text __kvm_flush_cpu_context(struct kvm_vcpu *vcpu) + { + struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm); + struct tlb_inv_context cxt; +@@ -191,6 +191,7 @@ void __hyp_text __kvm_tlb_flush_local_vm + __tlb_switch_to_guest(kvm, &cxt); + + __tlbi(vmalle1); ++ asm volatile("ic iallu"); + dsb(nsh); + isb(); + +--- a/virt/kvm/arm/arm.c ++++ b/virt/kvm/arm/arm.c +@@ -373,11 +373,17 @@ void kvm_arch_vcpu_load(struct kvm_vcpu + cpu_data = this_cpu_ptr(&kvm_host_data); + + /* ++ * We guarantee that both TLBs and I-cache are private to each ++ * vcpu. If detecting that a vcpu from the same VM has ++ * previously run on the same physical CPU, call into the ++ * hypervisor code to nuke the relevant contexts. ++ * ++ * We might get preempted before the vCPU actually runs, but + * We might get preempted before the vCPU actually runs, but + * over-invalidation doesn't affect correctness. + */ + if (*last_ran != vcpu->vcpu_id) { +- kvm_call_hyp(__kvm_tlb_flush_local_vmid, vcpu); ++ kvm_call_hyp(__kvm_flush_cpu_context, vcpu); + *last_ran = vcpu->vcpu_id; + } + diff --git a/queue-5.4/kvm-arm64-reject-vm-creation-when-the-default-ipa-size-is-unsupported.patch b/queue-5.4/kvm-arm64-reject-vm-creation-when-the-default-ipa-size-is-unsupported.patch new file mode 100644 index 00000000000..606baf26c89 --- /dev/null +++ b/queue-5.4/kvm-arm64-reject-vm-creation-when-the-default-ipa-size-is-unsupported.patch @@ -0,0 +1,91 @@ +From foo@baz Mon Mar 15 12:27:54 PM CET 2021 +From: Marc Zyngier +Date: Mon, 15 Mar 2021 11:09:52 +0000 +Subject: KVM: arm64: Reject VM creation when the default IPA size is unsupported +To: gregkh@linuxfoundation.org +Cc: kvmarm@lists.cs.columbia.edu, kernel-team@android.com, stable@vger.kernel.org, Andrew Jones , Eric Auger +Message-ID: <20210315110952.4136142-1-maz@kernel.org> + +From: Marc Zyngier + +Commit 7d717558dd5ef10d28866750d5c24ff892ea3778 upstream. + +KVM/arm64 has forever used a 40bit default IPA space, partially +due to its 32bit heritage (where the only choice is 40bit). + +However, there are implementations in the wild that have a *cough* +much smaller *cough* IPA space, which leads to a misprogramming of +VTCR_EL2, and a guest that is stuck on its first memory access +if userspace dares to ask for the default IPA setting (which most +VMMs do). + +Instead, blundly reject the creation of such VM, as we can't +satisfy the requirements from userspace (with a one-off warning). +Also clarify the boot warning, and document that the VM creation +will fail when an unsupported IPA size is provided. + +Although this is an ABI change, it doesn't really change much +for userspace: + +- the guest couldn't run before this change, but no error was + returned. At least userspace knows what is happening. + +- a memory slot that was accepted because it did fit the default + IPA space now doesn't even get a chance to be registered. + +The other thing that is left doing is to convince userspace to +actually use the IPA space setting instead of relying on the +antiquated default. + +Fixes: 233a7cb23531 ("kvm: arm64: Allow tuning the physical address size for VM") +Signed-off-by: Marc Zyngier +Cc: stable@vger.kernel.org +Reviewed-by: Andrew Jones +Reviewed-by: Eric Auger +Link: https://lore.kernel.org/r/20210311100016.3830038-2-maz@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/virt/kvm/api.txt | 3 +++ + arch/arm64/kvm/reset.c | 11 ++++++++--- + 2 files changed, 11 insertions(+), 3 deletions(-) + +--- a/Documentation/virt/kvm/api.txt ++++ b/Documentation/virt/kvm/api.txt +@@ -172,6 +172,9 @@ is dependent on the CPU capability and t + be retrieved using KVM_CAP_ARM_VM_IPA_SIZE of the KVM_CHECK_EXTENSION + ioctl() at run-time. + ++Creation of the VM will fail if the requested IPA size (whether it is ++implicit or explicit) is unsupported on the host. ++ + Please note that configuring the IPA size does not affect the capability + exposed by the guest CPUs in ID_AA64MMFR0_EL1[PARange]. It only affects + size of the address translated by the stage2 level (guest physical to +--- a/arch/arm64/kvm/reset.c ++++ b/arch/arm64/kvm/reset.c +@@ -378,10 +378,10 @@ void kvm_set_ipa_limit(void) + pr_info("kvm: Limiting the IPA size due to kernel %s Address limit\n", + (va_max < pa_max) ? "Virtual" : "Physical"); + +- WARN(ipa_max < KVM_PHYS_SHIFT, +- "KVM IPA limit (%d bit) is smaller than default size\n", ipa_max); + kvm_ipa_limit = ipa_max; +- kvm_info("IPA Size Limit: %dbits\n", kvm_ipa_limit); ++ kvm_info("IPA Size Limit: %d bits%s\n", kvm_ipa_limit, ++ ((kvm_ipa_limit < KVM_PHYS_SHIFT) ? ++ " (Reduced IPA size, limited VM/VMM compatibility)" : "")); + } + + /* +@@ -408,6 +408,11 @@ int kvm_arm_setup_stage2(struct kvm *kvm + return -EINVAL; + } else { + phys_shift = KVM_PHYS_SHIFT; ++ if (phys_shift > kvm_ipa_limit) { ++ pr_warn_once("%s using unsupported default IPA limit, upgrade your VMM\n", ++ current->comm); ++ return -EINVAL; ++ } + } + + parange = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1) & 7; diff --git a/queue-5.4/series b/queue-5.4/series index ea50d3fc1d1..3a1c1a1bcd8 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -162,3 +162,5 @@ x86-unwind-orc-disable-kasan-checking-in-the-orc-unwinder-part-2.patch kvm-arm64-fix-exclusive-limit-for-ipa-size.patch nvme-unlink-head-after-removing-last-namespace.patch nvme-release-namespace-head-reference-on-error.patch +kvm-arm64-ensure-i-cache-isolation-between-vcpus-of-a-same-vm.patch +kvm-arm64-reject-vm-creation-when-the-default-ipa-size-is-unsupported.patch