From e7f43365bd3f146ee62efa394016a1620aeca903 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 17 Jun 2024 07:30:34 -0400 Subject: [PATCH] Fixes for 4.19 Signed-off-by: Sasha Levin --- ...fix-rejecting-l2cap_conn_param_updat.patch | 108 +++++++++++ ...-fix-runtime-warning-on-panel-bridge.patch | 51 +++++ ...ove-unnecessary-warn_on-in-implement.patch | 67 +++++++ ...mmu-amd-fix-sysfs-leak-in-iommu-init.patch | 47 +++++ ...-amd-introduce-pci-segment-structure.patch | 182 ++++++++++++++++++ ...move-gart-fallback-to-amd_iommu_init.patch | 66 +++++++ ...-page-for-completion-wait-write-back.patch | 166 ++++++++++++++++ ...add-a-missing-check-on-proc_dointvec.patch | 46 +++++ ...a-null-pointer-handling-path-in-lio_.patch | 69 +++++++ ...-rt-cache-flush-via-sysctl-using-a-p.patch | 53 +++++ ...owlabel-flow-key-when-re-routing-man.patch | 41 ++++ queue-4.19/series | 12 ++ ...tcp-fix-race-in-tcp_v6_syn_recv_sock.patch | 54 ++++++ 13 files changed, 962 insertions(+) create mode 100644 queue-4.19/bluetooth-l2cap-fix-rejecting-l2cap_conn_param_updat.patch create mode 100644 queue-4.19/drm-bridge-panel-fix-runtime-warning-on-panel-bridge.patch create mode 100644 queue-4.19/hid-core-remove-unnecessary-warn_on-in-implement.patch create mode 100644 queue-4.19/iommu-amd-fix-sysfs-leak-in-iommu-init.patch create mode 100644 queue-4.19/iommu-amd-introduce-pci-segment-structure.patch create mode 100644 queue-4.19/iommu-amd-move-gart-fallback-to-amd_iommu_init.patch create mode 100644 queue-4.19/iommu-amd-use-4k-page-for-completion-wait-write-back.patch create mode 100644 queue-4.19/ipv6-route-add-a-missing-check-on-proc_dointvec.patch create mode 100644 queue-4.19/liquidio-adjust-a-null-pointer-handling-path-in-lio_.patch create mode 100644 queue-4.19/net-ipv6-fix-the-rt-cache-flush-via-sysctl-using-a-p.patch create mode 100644 queue-4.19/netfilter-use-flowlabel-flow-key-when-re-routing-man.patch create mode 100644 queue-4.19/tcp-fix-race-in-tcp_v6_syn_recv_sock.patch diff --git a/queue-4.19/bluetooth-l2cap-fix-rejecting-l2cap_conn_param_updat.patch b/queue-4.19/bluetooth-l2cap-fix-rejecting-l2cap_conn_param_updat.patch new file mode 100644 index 00000000000..f9bb15eefe5 --- /dev/null +++ b/queue-4.19/bluetooth-l2cap-fix-rejecting-l2cap_conn_param_updat.patch @@ -0,0 +1,108 @@ +From 16bb27c3bcaf1613fe3e5d5487f528284e764d63 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 May 2024 16:03:07 -0400 +Subject: Bluetooth: L2CAP: Fix rejecting L2CAP_CONN_PARAM_UPDATE_REQ + +From: Luiz Augusto von Dentz + +[ Upstream commit 806a5198c05987b748b50f3d0c0cfb3d417381a4 ] + +This removes the bogus check for max > hcon->le_conn_max_interval since +the later is just the initial maximum conn interval not the maximum the +stack could support which is really 3200=4000ms. + +In order to pass GAP/CONN/CPUP/BV-05-C one shall probably enter values +of the following fields in IXIT that would cause hci_check_conn_params +to fail: + +TSPX_conn_update_int_min +TSPX_conn_update_int_max +TSPX_conn_update_peripheral_latency +TSPX_conn_update_supervision_timeout + +Link: https://github.com/bluez/bluez/issues/847 +Fixes: e4b019515f95 ("Bluetooth: Enforce validation on max value of connection interval") +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + include/net/bluetooth/hci_core.h | 36 ++++++++++++++++++++++++++++---- + net/bluetooth/l2cap_core.c | 8 +------ + 2 files changed, 33 insertions(+), 11 deletions(-) + +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index 878e7e92d8efd..7aa8e8e615812 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -1430,18 +1430,46 @@ static inline int hci_check_conn_params(u16 min, u16 max, u16 latency, + { + u16 max_latency; + +- if (min > max || min < 6 || max > 3200) ++ if (min > max) { ++ BT_WARN("min %d > max %d", min, max); + return -EINVAL; ++ } ++ ++ if (min < 6) { ++ BT_WARN("min %d < 6", min); ++ return -EINVAL; ++ } ++ ++ if (max > 3200) { ++ BT_WARN("max %d > 3200", max); ++ return -EINVAL; ++ } ++ ++ if (to_multiplier < 10) { ++ BT_WARN("to_multiplier %d < 10", to_multiplier); ++ return -EINVAL; ++ } + +- if (to_multiplier < 10 || to_multiplier > 3200) ++ if (to_multiplier > 3200) { ++ BT_WARN("to_multiplier %d > 3200", to_multiplier); + return -EINVAL; ++ } + +- if (max >= to_multiplier * 8) ++ if (max >= to_multiplier * 8) { ++ BT_WARN("max %d >= to_multiplier %d * 8", max, to_multiplier); + return -EINVAL; ++ } + + max_latency = (to_multiplier * 4 / max) - 1; +- if (latency > 499 || latency > max_latency) ++ if (latency > 499) { ++ BT_WARN("latency %d > 499", latency); + return -EINVAL; ++ } ++ ++ if (latency > max_latency) { ++ BT_WARN("latency %d > max_latency %d", latency, max_latency); ++ return -EINVAL; ++ } + + return 0; + } +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 3c6e72c4fdde3..3f9b2b4a62ffd 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -5316,13 +5316,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, + + memset(&rsp, 0, sizeof(rsp)); + +- if (max > hcon->le_conn_max_interval) { +- BT_DBG("requested connection interval exceeds current bounds."); +- err = -EINVAL; +- } else { +- err = hci_check_conn_params(min, max, latency, to_multiplier); +- } +- ++ err = hci_check_conn_params(min, max, latency, to_multiplier); + if (err) + rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED); + else +-- +2.43.0 + diff --git a/queue-4.19/drm-bridge-panel-fix-runtime-warning-on-panel-bridge.patch b/queue-4.19/drm-bridge-panel-fix-runtime-warning-on-panel-bridge.patch new file mode 100644 index 00000000000..d58b40d856c --- /dev/null +++ b/queue-4.19/drm-bridge-panel-fix-runtime-warning-on-panel-bridge.patch @@ -0,0 +1,51 @@ +From 594757540d0194d0e5ec97ca6c18f1a12e29886c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Jun 2024 11:27:39 +0100 +Subject: drm/bridge/panel: Fix runtime warning on panel bridge release + +From: Adam Miotk + +[ Upstream commit ce62600c4dbee8d43b02277669dd91785a9b81d9 ] + +Device managed panel bridge wrappers are created by calling to +drm_panel_bridge_add_typed() and registering a release handler for +clean-up when the device gets unbound. + +Since the memory for this bridge is also managed and linked to the panel +device, the release function should not try to free that memory. +Moreover, the call to devm_kfree() inside drm_panel_bridge_remove() will +fail in this case and emit a warning because the panel bridge resource +is no longer on the device resources list (it has been removed from +there before the call to release handlers). + +Fixes: 67022227ffb1 ("drm/bridge: Add a devm_ allocator for panel bridge.") +Signed-off-by: Adam Miotk +Signed-off-by: Maxime Ripard +Link: https://patchwork.freedesktop.org/patch/msgid/20240610102739.139852-1-adam.miotk@arm.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/panel.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c +index 7cbaba213ef69..2d6f8280fc712 100644 +--- a/drivers/gpu/drm/bridge/panel.c ++++ b/drivers/gpu/drm/bridge/panel.c +@@ -205,9 +205,12 @@ EXPORT_SYMBOL(drm_panel_bridge_remove); + + static void devm_drm_panel_bridge_release(struct device *dev, void *res) + { +- struct drm_bridge **bridge = res; ++ struct drm_bridge *bridge = *(struct drm_bridge **)res; + +- drm_panel_bridge_remove(*bridge); ++ if (!bridge) ++ return; ++ ++ drm_bridge_remove(bridge); + } + + struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev, +-- +2.43.0 + diff --git a/queue-4.19/hid-core-remove-unnecessary-warn_on-in-implement.patch b/queue-4.19/hid-core-remove-unnecessary-warn_on-in-implement.patch new file mode 100644 index 00000000000..0526850d36a --- /dev/null +++ b/queue-4.19/hid-core-remove-unnecessary-warn_on-in-implement.patch @@ -0,0 +1,67 @@ +From 8bf4d5169a4b92b02e924531636d20390945ff19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 May 2024 07:19:14 -0700 +Subject: HID: core: remove unnecessary WARN_ON() in implement() + +From: Nikita Zhandarovich + +[ Upstream commit 4aa2dcfbad538adf7becd0034a3754e1bd01b2b5 ] + +Syzkaller hit a warning [1] in a call to implement() when trying +to write a value into a field of smaller size in an output report. + +Since implement() already has a warn message printed out with the +help of hid_warn() and value in question gets trimmed with: + ... + value &= m; + ... +WARN_ON may be considered superfluous. Remove it to suppress future +syzkaller triggers. + +[1] +WARNING: CPU: 0 PID: 5084 at drivers/hid/hid-core.c:1451 implement drivers/hid/hid-core.c:1451 [inline] +WARNING: CPU: 0 PID: 5084 at drivers/hid/hid-core.c:1451 hid_output_report+0x548/0x760 drivers/hid/hid-core.c:1863 +Modules linked in: +CPU: 0 PID: 5084 Comm: syz-executor424 Not tainted 6.9.0-rc7-syzkaller-00183-gcf87f46fd34d #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/02/2024 +RIP: 0010:implement drivers/hid/hid-core.c:1451 [inline] +RIP: 0010:hid_output_report+0x548/0x760 drivers/hid/hid-core.c:1863 +... +Call Trace: + + __usbhid_submit_report drivers/hid/usbhid/hid-core.c:591 [inline] + usbhid_submit_report+0x43d/0x9e0 drivers/hid/usbhid/hid-core.c:636 + hiddev_ioctl+0x138b/0x1f00 drivers/hid/usbhid/hiddev.c:726 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:904 [inline] + __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:890 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xf5/0x240 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +... + +Fixes: 95d1c8951e5b ("HID: simplify implement() a bit") +Reported-by: +Suggested-by: Alan Stern +Signed-off-by: Nikita Zhandarovich +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-core.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index dd1d8d0a46d12..0757097d25507 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1264,7 +1264,6 @@ static void implement(const struct hid_device *hid, u8 *report, + hid_warn(hid, + "%s() called with too large value %d (n: %d)! (%s)\n", + __func__, value, n, current->comm); +- WARN_ON(1); + value &= m; + } + } +-- +2.43.0 + diff --git a/queue-4.19/iommu-amd-fix-sysfs-leak-in-iommu-init.patch b/queue-4.19/iommu-amd-fix-sysfs-leak-in-iommu-init.patch new file mode 100644 index 00000000000..d1227850894 --- /dev/null +++ b/queue-4.19/iommu-amd-fix-sysfs-leak-in-iommu-init.patch @@ -0,0 +1,47 @@ +From c98f5e59e41062856eee569dc3273a8842204f3d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 May 2024 08:42:20 +0800 +Subject: iommu/amd: Fix sysfs leak in iommu init + +From: Kun(llfl) + +[ Upstream commit a295ec52c8624883885396fde7b4df1a179627c3 ] + +During the iommu initialization, iommu_init_pci() adds sysfs nodes. +However, these nodes aren't remove in free_iommu_resources() subsequently. + +Fixes: 39ab9555c241 ("iommu: Add sysfs bindings for struct iommu_device") +Signed-off-by: Kun(llfl) +Reviewed-by: Suravee Suthikulpanit +Link: https://lore.kernel.org/r/c8e0d11c6ab1ee48299c288009cf9c5dae07b42d.1715215003.git.llfl@linux.alibaba.com +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd_iommu_init.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c +index 7fb2a5e857b22..ff2d87422595e 100644 +--- a/drivers/iommu/amd_iommu_init.c ++++ b/drivers/iommu/amd_iommu_init.c +@@ -1460,8 +1460,17 @@ static void __init free_pci_segments(void) + } + } + ++static void __init free_sysfs(struct amd_iommu *iommu) ++{ ++ if (iommu->iommu.dev) { ++ iommu_device_unregister(&iommu->iommu); ++ iommu_device_sysfs_remove(&iommu->iommu); ++ } ++} ++ + static void __init free_iommu_one(struct amd_iommu *iommu) + { ++ free_sysfs(iommu); + free_cwwb_sem(iommu); + free_command_buffer(iommu); + free_event_buffer(iommu); +-- +2.43.0 + diff --git a/queue-4.19/iommu-amd-introduce-pci-segment-structure.patch b/queue-4.19/iommu-amd-introduce-pci-segment-structure.patch new file mode 100644 index 00000000000..a01cbffeb6c --- /dev/null +++ b/queue-4.19/iommu-amd-introduce-pci-segment-structure.patch @@ -0,0 +1,182 @@ +From fea787c736dbcda687f5abc30859dc542d730eb8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Jul 2022 17:07:52 +0530 +Subject: iommu/amd: Introduce pci segment structure + +From: Vasant Hegde + +[ Upstream commit 404ec4e4c169fb64da6b2a38b471c13ac0897c76 ] + +Newer AMD systems can support multiple PCI segments, where each segment +contains one or more IOMMU instances. However, an IOMMU instance can only +support a single PCI segment. + +Current code assumes that system contains only one pci segment (segment 0) +and creates global data structures such as device table, rlookup table, +etc. + +Introducing per PCI segment data structure, which contains segment +specific data structures. This will eventually replace the global +data structures. + +Also update `amd_iommu->pci_seg` variable to point to PCI segment +structure instead of PCI segment ID. + +Co-developed-by: Suravee Suthikulpanit +Signed-off-by: Suravee Suthikulpanit +Signed-off-by: Vasant Hegde +Link: https://lore.kernel.org/r/20220706113825.25582-3-vasant.hegde@amd.com +Signed-off-by: Joerg Roedel +Stable-dep-of: a295ec52c862 ("iommu/amd: Fix sysfs leak in iommu init") +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd_iommu_init.c | 46 ++++++++++++++++++++++++++++++++- + drivers/iommu/amd_iommu_types.h | 24 ++++++++++++++++- + 2 files changed, 68 insertions(+), 2 deletions(-) + +diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c +index a9190491f9c3d..7fb2a5e857b22 100644 +--- a/drivers/iommu/amd_iommu_init.c ++++ b/drivers/iommu/amd_iommu_init.c +@@ -167,6 +167,7 @@ LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings + we find in ACPI */ + bool amd_iommu_unmap_flush; /* if true, flush on every unmap */ + ++LIST_HEAD(amd_iommu_pci_seg_list); /* list of all PCI segments */ + LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the + system */ + +@@ -1422,6 +1423,43 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, + return 0; + } + ++/* Allocate PCI segment data structure */ ++static struct amd_iommu_pci_seg *__init alloc_pci_segment(u16 id) ++{ ++ struct amd_iommu_pci_seg *pci_seg; ++ ++ pci_seg = kzalloc(sizeof(struct amd_iommu_pci_seg), GFP_KERNEL); ++ if (pci_seg == NULL) ++ return NULL; ++ ++ pci_seg->id = id; ++ list_add_tail(&pci_seg->list, &amd_iommu_pci_seg_list); ++ ++ return pci_seg; ++} ++ ++static struct amd_iommu_pci_seg *__init get_pci_segment(u16 id) ++{ ++ struct amd_iommu_pci_seg *pci_seg; ++ ++ for_each_pci_segment(pci_seg) { ++ if (pci_seg->id == id) ++ return pci_seg; ++ } ++ ++ return alloc_pci_segment(id); ++} ++ ++static void __init free_pci_segments(void) ++{ ++ struct amd_iommu_pci_seg *pci_seg, *next; ++ ++ for_each_pci_segment_safe(pci_seg, next) { ++ list_del(&pci_seg->list); ++ kfree(pci_seg); ++ } ++} ++ + static void __init free_iommu_one(struct amd_iommu *iommu) + { + free_cwwb_sem(iommu); +@@ -1510,8 +1548,14 @@ static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu) + */ + static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) + { ++ struct amd_iommu_pci_seg *pci_seg; + int ret; + ++ pci_seg = get_pci_segment(h->pci_seg); ++ if (pci_seg == NULL) ++ return -ENOMEM; ++ iommu->pci_seg = pci_seg; ++ + raw_spin_lock_init(&iommu->lock); + iommu->cmd_sem_val = 0; + +@@ -1532,7 +1576,6 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) + */ + iommu->devid = h->devid; + iommu->cap_ptr = h->cap_ptr; +- iommu->pci_seg = h->pci_seg; + iommu->mmio_phys = h->mmio_phys; + + switch (h->type) { +@@ -2361,6 +2404,7 @@ static void __init free_iommu_resources(void) + amd_iommu_dev_table = NULL; + + free_iommu_all(); ++ free_pci_segments(); + } + + /* SB IOAPIC is always on this device in AMD systems */ +diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h +index af95dfc28870b..27e8c9d110da4 100644 +--- a/drivers/iommu/amd_iommu_types.h ++++ b/drivers/iommu/amd_iommu_types.h +@@ -431,6 +431,11 @@ extern bool amd_iommu_irq_remap; + /* kmem_cache to get tables with 128 byte alignement */ + extern struct kmem_cache *amd_iommu_irq_cache; + ++/* Make iterating over all pci segment easier */ ++#define for_each_pci_segment(pci_seg) \ ++ list_for_each_entry((pci_seg), &amd_iommu_pci_seg_list, list) ++#define for_each_pci_segment_safe(pci_seg, next) \ ++ list_for_each_entry_safe((pci_seg), (next), &amd_iommu_pci_seg_list, list) + /* + * Make iterating over all IOMMUs easier + */ +@@ -488,6 +493,17 @@ struct protection_domain { + unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */ + }; + ++/* ++ * This structure contains information about one PCI segment in the system. ++ */ ++struct amd_iommu_pci_seg { ++ /* List with all PCI segments in the system */ ++ struct list_head list; ++ ++ /* PCI segment number */ ++ u16 id; ++}; ++ + /* + * Structure where we save information about one hardware AMD IOMMU in the + * system. +@@ -539,7 +555,7 @@ struct amd_iommu { + u16 cap_ptr; + + /* pci domain of this IOMMU */ +- u16 pci_seg; ++ struct amd_iommu_pci_seg *pci_seg; + + /* start of exclusion range of that IOMMU */ + u64 exclusion_start; +@@ -666,6 +682,12 @@ extern struct list_head ioapic_map; + extern struct list_head hpet_map; + extern struct list_head acpihid_map; + ++/* ++ * List with all PCI segments in the system. This list is not locked because ++ * it is only written at driver initialization time ++ */ ++extern struct list_head amd_iommu_pci_seg_list; ++ + /* + * List with all IOMMUs in the system. This list is not locked because it is + * only written and read at driver initialization or suspend time +-- +2.43.0 + diff --git a/queue-4.19/iommu-amd-move-gart-fallback-to-amd_iommu_init.patch b/queue-4.19/iommu-amd-move-gart-fallback-to-amd_iommu_init.patch new file mode 100644 index 00000000000..7559828f5aa --- /dev/null +++ b/queue-4.19/iommu-amd-move-gart-fallback-to-amd_iommu_init.patch @@ -0,0 +1,66 @@ +From a0728242b8666a9c83ea289e2e91620bc6546a01 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Jun 2019 14:52:04 -0700 +Subject: iommu/amd: Move gart fallback to amd_iommu_init + +From: Kevin Mitchell + +[ Upstream commit bf4bff46eac151c3fd299741d71c4216e45b5d8b ] + +The fallback to the GART driver in the case amd_iommu doesn't work was +executed in a function called free_iommu_resources, which didn't really +make sense. This was even being called twice if amd_iommu=off was +specified on the command line. + +The only complication is that it needs to be verified that amd_iommu has +fully relinquished control by calling free_iommu_resources and emptying +the amd_iommu_list. + +Signed-off-by: Kevin Mitchell +Signed-off-by: Joerg Roedel +Stable-dep-of: a295ec52c862 ("iommu/amd: Fix sysfs leak in iommu init") +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd_iommu_init.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c +index efb11ca91dd72..05726f73a859f 100644 +--- a/drivers/iommu/amd_iommu_init.c ++++ b/drivers/iommu/amd_iommu_init.c +@@ -2343,15 +2343,6 @@ static void __init free_iommu_resources(void) + amd_iommu_dev_table = NULL; + + free_iommu_all(); +- +-#ifdef CONFIG_GART_IOMMU +- /* +- * We failed to initialize the AMD IOMMU - try fallback to GART +- * if possible. +- */ +- gart_iommu_init(); +- +-#endif + } + + /* SB IOAPIC is always on this device in AMD systems */ +@@ -2772,6 +2763,16 @@ static int __init amd_iommu_init(void) + } + } + ++#ifdef CONFIG_GART_IOMMU ++ if (ret && list_empty(&amd_iommu_list)) { ++ /* ++ * We failed to initialize the AMD IOMMU - try fallback ++ * to GART if possible. ++ */ ++ gart_iommu_init(); ++ } ++#endif ++ + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + +-- +2.43.0 + diff --git a/queue-4.19/iommu-amd-use-4k-page-for-completion-wait-write-back.patch b/queue-4.19/iommu-amd-use-4k-page-for-completion-wait-write-back.patch new file mode 100644 index 00000000000..bd4813c46ed --- /dev/null +++ b/queue-4.19/iommu-amd-use-4k-page-for-completion-wait-write-back.patch @@ -0,0 +1,166 @@ +From c249a884850d743ccb851f4b7a6aaceff31adab0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Sep 2020 12:13:45 +0000 +Subject: iommu/amd: Use 4K page for completion wait write-back semaphore + +From: Suravee Suthikulpanit + +[ Upstream commit c69d89aff393a212b9635c95990173b48d8bd74d ] + +IOMMU SNP support requires the completion wait write-back semaphore to be +implemented using a 4K-aligned page, where the page address is to be +programmed into the newly introduced MMIO base/range registers. + +This new scheme uses a per-iommu atomic variable to store the current +semaphore value, which is incremented for every completion wait command. + +Since this new scheme is also compatible with non-SNP mode, +generalize the driver to use 4K page for completion-wait semaphore in +both modes. + +Signed-off-by: Suravee Suthikulpanit +Cc: Brijesh Singh +Link: https://lore.kernel.org/r/20200923121347.25365-2-suravee.suthikulpanit@amd.com +Signed-off-by: Joerg Roedel +Stable-dep-of: a295ec52c862 ("iommu/amd: Fix sysfs leak in iommu init") +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd_iommu.c | 23 +++++++++++------------ + drivers/iommu/amd_iommu_init.c | 18 ++++++++++++++++++ + drivers/iommu/amd_iommu_types.h | 3 ++- + 3 files changed, 31 insertions(+), 13 deletions(-) + +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index 5d5941aca16ad..e512dfa0e0924 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -843,11 +843,11 @@ irqreturn_t amd_iommu_int_handler(int irq, void *data) + * + ****************************************************************************/ + +-static int wait_on_sem(volatile u64 *sem) ++static int wait_on_sem(struct amd_iommu *iommu, u64 data) + { + int i = 0; + +- while (*sem == 0 && i < LOOP_TIMEOUT) { ++ while (*iommu->cmd_sem != data && i < LOOP_TIMEOUT) { + udelay(1); + i += 1; + } +@@ -877,16 +877,16 @@ static void copy_cmd_to_buffer(struct amd_iommu *iommu, + writel(iommu->cmd_buf_tail, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); + } + +-static void build_completion_wait(struct iommu_cmd *cmd, u64 address) ++static void build_completion_wait(struct iommu_cmd *cmd, ++ struct amd_iommu *iommu, ++ u64 data) + { +- u64 paddr = iommu_virt_to_phys((void *)address); +- +- WARN_ON(address & 0x7ULL); ++ u64 paddr = iommu_virt_to_phys((void *)iommu->cmd_sem); + + memset(cmd, 0, sizeof(*cmd)); + cmd->data[0] = lower_32_bits(paddr) | CMD_COMPL_WAIT_STORE_MASK; + cmd->data[1] = upper_32_bits(paddr); +- cmd->data[2] = 1; ++ cmd->data[2] = data; + CMD_SET_TYPE(cmd, CMD_COMPL_WAIT); + } + +@@ -1095,22 +1095,21 @@ static int iommu_completion_wait(struct amd_iommu *iommu) + struct iommu_cmd cmd; + unsigned long flags; + int ret; ++ u64 data; + + if (!iommu->need_sync) + return 0; + +- +- build_completion_wait(&cmd, (u64)&iommu->cmd_sem); +- + raw_spin_lock_irqsave(&iommu->lock, flags); + +- iommu->cmd_sem = 0; ++ data = ++iommu->cmd_sem_val; ++ build_completion_wait(&cmd, iommu, data); + + ret = __iommu_queue_command_sync(iommu, &cmd, false); + if (ret) + goto out_unlock; + +- ret = wait_on_sem(&iommu->cmd_sem); ++ ret = wait_on_sem(iommu, data); + + out_unlock: + raw_spin_unlock_irqrestore(&iommu->lock, flags); +diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c +index 05726f73a859f..a9190491f9c3d 100644 +--- a/drivers/iommu/amd_iommu_init.c ++++ b/drivers/iommu/amd_iommu_init.c +@@ -835,6 +835,19 @@ static int iommu_init_ga(struct amd_iommu *iommu) + return ret; + } + ++static int __init alloc_cwwb_sem(struct amd_iommu *iommu) ++{ ++ iommu->cmd_sem = (void *)get_zeroed_page(GFP_KERNEL); ++ ++ return iommu->cmd_sem ? 0 : -ENOMEM; ++} ++ ++static void __init free_cwwb_sem(struct amd_iommu *iommu) ++{ ++ if (iommu->cmd_sem) ++ free_page((unsigned long)iommu->cmd_sem); ++} ++ + static void iommu_enable_xt(struct amd_iommu *iommu) + { + #ifdef CONFIG_IRQ_REMAP +@@ -1411,6 +1424,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, + + static void __init free_iommu_one(struct amd_iommu *iommu) + { ++ free_cwwb_sem(iommu); + free_command_buffer(iommu); + free_event_buffer(iommu); + free_ppr_log(iommu); +@@ -1499,6 +1513,7 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) + int ret; + + raw_spin_lock_init(&iommu->lock); ++ iommu->cmd_sem_val = 0; + + /* Add IOMMU to internal data structures */ + list_add_tail(&iommu->list, &amd_iommu_list); +@@ -1554,6 +1569,9 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) + if (!iommu->mmio_base) + return -ENOMEM; + ++ if (alloc_cwwb_sem(iommu)) ++ return -ENOMEM; ++ + if (alloc_command_buffer(iommu)) + return -ENOMEM; + +diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h +index 0948c425d6528..af95dfc28870b 100644 +--- a/drivers/iommu/amd_iommu_types.h ++++ b/drivers/iommu/amd_iommu_types.h +@@ -601,7 +601,8 @@ struct amd_iommu { + #endif + + u32 flags; +- volatile u64 __aligned(8) cmd_sem; ++ volatile u64 *cmd_sem; ++ u64 cmd_sem_val; + + #ifdef CONFIG_AMD_IOMMU_DEBUGFS + /* DebugFS Info */ +-- +2.43.0 + diff --git a/queue-4.19/ipv6-route-add-a-missing-check-on-proc_dointvec.patch b/queue-4.19/ipv6-route-add-a-missing-check-on-proc_dointvec.patch new file mode 100644 index 00000000000..34fa05af3e4 --- /dev/null +++ b/queue-4.19/ipv6-route-add-a-missing-check-on-proc_dointvec.patch @@ -0,0 +1,46 @@ +From b5bedf70273895d3eae3afe97c1917e58daf6103 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Dec 2018 10:30:17 -0600 +Subject: ipv6/route: Add a missing check on proc_dointvec + +From: Aditya Pakki + +[ Upstream commit f0fb9b288d0a7e9cc324ae362e2dfd2cc2217ded ] + +While flushing the cache via ipv6_sysctl_rtcache_flush(), the call +to proc_dointvec() may fail. The fix adds a check that returns the +error, on failure. + +Signed-off-by: Aditya Pakki +Signed-off-by: David S. Miller +Stable-dep-of: 14a20e5b4ad9 ("net/ipv6: Fix the RT cache flush via sysctl using a previous delay") +Signed-off-by: Sasha Levin +--- + net/ipv6/route.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index db349679b1127..50bf2ffe1f2a5 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -5166,12 +5166,16 @@ int ipv6_sysctl_rtcache_flush(struct ctl_table *ctl, int write, + { + struct net *net; + int delay; ++ int ret; + if (!write) + return -EINVAL; + + net = (struct net *)ctl->extra1; + delay = net->ipv6.sysctl.flush_delay; +- proc_dointvec(ctl, write, buffer, lenp, ppos); ++ ret = proc_dointvec(ctl, write, buffer, lenp, ppos); ++ if (ret) ++ return ret; ++ + fib6_run_gc(delay <= 0 ? 0 : (unsigned long)delay, net, delay > 0); + return 0; + } +-- +2.43.0 + diff --git a/queue-4.19/liquidio-adjust-a-null-pointer-handling-path-in-lio_.patch b/queue-4.19/liquidio-adjust-a-null-pointer-handling-path-in-lio_.patch new file mode 100644 index 00000000000..d5ece4d320b --- /dev/null +++ b/queue-4.19/liquidio-adjust-a-null-pointer-handling-path-in-lio_.patch @@ -0,0 +1,69 @@ +From 6b4cd141f51b3d15c5f296d8deea6a8ba28e749f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Jun 2024 13:11:35 +0300 +Subject: liquidio: Adjust a NULL pointer handling path in + lio_vf_rep_copy_packet + +From: Aleksandr Mishin + +[ Upstream commit c44711b78608c98a3e6b49ce91678cd0917d5349 ] + +In lio_vf_rep_copy_packet() pg_info->page is compared to a NULL value, +but then it is unconditionally passed to skb_add_rx_frag() which looks +strange and could lead to null pointer dereference. + +lio_vf_rep_copy_packet() call trace looks like: + octeon_droq_process_packets + octeon_droq_fast_process_packets + octeon_droq_dispatch_pkt + octeon_create_recv_info + ...search in the dispatch_list... + ->disp_fn(rdisp->rinfo, ...) + lio_vf_rep_pkt_recv(struct octeon_recv_info *recv_info, ...) +In this path there is no code which sets pg_info->page to NULL. +So this check looks unneeded and doesn't solve potential problem. +But I guess the author had reason to add a check and I have no such card +and can't do real test. +In addition, the code in the function liquidio_push_packet() in +liquidio/lio_core.c does exactly the same. + +Based on this, I consider the most acceptable compromise solution to +adjust this issue by moving skb_add_rx_frag() into conditional scope. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 1f233f327913 ("liquidio: switchdev support for LiquidIO NIC") +Signed-off-by: Aleksandr Mishin +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c +index a1bda1683ebfc..d90500573f5b7 100644 +--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c ++++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c +@@ -289,13 +289,12 @@ lio_vf_rep_copy_packet(struct octeon_device *oct, + pg_info->page_offset; + memcpy(skb->data, va, MIN_SKB_SIZE); + skb_put(skb, MIN_SKB_SIZE); ++ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, ++ pg_info->page, ++ pg_info->page_offset + MIN_SKB_SIZE, ++ len - MIN_SKB_SIZE, ++ LIO_RXBUFFER_SZ); + } +- +- skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, +- pg_info->page, +- pg_info->page_offset + MIN_SKB_SIZE, +- len - MIN_SKB_SIZE, +- LIO_RXBUFFER_SZ); + } else { + struct octeon_skb_page_info *pg_info = + ((struct octeon_skb_page_info *)(skb->cb)); +-- +2.43.0 + diff --git a/queue-4.19/net-ipv6-fix-the-rt-cache-flush-via-sysctl-using-a-p.patch b/queue-4.19/net-ipv6-fix-the-rt-cache-flush-via-sysctl-using-a-p.patch new file mode 100644 index 00000000000..6ba76385af5 --- /dev/null +++ b/queue-4.19/net-ipv6-fix-the-rt-cache-flush-via-sysctl-using-a-p.patch @@ -0,0 +1,53 @@ +From 245290714e91a5bb7471df067f1cd7743833b474 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Jun 2024 13:28:28 +0200 +Subject: net/ipv6: Fix the RT cache flush via sysctl using a previous delay + +From: Petr Pavlu + +[ Upstream commit 14a20e5b4ad998793c5f43b0330d9e1388446cf3 ] + +The net.ipv6.route.flush system parameter takes a value which specifies +a delay used during the flush operation for aging exception routes. The +written value is however not used in the currently requested flush and +instead utilized only in the next one. + +A problem is that ipv6_sysctl_rtcache_flush() first reads the old value +of net->ipv6.sysctl.flush_delay into a local delay variable and then +calls proc_dointvec() which actually updates the sysctl based on the +provided input. + +Fix the problem by switching the order of the two operations. + +Fixes: 4990509f19e8 ("[NETNS][IPV6]: Make sysctls route per namespace.") +Signed-off-by: Petr Pavlu +Reviewed-by: David Ahern +Link: https://lore.kernel.org/r/20240607112828.30285-1-petr.pavlu@suse.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/route.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 50bf2ffe1f2a5..d060b22554a22 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -5170,12 +5170,12 @@ int ipv6_sysctl_rtcache_flush(struct ctl_table *ctl, int write, + if (!write) + return -EINVAL; + +- net = (struct net *)ctl->extra1; +- delay = net->ipv6.sysctl.flush_delay; + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) + return ret; + ++ net = (struct net *)ctl->extra1; ++ delay = net->ipv6.sysctl.flush_delay; + fib6_run_gc(delay <= 0 ? 0 : (unsigned long)delay, net, delay > 0); + return 0; + } +-- +2.43.0 + diff --git a/queue-4.19/netfilter-use-flowlabel-flow-key-when-re-routing-man.patch b/queue-4.19/netfilter-use-flowlabel-flow-key-when-re-routing-man.patch new file mode 100644 index 00000000000..c3a890cd4da --- /dev/null +++ b/queue-4.19/netfilter-use-flowlabel-flow-key-when-re-routing-man.patch @@ -0,0 +1,41 @@ +From 8d3107f103d3a4742e730c313539e21cb6370af4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Jun 2024 12:23:31 +0200 +Subject: netfilter: Use flowlabel flow key when re-routing mangled packets + +From: Florian Westphal + +[ Upstream commit 6f8f132cc7bac2ac76911e47d5baa378aafda4cb ] + +'ip6 dscp set $v' in an nftables outpute route chain has no effect. +While nftables does detect the dscp change and calls the reroute hook. +But ip6_route_me_harder never sets the dscp/flowlabel: +flowlabel/dsfield routing rules are ignored and no reroute takes place. + +Thanks to Yi Chen for an excellent reproducer script that I used +to validate this change. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: Yi Chen +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/ipv6/netfilter.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c +index 5679fa3f696ad..abdb020dd338e 100644 +--- a/net/ipv6/netfilter.c ++++ b/net/ipv6/netfilter.c +@@ -32,6 +32,7 @@ int ip6_route_me_harder(struct net *net, struct sock *sk_partial, struct sk_buff + .flowi6_uid = sock_net_uid(net, sk), + .daddr = iph->daddr, + .saddr = iph->saddr, ++ .flowlabel = ip6_flowinfo(iph), + }; + int err; + +-- +2.43.0 + diff --git a/queue-4.19/series b/queue-4.19/series index 12f41668314..87b32988d01 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -35,3 +35,15 @@ xhci-apply-reset-resume-quirk-to-etron-ej188-xhci-host.patch xhci-apply-broken-streams-quirk-to-etron-ej188-xhci-host.patch input-try-trimming-too-long-modalias-strings.patch xsk-validate-user-input-for-xdp_-umem-completion-_fill_ring.patch +hid-core-remove-unnecessary-warn_on-in-implement.patch +iommu-amd-move-gart-fallback-to-amd_iommu_init.patch +iommu-amd-use-4k-page-for-completion-wait-write-back.patch +iommu-amd-introduce-pci-segment-structure.patch +iommu-amd-fix-sysfs-leak-in-iommu-init.patch +liquidio-adjust-a-null-pointer-handling-path-in-lio_.patch +drm-bridge-panel-fix-runtime-warning-on-panel-bridge.patch +tcp-fix-race-in-tcp_v6_syn_recv_sock.patch +bluetooth-l2cap-fix-rejecting-l2cap_conn_param_updat.patch +netfilter-use-flowlabel-flow-key-when-re-routing-man.patch +ipv6-route-add-a-missing-check-on-proc_dointvec.patch +net-ipv6-fix-the-rt-cache-flush-via-sysctl-using-a-p.patch diff --git a/queue-4.19/tcp-fix-race-in-tcp_v6_syn_recv_sock.patch b/queue-4.19/tcp-fix-race-in-tcp_v6_syn_recv_sock.patch new file mode 100644 index 00000000000..5302a2c5262 --- /dev/null +++ b/queue-4.19/tcp-fix-race-in-tcp_v6_syn_recv_sock.patch @@ -0,0 +1,54 @@ +From 92d4ab5f9e9e088138bfb09029a51c94f529a864 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Jun 2024 15:46:51 +0000 +Subject: tcp: fix race in tcp_v6_syn_recv_sock() + +From: Eric Dumazet + +[ Upstream commit d37fe4255abe8e7b419b90c5847e8ec2b8debb08 ] + +tcp_v6_syn_recv_sock() calls ip6_dst_store() before +inet_sk(newsk)->pinet6 has been set up. + +This means ip6_dst_store() writes over the parent (listener) +np->dst_cookie. + +This is racy because multiple threads could share the same +parent and their final np->dst_cookie could be wrong. + +Move ip6_dst_store() call after inet_sk(newsk)->pinet6 +has been changed and after the copy of parent ipv6_pinfo. + +Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets") +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv6/tcp_ipv6.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c +index 033cf81f34837..fca1b95d86a97 100644 +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -1177,7 +1177,6 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * + */ + + newsk->sk_gso_type = SKB_GSO_TCPV6; +- ip6_dst_store(newsk, dst, NULL, NULL); + inet6_sk_rx_dst_set(newsk, skb); + + newtcp6sk = (struct tcp6_sock *)newsk; +@@ -1189,6 +1188,8 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * + + memcpy(newnp, np, sizeof(struct ipv6_pinfo)); + ++ ip6_dst_store(newsk, dst, NULL, NULL); ++ + newsk->sk_v6_daddr = ireq->ir_v6_rmt_addr; + newnp->saddr = ireq->ir_v6_loc_addr; + newsk->sk_v6_rcv_saddr = ireq->ir_v6_loc_addr; +-- +2.43.0 + -- 2.47.3