]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Jun 2020 14:39:28 +0000 (16:39 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Jun 2020 14:39:28 +0000 (16:39 +0200)
added patches:
efi-efivars-add-missing-kobject_put-in-sysfs-entry-creation-error-path.patch
kvm-x86-fix-apic-page-invalidation-race.patch
x86-reboot-quirks-add-macbook6-1-reboot-quirk.patch

queue-4.19/efi-efivars-add-missing-kobject_put-in-sysfs-entry-creation-error-path.patch [new file with mode: 0644]
queue-4.19/kvm-x86-fix-apic-page-invalidation-race.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/x86-reboot-quirks-add-macbook6-1-reboot-quirk.patch [new file with mode: 0644]

diff --git a/queue-4.19/efi-efivars-add-missing-kobject_put-in-sysfs-entry-creation-error-path.patch b/queue-4.19/efi-efivars-add-missing-kobject_put-in-sysfs-entry-creation-error-path.patch
new file mode 100644 (file)
index 0000000..d35b6d7
--- /dev/null
@@ -0,0 +1,39 @@
+From d8bd8c6e2cfab8b78b537715255be8d7557791c0 Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ardb@kernel.org>
+Date: Fri, 22 May 2020 18:15:49 +0200
+Subject: efi/efivars: Add missing kobject_put() in sysfs entry creation error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+commit d8bd8c6e2cfab8b78b537715255be8d7557791c0 upstream.
+
+The documentation provided by kobject_init_and_add() clearly spells out
+the need to call kobject_put() on the kobject if an error is returned.
+Add this missing call to the error path.
+
+Cc: <stable@vger.kernel.org>
+Reported-by: 亿一 <teroincn@gmail.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/efi/efivars.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/firmware/efi/efivars.c
++++ b/drivers/firmware/efi/efivars.c
+@@ -586,8 +586,10 @@ efivar_create_sysfs_entry(struct efivar_
+       ret = kobject_init_and_add(&new_var->kobj, &efivar_ktype,
+                                  NULL, "%s", short_name);
+       kfree(short_name);
+-      if (ret)
++      if (ret) {
++              kobject_put(&new_var->kobj);
+               return ret;
++      }
+       kobject_uevent(&new_var->kobj, KOBJ_ADD);
+       if (efivar_entry_add(new_var, &efivar_sysfs_list)) {
diff --git a/queue-4.19/kvm-x86-fix-apic-page-invalidation-race.patch b/queue-4.19/kvm-x86-fix-apic-page-invalidation-race.patch
new file mode 100644 (file)
index 0000000..4f0c8b8
--- /dev/null
@@ -0,0 +1,163 @@
+From e649b3f0188f8fd34dd0dde8d43fd3312b902fb2 Mon Sep 17 00:00:00 2001
+From: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+Date: Sat, 6 Jun 2020 13:26:27 +0900
+Subject: KVM: x86: Fix APIC page invalidation race
+
+From: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+
+commit e649b3f0188f8fd34dd0dde8d43fd3312b902fb2 upstream.
+
+Commit b1394e745b94 ("KVM: x86: fix APIC page invalidation") tried
+to fix inappropriate APIC page invalidation by re-introducing arch
+specific kvm_arch_mmu_notifier_invalidate_range() and calling it from
+kvm_mmu_notifier_invalidate_range_start. However, the patch left a
+possible race where the VMCS APIC address cache is updated *before*
+it is unmapped:
+
+  (Invalidator) kvm_mmu_notifier_invalidate_range_start()
+  (Invalidator) kvm_make_all_cpus_request(kvm, KVM_REQ_APIC_PAGE_RELOAD)
+  (KVM VCPU) vcpu_enter_guest()
+  (KVM VCPU) kvm_vcpu_reload_apic_access_page()
+  (Invalidator) actually unmap page
+
+Because of the above race, there can be a mismatch between the
+host physical address stored in the APIC_ACCESS_PAGE VMCS field and
+the host physical address stored in the EPT entry for the APIC GPA
+(0xfee0000).  When this happens, the processor will not trap APIC
+accesses, and will instead show the raw contents of the APIC-access page.
+Because Windows OS periodically checks for unexpected modifications to
+the LAPIC register, this will show up as a BSOD crash with BugCheck
+CRITICAL_STRUCTURE_CORRUPTION (109) we are currently seeing in
+https://bugzilla.redhat.com/show_bug.cgi?id=1751017.
+
+The root cause of the issue is that kvm_arch_mmu_notifier_invalidate_range()
+cannot guarantee that no additional references are taken to the pages in
+the range before kvm_mmu_notifier_invalidate_range_end().  Fortunately,
+this case is supported by the MMU notifier API, as documented in
+include/linux/mmu_notifier.h:
+
+        * If the subsystem
+         * can't guarantee that no additional references are taken to
+         * the pages in the range, it has to implement the
+         * invalidate_range() notifier to remove any references taken
+         * after invalidate_range_start().
+
+The fix therefore is to reload the APIC-access page field in the VMCS
+from kvm_mmu_notifier_invalidate_range() instead of ..._range_start().
+
+Cc: stable@vger.kernel.org
+Fixes: b1394e745b94 ("KVM: x86: fix APIC page invalidation")
+Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=197951
+Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+Message-Id: <20200606042627.61070-1-eiichi.tsukata@nutanix.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index c26dd1363151..24de847af52e 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -8270,9 +8270,8 @@ static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu)
+       kvm_x86_ops.load_eoi_exitmap(vcpu, eoi_exit_bitmap);
+ }
+-int kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
+-              unsigned long start, unsigned long end,
+-              bool blockable)
++void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
++                                          unsigned long start, unsigned long end)
+ {
+       unsigned long apic_address;
+@@ -8283,8 +8282,6 @@ int kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
+       apic_address = gfn_to_hva(kvm, APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT);
+       if (start <= apic_address && apic_address < end)
+               kvm_make_all_cpus_request(kvm, KVM_REQ_APIC_PAGE_RELOAD);
+-
+-      return 0;
+ }
+ void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
+diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
+index d38d6b9c24be..e2f82131bb3e 100644
+--- a/include/linux/kvm_host.h
++++ b/include/linux/kvm_host.h
+@@ -1420,8 +1420,8 @@ static inline long kvm_arch_vcpu_async_ioctl(struct file *filp,
+ }
+ #endif /* CONFIG_HAVE_KVM_VCPU_ASYNC_IOCTL */
+-int kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
+-              unsigned long start, unsigned long end, bool blockable);
++void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
++                                          unsigned long start, unsigned long end);
+ #ifdef CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE
+ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu);
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 4db151f6101e..7b6013f2ba19 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -155,10 +155,9 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm);
+ static unsigned long long kvm_createvm_count;
+ static unsigned long long kvm_active_vms;
+-__weak int kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
+-              unsigned long start, unsigned long end, bool blockable)
++__weak void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
++                                                 unsigned long start, unsigned long end)
+ {
+-      return 0;
+ }
+ bool kvm_is_zone_device_pfn(kvm_pfn_t pfn)
+@@ -384,6 +383,18 @@ static inline struct kvm *mmu_notifier_to_kvm(struct mmu_notifier *mn)
+       return container_of(mn, struct kvm, mmu_notifier);
+ }
++static void kvm_mmu_notifier_invalidate_range(struct mmu_notifier *mn,
++                                            struct mm_struct *mm,
++                                            unsigned long start, unsigned long end)
++{
++      struct kvm *kvm = mmu_notifier_to_kvm(mn);
++      int idx;
++
++      idx = srcu_read_lock(&kvm->srcu);
++      kvm_arch_mmu_notifier_invalidate_range(kvm, start, end);
++      srcu_read_unlock(&kvm->srcu, idx);
++}
++
+ static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn,
+                                       struct mm_struct *mm,
+                                       unsigned long address,
+@@ -408,7 +419,6 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
+ {
+       struct kvm *kvm = mmu_notifier_to_kvm(mn);
+       int need_tlb_flush = 0, idx;
+-      int ret;
+       idx = srcu_read_lock(&kvm->srcu);
+       spin_lock(&kvm->mmu_lock);
+@@ -425,14 +435,9 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
+               kvm_flush_remote_tlbs(kvm);
+       spin_unlock(&kvm->mmu_lock);
+-
+-      ret = kvm_arch_mmu_notifier_invalidate_range(kvm, range->start,
+-                                      range->end,
+-                                      mmu_notifier_range_blockable(range));
+-
+       srcu_read_unlock(&kvm->srcu, idx);
+-      return ret;
++      return 0;
+ }
+ static void kvm_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
+@@ -538,6 +543,7 @@ static void kvm_mmu_notifier_release(struct mmu_notifier *mn,
+ }
+ static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
++      .invalidate_range       = kvm_mmu_notifier_invalidate_range,
+       .invalidate_range_start = kvm_mmu_notifier_invalidate_range_start,
+       .invalidate_range_end   = kvm_mmu_notifier_invalidate_range_end,
+       .clear_flush_young      = kvm_mmu_notifier_clear_flush_young,
index 9e8c18d4a2ccf7ae404918ae3f8d8c091252837a..d9d0673f5700d9304ba17e1b4812983c620f3a77 100644 (file)
@@ -28,3 +28,6 @@ btrfs-tree-checker-check-level-for-leaves-and-nodes.patch
 x86_64-fix-jiffies-odr-violation.patch
 x86-pci-mark-intel-c620-mroms-as-having-non-compliant-bars.patch
 x86-speculation-prevent-rogue-cross-process-ssbd-shutdown.patch
