From c39240c32995d77e57b83979cb3d094792544b9a Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 15 Jan 2023 18:59:00 -0500 Subject: [PATCH] Fixes for 4.19 Signed-off-by: Sasha Levin --- ...uble-hazard-against-entire-exchange-.patch | 185 +++++++++++++++++ ...m-virtio-fix-gem-handle-creation-uaf.patch | 57 ++++++ ...fi-fix-null-deref-in-init-error-path.patch | 56 ++++++ .../hvc-xen-lock-console-list-traversal.patch | 186 ++++++++++++++++++ ...1-add-error-handle-for-mtk_iommu_pro.patch | 58 ++++++ ...1-fix-an-error-handling-path-in-mtk_.patch | 52 +++++ ...x-ptp-max-frequency-adjustment-range.patch | 41 ++++ .../net-mlx5-rename-ptp-clock-info.patch | 34 ++++ ...or-out_urb-s-completion-in-pn533_usb.patch | 129 ++++++++++++ ...or-da9211-use-irq-handler-when-ready.patch | 66 +++++++ queue-4.19/series | 12 ++ ...trl-fix-task-closid-rmid-update-race.patch | 114 +++++++++++ ...task_curr-instead-of-task_struct-on_.patch | 64 ++++++ 13 files changed, 1054 insertions(+) create mode 100644 queue-4.19/arm64-cmpxchg_double-hazard-against-entire-exchange-.patch create mode 100644 queue-4.19/drm-virtio-fix-gem-handle-creation-uaf.patch create mode 100644 queue-4.19/efi-fix-null-deref-in-init-error-path.patch create mode 100644 queue-4.19/hvc-xen-lock-console-list-traversal.patch create mode 100644 queue-4.19/iommu-mediatek-v1-add-error-handle-for-mtk_iommu_pro.patch create mode 100644 queue-4.19/iommu-mediatek-v1-fix-an-error-handling-path-in-mtk_.patch create mode 100644 queue-4.19/net-mlx5-fix-ptp-max-frequency-adjustment-range.patch create mode 100644 queue-4.19/net-mlx5-rename-ptp-clock-info.patch create mode 100644 queue-4.19/nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch create mode 100644 queue-4.19/regulator-da9211-use-irq-handler-when-ready.patch create mode 100644 queue-4.19/x86-resctrl-fix-task-closid-rmid-update-race.patch create mode 100644 queue-4.19/x86-resctrl-use-task_curr-instead-of-task_struct-on_.patch diff --git a/queue-4.19/arm64-cmpxchg_double-hazard-against-entire-exchange-.patch b/queue-4.19/arm64-cmpxchg_double-hazard-against-entire-exchange-.patch new file mode 100644 index 00000000000..e3ccbb4f062 --- /dev/null +++ b/queue-4.19/arm64-cmpxchg_double-hazard-against-entire-exchange-.patch @@ -0,0 +1,185 @@ +From afca56c5d076296c499bcecfdc3872b87569d312 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Jan 2023 15:16:26 +0000 +Subject: arm64: cmpxchg_double*: hazard against entire exchange variable + +From: Mark Rutland + +[ Upstream commit 031af50045ea97ed4386eb3751ca2c134d0fc911 ] + +The inline assembly for arm64's cmpxchg_double*() implementations use a ++Q constraint to hazard against other accesses to the memory location +being exchanged. However, the pointer passed to the constraint is a +pointer to unsigned long, and thus the hazard only applies to the first +8 bytes of the location. + +GCC can take advantage of this, assuming that other portions of the +location are unchanged, leading to a number of potential problems. + +This is similar to what we fixed back in commit: + + fee960bed5e857eb ("arm64: xchg: hazard against entire exchange variable") + +... but we forgot to adjust cmpxchg_double*() similarly at the same +time. + +The same problem applies, as demonstrated with the following test: + +| struct big { +| u64 lo, hi; +| } __aligned(128); +| +| unsigned long foo(struct big *b) +| { +| u64 hi_old, hi_new; +| +| hi_old = b->hi; +| cmpxchg_double_local(&b->lo, &b->hi, 0x12, 0x34, 0x56, 0x78); +| hi_new = b->hi; +| +| return hi_old ^ hi_new; +| } + +... which GCC 12.1.0 compiles as: + +| 0000000000000000 : +| 0: d503233f paciasp +| 4: aa0003e4 mov x4, x0 +| 8: 1400000e b 40 +| c: d2800240 mov x0, #0x12 // #18 +| 10: d2800681 mov x1, #0x34 // #52 +| 14: aa0003e5 mov x5, x0 +| 18: aa0103e6 mov x6, x1 +| 1c: d2800ac2 mov x2, #0x56 // #86 +| 20: d2800f03 mov x3, #0x78 // #120 +| 24: 48207c82 casp x0, x1, x2, x3, [x4] +| 28: ca050000 eor x0, x0, x5 +| 2c: ca060021 eor x1, x1, x6 +| 30: aa010000 orr x0, x0, x1 +| 34: d2800000 mov x0, #0x0 // #0 <--- BANG +| 38: d50323bf autiasp +| 3c: d65f03c0 ret +| 40: d2800240 mov x0, #0x12 // #18 +| 44: d2800681 mov x1, #0x34 // #52 +| 48: d2800ac2 mov x2, #0x56 // #86 +| 4c: d2800f03 mov x3, #0x78 // #120 +| 50: f9800091 prfm pstl1strm, [x4] +| 54: c87f1885 ldxp x5, x6, [x4] +| 58: ca0000a5 eor x5, x5, x0 +| 5c: ca0100c6 eor x6, x6, x1 +| 60: aa0600a6 orr x6, x5, x6 +| 64: b5000066 cbnz x6, 70 +| 68: c8250c82 stxp w5, x2, x3, [x4] +| 6c: 35ffff45 cbnz w5, 54 +| 70: d2800000 mov x0, #0x0 // #0 <--- BANG +| 74: d50323bf autiasp +| 78: d65f03c0 ret + +Notice that at the lines with "BANG" comments, GCC has assumed that the +higher 8 bytes are unchanged by the cmpxchg_double() call, and that +`hi_old ^ hi_new` can be reduced to a constant zero, for both LSE and +LL/SC versions of cmpxchg_double(). + +This patch fixes the issue by passing a pointer to __uint128_t into the ++Q constraint, ensuring that the compiler hazards against the entire 16 +bytes being modified. + +With this change, GCC 12.1.0 compiles the above test as: + +| 0000000000000000 : +| 0: f9400407 ldr x7, [x0, #8] +| 4: d503233f paciasp +| 8: aa0003e4 mov x4, x0 +| c: 1400000f b 48 +| 10: d2800240 mov x0, #0x12 // #18 +| 14: d2800681 mov x1, #0x34 // #52 +| 18: aa0003e5 mov x5, x0 +| 1c: aa0103e6 mov x6, x1 +| 20: d2800ac2 mov x2, #0x56 // #86 +| 24: d2800f03 mov x3, #0x78 // #120 +| 28: 48207c82 casp x0, x1, x2, x3, [x4] +| 2c: ca050000 eor x0, x0, x5 +| 30: ca060021 eor x1, x1, x6 +| 34: aa010000 orr x0, x0, x1 +| 38: f9400480 ldr x0, [x4, #8] +| 3c: d50323bf autiasp +| 40: ca0000e0 eor x0, x7, x0 +| 44: d65f03c0 ret +| 48: d2800240 mov x0, #0x12 // #18 +| 4c: d2800681 mov x1, #0x34 // #52 +| 50: d2800ac2 mov x2, #0x56 // #86 +| 54: d2800f03 mov x3, #0x78 // #120 +| 58: f9800091 prfm pstl1strm, [x4] +| 5c: c87f1885 ldxp x5, x6, [x4] +| 60: ca0000a5 eor x5, x5, x0 +| 64: ca0100c6 eor x6, x6, x1 +| 68: aa0600a6 orr x6, x5, x6 +| 6c: b5000066 cbnz x6, 78 +| 70: c8250c82 stxp w5, x2, x3, [x4] +| 74: 35ffff45 cbnz w5, 5c +| 78: f9400480 ldr x0, [x4, #8] +| 7c: d50323bf autiasp +| 80: ca0000e0 eor x0, x7, x0 +| 84: d65f03c0 ret + +... sampling the high 8 bytes before and after the cmpxchg, and +performing an EOR, as we'd expect. + +For backporting, I've tested this atop linux-4.9.y with GCC 5.5.0. Note +that linux-4.9.y is oldest currently supported stable release, and +mandates GCC 5.1+. Unfortunately I couldn't get a GCC 5.1 binary to run +on my machines due to library incompatibilities. + +I've also used a standalone test to check that we can use a __uint128_t +pointer in a +Q constraint at least as far back as GCC 4.8.5 and LLVM +3.9.1. + +Fixes: 5284e1b4bc8a ("arm64: xchg: Implement cmpxchg_double") +Fixes: e9a4b795652f ("arm64: cmpxchg_dbl: patch in lse instructions when supported by the CPU") +Reported-by: Boqun Feng +Link: https://lore.kernel.org/lkml/Y6DEfQXymYVgL3oJ@boqun-archlinux/ +Reported-by: Peter Zijlstra +Link: https://lore.kernel.org/lkml/Y6GXoO4qmH9OIZ5Q@hirez.programming.kicks-ass.net/ +Signed-off-by: Mark Rutland +Cc: stable@vger.kernel.org +Cc: Arnd Bergmann +Cc: Catalin Marinas +Cc: Steve Capper +Cc: Will Deacon +Link: https://lore.kernel.org/r/20230104151626.3262137-1-mark.rutland@arm.com +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + arch/arm64/include/asm/atomic_ll_sc.h | 2 +- + arch/arm64/include/asm/atomic_lse.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/include/asm/atomic_ll_sc.h b/arch/arm64/include/asm/atomic_ll_sc.h +index 1cc42441bc67..a9b315dc7e24 100644 +--- a/arch/arm64/include/asm/atomic_ll_sc.h ++++ b/arch/arm64/include/asm/atomic_ll_sc.h +@@ -320,7 +320,7 @@ __LL_SC_PREFIX(__cmpxchg_double##name(unsigned long old1, \ + " cbnz %w0, 1b\n" \ + " " #mb "\n" \ + "2:" \ +- : "=&r" (tmp), "=&r" (ret), "+Q" (*(unsigned long *)ptr) \ ++ : "=&r" (tmp), "=&r" (ret), "+Q" (*(__uint128_t *)ptr) \ + : "r" (old1), "r" (old2), "r" (new1), "r" (new2) \ + : cl); \ + \ +diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h +index 80cadc789f1a..393d73797e73 100644 +--- a/arch/arm64/include/asm/atomic_lse.h ++++ b/arch/arm64/include/asm/atomic_lse.h +@@ -555,7 +555,7 @@ static inline long __cmpxchg_double##name(unsigned long old1, \ + " eor %[old2], %[old2], %[oldval2]\n" \ + " orr %[old1], %[old1], %[old2]") \ + : [old1] "+&r" (x0), [old2] "+&r" (x1), \ +- [v] "+Q" (*(unsigned long *)ptr) \ ++ [v] "+Q" (*(__uint128_t *)ptr) \ + : [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4), \ + [oldval1] "r" (oldval1), [oldval2] "r" (oldval2) \ + : __LL_SC_CLOBBERS, ##cl); \ +-- +2.35.1 + diff --git a/queue-4.19/drm-virtio-fix-gem-handle-creation-uaf.patch b/queue-4.19/drm-virtio-fix-gem-handle-creation-uaf.patch new file mode 100644 index 00000000000..70de7f4c801 --- /dev/null +++ b/queue-4.19/drm-virtio-fix-gem-handle-creation-uaf.patch @@ -0,0 +1,57 @@ +From bbca764a1324b52ab58dcee7935dc73fa0a6b951 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Dec 2022 15:33:55 -0800 +Subject: drm/virtio: Fix GEM handle creation UAF + +From: Rob Clark + +[ Upstream commit 52531258318ed59a2dc5a43df2eaf0eb1d65438e ] + +Userspace can guess the handle value and try to race GEM object creation +with handle close, resulting in a use-after-free if we dereference the +object after dropping the handle's reference. For that reason, dropping +the handle's reference must be done *after* we are done dereferencing +the object. + +Signed-off-by: Rob Clark +Reviewed-by: Chia-I Wu +Fixes: 62fb7a5e1096 ("virtio-gpu: add 3d/virgl support") +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Osipenko +Link: https://patchwork.freedesktop.org/patch/msgid/20221216233355.542197-2-robdclark@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/virtio/virtgpu_ioctl.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c +index 8d2f5ded86d6..a539843a03ba 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c ++++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c +@@ -309,7 +309,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, + } + return ret; + } +- drm_gem_object_put_unlocked(obj); + + rc->res_handle = res_id; /* similiar to a VM address */ + rc->bo_handle = handle; +@@ -318,6 +317,15 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, + virtio_gpu_unref_list(&validate_list); + dma_fence_put(&fence->f); + } ++ ++ /* ++ * The handle owns the reference now. But we must drop our ++ * remaining reference *after* we no longer need to dereference ++ * the obj. Otherwise userspace could guess the handle and ++ * race closing it from another thread. ++ */ ++ drm_gem_object_put_unlocked(obj); ++ + return 0; + fail_unref: + if (vgdev->has_virgl_3d) { +-- +2.35.1 + diff --git a/queue-4.19/efi-fix-null-deref-in-init-error-path.patch b/queue-4.19/efi-fix-null-deref-in-init-error-path.patch new file mode 100644 index 00000000000..5e6cec3ac49 --- /dev/null +++ b/queue-4.19/efi-fix-null-deref-in-init-error-path.patch @@ -0,0 +1,56 @@ +From f3be9cb8e90acd1796e0dd4696e7691b2026ad14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Dec 2022 10:10:04 +0100 +Subject: efi: fix NULL-deref in init error path + +From: Johan Hovold + +[ Upstream commit 703c13fe3c9af557d312f5895ed6a5fda2711104 ] + +In cases where runtime services are not supported or have been disabled, +the runtime services workqueue will never have been allocated. + +Do not try to destroy the workqueue unconditionally in the unlikely +event that EFI initialisation fails to avoid dereferencing a NULL +pointer. + +Fixes: 98086df8b70c ("efi: add missed destroy_workqueue when efisubsys_init fails") +Cc: stable@vger.kernel.org +Cc: Li Heng +Signed-off-by: Johan Hovold +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/efi.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c +index f0ef2643b70e..c966a23de85d 100644 +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -359,8 +359,8 @@ static int __init efisubsys_init(void) + efi_kobj = kobject_create_and_add("efi", firmware_kobj); + if (!efi_kobj) { + pr_err("efi: Firmware registration failed.\n"); +- destroy_workqueue(efi_rts_wq); +- return -ENOMEM; ++ error = -ENOMEM; ++ goto err_destroy_wq; + } + + error = generic_ops_register(); +@@ -396,7 +396,10 @@ static int __init efisubsys_init(void) + generic_ops_unregister(); + err_put: + kobject_put(efi_kobj); +- destroy_workqueue(efi_rts_wq); ++err_destroy_wq: ++ if (efi_rts_wq) ++ destroy_workqueue(efi_rts_wq); ++ + return error; + } + +-- +2.35.1 + diff --git a/queue-4.19/hvc-xen-lock-console-list-traversal.patch b/queue-4.19/hvc-xen-lock-console-list-traversal.patch new file mode 100644 index 00000000000..213008b8d6c --- /dev/null +++ b/queue-4.19/hvc-xen-lock-console-list-traversal.patch @@ -0,0 +1,186 @@ +From 6fb5aebcb88db63685433c964cc170c47c52a9d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Nov 2022 17:36:02 +0100 +Subject: hvc/xen: lock console list traversal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Roger Pau Monne + +[ Upstream commit c0dccad87cf68fc6012aec7567e354353097ec1a ] + +The currently lockless access to the xen console list in +vtermno_to_xencons() is incorrect, as additions and removals from the +list can happen anytime, and as such the traversal of the list to get +the private console data for a given termno needs to happen with the +lock held. Note users that modify the list already do so with the +lock taken. + +Adjust current lock takers to use the _irq{save,restore} helpers, +since the context in which vtermno_to_xencons() is called can have +interrupts disabled. Use the _irq{save,restore} set of helpers to +switch the current callers to disable interrupts in the locked region. +I haven't checked if existing users could instead use the _irq +variant, as I think it's safer to use _irq{save,restore} upfront. + +While there switch from using list_for_each_entry_safe to +list_for_each_entry: the current entry cursor won't be removed as +part of the code in the loop body, so using the _safe variant is +pointless. + +Fixes: 02e19f9c7cac ('hvc_xen: implement multiconsole support') +Signed-off-by: Roger Pau Monné +Reviewed-by: Stefano Stabellini +Link: https://lore.kernel.org/r/20221130163611.14686-1-roger.pau@citrix.com +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/tty/hvc/hvc_xen.c | 46 ++++++++++++++++++++++++--------------- + 1 file changed, 29 insertions(+), 17 deletions(-) + +diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c +index 080adf7bcae4..47ffb485ff34 100644 +--- a/drivers/tty/hvc/hvc_xen.c ++++ b/drivers/tty/hvc/hvc_xen.c +@@ -52,17 +52,22 @@ static DEFINE_SPINLOCK(xencons_lock); + + static struct xencons_info *vtermno_to_xencons(int vtermno) + { +- struct xencons_info *entry, *n, *ret = NULL; ++ struct xencons_info *entry, *ret = NULL; ++ unsigned long flags; + +- if (list_empty(&xenconsoles)) +- return NULL; ++ spin_lock_irqsave(&xencons_lock, flags); ++ if (list_empty(&xenconsoles)) { ++ spin_unlock_irqrestore(&xencons_lock, flags); ++ return NULL; ++ } + +- list_for_each_entry_safe(entry, n, &xenconsoles, list) { ++ list_for_each_entry(entry, &xenconsoles, list) { + if (entry->vtermno == vtermno) { + ret = entry; + break; + } + } ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return ret; + } +@@ -223,7 +228,7 @@ static int xen_hvm_console_init(void) + { + int r; + uint64_t v = 0; +- unsigned long gfn; ++ unsigned long gfn, flags; + struct xencons_info *info; + + if (!xen_hvm_domain()) +@@ -258,9 +263,9 @@ static int xen_hvm_console_init(void) + goto err; + info->vtermno = HVC_COOKIE; + +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_add_tail(&info->list, &xenconsoles); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return 0; + err: +@@ -283,6 +288,7 @@ static int xencons_info_pv_init(struct xencons_info *info, int vtermno) + static int xen_pv_console_init(void) + { + struct xencons_info *info; ++ unsigned long flags; + + if (!xen_pv_domain()) + return -ENODEV; +@@ -299,9 +305,9 @@ static int xen_pv_console_init(void) + /* already configured */ + return 0; + } +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + xencons_info_pv_init(info, HVC_COOKIE); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return 0; + } +@@ -309,6 +315,7 @@ static int xen_pv_console_init(void) + static int xen_initial_domain_console_init(void) + { + struct xencons_info *info; ++ unsigned long flags; + + if (!xen_initial_domain()) + return -ENODEV; +@@ -323,9 +330,9 @@ static int xen_initial_domain_console_init(void) + info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false); + info->vtermno = HVC_COOKIE; + +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_add_tail(&info->list, &xenconsoles); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return 0; + } +@@ -380,10 +387,12 @@ static void xencons_free(struct xencons_info *info) + + static int xen_console_remove(struct xencons_info *info) + { ++ unsigned long flags; ++ + xencons_disconnect_backend(info); +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_del(&info->list); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + if (info->xbdev != NULL) + xencons_free(info); + else { +@@ -464,6 +473,7 @@ static int xencons_probe(struct xenbus_device *dev, + { + int ret, devid; + struct xencons_info *info; ++ unsigned long flags; + + devid = dev->nodename[strlen(dev->nodename) - 1] - '0'; + if (devid == 0) +@@ -482,9 +492,9 @@ static int xencons_probe(struct xenbus_device *dev, + ret = xencons_connect_backend(dev, info); + if (ret < 0) + goto error; +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_add_tail(&info->list, &xenconsoles); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + + return 0; + +@@ -583,10 +593,12 @@ static int __init xen_hvc_init(void) + + info->hvc = hvc_alloc(HVC_COOKIE, info->irq, ops, 256); + if (IS_ERR(info->hvc)) { ++ unsigned long flags; ++ + r = PTR_ERR(info->hvc); +- spin_lock(&xencons_lock); ++ spin_lock_irqsave(&xencons_lock, flags); + list_del(&info->list); +- spin_unlock(&xencons_lock); ++ spin_unlock_irqrestore(&xencons_lock, flags); + if (info->irq) + unbind_from_irqhandler(info->irq, NULL); + kfree(info); +-- +2.35.1 + diff --git a/queue-4.19/iommu-mediatek-v1-add-error-handle-for-mtk_iommu_pro.patch b/queue-4.19/iommu-mediatek-v1-add-error-handle-for-mtk_iommu_pro.patch new file mode 100644 index 00000000000..ea5bb1cd01f --- /dev/null +++ b/queue-4.19/iommu-mediatek-v1-add-error-handle-for-mtk_iommu_pro.patch @@ -0,0 +1,58 @@ +From 6095ec45c1da49c7e407c0a47e52ef5a7d9bb694 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 Apr 2021 14:48:43 +0800 +Subject: iommu/mediatek-v1: Add error handle for mtk_iommu_probe + +From: Yong Wu + +[ Upstream commit ac304c070c54413efabf29f9e73c54576d329774 ] + +In the original code, we lack the error handle. This patch adds them. + +Signed-off-by: Yong Wu +Link: https://lore.kernel.org/r/20210412064843.11614-2-yong.wu@mediatek.com +Signed-off-by: Joerg Roedel +Stable-dep-of: 142e821f68cf ("iommu/mediatek-v1: Fix an error handling path in mtk_iommu_v1_probe()") +Signed-off-by: Sasha Levin +--- + drivers/iommu/mtk_iommu_v1.c | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c +index 676c029494e4..1a1f9a05982f 100644 +--- a/drivers/iommu/mtk_iommu_v1.c ++++ b/drivers/iommu/mtk_iommu_v1.c +@@ -632,12 +632,26 @@ static int mtk_iommu_probe(struct platform_device *pdev) + + ret = iommu_device_register(&data->iommu); + if (ret) +- return ret; ++ goto out_sysfs_remove; + +- if (!iommu_present(&platform_bus_type)) +- bus_set_iommu(&platform_bus_type, &mtk_iommu_ops); ++ if (!iommu_present(&platform_bus_type)) { ++ ret = bus_set_iommu(&platform_bus_type, &mtk_iommu_ops); ++ if (ret) ++ goto out_dev_unreg; ++ } + +- return component_master_add_with_match(dev, &mtk_iommu_com_ops, match); ++ ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match); ++ if (ret) ++ goto out_bus_set_null; ++ return ret; ++ ++out_bus_set_null: ++ bus_set_iommu(&platform_bus_type, NULL); ++out_dev_unreg: ++ iommu_device_unregister(&data->iommu); ++out_sysfs_remove: ++ iommu_device_sysfs_remove(&data->iommu); ++ return ret; + } + + static int mtk_iommu_remove(struct platform_device *pdev) +-- +2.35.1 + diff --git a/queue-4.19/iommu-mediatek-v1-fix-an-error-handling-path-in-mtk_.patch b/queue-4.19/iommu-mediatek-v1-fix-an-error-handling-path-in-mtk_.patch new file mode 100644 index 00000000000..47aa296bd24 --- /dev/null +++ b/queue-4.19/iommu-mediatek-v1-fix-an-error-handling-path-in-mtk_.patch @@ -0,0 +1,52 @@ +From 33b6dbd30f0f150f9a1c30860804c72267667d31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Dec 2022 19:06:22 +0100 +Subject: iommu/mediatek-v1: Fix an error handling path in mtk_iommu_v1_probe() + +From: Christophe JAILLET + +[ Upstream commit 142e821f68cf5da79ce722cb9c1323afae30e185 ] + +A clk, prepared and enabled in mtk_iommu_v1_hw_init(), is not released in +the error handling path of mtk_iommu_v1_probe(). + +Add the corresponding clk_disable_unprepare(), as already done in the +remove function. + +Fixes: b17336c55d89 ("iommu/mediatek: add support for mtk iommu generation one HW") +Signed-off-by: Christophe JAILLET +Reviewed-by: Yong Wu +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Matthias Brugger +Link: https://lore.kernel.org/r/593e7b7d97c6e064b29716b091a9d4fd122241fb.1671473163.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/mtk_iommu_v1.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c +index 1a1f9a05982f..94b16cacb80f 100644 +--- a/drivers/iommu/mtk_iommu_v1.c ++++ b/drivers/iommu/mtk_iommu_v1.c +@@ -626,7 +626,7 @@ static int mtk_iommu_probe(struct platform_device *pdev) + ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL, + dev_name(&pdev->dev)); + if (ret) +- return ret; ++ goto out_clk_unprepare; + + iommu_device_set_ops(&data->iommu, &mtk_iommu_ops); + +@@ -651,6 +651,8 @@ static int mtk_iommu_probe(struct platform_device *pdev) + iommu_device_unregister(&data->iommu); + out_sysfs_remove: + iommu_device_sysfs_remove(&data->iommu); ++out_clk_unprepare: ++ clk_disable_unprepare(data->bclk); + return ret; + } + +-- +2.35.1 + diff --git a/queue-4.19/net-mlx5-fix-ptp-max-frequency-adjustment-range.patch b/queue-4.19/net-mlx5-fix-ptp-max-frequency-adjustment-range.patch new file mode 100644 index 00000000000..e7c771a35d4 --- /dev/null +++ b/queue-4.19/net-mlx5-fix-ptp-max-frequency-adjustment-range.patch @@ -0,0 +1,41 @@ +From 1071006a5d446185bdf4003e38beef0544f4550d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Dec 2022 14:26:09 -0800 +Subject: net/mlx5: Fix ptp max frequency adjustment range + +From: Rahul Rameshbabu + +[ Upstream commit fe91d57277eef8bb4aca05acfa337b4a51d0bba4 ] + +.max_adj of ptp_clock_info acts as an absolute value for the amount in ppb +that can be set for a single call of .adjfine. This means that a single +call to .getfine cannot be greater than .max_adj or less than -(.max_adj). +Provides correct value for max frequency adjustment value supported by +devices. + +Fixes: 3d8c38af1493 ("net/mlx5e: Add PTP Hardware Clock (PHC) support") +Signed-off-by: Rahul Rameshbabu +Reviewed-by: Gal Pressman +Reviewed-by: Tariq Toukan +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +index 3ef63103d33f..dee65443d76b 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +@@ -396,7 +396,7 @@ static int mlx5_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin, + static const struct ptp_clock_info mlx5_ptp_clock_info = { + .owner = THIS_MODULE, + .name = "mlx5_ptp", +- .max_adj = 100000000, ++ .max_adj = 50000000, + .n_alarm = 0, + .n_ext_ts = 0, + .n_per_out = 0, +-- +2.35.1 + diff --git a/queue-4.19/net-mlx5-rename-ptp-clock-info.patch b/queue-4.19/net-mlx5-rename-ptp-clock-info.patch new file mode 100644 index 00000000000..76afe6d158b --- /dev/null +++ b/queue-4.19/net-mlx5-rename-ptp-clock-info.patch @@ -0,0 +1,34 @@ +From fa739ee1f5ed533477f08211f1f488dcc45cc60d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Jun 2020 10:58:31 +0300 +Subject: net/mlx5: Rename ptp clock info + +From: Eran Ben Elisha + +[ Upstream commit aac2df7f022eccb5d117f07b1e231410db1a863a ] + +Fix a typo in ptp_clock_info naming: mlx5_p2p -> mlx5_ptp. + +Signed-off-by: Eran Ben Elisha +Stable-dep-of: fe91d57277ee ("net/mlx5: Fix ptp max frequency adjustment range") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +index 0fd62510fb27..3ef63103d33f 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +@@ -395,7 +395,7 @@ static int mlx5_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin, + + static const struct ptp_clock_info mlx5_ptp_clock_info = { + .owner = THIS_MODULE, +- .name = "mlx5_p2p", ++ .name = "mlx5_ptp", + .max_adj = 100000000, + .n_alarm = 0, + .n_ext_ts = 0, +-- +2.35.1 + diff --git a/queue-4.19/nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch b/queue-4.19/nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch new file mode 100644 index 00000000000..63777c67772 --- /dev/null +++ b/queue-4.19/nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch @@ -0,0 +1,129 @@ +From 56699d2ab832e2c1902934eda9cd9e5b1999ef12 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Jan 2023 17:23:44 +0900 +Subject: nfc: pn533: Wait for out_urb's completion in pn533_usb_send_frame() + +From: Minsuk Kang + +[ Upstream commit 9dab880d675b9d0dd56c6428e4e8352a3339371d ] + +Fix a use-after-free that occurs in hcd when in_urb sent from +pn533_usb_send_frame() is completed earlier than out_urb. Its callback +frees the skb data in pn533_send_async_complete() that is used as a +transfer buffer of out_urb. Wait before sending in_urb until the +callback of out_urb is called. To modify the callback of out_urb alone, +separate the complete function of out_urb and ack_urb. + +Found by a modified version of syzkaller. + +BUG: KASAN: use-after-free in dummy_timer +Call Trace: + memcpy (mm/kasan/shadow.c:65) + dummy_perform_transfer (drivers/usb/gadget/udc/dummy_hcd.c:1352) + transfer (drivers/usb/gadget/udc/dummy_hcd.c:1453) + dummy_timer (drivers/usb/gadget/udc/dummy_hcd.c:1972) + arch_static_branch (arch/x86/include/asm/jump_label.h:27) + static_key_false (include/linux/jump_label.h:207) + timer_expire_exit (include/trace/events/timer.h:127) + call_timer_fn (kernel/time/timer.c:1475) + expire_timers (kernel/time/timer.c:1519) + __run_timers (kernel/time/timer.c:1790) + run_timer_softirq (kernel/time/timer.c:1803) + +Fixes: c46ee38620a2 ("NFC: pn533: add NXP pn533 nfc device driver") +Signed-off-by: Minsuk Kang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/nfc/pn533/usb.c | 44 ++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 41 insertions(+), 3 deletions(-) + +diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c +index a2c9b3f3bc23..c7da364b6358 100644 +--- a/drivers/nfc/pn533/usb.c ++++ b/drivers/nfc/pn533/usb.c +@@ -165,10 +165,17 @@ static int pn533_usb_send_ack(struct pn533 *dev, gfp_t flags) + return usb_submit_urb(phy->ack_urb, flags); + } + ++struct pn533_out_arg { ++ struct pn533_usb_phy *phy; ++ struct completion done; ++}; ++ + static int pn533_usb_send_frame(struct pn533 *dev, + struct sk_buff *out) + { + struct pn533_usb_phy *phy = dev->phy; ++ struct pn533_out_arg arg; ++ void *cntx; + int rc; + + if (phy->priv == NULL) +@@ -180,10 +187,17 @@ static int pn533_usb_send_frame(struct pn533 *dev, + print_hex_dump_debug("PN533 TX: ", DUMP_PREFIX_NONE, 16, 1, + out->data, out->len, false); + ++ init_completion(&arg.done); ++ cntx = phy->out_urb->context; ++ phy->out_urb->context = &arg; ++ + rc = usb_submit_urb(phy->out_urb, GFP_KERNEL); + if (rc) + return rc; + ++ wait_for_completion(&arg.done); ++ phy->out_urb->context = cntx; ++ + if (dev->protocol_type == PN533_PROTO_REQ_RESP) { + /* request for response for sent packet directly */ + rc = pn533_submit_urb_for_response(phy, GFP_KERNEL); +@@ -424,7 +438,31 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy) + return arg.rc; + } + +-static void pn533_send_complete(struct urb *urb) ++static void pn533_out_complete(struct urb *urb) ++{ ++ struct pn533_out_arg *arg = urb->context; ++ struct pn533_usb_phy *phy = arg->phy; ++ ++ switch (urb->status) { ++ case 0: ++ break; /* success */ ++ case -ECONNRESET: ++ case -ENOENT: ++ dev_dbg(&phy->udev->dev, ++ "The urb has been stopped (status %d)\n", ++ urb->status); ++ break; ++ case -ESHUTDOWN: ++ default: ++ nfc_err(&phy->udev->dev, ++ "Urb failure (status %d)\n", ++ urb->status); ++ } ++ ++ complete(&arg->done); ++} ++ ++static void pn533_ack_complete(struct urb *urb) + { + struct pn533_usb_phy *phy = urb->context; + +@@ -512,10 +550,10 @@ static int pn533_usb_probe(struct usb_interface *interface, + + usb_fill_bulk_urb(phy->out_urb, phy->udev, + usb_sndbulkpipe(phy->udev, out_endpoint), +- NULL, 0, pn533_send_complete, phy); ++ NULL, 0, pn533_out_complete, phy); + usb_fill_bulk_urb(phy->ack_urb, phy->udev, + usb_sndbulkpipe(phy->udev, out_endpoint), +- NULL, 0, pn533_send_complete, phy); ++ NULL, 0, pn533_ack_complete, phy); + + switch (id->driver_info) { + case PN533_DEVICE_STD: +-- +2.35.1 + diff --git a/queue-4.19/regulator-da9211-use-irq-handler-when-ready.patch b/queue-4.19/regulator-da9211-use-irq-handler-when-ready.patch new file mode 100644 index 00000000000..cf152a69bf1 --- /dev/null +++ b/queue-4.19/regulator-da9211-use-irq-handler-when-ready.patch @@ -0,0 +1,66 @@ +From 56aa8e58e8faf7cd99fa187b27fd993e0a1b0da2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Nov 2022 22:06:02 +0100 +Subject: regulator: da9211: Use irq handler when ready + +From: Ricardo Ribalda + +[ Upstream commit 02228f6aa6a64d588bc31e3267d05ff184d772eb ] + +If the system does not come from reset (like when it is kexec()), the +regulator might have an IRQ waiting for us. + +If we enable the IRQ handler before its structures are ready, we crash. + +This patch fixes: + +[ 1.141839] Unable to handle kernel read from unreadable memory at virtual address 0000000000000078 +[ 1.316096] Call trace: +[ 1.316101] blocking_notifier_call_chain+0x20/0xa8 +[ 1.322757] cpu cpu0: dummy supplies not allowed for exclusive requests +[ 1.327823] regulator_notifier_call_chain+0x1c/0x2c +[ 1.327825] da9211_irq_handler+0x68/0xf8 +[ 1.327829] irq_thread+0x11c/0x234 +[ 1.327833] kthread+0x13c/0x154 + +Signed-off-by: Ricardo Ribalda +Reviewed-by: Adam Ward +Link: https://lore.kernel.org/r/20221124-da9211-v2-0-1779e3c5d491@chromium.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/da9211-regulator.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c +index 6c122b3df5d0..8847d15c2b90 100644 +--- a/drivers/regulator/da9211-regulator.c ++++ b/drivers/regulator/da9211-regulator.c +@@ -469,6 +469,12 @@ static int da9211_i2c_probe(struct i2c_client *i2c, + + chip->chip_irq = i2c->irq; + ++ ret = da9211_regulator_init(chip); ++ if (ret < 0) { ++ dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret); ++ return ret; ++ } ++ + if (chip->chip_irq != 0) { + ret = devm_request_threaded_irq(chip->dev, chip->chip_irq, NULL, + da9211_irq_handler, +@@ -483,11 +489,6 @@ static int da9211_i2c_probe(struct i2c_client *i2c, + dev_warn(chip->dev, "No IRQ configured\n"); + } + +- ret = da9211_regulator_init(chip); +- +- if (ret < 0) +- dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret); +- + return ret; + } + +-- +2.35.1 + diff --git a/queue-4.19/series b/queue-4.19/series index f46b525b971..c17b1e043b3 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -502,3 +502,15 @@ ext4-fix-delayed-allocation-bug-in-ext4_clu_mapped-f.patch netfilter-ipset-fix-overflow-before-widen-in-the-bitmap_ip_create-function.patch x86-boot-avoid-using-intel-mnemonics-in-at-t-syntax-asm.patch edac-device-fix-period-calculation-in-edac_device_reset_delay_period.patch +regulator-da9211-use-irq-handler-when-ready.patch +hvc-xen-lock-console-list-traversal.patch +nfc-pn533-wait-for-out_urb-s-completion-in-pn533_usb.patch +net-mlx5-rename-ptp-clock-info.patch +net-mlx5-fix-ptp-max-frequency-adjustment-range.patch +iommu-mediatek-v1-add-error-handle-for-mtk_iommu_pro.patch +iommu-mediatek-v1-fix-an-error-handling-path-in-mtk_.patch +x86-resctrl-use-task_curr-instead-of-task_struct-on_.patch +x86-resctrl-fix-task-closid-rmid-update-race.patch +drm-virtio-fix-gem-handle-creation-uaf.patch +arm64-cmpxchg_double-hazard-against-entire-exchange-.patch +efi-fix-null-deref-in-init-error-path.patch diff --git a/queue-4.19/x86-resctrl-fix-task-closid-rmid-update-race.patch b/queue-4.19/x86-resctrl-fix-task-closid-rmid-update-race.patch new file mode 100644 index 00000000000..a601644df18 --- /dev/null +++ b/queue-4.19/x86-resctrl-fix-task-closid-rmid-update-race.patch @@ -0,0 +1,114 @@ +From 43426e36aa54fdc446332f04cca2d93d46e4227d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Dec 2022 17:11:23 +0100 +Subject: x86/resctrl: Fix task CLOSID/RMID update race + +From: Peter Newman + +[ Upstream commit fe1f0714385fbcf76b0cbceb02b7277d842014fc ] + +When the user moves a running task to a new rdtgroup using the task's +file interface or by deleting its rdtgroup, the resulting change in +CLOSID/RMID must be immediately propagated to the PQR_ASSOC MSR on the +task(s) CPUs. + +x86 allows reordering loads with prior stores, so if the task starts +running between a task_curr() check that the CPU hoisted before the +stores in the CLOSID/RMID update then it can start running with the old +CLOSID/RMID until it is switched again because __rdtgroup_move_task() +failed to determine that it needs to be interrupted to obtain the new +CLOSID/RMID. + +Refer to the diagram below: + +CPU 0 CPU 1 +----- ----- +__rdtgroup_move_task(): + curr <- t1->cpu->rq->curr + __schedule(): + rq->curr <- t1 + resctrl_sched_in(): + t1->{closid,rmid} -> {1,1} + t1->{closid,rmid} <- {2,2} + if (curr == t1) // false + IPI(t1->cpu) + +A similar race impacts rdt_move_group_tasks(), which updates tasks in a +deleted rdtgroup. + +In both cases, use smp_mb() to order the task_struct::{closid,rmid} +stores before the loads in task_curr(). In particular, in the +rdt_move_group_tasks() case, simply execute an smp_mb() on every +iteration with a matching task. + +It is possible to use a single smp_mb() in rdt_move_group_tasks(), but +this would require two passes and a means of remembering which +task_structs were updated in the first loop. However, benchmarking +results below showed too little performance impact in the simple +approach to justify implementing the two-pass approach. + +Times below were collected using `perf stat` to measure the time to +remove a group containing a 1600-task, parallel workload. + +CPU: Intel(R) Xeon(R) Platinum P-8136 CPU @ 2.00GHz (112 threads) + + # mkdir /sys/fs/resctrl/test + # echo $$ > /sys/fs/resctrl/test/tasks + # perf bench sched messaging -g 40 -l 100000 + +task-clock time ranges collected using: + + # perf stat rmdir /sys/fs/resctrl/test + +Baseline: 1.54 - 1.60 ms +smp_mb() every matching task: 1.57 - 1.67 ms + + [ bp: Massage commit message. ] + +Fixes: ae28d1aae48a ("x86/resctrl: Use an IPI instead of task_work_add() to update PQR_ASSOC MSR") +Fixes: 0efc89be9471 ("x86/intel_rdt: Update task closid immediately on CPU in rmdir and unmount") +Signed-off-by: Peter Newman +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Reinette Chatre +Reviewed-by: Babu Moger +Cc: +Link: https://lore.kernel.org/r/20221220161123.432120-1-peternewman@google.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +index 8c405149c671..1125f752f126 100644 +--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c ++++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +@@ -585,8 +585,10 @@ static int __rdtgroup_move_task(struct task_struct *tsk, + /* + * Ensure the task's closid and rmid are written before determining if + * the task is current that will decide if it will be interrupted. ++ * This pairs with the full barrier between the rq->curr update and ++ * resctrl_sched_in() during context switch. + */ +- barrier(); ++ smp_mb(); + + /* + * By now, the task's closid and rmid are set. If the task is current +@@ -2140,6 +2142,14 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to, + t->closid = to->closid; + t->rmid = to->mon.rmid; + ++ /* ++ * Order the closid/rmid stores above before the loads ++ * in task_curr(). This pairs with the full barrier ++ * between the rq->curr update and resctrl_sched_in() ++ * during context switch. ++ */ ++ smp_mb(); ++ + /* + * If the task is on a CPU, set the CPU in the mask. + * The detection is inaccurate as tasks might move or +-- +2.35.1 + diff --git a/queue-4.19/x86-resctrl-use-task_curr-instead-of-task_struct-on_.patch b/queue-4.19/x86-resctrl-use-task_curr-instead-of-task_struct-on_.patch new file mode 100644 index 00000000000..0439b44e7e9 --- /dev/null +++ b/queue-4.19/x86-resctrl-use-task_curr-instead-of-task_struct-on_.patch @@ -0,0 +1,64 @@ +From f9bd347aa46b67363257b15846bc67cf43da7877 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Dec 2020 14:31:20 -0800 +Subject: x86/resctrl: Use task_curr() instead of task_struct->on_cpu to + prevent unnecessary IPI + +From: Reinette Chatre + +[ Upstream commit e0ad6dc8969f790f14bddcfd7ea284b7e5f88a16 ] + +James reported in [1] that there could be two tasks running on the same CPU +with task_struct->on_cpu set. Using task_struct->on_cpu as a test if a task +is running on a CPU may thus match the old task for a CPU while the +scheduler is running and IPI it unnecessarily. + +task_curr() is the correct helper to use. While doing so move the #ifdef +check of the CONFIG_SMP symbol to be a C conditional used to determine +if this helper should be used to ensure the code is always checked for +correctness by the compiler. + +[1] https://lore.kernel.org/lkml/a782d2f3-d2f6-795f-f4b1-9462205fd581@arm.com + +Reported-by: James Morse +Signed-off-by: Reinette Chatre +Signed-off-by: Borislav Petkov +Link: https://lkml.kernel.org/r/e9e68ce1441a73401e08b641cc3b9a3cf13fe6d4.1608243147.git.reinette.chatre@intel.com +Stable-dep-of: fe1f0714385f ("x86/resctrl: Fix task CLOSID/RMID update race") +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +index f406e3b85bdb..8c405149c671 100644 +--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c ++++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +@@ -2140,19 +2140,15 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to, + t->closid = to->closid; + t->rmid = to->mon.rmid; + +-#ifdef CONFIG_SMP + /* +- * This is safe on x86 w/o barriers as the ordering +- * of writing to task_cpu() and t->on_cpu is +- * reverse to the reading here. The detection is +- * inaccurate as tasks might move or schedule +- * before the smp function call takes place. In +- * such a case the function call is pointless, but ++ * If the task is on a CPU, set the CPU in the mask. ++ * The detection is inaccurate as tasks might move or ++ * schedule before the smp function call takes place. ++ * In such a case the function call is pointless, but + * there is no other side effect. + */ +- if (mask && t->on_cpu) ++ if (IS_ENABLED(CONFIG_SMP) && mask && task_curr(t)) + cpumask_set_cpu(task_cpu(t), mask); +-#endif + } + } + read_unlock(&tasklist_lock); +-- +2.35.1 + -- 2.47.3