From 01d7c07920cc2bda22a7c92e721746b2bdc3da4d Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Thu, 14 Jul 2022 10:58:27 +0200 Subject: [PATCH] pc/linux: add contrib patches - intel_fb: avoid pagefault in fliphandler - usb_host: avoid hang of usb xhci hardware Fixes #4556 --- repos/dde_linux/patches/i915_irq.patch | 14 ++++ repos/dde_linux/patches/xhci_abort_ring.patch | 71 +++++++++++++++++++ repos/dde_linux/ports/linux.hash | 2 +- repos/dde_linux/ports/linux.port | 10 +++ 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 repos/dde_linux/patches/i915_irq.patch create mode 100644 repos/dde_linux/patches/xhci_abort_ring.patch diff --git a/repos/dde_linux/patches/i915_irq.patch b/repos/dde_linux/patches/i915_irq.patch new file mode 100644 index 0000000000..1af100c505 --- /dev/null +++ b/repos/dde_linux/patches/i915_irq.patch @@ -0,0 +1,14 @@ +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index c3816f5..c692ddb 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1337,7 +1337,8 @@ static void flip_done_handler(struct drm_i915_private *i915, + + crtc_state->event = NULL; + +- drm_crtc_send_vblank_event(&crtc->base, e); ++ if (e) ++ drm_crtc_send_vblank_event(&crtc->base, e); + + spin_unlock_irqrestore(&dev->event_lock, irqflags); + } diff --git a/repos/dde_linux/patches/xhci_abort_ring.patch b/repos/dde_linux/patches/xhci_abort_ring.patch new file mode 100644 index 0000000000..fed3aa230a --- /dev/null +++ b/repos/dde_linux/patches/xhci_abort_ring.patch @@ -0,0 +1,71 @@ +From 09f736aa95476631227d2dc0e6b9aeee1ad7ed58 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Fri, 26 Nov 2021 14:23:40 +0200 +Subject: xhci: Fix commad ring abort, write all 64 bits to CRCR register. + +Turns out some xHC controllers require all 64 bits in the CRCR register +to be written to execute a command abort. + +The lower 32 bits containing the command abort bit is written first. +In case the command ring stops before we write the upper 32 bits then +hardware may use these upper bits to set the commnd ring dequeue pointer. + +Solve this by making sure the upper 32 bits contain a valid command +ring dequeue pointer. + +The original patch that only wrote the first 32 to stop the ring went +to stable, so this fix should go there as well. + +Fixes: ff0e50d3564f ("xhci: Fix command ring pointer corruption while aborting a command") +Cc: stable@vger.kernel.org +Tested-by: Pavankumar Kondeti +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20211126122340.1193239-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-ring.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 311597bba80e2..eaa49aef29352 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -366,7 +366,9 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci, + /* Must be called with xhci->lock held, releases and aquires lock back */ + static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags) + { +- u32 temp_32; ++ struct xhci_segment *new_seg = xhci->cmd_ring->deq_seg; ++ union xhci_trb *new_deq = xhci->cmd_ring->dequeue; ++ u64 crcr; + int ret; + + xhci_dbg(xhci, "Abort command ring\n"); +@@ -375,13 +377,18 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags) + + /* + * The control bits like command stop, abort are located in lower +- * dword of the command ring control register. Limit the write +- * to the lower dword to avoid corrupting the command ring pointer +- * in case if the command ring is stopped by the time upper dword +- * is written. ++ * dword of the command ring control register. ++ * Some controllers require all 64 bits to be written to abort the ring. ++ * Make sure the upper dword is valid, pointing to the next command, ++ * avoiding corrupting the command ring pointer in case the command ring ++ * is stopped by the time the upper dword is written. + */ +- temp_32 = readl(&xhci->op_regs->cmd_ring); +- writel(temp_32 | CMD_RING_ABORT, &xhci->op_regs->cmd_ring); ++ next_trb(xhci, NULL, &new_seg, &new_deq); ++ if (trb_is_link(new_deq)) ++ next_trb(xhci, NULL, &new_seg, &new_deq); ++ ++ crcr = xhci_trb_virt_to_dma(new_seg, new_deq); ++ xhci_write_64(xhci, crcr | CMD_RING_ABORT, &xhci->op_regs->cmd_ring); + + /* Section 4.6.1.2 of xHCI 1.0 spec says software should also time the + * completion of the Command Abort operation. If CRR is not negated in 5 +-- +cgit + diff --git a/repos/dde_linux/ports/linux.hash b/repos/dde_linux/ports/linux.hash index 7ffa8ee4df..68028b4d6c 100644 --- a/repos/dde_linux/ports/linux.hash +++ b/repos/dde_linux/ports/linux.hash @@ -1 +1 @@ -b00fd4b8dc40ca35d3a9f8f27bfd7ec8c671bd4b +7dfb92febaf5942b4b84612dcca182eddb088a00 diff --git a/repos/dde_linux/ports/linux.port b/repos/dde_linux/ports/linux.port index a3164611a6..e6cca8823c 100644 --- a/repos/dde_linux/ports/linux.port +++ b/repos/dde_linux/ports/linux.port @@ -5,3 +5,13 @@ DOWNLOADS := linux.archive URL(linux) := https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-$(VERSION).tar.xz SHA(linux) := f41a259cb2002dd2e3286524b2bb4e803f4f982992d092706ecea613584023b3 DIR(linux) := src/linux + +# +# Patches +# +PATCHES += $(addprefix patches/,$(notdir $(REP_DIR)/patches/i915_irq.patch)) +PATCHES += $(addprefix patches/,$(notdir $(REP_DIR)/patches/xhci_abort_ring.patch)) + +# i915 +PATCH_OPT(patches/i915_irq.patch) := -p1 -d${DIR(linux)} +PATCH_OPT(patches/xhci_abort_ring.patch) := -p1 -d${DIR(linux)}