From: Greg Kroah-Hartman Date: Thu, 27 Apr 2023 08:36:56 +0000 (+0200) Subject: 5.15-stable patches X-Git-Tag: v5.15.110~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5bb0af67c13da6a5a8c08f7ff2536b684ce3b9a1;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches 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 --- 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 index 00000000000..5ad6fad1e1f --- /dev/null +++ b/queue-5.15/kvm-arm64-fix-buffer-overflow-in-kvm_arm_set_fw_reg.patch @@ -0,0 +1,38 @@ +From a25bc8486f9c01c1af6b6c5657234b2eee2c39d6 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 19 Apr 2023 13:16:13 +0300 +Subject: KVM: arm64: Fix buffer overflow in kvm_arm_set_fw_reg() + +From: Dan Carpenter + +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 +Reviewed-by: Steven Price +Reviewed-by: Eric Auger +Reviewed-by: Marc Zyngier +Link: https://lore.kernel.org/r/4efbab8c-640f-43b2-8ac6-6d68e08280fe@kili.mountain +Signed-off-by: Oliver Upton +[will: kvm_arm_set_fw_reg() lives in psci.c not hypercalls.c] +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..8a30b7795bf --- /dev/null +++ b/queue-5.15/kvm-arm64-retry-fault-if-vma_lookup-results-become-invalid.patch @@ -0,0 +1,108 @@ +From 13ec9308a85702af7c31f3638a2720863848a7f2 Mon Sep 17 00:00:00 2001 +From: David Matlack +Date: Mon, 13 Mar 2023 16:54:54 -0700 +Subject: KVM: arm64: Retry fault if vma_lookup() results become invalid + +From: David Matlack + +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 +Signed-off-by: David Matlack +Reviewed-by: Marc Zyngier +Link: https://lore.kernel.org/r/20230313235454.2964067-1-dmatlack@google.com +Signed-off-by: Oliver Upton +[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 +Signed-off-by: Greg Kroah-Hartman +--- + 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_. ++ * 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 index 00000000000..3f19aabe071 --- /dev/null +++ b/queue-5.15/pci-aspm-remove-pcie_aspm_pm_state_change.patch @@ -0,0 +1,92 @@ +From 08d0cc5f34265d1a1e3031f319f594bd1970976c Mon Sep 17 00:00:00 2001 +From: Kai-Heng Feng +Date: Mon, 11 Jul 2022 18:07:01 -0500 +Subject: PCI/ASPM: Remove pcie_aspm_pm_state_change() + +From: Kai-Heng Feng + +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 +Signed-off-by: Bjorn Helgaas +[manual backport: pci_set_low_power_state does not exist in v5.15] +Signed-off-by: Mark Hasemeyer +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..b020a62a47e --- /dev/null +++ b/queue-5.15/selftests-kselftest-runner-run_one-allow-running-non-executable-files.patch @@ -0,0 +1,82 @@ +From 303f8e2d02002dbe331cab7813ee091aead3cd39 Mon Sep 17 00:00:00 2001 +From: SeongJae Park +Date: Mon, 8 Nov 2021 18:35:56 -0800 +Subject: selftests/kselftest/runner/run_one(): allow running non-executable files + +From: SeongJae Park + +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 +Suggested-by: Greg Kroah-Hartman +Cc: Shuah Khan +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..ce71ac7fc04 --- /dev/null +++ b/queue-5.15/series @@ -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