]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 12 May 2021 10:49:08 +0000 (12:49 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 12 May 2021 10:49:08 +0000 (12:49 +0200)
added patches:
kvm-nvmx-truncate-bits-63-32-of-vmcs-field-on-nested-check-in-64-bit.patch
kvm-stop-looking-for-coalesced-mmio-zones-if-the-bus-is-destroyed.patch

queue-5.4/kvm-nvmx-truncate-bits-63-32-of-vmcs-field-on-nested-check-in-64-bit.patch [new file with mode: 0644]
queue-5.4/kvm-stop-looking-for-coalesced-mmio-zones-if-the-bus-is-destroyed.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/kvm-nvmx-truncate-bits-63-32-of-vmcs-field-on-nested-check-in-64-bit.patch b/queue-5.4/kvm-nvmx-truncate-bits-63-32-of-vmcs-field-on-nested-check-in-64-bit.patch
new file mode 100644 (file)
index 0000000..3a43505
--- /dev/null
@@ -0,0 +1,38 @@
+From ee050a577523dfd5fac95e6cc182ebe0293ead59 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Wed, 21 Apr 2021 19:21:24 -0700
+Subject: KVM: nVMX: Truncate bits 63:32 of VMCS field on nested check in !64-bit
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit ee050a577523dfd5fac95e6cc182ebe0293ead59 upstream.
+
+Drop bits 63:32 of the VMCS field encoding when checking for a nested
+VM-Exit on VMREAD/VMWRITE in !64-bit mode.  VMREAD and VMWRITE always
+use 32-bit operands outside of 64-bit mode.
+
+The actual emulation of VMREAD/VMWRITE does the right thing, this bug is
+purely limited to incorrectly causing a nested VM-Exit if a GPR happens
+to have bits 63:32 set outside of 64-bit mode.
+
+Fixes: a7cde481b6e8 ("KVM: nVMX: Do not forward VMREAD/VMWRITE VMExits to L1 if required so by vmcs12 vmread/vmwrite bitmaps")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210422022128.3464144-6-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/vmx/nested.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -5308,7 +5308,7 @@ static bool nested_vmx_exit_handled_vmcs
+       /* Decode instruction info and find the field to access */
+       vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
+-      field = kvm_register_read(vcpu, (((vmx_instruction_info) >> 28) & 0xf));
++      field = kvm_register_readl(vcpu, (((vmx_instruction_info) >> 28) & 0xf));
+       /* Out-of-range fields always cause a VM exit from L2 to L1 */
+       if (field >> 15)
diff --git a/queue-5.4/kvm-stop-looking-for-coalesced-mmio-zones-if-the-bus-is-destroyed.patch b/queue-5.4/kvm-stop-looking-for-coalesced-mmio-zones-if-the-bus-is-destroyed.patch
new file mode 100644 (file)
index 0000000..26edf4d
--- /dev/null
@@ -0,0 +1,128 @@
+From 5d3c4c79384af06e3c8e25b7770b6247496b4417 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Mon, 12 Apr 2021 15:20:49 -0700
+Subject: KVM: Stop looking for coalesced MMIO zones if the bus is destroyed
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 5d3c4c79384af06e3c8e25b7770b6247496b4417 upstream.
+
+Abort the walk of coalesced MMIO zones if kvm_io_bus_unregister_dev()
+fails to allocate memory for the new instance of the bus.  If it can't
+instantiate a new bus, unregister_dev() destroys all devices _except_ the
+target device.   But, it doesn't tell the caller that it obliterated the
+bus and invoked the destructor for all devices that were on the bus.  In
+the coalesced MMIO case, this can result in a deleted list entry
+dereference due to attempting to continue iterating on coalesced_zones
+after future entries (in the walk) have been deleted.
+
+Opportunistically add curly braces to the for-loop, which encompasses
+many lines but sneaks by without braces due to the guts being a single
+if statement.
+
+Fixes: f65886606c2d ("KVM: fix memory leak in kvm_io_bus_unregister_dev()")
+Cc: stable@vger.kernel.org
+Reported-by: Hao Sun <sunhao.th@gmail.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20210412222050.876100-3-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/kvm_host.h  |    4 ++--
+ virt/kvm/coalesced_mmio.c |   19 +++++++++++++++++--
+ virt/kvm/kvm_main.c       |   10 +++++-----
+ 3 files changed, 24 insertions(+), 9 deletions(-)
+
+--- a/include/linux/kvm_host.h
++++ b/include/linux/kvm_host.h
+@@ -192,8 +192,8 @@ int kvm_io_bus_read(struct kvm_vcpu *vcp
+                   int len, void *val);
+ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
+                           int len, struct kvm_io_device *dev);
+-void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+-                             struct kvm_io_device *dev);
++int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
++                            struct kvm_io_device *dev);
+ struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+                                        gpa_t addr);
+--- a/virt/kvm/coalesced_mmio.c
++++ b/virt/kvm/coalesced_mmio.c
+@@ -178,21 +178,36 @@ int kvm_vm_ioctl_unregister_coalesced_mm
+                                          struct kvm_coalesced_mmio_zone *zone)
+ {
+       struct kvm_coalesced_mmio_dev *dev, *tmp;
++      int r;
+       if (zone->pio != 1 && zone->pio != 0)
+               return -EINVAL;
+       mutex_lock(&kvm->slots_lock);
+-      list_for_each_entry_safe(dev, tmp, &kvm->coalesced_zones, list)
++      list_for_each_entry_safe(dev, tmp, &kvm->coalesced_zones, list) {
+               if (zone->pio == dev->zone.pio &&
+                   coalesced_mmio_in_range(dev, zone->addr, zone->size)) {
+-                      kvm_io_bus_unregister_dev(kvm,
++                      r = kvm_io_bus_unregister_dev(kvm,
+                               zone->pio ? KVM_PIO_BUS : KVM_MMIO_BUS, &dev->dev);
+                       kvm_iodevice_destructor(&dev->dev);
++
++                      /*
++                       * On failure, unregister destroys all devices on the
++                       * bus _except_ the target device, i.e. coalesced_zones
++                       * has been modified.  No need to restart the walk as
++                       * there aren't any zones left.
++                       */
++                      if (r)
++                              break;
+               }
++      }
+       mutex_unlock(&kvm->slots_lock);
++      /*
++       * Ignore the result of kvm_io_bus_unregister_dev(), from userspace's
++       * perspective, the coalesced MMIO is most definitely unregistered.
++       */
+       return 0;
+ }
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -4017,15 +4017,15 @@ int kvm_io_bus_register_dev(struct kvm *
+ }
+ /* Caller must hold slots_lock. */
+-void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+-                             struct kvm_io_device *dev)
++int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
++                            struct kvm_io_device *dev)
+ {
+       int i, j;
+       struct kvm_io_bus *new_bus, *bus;
+       bus = kvm_get_bus(kvm, bus_idx);
+       if (!bus)
+-              return;
++              return 0;
+       for (i = 0; i < bus->dev_count; i++)
+               if (bus->range[i].dev == dev) {
+@@ -4033,7 +4033,7 @@ void kvm_io_bus_unregister_dev(struct kv
+               }
+       if (i == bus->dev_count)
+-              return;
++              return 0;
+       new_bus = kmalloc(struct_size(bus, range, bus->dev_count - 1),
+                         GFP_KERNEL_ACCOUNT);
+@@ -4054,7 +4054,7 @@ void kvm_io_bus_unregister_dev(struct kv
+       rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
+       synchronize_srcu_expedited(&kvm->srcu);
+       kfree(bus);
+-      return;
++      return new_bus ? 0 : -ENOMEM;
+ }
+ struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,
index 61397986b87bc58cefae9f0a0b77213efdc10fdb..244b3a3c2750b8fdcf81d9288ef01abc29f46d5e 100644 (file)
@@ -60,3 +60,5 @@ s390-fix-detection-of-vector-enhancements-facility-1-vs.-vector-packed-decimal-f
 kvm-s390-vsie-fix-mvpg-handling-for-prefixing-and-mso.patch
 kvm-s390-split-kvm_s390_real_to_abs.patch
 kvm-s390-extend-kvm_s390_shadow_fault-to-return-entry-pointer.patch
+kvm-nvmx-truncate-bits-63-32-of-vmcs-field-on-nested-check-in-64-bit.patch
+kvm-stop-looking-for-coalesced-mmio-zones-if-the-bus-is-destroyed.patch