]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 12 Mar 2022 11:16:36 +0000 (12:16 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 12 Mar 2022 11:16:36 +0000 (12:16 +0100)
added patches:
kvm-arm64-reset-pmc_el0-to-avoid-a-panic-on-systems-with-no-pmu.patch
net-macb-fix-lost-rx-packet-wakeup-race-in-napi-receive.patch
riscv-fix-auipc-jalr-relocation-range-checks.patch
staging-gdm724x-fix-use-after-free-in-gdm_lte_rx.patch

queue-4.19/kvm-arm64-reset-pmc_el0-to-avoid-a-panic-on-systems-with-no-pmu.patch [new file with mode: 0644]
queue-4.19/net-macb-fix-lost-rx-packet-wakeup-race-in-napi-receive.patch [new file with mode: 0644]
queue-4.19/riscv-fix-auipc-jalr-relocation-range-checks.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/staging-gdm724x-fix-use-after-free-in-gdm_lte_rx.patch [new file with mode: 0644]

diff --git a/queue-4.19/kvm-arm64-reset-pmc_el0-to-avoid-a-panic-on-systems-with-no-pmu.patch b/queue-4.19/kvm-arm64-reset-pmc_el0-to-avoid-a-panic-on-systems-with-no-pmu.patch
new file mode 100644 (file)
index 0000000..08d1248
--- /dev/null
@@ -0,0 +1,67 @@
+From james.morse@arm.com  Sat Mar 12 12:08:36 2022
+From: James Morse <james.morse@arm.com>
+Date: Tue,  8 Mar 2022 16:29:39 +0000
+Subject: KVM: arm64: Reset PMC_EL0 to avoid a panic() on systems with no PMU
+To: stable@vger.kernel.org, kvmarm@lists.cs.columbia.edu
+Cc: Marc Zyngier <maz@kernel.org>, Alexandru Elisei <alexandru.elisei@arm.com>, james.morse@arm.com
+Message-ID: <20220308162939.603335-1-james.morse@arm.com>
+
+From: James Morse <james.morse@arm.com>
+
+The logic in commit 2a5f1b67ec57 "KVM: arm64: Don't access PMCR_EL0 when no
+PMU is available" relies on an empty reset handler being benign.  This was
+not the case in earlier kernel versions, so the stable backport of this
+patch is causing problems.
+
+KVMs behaviour in this area changed over time. In particular, prior to commit
+03fdfb269009 ("KVM: arm64: Don't write junk to sysregs on reset"), an empty
+reset handler will trigger a warning, as the guest registers have been
+poisoned.
+Prior to commit 20589c8cc47d ("arm/arm64: KVM: Don't panic on failure to
+properly reset system registers"), this warning was a panic().
+
+Instead of reverting the backport, make it write 0 to the sys_reg[] array.
+This keeps the reset logic happy, and the dodgy value can't be seen by
+the guest as it can't request the emulation.
+
+The original bug was accessing the PMCR_EL0 register on CPUs that don't
+implement that feature. There is no known silicon that does this, but
+v4.9's ACPI support is unable to find the PMU, so triggers this code:
+
+| Kernel panic - not syncing: Didn't reset vcpu_sys_reg(24)
+| CPU: 1 PID: 3055 Comm: lkvm Not tainted 4.9.302-00032-g64e078a56789 #13476
+| Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform, BIOS EDK II Jul 30 2018
+| Call trace:
+| [<ffff00000808b4b0>] dump_backtrace+0x0/0x1a0
+| [<ffff00000808b664>] show_stack+0x14/0x20
+| [<ffff0000088f0e18>] dump_stack+0x98/0xb8
+| [<ffff0000088eef08>] panic+0x118/0x274
+| [<ffff0000080b50e0>] access_actlr+0x0/0x20
+| [<ffff0000080b2620>] kvm_reset_vcpu+0x5c/0xac
+| [<ffff0000080ac688>] kvm_arch_vcpu_ioctl+0x3e4/0x490
+| [<ffff0000080a382c>] kvm_vcpu_ioctl+0x5b8/0x720
+| [<ffff000008201e44>] do_vfs_ioctl+0x2f4/0x884
+| [<ffff00000820244c>] SyS_ioctl+0x78/0x9c
+| [<ffff000008083a9c>] __sys_trace_return+0x0/0x4
+
+Cc: <stable@vger.kernel.org> # < v5.3 with 2a5f1b67ec57 backported
+Signed-off-by: James Morse <james.morse@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/sys_regs.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/kvm/sys_regs.c
++++ b/arch/arm64/kvm/sys_regs.c
+@@ -620,8 +620,10 @@ static void reset_pmcr(struct kvm_vcpu *
+       u64 pmcr, val;
+       /* No PMU available, PMCR_EL0 may UNDEF... */
+-      if (!kvm_arm_support_pmu_v3())
++      if (!kvm_arm_support_pmu_v3()) {
++              vcpu_sys_reg(vcpu, PMCR_EL0) = 0;
+               return;
++      }
+       pmcr = read_sysreg(pmcr_el0);
+       /*
diff --git a/queue-4.19/net-macb-fix-lost-rx-packet-wakeup-race-in-napi-receive.patch b/queue-4.19/net-macb-fix-lost-rx-packet-wakeup-race-in-napi-receive.patch
new file mode 100644 (file)
index 0000000..56fca79
--- /dev/null
@@ -0,0 +1,81 @@
+From 0bf476fc3624e3a72af4ba7340d430a91c18cd67 Mon Sep 17 00:00:00 2001
+From: Robert Hancock <robert.hancock@calian.com>
+Date: Thu, 3 Mar 2022 12:10:27 -0600
+Subject: net: macb: Fix lost RX packet wakeup race in NAPI receive
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+commit 0bf476fc3624e3a72af4ba7340d430a91c18cd67 upstream.
+
+There is an oddity in the way the RSR register flags propagate to the
+ISR register (and the actual interrupt output) on this hardware: it
+appears that RSR register bits only result in ISR being asserted if the
+interrupt was actually enabled at the time, so enabling interrupts with
+RSR bits already set doesn't trigger an interrupt to be raised. There
+was already a partial fix for this race in the macb_poll function where
+it checked for RSR bits being set and re-triggered NAPI receive.
+However, there was a still a race window between checking RSR and
+actually enabling interrupts, where a lost wakeup could happen. It's
+necessary to check again after enabling interrupts to see if RSR was set
+just prior to the interrupt being enabled, and re-trigger receive in that
+case.
+
+This issue was noticed in a point-to-point UDP request-response protocol
+which periodically saw timeouts or abnormally high response times due to
+received packets not being processed in a timely fashion. In many
+applications, more packets arriving, including TCP retransmissions, would
+cause the original packet to be processed, thus masking the issue.
+
+Fixes: 02f7a34f34e3 ("net: macb: Re-enable RX interrupt only when RX is done")
+Cc: stable@vger.kernel.org
+Co-developed-by: Scott McNutt <scott.mcnutt@siriusxm.com>
+Signed-off-by: Scott McNutt <scott.mcnutt@siriusxm.com>
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Tested-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c |   25 ++++++++++++++++++++++++-
+ 1 file changed, 24 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -1269,7 +1269,14 @@ static int macb_poll(struct napi_struct
+       if (work_done < budget) {
+               napi_complete_done(napi, work_done);
+-              /* Packets received while interrupts were disabled */
++              /* RSR bits only seem to propagate to raise interrupts when
++               * interrupts are enabled at the time, so if bits are already
++               * set due to packets received while interrupts were disabled,
++               * they will not cause another interrupt to be generated when
++               * interrupts are re-enabled.
++               * Check for this case here. This has been seen to happen
++               * around 30% of the time under heavy network load.
++               */
+               status = macb_readl(bp, RSR);
+               if (status) {
+                       if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+@@ -1277,6 +1284,22 @@ static int macb_poll(struct napi_struct
+                       napi_reschedule(napi);
+               } else {
+                       queue_writel(queue, IER, bp->rx_intr_mask);
++
++                      /* In rare cases, packets could have been received in
++                       * the window between the check above and re-enabling
++                       * interrupts. Therefore, a double-check is required
++                       * to avoid losing a wakeup. This can potentially race
++                       * with the interrupt handler doing the same actions
++                       * if an interrupt is raised just after enabling them,
++                       * but this should be harmless.
++                       */
++                      status = macb_readl(bp, RSR);
++                      if (unlikely(status)) {
++                              queue_writel(queue, IDR, bp->rx_intr_mask);
++                              if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
++                                      queue_writel(queue, ISR, MACB_BIT(RCOMP));
++                              napi_schedule(napi);
++                      }
+               }
+       }
diff --git a/queue-4.19/riscv-fix-auipc-jalr-relocation-range-checks.patch b/queue-4.19/riscv-fix-auipc-jalr-relocation-range-checks.patch
new file mode 100644 (file)
index 0000000..b5bbc14
--- /dev/null
@@ -0,0 +1,100 @@
+From 0966d385830de3470b7131db8e86c0c5bc9c52dc Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Wed, 23 Feb 2022 20:12:57 +0100
+Subject: riscv: Fix auipc+jalr relocation range checks
+
+From: Emil Renner Berthing <kernel@esmil.dk>
+
+commit 0966d385830de3470b7131db8e86c0c5bc9c52dc upstream.
+
+RISC-V can do PC-relative jumps with a 32bit range using the following
+two instructions:
+
+       auipc   t0, imm20       ; t0 = PC + imm20 * 2^12
+       jalr    ra, t0, imm12   ; ra = PC + 4, PC = t0 + imm12
+
+Crucially both the 20bit immediate imm20 and the 12bit immediate imm12
+are treated as two's-complement signed values. For this reason the
+immediates are usually calculated like this:
+
+       imm20 = (offset + 0x800) >> 12
+       imm12 = offset & 0xfff
+
+..where offset is the signed offset from the auipc instruction. When
+the 11th bit of offset is 0 the addition of 0x800 doesn't change the top
+20 bits and imm12 considered positive. When the 11th bit is 1 the carry
+of the addition by 0x800 means imm20 is one higher, but since imm12 is
+then considered negative the two's complement representation means it
+all cancels out nicely.
+
+However, this addition by 0x800 (2^11) means an offset greater than or
+equal to 2^31 - 2^11 would overflow so imm20 is considered negative and
+result in a backwards jump. Similarly the lower range of offset is also
+moved down by 2^11 and hence the true 32bit range is
+
+       [-2^31 - 2^11, 2^31 - 2^11)
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Fixes: e2c0cdfba7f6 ("RISC-V: User-facing API")
+Cc: stable@vger.kernel.org
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/kernel/module.c |   21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+--- a/arch/riscv/kernel/module.c
++++ b/arch/riscv/kernel/module.c
+@@ -21,6 +21,19 @@
+ #include <asm/pgtable.h>
+ #include <asm/sections.h>
++/*
++ * The auipc+jalr instruction pair can reach any PC-relative offset
++ * in the range [-2^31 - 2^11, 2^31 - 2^11)
++ */
++static bool riscv_insn_valid_32bit_offset(ptrdiff_t val)
++{
++#ifdef CONFIG_32BIT
++      return true;
++#else
++      return (-(1L << 31) - (1L << 11)) <= val && val < ((1L << 31) - (1L << 11));
++#endif
++}
++
+ static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v)
+ {
+       if (v != (u32)v) {
+@@ -103,7 +116,7 @@ static int apply_r_riscv_pcrel_hi20_rela
+       ptrdiff_t offset = (void *)v - (void *)location;
+       s32 hi20;
+-      if (offset != (s32)offset) {
++      if (!riscv_insn_valid_32bit_offset(offset)) {
+               pr_err(
+                 "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
+                 me->name, (long long)v, location);
+@@ -205,10 +218,9 @@ static int apply_r_riscv_call_plt_rela(s
+                                      Elf_Addr v)
+ {
+       ptrdiff_t offset = (void *)v - (void *)location;
+-      s32 fill_v = offset;
+       u32 hi20, lo12;
+-      if (offset != fill_v) {
++      if (!riscv_insn_valid_32bit_offset(offset)) {
+               /* Only emit the plt entry if offset over 32-bit range */
+               if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) {
+                       offset = module_emit_plt_entry(me, v);
+@@ -232,10 +244,9 @@ static int apply_r_riscv_call_rela(struc
+                                  Elf_Addr v)
+ {
+       ptrdiff_t offset = (void *)v - (void *)location;
+-      s32 fill_v = offset;
+       u32 hi20, lo12;
+-      if (offset != fill_v) {
++      if (!riscv_insn_valid_32bit_offset(offset)) {
+               pr_err(
+                 "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
+                 me->name, (long long)v, location);
index 14d2de8e998a6849633400de1c96b02a538f49ee..89ac01b79a0eedc7702c7e3eee36001b757dede0 100644 (file)
@@ -16,3 +16,7 @@ revert-xen-netback-check-for-hotplug-status-existenc.patch
 tracing-ensure-trace-buffer-is-at-least-4096-bytes-l.patch
 selftests-memfd-clean-up-mapping-in-mfd_fail_write.patch
 arm-spectre-bhb-provide-empty-stub-for-non-config.patch
+staging-gdm724x-fix-use-after-free-in-gdm_lte_rx.patch
+net-macb-fix-lost-rx-packet-wakeup-race-in-napi-receive.patch
+riscv-fix-auipc-jalr-relocation-range-checks.patch
+kvm-arm64-reset-pmc_el0-to-avoid-a-panic-on-systems-with-no-pmu.patch
diff --git a/queue-4.19/staging-gdm724x-fix-use-after-free-in-gdm_lte_rx.patch b/queue-4.19/staging-gdm724x-fix-use-after-free-in-gdm_lte_rx.patch
new file mode 100644 (file)
index 0000000..da3f608
--- /dev/null
@@ -0,0 +1,42 @@
+From fc7f750dc9d102c1ed7bbe4591f991e770c99033 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Mon, 28 Feb 2022 10:43:31 +0300
+Subject: staging: gdm724x: fix use after free in gdm_lte_rx()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit fc7f750dc9d102c1ed7bbe4591f991e770c99033 upstream.
+
+The netif_rx_ni() function frees the skb so we can't dereference it to
+save the skb->len.
+
+Fixes: 61e121047645 ("staging: gdm7240: adding LTE USB driver")
+Cc: stable <stable@vger.kernel.org>
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/20220228074331.GA13685@kili
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/gdm724x/gdm_lte.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/gdm724x/gdm_lte.c
++++ b/drivers/staging/gdm724x/gdm_lte.c
+@@ -76,14 +76,15 @@ static void tx_complete(void *arg)
+ static int gdm_lte_rx(struct sk_buff *skb, struct nic *nic, int nic_type)
+ {
+-      int ret;
++      int ret, len;
++      len = skb->len + ETH_HLEN;
+       ret = netif_rx_ni(skb);
+       if (ret == NET_RX_DROP) {
+               nic->stats.rx_dropped++;
+       } else {
+               nic->stats.rx_packets++;
+-              nic->stats.rx_bytes += skb->len + ETH_HLEN;
++              nic->stats.rx_bytes += len;
+       }
+       return 0;