]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Apr 2023 08:36:56 +0000 (10:36 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Apr 2023 08:36:56 +0000 (10:36 +0200)
added patches:
kvm-arm64-fix-buffer-overflow-in-kvm_arm_set_fw_reg.patch
kvm-arm64-retry-fault-if-vma_lookup-results-become-invalid.patch
pci-aspm-remove-pcie_aspm_pm_state_change.patch
selftests-kselftest-runner-run_one-allow-running-non-executable-files.patch
series

queue-5.15/kvm-arm64-fix-buffer-overflow-in-kvm_arm_set_fw_reg.patch [new file with mode: 0644]
queue-5.15/kvm-arm64-retry-fault-if-vma_lookup-results-become-invalid.patch [new file with mode: 0644]
queue-5.15/pci-aspm-remove-pcie_aspm_pm_state_change.patch [new file with mode: 0644]
queue-5.15/selftests-kselftest-runner-run_one-allow-running-non-executable-files.patch [new file with mode: 0644]
queue-5.15/series [new file with mode: 0644]

diff --git a/queue-5.15/kvm-arm64-fix-buffer-overflow-in-kvm_arm_set_fw_reg.patch b/queue-5.15/kvm-arm64-fix-buffer-overflow-in-kvm_arm_set_fw_reg.patch
new file mode 100644 (file)
index 0000000..5ad6fad
--- /dev/null
@@ -0,0 +1,38 @@
+From a25bc8486f9c01c1af6b6c5657234b2eee2c39d6 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@linaro.org>
+Date: Wed, 19 Apr 2023 13:16:13 +0300
+Subject: KVM: arm64: Fix buffer overflow in kvm_arm_set_fw_reg()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+commit a25bc8486f9c01c1af6b6c5657234b2eee2c39d6 upstream.
+
+The KVM_REG_SIZE() comes from the ioctl and it can be a power of two
+between 0-32768 but if it is more than sizeof(long) this will corrupt
+memory.
+
+Fixes: 99adb567632b ("KVM: arm/arm64: Add save/restore support for firmware workaround state")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Steven Price <steven.price@arm.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/4efbab8c-640f-43b2-8ac6-6d68e08280fe@kili.mountain
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+[will: kvm_arm_set_fw_reg() lives in psci.c not hypercalls.c]
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/psci.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/kvm/psci.c
++++ b/arch/arm64/kvm/psci.c
+@@ -508,6 +508,8 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *
+       u64 val;
+       int wa_level;
++      if (KVM_REG_SIZE(reg->id) != sizeof(val))
++              return -ENOENT;
+       if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)))
+               return -EFAULT;
diff --git a/queue-5.15/kvm-arm64-retry-fault-if-vma_lookup-results-become-invalid.patch b/queue-5.15/kvm-arm64-retry-fault-if-vma_lookup-results-become-invalid.patch
new file mode 100644 (file)
index 0000000..8a30b77
--- /dev/null
@@ -0,0 +1,108 @@
+From 13ec9308a85702af7c31f3638a2720863848a7f2 Mon Sep 17 00:00:00 2001
+From: David Matlack <dmatlack@google.com>
+Date: Mon, 13 Mar 2023 16:54:54 -0700
+Subject: KVM: arm64: Retry fault if vma_lookup() results become invalid
+
+From: David Matlack <dmatlack@google.com>
+
+commit 13ec9308a85702af7c31f3638a2720863848a7f2 upstream.
+
+Read mmu_invalidate_seq before dropping the mmap_lock so that KVM can
+detect if the results of vma_lookup() (e.g. vma_shift) become stale
+before it acquires kvm->mmu_lock. This fixes a theoretical bug where a
+VMA could be changed by userspace after vma_lookup() and before KVM
+reads the mmu_invalidate_seq, causing KVM to install page table entries
+based on a (possibly) no-longer-valid vma_shift.
+
+Re-order the MMU cache top-up to earlier in user_mem_abort() so that it
+is not done after KVM has read mmu_invalidate_seq (i.e. so as to avoid
+inducing spurious fault retries).
+
+This bug has existed since KVM/ARM's inception. It's unlikely that any
+sane userspace currently modifies VMAs in such a way as to trigger this
+race. And even with directed testing I was unable to reproduce it. But a
+sufficiently motivated host userspace might be able to exploit this
+race.
+
+Fixes: 94f8e6418d39 ("KVM: ARM: Handle guest faults in KVM")
+Cc: stable@vger.kernel.org
+Reported-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: David Matlack <dmatlack@google.com>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230313235454.2964067-1-dmatlack@google.com
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+[will: Use FSC_PERM instead of ESR_ELx_FSC_PERM. Read 'mmu_notifier_seq'
+ instead of 'mmu_invalidate_seq'. Fix up function references in comment.]
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/mmu.c |   47 +++++++++++++++++++++--------------------------
+ 1 file changed, 21 insertions(+), 26 deletions(-)
+
+--- a/arch/arm64/kvm/mmu.c
++++ b/arch/arm64/kvm/mmu.c
+@@ -998,6 +998,20 @@ static int user_mem_abort(struct kvm_vcp
+       }
+       /*
++       * Permission faults just need to update the existing leaf entry,
++       * and so normally don't require allocations from the memcache. The
++       * only exception to this is when dirty logging is enabled at runtime
++       * and a write fault needs to collapse a block entry into a table.
++       */
++      if (fault_status != FSC_PERM ||
++          (logging_active && write_fault)) {
++              ret = kvm_mmu_topup_memory_cache(memcache,
++                                               kvm_mmu_cache_min_pages(kvm));
++              if (ret)
++                      return ret;
++      }
++
++      /*
+        * Let's check if we will get back a huge page backed by hugetlbfs, or
+        * get block mapping for device MMIO region.
+        */
+@@ -1051,36 +1065,17 @@ static int user_mem_abort(struct kvm_vcp
+               fault_ipa &= ~(vma_pagesize - 1);
+       gfn = fault_ipa >> PAGE_SHIFT;
+-      mmap_read_unlock(current->mm);
+-
+-      /*
+-       * Permission faults just need to update the existing leaf entry,
+-       * and so normally don't require allocations from the memcache. The
+-       * only exception to this is when dirty logging is enabled at runtime
+-       * and a write fault needs to collapse a block entry into a table.
+-       */
+-      if (fault_status != FSC_PERM || (logging_active && write_fault)) {
+-              ret = kvm_mmu_topup_memory_cache(memcache,
+-                                               kvm_mmu_cache_min_pages(kvm));
+-              if (ret)
+-                      return ret;
+-      }
+-      mmu_seq = vcpu->kvm->mmu_notifier_seq;
+       /*
+-       * Ensure the read of mmu_notifier_seq happens before we call
+-       * gfn_to_pfn_prot (which calls get_user_pages), so that we don't risk
+-       * the page we just got a reference to gets unmapped before we have a
+-       * chance to grab the mmu_lock, which ensure that if the page gets
+-       * unmapped afterwards, the call to kvm_unmap_gfn will take it away
+-       * from us again properly. This smp_rmb() interacts with the smp_wmb()
+-       * in kvm_mmu_notifier_invalidate_<page|range_end>.
++       * Read mmu_notifier_seq so that KVM can detect if the results of
++       * vma_lookup() or __gfn_to_pfn_memslot() become stale prior to
++       * acquiring kvm->mmu_lock.
+        *
+-       * Besides, __gfn_to_pfn_memslot() instead of gfn_to_pfn_prot() is
+-       * used to avoid unnecessary overhead introduced to locate the memory
+-       * slot because it's always fixed even @gfn is adjusted for huge pages.
++       * Rely on mmap_read_unlock() for an implicit smp_rmb(), which pairs
++       * with the smp_wmb() in kvm_dec_notifier_count().
+        */
+-      smp_rmb();
++      mmu_seq = vcpu->kvm->mmu_notifier_seq;
++      mmap_read_unlock(current->mm);
+       pfn = __gfn_to_pfn_memslot(memslot, gfn, false, NULL,
+                                  write_fault, &writable, NULL);
diff --git a/queue-5.15/pci-aspm-remove-pcie_aspm_pm_state_change.patch b/queue-5.15/pci-aspm-remove-pcie_aspm_pm_state_change.patch
new file mode 100644 (file)
index 0000000..3f19aab
--- /dev/null
@@ -0,0 +1,92 @@
+From 08d0cc5f34265d1a1e3031f319f594bd1970976c Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Date: Mon, 11 Jul 2022 18:07:01 -0500
+Subject: PCI/ASPM: Remove pcie_aspm_pm_state_change()
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+commit 08d0cc5f34265d1a1e3031f319f594bd1970976c upstream.
+
+pcie_aspm_pm_state_change() was introduced at the inception of PCIe ASPM
+code, but it can cause some issues. For instance, when ASPM config is
+changed via sysfs, those changes won't persist across power state change
+because pcie_aspm_pm_state_change() overwrites them.
+
+Also, if the driver restores L1SS [1] after system resume, the restored
+state will also be overwritten by pcie_aspm_pm_state_change().
+
+Remove pcie_aspm_pm_state_change().  If there's any hardware that really
+needs it to function, a quirk can be used instead.
+
+[1] https://lore.kernel.org/linux-pci/20220201123536.12962-1-vidyas@nvidia.com/
+Link: https://lore.kernel.org/r/20220509073639.2048236-1-kai.heng.feng@canonical.com
+[bhelgaas: remove additional pcie_aspm_pm_state_change() call in
+pci_set_low_power_state(), added by
+10aa5377fc8a ("PCI/PM: Split pci_raw_set_power_state()") and moved by
+7957d201456f ("PCI/PM: Relocate pci_set_low_power_state()")]
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+[manual backport: pci_set_low_power_state does not exist in v5.15]
+Signed-off-by: Mark Hasemeyer <markhas@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/pci.c       |    3 ---
+ drivers/pci/pci.h       |    2 --
+ drivers/pci/pcie/aspm.c |   19 -------------------
+ 3 files changed, 24 deletions(-)
+
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -1140,9 +1140,6 @@ static int pci_raw_set_power_state(struc
+       if (need_restore)
+               pci_restore_bars(dev);
+-      if (dev->bus->self)
+-              pcie_aspm_pm_state_change(dev->bus->self);
+-
+       return 0;
+ }
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -595,12 +595,10 @@ bool pcie_wait_for_link(struct pci_dev *
+ #ifdef CONFIG_PCIEASPM
+ void pcie_aspm_init_link_state(struct pci_dev *pdev);
+ void pcie_aspm_exit_link_state(struct pci_dev *pdev);
+-void pcie_aspm_pm_state_change(struct pci_dev *pdev);
+ void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
+ #else
+ static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { }
+ static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { }
+-static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { }
+ static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { }
+ #endif
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -1020,25 +1020,6 @@ out:
+       up_read(&pci_bus_sem);
+ }
+-/* @pdev: the root port or switch downstream port */
+-void pcie_aspm_pm_state_change(struct pci_dev *pdev)
+-{
+-      struct pcie_link_state *link = pdev->link_state;
+-
+-      if (aspm_disabled || !link)
+-              return;
+-      /*
+-       * Devices changed PM state, we should recheck if latency
+-       * meets all functions' requirement
+-       */
+-      down_read(&pci_bus_sem);
+-      mutex_lock(&aspm_lock);
+-      pcie_update_aspm_capable(link->root);
+-      pcie_config_aspm_path(link);
+-      mutex_unlock(&aspm_lock);
+-      up_read(&pci_bus_sem);
+-}
+-
+ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
+ {
+       struct pcie_link_state *link = pdev->link_state;
diff --git a/queue-5.15/selftests-kselftest-runner-run_one-allow-running-non-executable-files.patch b/queue-5.15/selftests-kselftest-runner-run_one-allow-running-non-executable-files.patch
new file mode 100644 (file)
index 0000000..b020a62
--- /dev/null
@@ -0,0 +1,82 @@
+From 303f8e2d02002dbe331cab7813ee091aead3cd39 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sjpark@amazon.de>
+Date: Mon, 8 Nov 2021 18:35:56 -0800
+Subject: selftests/kselftest/runner/run_one(): allow running non-executable files
+
+From: SeongJae Park <sjpark@amazon.de>
+
+commit 303f8e2d02002dbe331cab7813ee091aead3cd39 upstream.
+
+When running a test program, 'run_one()' checks if the program has the
+execution permission and fails if it doesn't.  However, it's easy to
+mistakenly lose the permissions, as some common tools like 'diff' don't
+support the permission change well[1].  Compared to that, making mistakes
+in the test program's path would only rare, as those are explicitly listed
+in 'TEST_PROGS'.  Therefore, it might make more sense to resolve the
+situation on our own and run the program.
+
+For this reason, this commit makes the test program runner function still
+print the warning message but to try parsing the interpreter of the
+program and to explicitly run it with the interpreter, in this case.
+
+[1] https://lore.kernel.org/mm-commits/YRJisBs9AunccCD4@kroah.com/
+
+Link: https://lkml.kernel.org/r/20210810164534.25902-1-sj38.park@gmail.com
+Signed-off-by: SeongJae Park <sjpark@amazon.de>
+Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Shuah Khan <shuah@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/kselftest/runner.sh |   28 ++++++++++++++++++----------
+ 1 file changed, 18 insertions(+), 10 deletions(-)
+
+--- a/tools/testing/selftests/kselftest/runner.sh
++++ b/tools/testing/selftests/kselftest/runner.sh
+@@ -33,9 +33,9 @@ tap_timeout()
+ {
+       # Make sure tests will time out if utility is available.
+       if [ -x /usr/bin/timeout ] ; then
+-              /usr/bin/timeout --foreground "$kselftest_timeout" "$1"
++              /usr/bin/timeout --foreground "$kselftest_timeout" $1
+       else
+-              "$1"
++              $1
+       fi
+ }
+@@ -65,17 +65,25 @@ run_one()
+       TEST_HDR_MSG="selftests: $DIR: $BASENAME_TEST"
+       echo "# $TEST_HDR_MSG"
+-      if [ ! -x "$TEST" ]; then
+-              echo -n "# Warning: file $TEST is "
+-              if [ ! -e "$TEST" ]; then
+-                      echo "missing!"
+-              else
+-                      echo "not executable, correct this."
+-              fi
++      if [ ! -e "$TEST" ]; then
++              echo "# Warning: file $TEST is missing!"
+               echo "not ok $test_num $TEST_HDR_MSG"
+       else
++              cmd="./$BASENAME_TEST"
++              if [ ! -x "$TEST" ]; then
++                      echo "# Warning: file $TEST is not executable"
++
++                      if [ $(head -n 1 "$TEST" | cut -c -2) = "#!" ]
++                      then
++                              interpreter=$(head -n 1 "$TEST" | cut -c 3-)
++                              cmd="$interpreter ./$BASENAME_TEST"
++                      else
++                              echo "not ok $test_num $TEST_HDR_MSG"
++                              return
++                      fi
++              fi
+               cd `dirname $TEST` > /dev/null
+-              ((((( tap_timeout ./$BASENAME_TEST 2>&1; echo $? >&3) |
++              ((((( tap_timeout "$cmd" 2>&1; echo $? >&3) |
+                       tap_prefix >&4) 3>&1) |
+                       (read xs; exit $xs)) 4>>"$logfile" &&
+               echo "ok $test_num $TEST_HDR_MSG") ||
diff --git a/queue-5.15/series b/queue-5.15/series
new file mode 100644 (file)
index 0000000..ce71ac7
--- /dev/null
@@ -0,0 +1,4 @@
+pci-aspm-remove-pcie_aspm_pm_state_change.patch
+selftests-kselftest-runner-run_one-allow-running-non-executable-files.patch
+kvm-arm64-retry-fault-if-vma_lookup-results-become-invalid.patch
+kvm-arm64-fix-buffer-overflow-in-kvm_arm_set_fw_reg.patch