]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Mar 2021 11:31:25 +0000 (12:31 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Mar 2021 11:31:25 +0000 (12:31 +0100)
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

queue-5.4/kvm-arm64-ensure-i-cache-isolation-between-vcpus-of-a-same-vm.patch [new file with mode: 0644]
queue-5.4/kvm-arm64-reject-vm-creation-when-the-default-ipa-size-is-unsupported.patch [new file with mode: 0644]
queue-5.4/series

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 (file)
index 0000000..758f53a
--- /dev/null
@@ -0,0 +1,132 @@
+From foo@baz Mon Mar 15 12:27:33 PM CET 2021
+From: Marc Zyngier <maz@kernel.org>
+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 <will@kernel.org>, Catalin Marinas <catalin.marinas@arm.com>
+Message-ID: <20210315111000.4136196-1-maz@kernel.org>
+
+From: Marc Zyngier <maz@kernel.org>
+
+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 <maz@kernel.org>
+Acked-by: Will Deacon <will@kernel.org>
+Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+Link: https://lore.kernel.org/r/20210303164505.68492-1-maz@kernel.org
+[maz: added 32bit ARM support]
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..606baf2
--- /dev/null
@@ -0,0 +1,91 @@
+From foo@baz Mon Mar 15 12:27:54 PM CET 2021
+From: Marc Zyngier <maz@kernel.org>
+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 <drjones@redhat.com>, Eric Auger <eric.auger@redhat.com>
+Message-ID: <20210315110952.4136142-1-maz@kernel.org>
+
+From: Marc Zyngier <maz@kernel.org>
+
+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 <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Reviewed-by: Andrew Jones <drjones@redhat.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Link: https://lore.kernel.org/r/20210311100016.3830038-2-maz@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
index ea50d3fc1d122b196c56bf392da77e9f71d0078d..3a1c1a1bcd85501a32abcd9183c4efbbd7847c08 100644 (file)
@@ -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