]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Mar 2024 12:27:14 +0000 (13:27 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Mar 2024 12:27:14 +0000 (13:27 +0100)
added patches:
kvm-arm64-limit-stage2_apply_range-batch-size-to-largest-block.patch
kvm-arm64-work-out-supported-block-level-at-compile-time.patch
tty-serial-imx-fix-broken-rs485.patch

queue-5.15/kvm-arm64-limit-stage2_apply_range-batch-size-to-largest-block.patch [new file with mode: 0644]
queue-5.15/kvm-arm64-work-out-supported-block-level-at-compile-time.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/tty-serial-imx-fix-broken-rs485.patch [new file with mode: 0644]

diff --git a/queue-5.15/kvm-arm64-limit-stage2_apply_range-batch-size-to-largest-block.patch b/queue-5.15/kvm-arm64-limit-stage2_apply_range-batch-size-to-largest-block.patch
new file mode 100644 (file)
index 0000000..a473ecb
--- /dev/null
@@ -0,0 +1,142 @@
+From 5994bc9e05c2f8811f233aa434e391cd2783f0f5 Mon Sep 17 00:00:00 2001
+From: Oliver Upton <oliver.upton@linux.dev>
+Date: Fri, 7 Oct 2022 23:41:51 +0000
+Subject: KVM: arm64: Limit stage2_apply_range() batch size to largest block
+
+From: Oliver Upton <oliver.upton@linux.dev>
+
+commit 5994bc9e05c2f8811f233aa434e391cd2783f0f5 upstream.
+
+Presently stage2_apply_range() works on a batch of memory addressed by a
+stage 2 root table entry for the VM. Depending on the IPA limit of the
+VM and PAGE_SIZE of the host, this could address a massive range of
+memory. Some examples:
+
+  4 level, 4K paging -> 512 GB batch size
+
+  3 level, 64K paging -> 4TB batch size
+
+Unsurprisingly, working on such a large range of memory can lead to soft
+lockups. When running dirty_log_perf_test:
+
+  ./dirty_log_perf_test -m -2 -s anonymous_thp -b 4G -v 48
+
+  watchdog: BUG: soft lockup - CPU#0 stuck for 45s! [dirty_log_perf_:16703]
+  Modules linked in: vfat fat cdc_ether usbnet mii xhci_pci xhci_hcd sha3_generic gq(O)
+  CPU: 0 PID: 16703 Comm: dirty_log_perf_ Tainted: G           O       6.0.0-smp-DEV #1
+  pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+  pc : dcache_clean_inval_poc+0x24/0x38
+  lr : clean_dcache_guest_page+0x28/0x4c
+  sp : ffff800021763990
+  pmr_save: 000000e0
+  x29: ffff800021763990 x28: 0000000000000005 x27: 0000000000000de0
+  x26: 0000000000000001 x25: 00400830b13bc77f x24: ffffad4f91ead9c0
+  x23: 0000000000000000 x22: ffff8000082ad9c8 x21: 0000fffafa7bc000
+  x20: ffffad4f9066ce50 x19: 0000000000000003 x18: ffffad4f92402000
+  x17: 000000000000011b x16: 000000000000011b x15: 0000000000000124
+  x14: ffff07ff8301d280 x13: 0000000000000000 x12: 00000000ffffffff
+  x11: 0000000000010001 x10: fffffc0000000000 x9 : ffffad4f9069e580
+  x8 : 000000000000000c x7 : 0000000000000000 x6 : 000000000000003f
+  x5 : ffff07ffa2076980 x4 : 0000000000000001 x3 : 000000000000003f
+  x2 : 0000000000000040 x1 : ffff0830313bd000 x0 : ffff0830313bcc40
+  Call trace:
+   dcache_clean_inval_poc+0x24/0x38
+   stage2_unmap_walker+0x138/0x1ec
+   __kvm_pgtable_walk+0x130/0x1d4
+   __kvm_pgtable_walk+0x170/0x1d4
+   __kvm_pgtable_walk+0x170/0x1d4
+   __kvm_pgtable_walk+0x170/0x1d4
+   kvm_pgtable_stage2_unmap+0xc4/0xf8
+   kvm_arch_flush_shadow_memslot+0xa4/0x10c
+   kvm_set_memslot+0xb8/0x454
+   __kvm_set_memory_region+0x194/0x244
+   kvm_vm_ioctl_set_memory_region+0x58/0x7c
+   kvm_vm_ioctl+0x49c/0x560
+   __arm64_sys_ioctl+0x9c/0xd4
+   invoke_syscall+0x4c/0x124
+   el0_svc_common+0xc8/0x194
+   do_el0_svc+0x38/0xc0
+   el0_svc+0x2c/0xa4
+   el0t_64_sync_handler+0x84/0xf0
+   el0t_64_sync+0x1a0/0x1a4
+
+Use the largest supported block mapping for the configured page size as
+the batch granularity. In so doing the walker is guaranteed to visit a
+leaf only once.
+
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20221007234151.461779-3-oliver.upton@linux.dev
+Signed-off-by: Krister Johansen <kjlx@templeofstupid.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/include/asm/stage2_pgtable.h |   20 --------------------
+ arch/arm64/kvm/mmu.c                    |    9 ++++++++-
+ 2 files changed, 8 insertions(+), 21 deletions(-)
+
+--- a/arch/arm64/include/asm/stage2_pgtable.h
++++ b/arch/arm64/include/asm/stage2_pgtable.h
+@@ -11,13 +11,6 @@
+ #include <linux/pgtable.h>
+ /*
+- * PGDIR_SHIFT determines the size a top-level page table entry can map
+- * and depends on the number of levels in the page table. Compute the
+- * PGDIR_SHIFT for a given number of levels.
+- */
+-#define pt_levels_pgdir_shift(lvls)   ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - (lvls))
+-
+-/*
+  * The hardware supports concatenation of up to 16 tables at stage2 entry
+  * level and we use the feature whenever possible, which means we resolve 4
+  * additional bits of address at the entry level.
+@@ -30,11 +23,6 @@
+ #define stage2_pgtable_levels(ipa)    ARM64_HW_PGTABLE_LEVELS((ipa) - 4)
+ #define kvm_stage2_levels(kvm)                VTCR_EL2_LVLS(kvm->arch.vtcr)
+-/* stage2_pgdir_shift() is the size mapped by top-level stage2 entry for the VM */
+-#define stage2_pgdir_shift(kvm)               pt_levels_pgdir_shift(kvm_stage2_levels(kvm))
+-#define stage2_pgdir_size(kvm)                (1ULL << stage2_pgdir_shift(kvm))
+-#define stage2_pgdir_mask(kvm)                ~(stage2_pgdir_size(kvm) - 1)
+-
+ /*
+  * kvm_mmmu_cache_min_pages() is the number of pages required to install
+  * a stage-2 translation. We pre-allocate the entry level page table at
+@@ -42,12 +30,4 @@
+  */
+ #define kvm_mmu_cache_min_pages(kvm)  (kvm_stage2_levels(kvm) - 1)
+-static inline phys_addr_t
+-stage2_pgd_addr_end(struct kvm *kvm, phys_addr_t addr, phys_addr_t end)
+-{
+-      phys_addr_t boundary = (addr + stage2_pgdir_size(kvm)) & stage2_pgdir_mask(kvm);
+-
+-      return (boundary - 1 < end - 1) ? boundary : end;
+-}
+-
+ #endif        /* __ARM64_S2_PGTABLE_H_ */
+--- a/arch/arm64/kvm/mmu.c
++++ b/arch/arm64/kvm/mmu.c
+@@ -31,6 +31,13 @@ static phys_addr_t hyp_idmap_vector;
+ static unsigned long io_map_base;
++static phys_addr_t stage2_range_addr_end(phys_addr_t addr, phys_addr_t end)
++{
++      phys_addr_t size = kvm_granule_size(KVM_PGTABLE_MIN_BLOCK_LEVEL);
++      phys_addr_t boundary = ALIGN_DOWN(addr + size, size);
++
++      return (boundary - 1 < end - 1) ? boundary : end;
++}
+ /*
+  * Release kvm_mmu_lock periodically if the memory region is large. Otherwise,
+@@ -52,7 +59,7 @@ static int stage2_apply_range(struct kvm
+               if (!pgt)
+                       return -EINVAL;
+-              next = stage2_pgd_addr_end(kvm, addr, end);
++              next = stage2_range_addr_end(addr, end);
+               ret = fn(pgt, addr, next - addr);
+               if (ret)
+                       break;
diff --git a/queue-5.15/kvm-arm64-work-out-supported-block-level-at-compile-time.patch b/queue-5.15/kvm-arm64-work-out-supported-block-level-at-compile-time.patch
new file mode 100644 (file)
index 0000000..6b627df
--- /dev/null
@@ -0,0 +1,57 @@
+From 3b5c082bbfa20d9a57924edd655bbe63fe98ab06 Mon Sep 17 00:00:00 2001
+From: Oliver Upton <oliver.upton@linux.dev>
+Date: Fri, 7 Oct 2022 23:41:50 +0000
+Subject: KVM: arm64: Work out supported block level at compile time
+
+From: Oliver Upton <oliver.upton@linux.dev>
+
+commit 3b5c082bbfa20d9a57924edd655bbe63fe98ab06 upstream.
+
+Work out the minimum page table level where KVM supports block mappings
+at compile time. While at it, rewrite the comment around supported block
+mappings to directly describe what KVM supports instead of phrasing in
+terms of what it does not.
+
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20221007234151.461779-2-oliver.upton@linux.dev
+Signed-off-by: Krister Johansen <kjlx@templeofstupid.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/include/asm/kvm_pgtable.h |   18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+--- a/arch/arm64/include/asm/kvm_pgtable.h
++++ b/arch/arm64/include/asm/kvm_pgtable.h
+@@ -13,6 +13,18 @@
+ #define KVM_PGTABLE_MAX_LEVELS                4U
++/*
++ * The largest supported block sizes for KVM (no 52-bit PA support):
++ *  - 4K (level 1):   1GB
++ *  - 16K (level 2):  32MB
++ *  - 64K (level 2):  512MB
++ */
++#ifdef CONFIG_ARM64_4K_PAGES
++#define KVM_PGTABLE_MIN_BLOCK_LEVEL   1U
++#else
++#define KVM_PGTABLE_MIN_BLOCK_LEVEL   2U
++#endif
++
+ static inline u64 kvm_get_parange(u64 mmfr0)
+ {
+       u64 parange = cpuid_feature_extract_unsigned_field(mmfr0,
+@@ -58,11 +70,7 @@ static inline u64 kvm_granule_size(u32 l
+ static inline bool kvm_level_supports_block_mapping(u32 level)
+ {
+-      /*
+-       * Reject invalid block mappings and don't bother with 4TB mappings for
+-       * 52-bit PAs.
+-       */
+-      return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1));
++      return level >= KVM_PGTABLE_MIN_BLOCK_LEVEL;
+ }
+ /**
index d958bfa30e7ba1e33e0f1c31ed3a976a09cfcd04..4990e9ddbeacb131d658c4cbef9f1c0f6e8b18d6 100644 (file)
@@ -146,3 +146,6 @@ dma-mapping-add-dma_opt_mapping_size.patch
 dma-iommu-add-iommu_dma_opt_mapping_size.patch
 iommu-dma-force-swiotlb_max_mapping_size-on-an-untru.patch
 printk-update-console_may_schedule-in-console_tryloc.patch
+tty-serial-imx-fix-broken-rs485.patch
+kvm-arm64-work-out-supported-block-level-at-compile-time.patch
+kvm-arm64-limit-stage2_apply_range-batch-size-to-largest-block.patch
diff --git a/queue-5.15/tty-serial-imx-fix-broken-rs485.patch b/queue-5.15/tty-serial-imx-fix-broken-rs485.patch
new file mode 100644 (file)
index 0000000..e6131a1
--- /dev/null
@@ -0,0 +1,85 @@
+From 672448ccf9b6a676f96f9352cbf91f4d35f4084a Mon Sep 17 00:00:00 2001
+From: Rickard x Andersson <rickaran@axis.com>
+Date: Wed, 21 Feb 2024 12:53:04 +0100
+Subject: tty: serial: imx: Fix broken RS485
+
+From: Rickard x Andersson <rickaran@axis.com>
+
+commit 672448ccf9b6a676f96f9352cbf91f4d35f4084a upstream.
+
+When about to transmit the function imx_uart_start_tx is called and in
+some RS485 configurations this function will call imx_uart_stop_rx. The
+problem is that imx_uart_stop_rx will enable loopback in order to
+release the RS485 bus, but when loopback is enabled transmitted data
+will just be looped to RX.
+
+This patch fixes the above problem by not enabling loopback when about
+to transmit.
+
+This driver now works well when used for RS485 half duplex master
+configurations.
+
+Fixes: 79d0224f6bf2 ("tty: serial: imx: Handle RS485 DE signal active high")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Rickard x Andersson <rickaran@axis.com>
+Tested-by: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+Link: https://lore.kernel.org/r/20240221115304.509811-1-rickaran@axis.com
+Signed-off-by: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/imx.c |   22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -491,8 +491,7 @@ static void imx_uart_stop_tx(struct uart
+       }
+ }
+-/* called with port.lock taken and irqs off */
+-static void imx_uart_stop_rx(struct uart_port *port)
++static void imx_uart_stop_rx_with_loopback_ctrl(struct uart_port *port, bool loopback)
+ {
+       struct imx_port *sport = (struct imx_port *)port;
+       u32 ucr1, ucr2, ucr4, uts;
+@@ -514,7 +513,7 @@ static void imx_uart_stop_rx(struct uart
+       /* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */
+       if (port->rs485.flags & SER_RS485_ENABLED &&
+           port->rs485.flags & SER_RS485_RTS_ON_SEND &&
+-          sport->have_rtscts && !sport->have_rtsgpio) {
++          sport->have_rtscts && !sport->have_rtsgpio && loopback) {
+               uts = imx_uart_readl(sport, imx_uart_uts_reg(sport));
+               uts |= UTS_LOOP;
+               imx_uart_writel(sport, uts, imx_uart_uts_reg(sport));
+@@ -527,6 +526,16 @@ static void imx_uart_stop_rx(struct uart
+ }
+ /* called with port.lock taken and irqs off */
++static void imx_uart_stop_rx(struct uart_port *port)
++{
++      /*
++       * Stop RX and enable loopback in order to make sure RS485 bus
++       * is not blocked. Se comment in imx_uart_probe().
++       */
++      imx_uart_stop_rx_with_loopback_ctrl(port, true);
++}
++
++/* called with port.lock taken and irqs off */
+ static void imx_uart_enable_ms(struct uart_port *port)
+ {
+       struct imx_port *sport = (struct imx_port *)port;
+@@ -714,8 +723,13 @@ static void imx_uart_start_tx(struct uar
+                               imx_uart_rts_inactive(sport, &ucr2);
+                       imx_uart_writel(sport, ucr2, UCR2);
++                      /*
++                       * Since we are about to transmit we can not stop RX
++                       * with loopback enabled because that will make our
++                       * transmitted data being just looped to RX.
++                       */
+                       if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
+-                              imx_uart_stop_rx(port);
++                              imx_uart_stop_rx_with_loopback_ctrl(port, false);
+                       sport->tx_state = WAIT_AFTER_RTS;
+                       start_hrtimer_ms(&sport->trigger_start_tx,