+x86-reboot-quirks-add-macbook6-1-reboot-quirk.patch
+efi-efivars-add-missing-kobject_put-in-sysfs-entry-creation-error-path.patch
+kvm-x86-fix-apic-page-invalidation-race.patch
diff --git a/queue-4.19/x86-reboot-quirks-add-macbook6-1-reboot-quirk.patch b/queue-4.19/x86-reboot-quirks-add-macbook6-1-reboot-quirk.patch
new file mode 100644 (file)
index 0000000..a309f57
--- /dev/null
@@ -0,0 +1,39 @@
+From 140fd4ac78d385e6c8e6a5757585f6c707085f87 Mon Sep 17 00:00:00 2001
+From: Hill Ma <maahiuzeon@gmail.com>
+Date: Sat, 25 Apr 2020 13:06:41 -0700
+Subject: x86/reboot/quirks: Add MacBook6,1 reboot quirk
+
+From: Hill Ma <maahiuzeon@gmail.com>
+
+commit 140fd4ac78d385e6c8e6a5757585f6c707085f87 upstream.
+
+On MacBook6,1 reboot would hang unless parameter reboot=pci is added.
+Make it automatic.
+
+Signed-off-by: Hill Ma <maahiuzeon@gmail.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20200425200641.GA1554@cslab.localdomain
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/reboot.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/x86/kernel/reboot.c
++++ b/arch/x86/kernel/reboot.c
+@@ -197,6 +197,14 @@ static const struct dmi_system_id reboot
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5"),
+               },
+       },
++      {       /* Handle problems with rebooting on Apple MacBook6,1 */
++              .callback = set_pci_reboot,
++              .ident = "Apple MacBook6,1",
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "MacBook6,1"),
++              },
++      },
+       {       /* Handle problems with rebooting on Apple MacBookPro5 */
+               .callback = set_pci_reboot,
+               .ident = "Apple MacBookPro5",