From: Greg Kroah-Hartman Date: Tue, 17 Jun 2025 14:31:34 +0000 (+0200) Subject: 6.6-stable patches X-Git-Tag: v6.6.94~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=903dbb7eb835827be0798e92c8077260800247ac;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: usb-cdnsp-fix-issue-with-detecting-command-completion-event.patch usb-cdnsp-fix-issue-with-detecting-usb-3.2-speed.patch usb-flush-altsetting-0-endpoints-before-reinitializating-them-after-reset.patch usb-typec-tcpm-tcpci_maxim-fix-bounds-check-in-process_rx.patch usb-usbtmc-fix-read_stb-function-and-get_stb-ioctl.patch vmci-fix-race-between-vmci_host_setup_notify-and-vmci_ctx_unset_notify.patch x86-iopl-cure-tif_io_bitmap-inconsistencies.patch xen-arm-call-uaccess_ttbr0_enable-for-dm_op-hypercall.patch --- diff --git a/queue-6.6/series b/queue-6.6/series index ff92254949..1e1f1f631f 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -343,3 +343,11 @@ io_uring-rw-fix-wrong-nowait-check-in-io_rw_init_file.patch revert-io_uring-ensure-deferred-completions-are-posted-for-multishot.patch posix-cpu-timers-fix-race-between-handle_posix_cpu_timers-and-posix_cpu_timer_del.patch kbuild-disable-wdefault-const-init-unsafe.patch +usb-usbtmc-fix-read_stb-function-and-get_stb-ioctl.patch +vmci-fix-race-between-vmci_host_setup_notify-and-vmci_ctx_unset_notify.patch +usb-cdnsp-fix-issue-with-detecting-command-completion-event.patch +usb-cdnsp-fix-issue-with-detecting-usb-3.2-speed.patch +usb-flush-altsetting-0-endpoints-before-reinitializating-them-after-reset.patch +usb-typec-tcpm-tcpci_maxim-fix-bounds-check-in-process_rx.patch +xen-arm-call-uaccess_ttbr0_enable-for-dm_op-hypercall.patch +x86-iopl-cure-tif_io_bitmap-inconsistencies.patch diff --git a/queue-6.6/usb-cdnsp-fix-issue-with-detecting-command-completion-event.patch b/queue-6.6/usb-cdnsp-fix-issue-with-detecting-command-completion-event.patch new file mode 100644 index 0000000000..c0bd1ab2c2 --- /dev/null +++ b/queue-6.6/usb-cdnsp-fix-issue-with-detecting-command-completion-event.patch @@ -0,0 +1,75 @@ +From f4ecdc352646f7d23f348e5c544dbe3212c94fc8 Mon Sep 17 00:00:00 2001 +From: Pawel Laszczak +Date: Tue, 13 May 2025 05:30:09 +0000 +Subject: usb: cdnsp: Fix issue with detecting command completion event + +From: Pawel Laszczak + +commit f4ecdc352646f7d23f348e5c544dbe3212c94fc8 upstream. + +In some cases, there is a small-time gap in which CMD_RING_BUSY can be +cleared by controller but adding command completion event to event ring +will be delayed. As the result driver will return error code. + +This behavior has been detected on usbtest driver (test 9) with +configuration including ep1in/ep1out bulk and ep2in/ep2out isoc +endpoint. + +Probably this gap occurred because controller was busy with adding some +other events to event ring. + +The CMD_RING_BUSY is cleared to '0' when the Command Descriptor has been +executed and not when command completion event has been added to event +ring. + +To fix this issue for this test the small delay is sufficient less than +10us) but to make sure the problem doesn't happen again in the future +the patch introduces 10 retries to check with delay about 20us before +returning error code. + +Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") +Cc: stable +Signed-off-by: Pawel Laszczak +Acked-by: Peter Chen +Link: https://lore.kernel.org/r/PH7PR07MB9538AA45362ACCF1B94EE9B7DD96A@PH7PR07MB9538.namprd07.prod.outlook.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/cdnsp-gadget.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +--- a/drivers/usb/cdns3/cdnsp-gadget.c ++++ b/drivers/usb/cdns3/cdnsp-gadget.c +@@ -546,6 +546,7 @@ int cdnsp_wait_for_cmd_compl(struct cdns + dma_addr_t cmd_deq_dma; + union cdnsp_trb *event; + u32 cycle_state; ++ u32 retry = 10; + int ret, val; + u64 cmd_dma; + u32 flags; +@@ -577,8 +578,23 @@ int cdnsp_wait_for_cmd_compl(struct cdns + flags = le32_to_cpu(event->event_cmd.flags); + + /* Check the owner of the TRB. */ +- if ((flags & TRB_CYCLE) != cycle_state) ++ if ((flags & TRB_CYCLE) != cycle_state) { ++ /* ++ * Give some extra time to get chance controller ++ * to finish command before returning error code. ++ * Checking CMD_RING_BUSY is not sufficient because ++ * this bit is cleared to '0' when the Command ++ * Descriptor has been executed by controller ++ * and not when command completion event has ++ * be added to event ring. ++ */ ++ if (retry--) { ++ udelay(20); ++ continue; ++ } ++ + return -EINVAL; ++ } + + cmd_dma = le64_to_cpu(event->event_cmd.cmd_trb); + diff --git a/queue-6.6/usb-cdnsp-fix-issue-with-detecting-usb-3.2-speed.patch b/queue-6.6/usb-cdnsp-fix-issue-with-detecting-usb-3.2-speed.patch new file mode 100644 index 0000000000..90f736b8fa --- /dev/null +++ b/queue-6.6/usb-cdnsp-fix-issue-with-detecting-usb-3.2-speed.patch @@ -0,0 +1,53 @@ +From 2852788cfbe9ca1ab68509d65804413871f741f9 Mon Sep 17 00:00:00 2001 +From: Pawel Laszczak +Date: Tue, 13 May 2025 06:54:03 +0000 +Subject: usb: cdnsp: Fix issue with detecting USB 3.2 speed + +From: Pawel Laszczak + +commit 2852788cfbe9ca1ab68509d65804413871f741f9 upstream. + +Patch adds support for detecting SuperSpeedPlus Gen1 x2 and +SuperSpeedPlus Gen2 x2 speed. + +Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") +Cc: stable +Signed-off-by: Pawel Laszczak +Acked-by: Peter Chen +Link: https://lore.kernel.org/r/PH7PR07MB95387AD98EDCA695FECE52BADD96A@PH7PR07MB9538.namprd07.prod.outlook.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/cdnsp-gadget.c | 3 ++- + drivers/usb/cdns3/cdnsp-gadget.h | 4 ++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/usb/cdns3/cdnsp-gadget.c ++++ b/drivers/usb/cdns3/cdnsp-gadget.c +@@ -28,7 +28,8 @@ + unsigned int cdnsp_port_speed(unsigned int port_status) + { + /*Detect gadget speed based on PORTSC register*/ +- if (DEV_SUPERSPEEDPLUS(port_status)) ++ if (DEV_SUPERSPEEDPLUS(port_status) || ++ DEV_SSP_GEN1x2(port_status) || DEV_SSP_GEN2x2(port_status)) + return USB_SPEED_SUPER_PLUS; + else if (DEV_SUPERSPEED(port_status)) + return USB_SPEED_SUPER; +--- a/drivers/usb/cdns3/cdnsp-gadget.h ++++ b/drivers/usb/cdns3/cdnsp-gadget.h +@@ -285,11 +285,15 @@ struct cdnsp_port_regs { + #define XDEV_HS (0x3 << 10) + #define XDEV_SS (0x4 << 10) + #define XDEV_SSP (0x5 << 10) ++#define XDEV_SSP1x2 (0x6 << 10) ++#define XDEV_SSP2x2 (0x7 << 10) + #define DEV_UNDEFSPEED(p) (((p) & DEV_SPEED_MASK) == (0x0 << 10)) + #define DEV_FULLSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_FS) + #define DEV_HIGHSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_HS) + #define DEV_SUPERSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_SS) + #define DEV_SUPERSPEEDPLUS(p) (((p) & DEV_SPEED_MASK) == XDEV_SSP) ++#define DEV_SSP_GEN1x2(p) (((p) & DEV_SPEED_MASK) == XDEV_SSP1x2) ++#define DEV_SSP_GEN2x2(p) (((p) & DEV_SPEED_MASK) == XDEV_SSP2x2) + #define DEV_SUPERSPEED_ANY(p) (((p) & DEV_SPEED_MASK) >= XDEV_SS) + #define DEV_PORT_SPEED(p) (((p) >> 10) & 0x0f) + /* Port Link State Write Strobe - set this when changing link state */ diff --git a/queue-6.6/usb-flush-altsetting-0-endpoints-before-reinitializating-them-after-reset.patch b/queue-6.6/usb-flush-altsetting-0-endpoints-before-reinitializating-them-after-reset.patch new file mode 100644 index 0000000000..7689a007e2 --- /dev/null +++ b/queue-6.6/usb-flush-altsetting-0-endpoints-before-reinitializating-them-after-reset.patch @@ -0,0 +1,75 @@ +From 89bb3dc13ac29a563f4e4c555e422882f64742bd Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Wed, 14 May 2025 16:25:20 +0300 +Subject: usb: Flush altsetting 0 endpoints before reinitializating them after reset. + +From: Mathias Nyman + +commit 89bb3dc13ac29a563f4e4c555e422882f64742bd upstream. + +usb core avoids sending a Set-Interface altsetting 0 request after device +reset, and instead relies on calling usb_disable_interface() and +usb_enable_interface() to flush and reset host-side of those endpoints. + +xHCI hosts allocate and set up endpoint ring buffers and host_ep->hcpriv +during usb_hcd_alloc_bandwidth() callback, which in this case is called +before flushing the endpoint in usb_disable_interface(). + +Call usb_disable_interface() before usb_hcd_alloc_bandwidth() to ensure +URBs are flushed before new ring buffers for the endpoints are allocated. + +Otherwise host driver will attempt to find and remove old stale URBs +from a freshly allocated new ringbuffer. + +Cc: stable +Fixes: 4fe0387afa89 ("USB: don't send Set-Interface after reset") +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250514132520.225345-1-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/hub.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -6103,6 +6103,7 @@ static int usb_reset_and_verify_device(s + struct usb_hub *parent_hub; + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + struct usb_device_descriptor descriptor; ++ struct usb_interface *intf; + struct usb_host_bos *bos; + int i, j, ret = 0; + int port1 = udev->portnum; +@@ -6160,6 +6161,18 @@ static int usb_reset_and_verify_device(s + if (!udev->actconfig) + goto done; + ++ /* ++ * Some devices can't handle setting default altsetting 0 with a ++ * Set-Interface request. Disable host-side endpoints of those ++ * interfaces here. Enable and reset them back after host has set ++ * its internal endpoint structures during usb_hcd_alloc_bandwith() ++ */ ++ for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { ++ intf = udev->actconfig->interface[i]; ++ if (intf->cur_altsetting->desc.bAlternateSetting == 0) ++ usb_disable_interface(udev, intf, true); ++ } ++ + mutex_lock(hcd->bandwidth_mutex); + ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL); + if (ret < 0) { +@@ -6191,12 +6204,11 @@ static int usb_reset_and_verify_device(s + */ + for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { + struct usb_host_config *config = udev->actconfig; +- struct usb_interface *intf = config->interface[i]; + struct usb_interface_descriptor *desc; + ++ intf = config->interface[i]; + desc = &intf->cur_altsetting->desc; + if (desc->bAlternateSetting == 0) { +- usb_disable_interface(udev, intf, true); + usb_enable_interface(udev, intf, true); + ret = 0; + } else { diff --git a/queue-6.6/usb-typec-tcpm-tcpci_maxim-fix-bounds-check-in-process_rx.patch b/queue-6.6/usb-typec-tcpm-tcpci_maxim-fix-bounds-check-in-process_rx.patch new file mode 100644 index 0000000000..c3cd79e558 --- /dev/null +++ b/queue-6.6/usb-typec-tcpm-tcpci_maxim-fix-bounds-check-in-process_rx.patch @@ -0,0 +1,44 @@ +From 0736299d090f5c6a1032678705c4bc0a9511a3db Mon Sep 17 00:00:00 2001 +From: Amit Sunil Dhamne +Date: Fri, 2 May 2025 16:57:03 -0700 +Subject: usb: typec: tcpm/tcpci_maxim: Fix bounds check in process_rx() + +From: Amit Sunil Dhamne + +commit 0736299d090f5c6a1032678705c4bc0a9511a3db upstream. + +Register read of TCPC_RX_BYTE_CNT returns the total size consisting of: + + PD message (pending read) size + 1 Byte for Frame Type (SOP*) + +This is validated against the max PD message (`struct pd_message`) size +without accounting for the extra byte for the frame type. Note that the +struct pd_message does not contain a field for the frame_type. This +results in false negatives when the "PD message (pending read)" is equal +to the max PD message size. + +Fixes: 6f413b559f86 ("usb: typec: tcpci_maxim: Chip level TCPC driver") +Signed-off-by: Amit Sunil Dhamne +Signed-off-by: Badhri Jagan Sridharan +Reviewed-by: Kyle Tso +Cc: stable +Link: https://lore.kernel.org/stable/20250502-b4-new-fix-pd-rx-count-v1-1-e5711ed09b3d%40google.com +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20250502-b4-new-fix-pd-rx-count-v1-1-e5711ed09b3d@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/tcpm/tcpci_maxim_core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/typec/tcpm/tcpci_maxim_core.c ++++ b/drivers/usb/typec/tcpm/tcpci_maxim_core.c +@@ -145,7 +145,8 @@ static void process_rx(struct max_tcpci_ + return; + } + +- if (count > sizeof(struct pd_message) || count + 1 > TCPC_RECEIVE_BUFFER_LEN) { ++ if (count > sizeof(struct pd_message) + 1 || ++ count + 1 > TCPC_RECEIVE_BUFFER_LEN) { + dev_err(chip->dev, "Invalid TCPC_RX_BYTE_CNT %d\n", count); + return; + } diff --git a/queue-6.6/usb-usbtmc-fix-read_stb-function-and-get_stb-ioctl.patch b/queue-6.6/usb-usbtmc-fix-read_stb-function-and-get_stb-ioctl.patch new file mode 100644 index 0000000000..582d68fa73 --- /dev/null +++ b/queue-6.6/usb-usbtmc-fix-read_stb-function-and-get_stb-ioctl.patch @@ -0,0 +1,69 @@ +From acb3dac2805d3342ded7dbbd164add32bbfdf21c Mon Sep 17 00:00:00 2001 +From: Dave Penkler +Date: Wed, 21 May 2025 14:16:55 +0200 +Subject: usb: usbtmc: Fix read_stb function and get_stb ioctl + +From: Dave Penkler + +commit acb3dac2805d3342ded7dbbd164add32bbfdf21c upstream. + +The usbtmc488_ioctl_read_stb function relied on a positive return from +usbtmc_get_stb to reset the srq condition in the driver. The +USBTMC_IOCTL_GET_STB case tested for a positive return to return the stb +to the user. + +Commit: ("usb: usbtmc: Fix erroneous get_stb ioctl +error returns") changed the return value of usbtmc_get_stb to 0 on +success instead of returning the value of usb_control_msg which is +positive in the normal case. This change caused the function +usbtmc488_ioctl_read_stb and the USBTMC_IOCTL_GET_STB ioctl to no +longer function correctly. + +Change the test in usbtmc488_ioctl_read_stb to test for failure +first and return the failure code immediately. +Change the test for the USBTMC_IOCTL_GET_STB ioctl to test for 0 +instead of a positive value. + +Fixes: cac01bd178d6 ("usb: usbtmc: Fix erroneous get_stb ioctl error returns") +Cc: stable@vger.kernel.org +Signed-off-by: Dave Penkler +Link: https://lore.kernel.org/r/20250521121656.18174-3-dpenkler@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/usbtmc.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/drivers/usb/class/usbtmc.c ++++ b/drivers/usb/class/usbtmc.c +@@ -565,14 +565,15 @@ static int usbtmc488_ioctl_read_stb(stru + + rv = usbtmc_get_stb(file_data, &stb); + +- if (rv > 0) { +- srq_asserted = atomic_xchg(&file_data->srq_asserted, +- srq_asserted); +- if (srq_asserted) +- stb |= 0x40; /* Set RQS bit */ ++ if (rv < 0) ++ return rv; ++ ++ srq_asserted = atomic_xchg(&file_data->srq_asserted, srq_asserted); ++ if (srq_asserted) ++ stb |= 0x40; /* Set RQS bit */ ++ ++ rv = put_user(stb, (__u8 __user *)arg); + +- rv = put_user(stb, (__u8 __user *)arg); +- } + return rv; + + } +@@ -2201,7 +2202,7 @@ static long usbtmc_ioctl(struct file *fi + + case USBTMC_IOCTL_GET_STB: + retval = usbtmc_get_stb(file_data, &tmp_byte); +- if (retval > 0) ++ if (!retval) + retval = put_user(tmp_byte, (__u8 __user *)arg); + break; + diff --git a/queue-6.6/vmci-fix-race-between-vmci_host_setup_notify-and-vmci_ctx_unset_notify.patch b/queue-6.6/vmci-fix-race-between-vmci_host_setup_notify-and-vmci_ctx_unset_notify.patch new file mode 100644 index 0000000000..e7261b700a --- /dev/null +++ b/queue-6.6/vmci-fix-race-between-vmci_host_setup_notify-and-vmci_ctx_unset_notify.patch @@ -0,0 +1,95 @@ +From 1bd6406fb5f36c2bb1e96e27d4c3e9f4d09edde4 Mon Sep 17 00:00:00 2001 +From: Wupeng Ma +Date: Sat, 10 May 2025 11:30:40 +0800 +Subject: VMCI: fix race between vmci_host_setup_notify and vmci_ctx_unset_notify + +From: Wupeng Ma + +commit 1bd6406fb5f36c2bb1e96e27d4c3e9f4d09edde4 upstream. + +During our test, it is found that a warning can be trigger in try_grab_folio +as follow: + + ------------[ cut here ]------------ + WARNING: CPU: 0 PID: 1678 at mm/gup.c:147 try_grab_folio+0x106/0x130 + Modules linked in: + CPU: 0 UID: 0 PID: 1678 Comm: syz.3.31 Not tainted 6.15.0-rc5 #163 PREEMPT(undef) + RIP: 0010:try_grab_folio+0x106/0x130 + Call Trace: + + follow_huge_pmd+0x240/0x8e0 + follow_pmd_mask.constprop.0.isra.0+0x40b/0x5c0 + follow_pud_mask.constprop.0.isra.0+0x14a/0x170 + follow_page_mask+0x1c2/0x1f0 + __get_user_pages+0x176/0x950 + __gup_longterm_locked+0x15b/0x1060 + ? gup_fast+0x120/0x1f0 + gup_fast_fallback+0x17e/0x230 + get_user_pages_fast+0x5f/0x80 + vmci_host_unlocked_ioctl+0x21c/0xf80 + RIP: 0033:0x54d2cd + ---[ end trace 0000000000000000 ]--- + +Digging into the source, context->notify_page may init by get_user_pages_fast +and can be seen in vmci_ctx_unset_notify which will try to put_page. However +get_user_pages_fast is not finished here and lead to following +try_grab_folio warning. The race condition is shown as follow: + +cpu0 cpu1 +vmci_host_do_set_notify +vmci_host_setup_notify +get_user_pages_fast(uva, 1, FOLL_WRITE, &context->notify_page); +lockless_pages_from_mm +gup_pgd_range +gup_huge_pmd // update &context->notify_page + vmci_host_do_set_notify + vmci_ctx_unset_notify + notify_page = context->notify_page; + if (notify_page) + put_page(notify_page); // page is freed +__gup_longterm_locked +__get_user_pages +follow_trans_huge_pmd +try_grab_folio // warn here + +To slove this, use local variable page to make notify_page can be seen +after finish get_user_pages_fast. + +Fixes: a1d88436d53a ("VMCI: Fix two UVA mapping bugs") +Cc: stable +Closes: https://lore.kernel.org/all/e91da589-ad57-3969-d979-879bbd10dddd@huawei.com/ +Signed-off-by: Wupeng Ma +Link: https://lore.kernel.org/r/20250510033040.901582-1-mawupeng1@huawei.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/misc/vmw_vmci/vmci_host.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +--- a/drivers/misc/vmw_vmci/vmci_host.c ++++ b/drivers/misc/vmw_vmci/vmci_host.c +@@ -227,6 +227,7 @@ static int drv_cp_harray_to_user(void __ + static int vmci_host_setup_notify(struct vmci_ctx *context, + unsigned long uva) + { ++ struct page *page; + int retval; + + if (context->notify_page) { +@@ -243,13 +244,11 @@ static int vmci_host_setup_notify(struct + /* + * Lock physical page backing a given user VA. + */ +- retval = get_user_pages_fast(uva, 1, FOLL_WRITE, &context->notify_page); +- if (retval != 1) { +- context->notify_page = NULL; ++ retval = get_user_pages_fast(uva, 1, FOLL_WRITE, &page); ++ if (retval != 1) + return VMCI_ERROR_GENERIC; +- } +- if (context->notify_page == NULL) +- return VMCI_ERROR_UNAVAILABLE; ++ ++ context->notify_page = page; + + /* + * Map the locked page and set up notify pointer. diff --git a/queue-6.6/x86-iopl-cure-tif_io_bitmap-inconsistencies.patch b/queue-6.6/x86-iopl-cure-tif_io_bitmap-inconsistencies.patch new file mode 100644 index 0000000000..898edc2c73 --- /dev/null +++ b/queue-6.6/x86-iopl-cure-tif_io_bitmap-inconsistencies.patch @@ -0,0 +1,118 @@ +From 8b68e978718f14fdcb080c2a7791c52a0d09bc6d Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Wed, 26 Feb 2025 16:01:57 +0100 +Subject: x86/iopl: Cure TIF_IO_BITMAP inconsistencies + +From: Thomas Gleixner + +commit 8b68e978718f14fdcb080c2a7791c52a0d09bc6d upstream. + +io_bitmap_exit() is invoked from exit_thread() when a task exists or +when a fork fails. In the latter case the exit_thread() cleans up +resources which were allocated during fork(). + +io_bitmap_exit() invokes task_update_io_bitmap(), which in turn ends up +in tss_update_io_bitmap(). tss_update_io_bitmap() operates on the +current task. If current has TIF_IO_BITMAP set, but no bitmap installed, +tss_update_io_bitmap() crashes with a NULL pointer dereference. + +There are two issues, which lead to that problem: + + 1) io_bitmap_exit() should not invoke task_update_io_bitmap() when + the task, which is cleaned up, is not the current task. That's a + clear indicator for a cleanup after a failed fork(). + + 2) A task should not have TIF_IO_BITMAP set and neither a bitmap + installed nor IOPL emulation level 3 activated. + + This happens when a kernel thread is created in the context of + a user space thread, which has TIF_IO_BITMAP set as the thread + flags are copied and the IO bitmap pointer is cleared. + + Other than in the failed fork() case this has no impact because + kernel threads including IO workers never return to user space and + therefore never invoke tss_update_io_bitmap(). + +Cure this by adding the missing cleanups and checks: + + 1) Prevent io_bitmap_exit() to invoke task_update_io_bitmap() if + the to be cleaned up task is not the current task. + + 2) Clear TIF_IO_BITMAP in copy_thread() unconditionally. For user + space forks it is set later, when the IO bitmap is inherited in + io_bitmap_share(). + +For paranoia sake, add a warning into tss_update_io_bitmap() to catch +the case, when that code is invoked with inconsistent state. + +Fixes: ea5f1cd7ab49 ("x86/ioperm: Remove bitmap if all permissions dropped") +Reported-by: syzbot+e2b1803445d236442e54@syzkaller.appspotmail.com +Signed-off-by: Thomas Gleixner +Signed-off-by: Borislav Petkov (AMD) +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/87wmdceom2.ffs@tglx +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/ioport.c | 13 +++++++++---- + arch/x86/kernel/process.c | 6 ++++++ + 2 files changed, 15 insertions(+), 4 deletions(-) + +--- a/arch/x86/kernel/ioport.c ++++ b/arch/x86/kernel/ioport.c +@@ -33,8 +33,9 @@ void io_bitmap_share(struct task_struct + set_tsk_thread_flag(tsk, TIF_IO_BITMAP); + } + +-static void task_update_io_bitmap(struct task_struct *tsk) ++static void task_update_io_bitmap(void) + { ++ struct task_struct *tsk = current; + struct thread_struct *t = &tsk->thread; + + if (t->iopl_emul == 3 || t->io_bitmap) { +@@ -54,7 +55,12 @@ void io_bitmap_exit(struct task_struct * + struct io_bitmap *iobm = tsk->thread.io_bitmap; + + tsk->thread.io_bitmap = NULL; +- task_update_io_bitmap(tsk); ++ /* ++ * Don't touch the TSS when invoked on a failed fork(). TSS ++ * reflects the state of @current and not the state of @tsk. ++ */ ++ if (tsk == current) ++ task_update_io_bitmap(); + if (iobm && refcount_dec_and_test(&iobm->refcnt)) + kfree(iobm); + } +@@ -192,8 +198,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, leve + } + + t->iopl_emul = level; +- task_update_io_bitmap(current); +- ++ task_update_io_bitmap(); + return 0; + } + +--- a/arch/x86/kernel/process.c ++++ b/arch/x86/kernel/process.c +@@ -180,6 +180,7 @@ int copy_thread(struct task_struct *p, c + frame->ret_addr = (unsigned long) ret_from_fork_asm; + p->thread.sp = (unsigned long) fork_frame; + p->thread.io_bitmap = NULL; ++ clear_tsk_thread_flag(p, TIF_IO_BITMAP); + p->thread.iopl_warn = 0; + memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); + +@@ -468,6 +469,11 @@ void native_tss_update_io_bitmap(void) + } else { + struct io_bitmap *iobm = t->io_bitmap; + ++ if (WARN_ON_ONCE(!iobm)) { ++ clear_thread_flag(TIF_IO_BITMAP); ++ native_tss_invalidate_io_bitmap(); ++ } ++ + /* + * Only copy bitmap data when the sequence number differs. The + * update time is accounted to the incoming task. diff --git a/queue-6.6/xen-arm-call-uaccess_ttbr0_enable-for-dm_op-hypercall.patch b/queue-6.6/xen-arm-call-uaccess_ttbr0_enable-for-dm_op-hypercall.patch new file mode 100644 index 0000000000..34e74ecf37 --- /dev/null +++ b/queue-6.6/xen-arm-call-uaccess_ttbr0_enable-for-dm_op-hypercall.patch @@ -0,0 +1,63 @@ +From 7f9bbc1140ff8796230bc2634055763e271fd692 Mon Sep 17 00:00:00 2001 +From: Stefano Stabellini +Date: Mon, 12 May 2025 14:54:52 -0700 +Subject: xen/arm: call uaccess_ttbr0_enable for dm_op hypercall + +From: Stefano Stabellini + +commit 7f9bbc1140ff8796230bc2634055763e271fd692 upstream. + +dm_op hypercalls might come from userspace and pass memory addresses as +parameters. The memory addresses typically correspond to buffers +allocated in userspace to hold extra hypercall parameters. + +On ARM, when CONFIG_ARM64_SW_TTBR0_PAN is enabled, they might not be +accessible by Xen, as a result ioreq hypercalls might fail. See the +existing comment in arch/arm64/xen/hypercall.S regarding privcmd_call +for reference. + +For privcmd_call, Linux calls uaccess_ttbr0_enable before issuing the +hypercall thanks to commit 9cf09d68b89a. We need to do the same for +dm_op. This resolves the problem. + +Cc: stable@kernel.org +Fixes: 9cf09d68b89a ("arm64: xen: Enable user access before a privcmd hvc call") +Signed-off-by: Stefano Stabellini +Reviewed-by: Juergen Gross +Message-ID: +Signed-off-by: Juergen Gross +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/xen/hypercall.S | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +--- a/arch/arm64/xen/hypercall.S ++++ b/arch/arm64/xen/hypercall.S +@@ -83,7 +83,26 @@ HYPERCALL3(vcpu_op); + HYPERCALL1(platform_op_raw); + HYPERCALL2(multicall); + HYPERCALL2(vm_assist); +-HYPERCALL3(dm_op); ++ ++SYM_FUNC_START(HYPERVISOR_dm_op) ++ mov x16, #__HYPERVISOR_dm_op; \ ++ /* ++ * dm_op hypercalls are issued by the userspace. The kernel needs to ++ * enable access to TTBR0_EL1 as the hypervisor would issue stage 1 ++ * translations to user memory via AT instructions. Since AT ++ * instructions are not affected by the PAN bit (ARMv8.1), we only ++ * need the explicit uaccess_enable/disable if the TTBR0 PAN emulation ++ * is enabled (it implies that hardware UAO and PAN disabled). ++ */ ++ uaccess_ttbr0_enable x6, x7, x8 ++ hvc XEN_IMM ++ ++ /* ++ * Disable userspace access from kernel once the hyp call completed. ++ */ ++ uaccess_ttbr0_disable x6, x7 ++ ret ++SYM_FUNC_END(HYPERVISOR_dm_op); + + SYM_FUNC_START(privcmd_call) + mov x16, x0