From: Sasha Levin Date: Sat, 21 Oct 2023 00:51:09 +0000 (-0400) Subject: Fixes for 5.15 X-Git-Tag: v4.14.328~72 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ea20ae5ac61b1af9c12d4cb5292920136a683199;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/arm-dts-ti-omap-fix-noisy-serial-with-overrun-thrott.patch b/queue-5.15/arm-dts-ti-omap-fix-noisy-serial-with-overrun-thrott.patch new file mode 100644 index 00000000000..4011cca3293 --- /dev/null +++ b/queue-5.15/arm-dts-ti-omap-fix-noisy-serial-with-overrun-thrott.patch @@ -0,0 +1,44 @@ +From a4863987676d196241d7d390bc354dfce779a6c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Sep 2023 07:07:38 +0300 +Subject: ARM: dts: ti: omap: Fix noisy serial with overrun-throttle-ms for + mapphone + +From: Tony Lindgren + +[ Upstream commit 5ad37b5e30433afa7a5513e3eb61f69fa0976785 ] + +On mapphone devices we may get lots of noise on the micro-USB port in debug +uart mode until the phy-cpcap-usb driver probes. Let's limit the noise by +using overrun-throttle-ms. + +Note that there is also a related separate issue where the charger cable +connected may cause random sysrq requests until phy-cpcap-usb probes that +still remains. + +Cc: Ivaylo Dimitrov +Cc: Carl Philipp Klemm +Cc: Merlijn Wajer +Cc: Pavel Machek +Reviewed-by: Sebastian Reichel +Signed-off-by: Tony Lindgren +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/motorola-mapphone-common.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi +index 67c68c61ae029..2ac1ed8ad8197 100644 +--- a/arch/arm/boot/dts/motorola-mapphone-common.dtsi ++++ b/arch/arm/boot/dts/motorola-mapphone-common.dtsi +@@ -640,6 +640,7 @@ &uart1 { + &uart3 { + interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH + &omap4_pmx_core 0x17c>; ++ overrun-throttle-ms = <500>; + }; + + &uart4 { +-- +2.40.1 + diff --git a/queue-5.15/ata-libata-core-fix-compilation-warning-in-ata_dev_c.patch b/queue-5.15/ata-libata-core-fix-compilation-warning-in-ata_dev_c.patch new file mode 100644 index 00000000000..28cc0179e1f --- /dev/null +++ b/queue-5.15/ata-libata-core-fix-compilation-warning-in-ata_dev_c.patch @@ -0,0 +1,60 @@ +From bcba3c45199c507aba8a6bd6c6062ec274a949a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 08:46:22 +0900 +Subject: ata: libata-core: Fix compilation warning in ata_dev_config_ncq() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Damien Le Moal + +[ Upstream commit ed518d9ba980dc0d27c7d1dea1e627ba001d1977 ] + +The 24 bytes length allocated to the ncq_desc string in +ata_dev_config_lba() for ata_dev_config_ncq() to use is too short, +causing the following gcc compilation warnings when compiling with W=1: + +drivers/ata/libata-core.c: In function ‘ata_dev_configure’: +drivers/ata/libata-core.c:2378:56: warning: ‘%d’ directive output may be truncated writing between 1 and 2 bytes into a region of size between 1 and 11 [-Wformat-truncation=] + 2378 | snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth, + | ^~ +In function ‘ata_dev_config_ncq’, + inlined from ‘ata_dev_config_lba’ at drivers/ata/libata-core.c:2649:8, + inlined from ‘ata_dev_configure’ at drivers/ata/libata-core.c:2952:9: +drivers/ata/libata-core.c:2378:41: note: directive argument in the range [1, 32] + 2378 | snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth, + | ^~~~~~~~~~~~~~~~~~~~~ +drivers/ata/libata-core.c:2378:17: note: ‘snprintf’ output between 16 and 31 bytes into a destination of size 24 + 2378 | snprintf(desc, desc_sz, "NCQ (depth %d/%d)%s", hdepth, + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2379 | ddepth, aa_desc); + | ~~~~~~~~~~~~~~~~ + +Avoid these warnings and the potential truncation by changing the size +of the ncq_desc string to 32 characters. + +Signed-off-by: Damien Le Moal +Reviewed-by: Hannes Reinecke +Tested-by: Geert Uytterhoeven +Reviewed-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ata/libata-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 96786d6fcf37b..383398af836c8 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -2382,7 +2382,7 @@ static int ata_dev_config_lba(struct ata_device *dev) + struct ata_port *ap = dev->link->ap; + const u16 *id = dev->id; + const char *lba_desc; +- char ncq_desc[24]; ++ char ncq_desc[32]; + int ret; + + dev->flags |= ATA_DFLAG_LBA; +-- +2.40.1 + diff --git a/queue-5.15/ata-libata-eh-fix-compilation-warning-in-ata_eh_link.patch b/queue-5.15/ata-libata-eh-fix-compilation-warning-in-ata_eh_link.patch new file mode 100644 index 00000000000..c130a7aa87d --- /dev/null +++ b/queue-5.15/ata-libata-eh-fix-compilation-warning-in-ata_eh_link.patch @@ -0,0 +1,55 @@ +From b7acc90a30e611d37f1a42338611eb4114afd26b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 09:08:40 +0900 +Subject: ata: libata-eh: Fix compilation warning in ata_eh_link_report() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Damien Le Moal + +[ Upstream commit 49728bdc702391902a473b9393f1620eea32acb0 ] + +The 6 bytes length of the tries_buf string in ata_eh_link_report() is +too short and results in a gcc compilation warning with W-!: + +drivers/ata/libata-eh.c: In function ‘ata_eh_link_report’: +drivers/ata/libata-eh.c:2371:59: warning: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size 4 [-Wformat-truncation=] + 2371 | snprintf(tries_buf, sizeof(tries_buf), " t%d", + | ^~ +drivers/ata/libata-eh.c:2371:56: note: directive argument in the range [-2147483648, 4] + 2371 | snprintf(tries_buf, sizeof(tries_buf), " t%d", + | ^~~~~~ +drivers/ata/libata-eh.c:2371:17: note: ‘snprintf’ output between 4 and 14 bytes into a destination of size 6 + 2371 | snprintf(tries_buf, sizeof(tries_buf), " t%d", + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2372 | ap->eh_tries); + | ~~~~~~~~~~~~~ + +Avoid this warning by increasing the string size to 16B. + +Signed-off-by: Damien Le Moal +Reviewed-by: Hannes Reinecke +Tested-by: Geert Uytterhoeven +Reviewed-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ata/libata-eh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c +index 8444832008703..10742d72f44fb 100644 +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -2223,7 +2223,7 @@ static void ata_eh_link_report(struct ata_link *link) + struct ata_eh_context *ehc = &link->eh_context; + struct ata_queued_cmd *qc; + const char *frozen, *desc; +- char tries_buf[6] = ""; ++ char tries_buf[16] = ""; + int tag, nr_failed = 0; + + if (ehc->i.flags & ATA_EHI_QUIET) +-- +2.40.1 + diff --git a/queue-5.15/bluetooth-avoid-redundant-authentication.patch b/queue-5.15/bluetooth-avoid-redundant-authentication.patch new file mode 100644 index 00000000000..acc61dc9b9a --- /dev/null +++ b/queue-5.15/bluetooth-avoid-redundant-authentication.patch @@ -0,0 +1,106 @@ +From 9c69a0ad1cc8bdf8e7526941dd07a398632b4334 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 04:39:34 +0000 +Subject: Bluetooth: Avoid redundant authentication + +From: Ying Hsu + +[ Upstream commit 1d8e801422d66e4b8c7b187c52196bef94eed887 ] + +While executing the Android 13 CTS Verifier Secure Server test on a +ChromeOS device, it was observed that the Bluetooth host initiates +authentication for an RFCOMM connection after SSP completes. +When this happens, some Intel Bluetooth controllers, like AC9560, would +disconnect with "Connection Rejected due to Security Reasons (0x0e)". + +Historically, BlueZ did not mandate this authentication while an +authenticated combination key was already in use for the connection. +This behavior was changed since commit 7b5a9241b780 +("Bluetooth: Introduce requirements for security level 4"). +So, this patch addresses the aforementioned disconnection issue by +restoring the previous behavior. + +Signed-off-by: Ying Hsu +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_conn.c | 63 ++++++++++++++++++++++------------------ + 1 file changed, 35 insertions(+), 28 deletions(-) + +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index d6a7ab3239c21..5f1e388c2b951 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -1486,34 +1486,41 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type, + if (!test_bit(HCI_CONN_AUTH, &conn->flags)) + goto auth; + +- /* An authenticated FIPS approved combination key has sufficient +- * security for security level 4. */ +- if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256 && +- sec_level == BT_SECURITY_FIPS) +- goto encrypt; +- +- /* An authenticated combination key has sufficient security for +- security level 3. */ +- if ((conn->key_type == HCI_LK_AUTH_COMBINATION_P192 || +- conn->key_type == HCI_LK_AUTH_COMBINATION_P256) && +- sec_level == BT_SECURITY_HIGH) +- goto encrypt; +- +- /* An unauthenticated combination key has sufficient security for +- security level 1 and 2. */ +- if ((conn->key_type == HCI_LK_UNAUTH_COMBINATION_P192 || +- conn->key_type == HCI_LK_UNAUTH_COMBINATION_P256) && +- (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW)) +- goto encrypt; +- +- /* A combination key has always sufficient security for the security +- levels 1 or 2. High security level requires the combination key +- is generated using maximum PIN code length (16). +- For pre 2.1 units. */ +- if (conn->key_type == HCI_LK_COMBINATION && +- (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW || +- conn->pin_length == 16)) +- goto encrypt; ++ switch (conn->key_type) { ++ case HCI_LK_AUTH_COMBINATION_P256: ++ /* An authenticated FIPS approved combination key has ++ * sufficient security for security level 4 or lower. ++ */ ++ if (sec_level <= BT_SECURITY_FIPS) ++ goto encrypt; ++ break; ++ case HCI_LK_AUTH_COMBINATION_P192: ++ /* An authenticated combination key has sufficient security for ++ * security level 3 or lower. ++ */ ++ if (sec_level <= BT_SECURITY_HIGH) ++ goto encrypt; ++ break; ++ case HCI_LK_UNAUTH_COMBINATION_P192: ++ case HCI_LK_UNAUTH_COMBINATION_P256: ++ /* An unauthenticated combination key has sufficient security ++ * for security level 2 or lower. ++ */ ++ if (sec_level <= BT_SECURITY_MEDIUM) ++ goto encrypt; ++ break; ++ case HCI_LK_COMBINATION: ++ /* A combination key has always sufficient security for the ++ * security levels 2 or lower. High security level requires the ++ * combination key is generated using maximum PIN code length ++ * (16). For pre 2.1 units. ++ */ ++ if (sec_level <= BT_SECURITY_MEDIUM || conn->pin_length == 16) ++ goto encrypt; ++ break; ++ default: ++ break; ++ } + + auth: + if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) +-- +2.40.1 + diff --git a/queue-5.15/bluetooth-btusb-add-shutdown-function-for-qca6174.patch b/queue-5.15/bluetooth-btusb-add-shutdown-function-for-qca6174.patch new file mode 100644 index 00000000000..fd22b15447e --- /dev/null +++ b/queue-5.15/bluetooth-btusb-add-shutdown-function-for-qca6174.patch @@ -0,0 +1,34 @@ +From 16a153afd5346c99c632329f7c636d1d7aa45743 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Aug 2023 14:46:26 +0800 +Subject: Bluetooth: btusb: add shutdown function for QCA6174 + +From: Rocky Liao + +[ Upstream commit 187f8b648cc16f07c66ab1d89d961bdcff779bf7 ] + +We should send hci reset command before bt turn off, which can reset bt +firmware status. + +Signed-off-by: Rocky Liao +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 84a42348b3bcb..c01d02f41bcb3 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -3949,6 +3949,7 @@ static int btusb_probe(struct usb_interface *intf, + + if (id->driver_info & BTUSB_QCA_ROME) { + data->setup_on_usb = btusb_setup_qca; ++ hdev->shutdown = btusb_shutdown_qca; + hdev->set_bdaddr = btusb_set_bdaddr_ath3012; + hdev->cmd_timeout = btusb_qca_cmd_timeout; + set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); +-- +2.40.1 + diff --git a/queue-5.15/bluetooth-hci_core-fix-build-warnings.patch b/queue-5.15/bluetooth-hci_core-fix-build-warnings.patch new file mode 100644 index 00000000000..26140f73e3c --- /dev/null +++ b/queue-5.15/bluetooth-hci_core-fix-build-warnings.patch @@ -0,0 +1,78 @@ +From 273a769845621869f26e2f85d3bac59de4115320 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 14:42:27 -0700 +Subject: Bluetooth: hci_core: Fix build warnings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Luiz Augusto von Dentz + +[ Upstream commit dcda165706b9fbfd685898d46a6749d7d397e0c0 ] + +This fixes the following warnings: + +net/bluetooth/hci_core.c: In function ‘hci_register_dev’: +net/bluetooth/hci_core.c:2620:54: warning: ‘%d’ directive output may +be truncated writing between 1 and 10 bytes into a region of size 5 +[-Wformat-truncation=] + 2620 | snprintf(hdev->name, sizeof(hdev->name), "hci%d", id); + | ^~ +net/bluetooth/hci_core.c:2620:50: note: directive argument in the range +[0, 2147483647] + 2620 | snprintf(hdev->name, sizeof(hdev->name), "hci%d", id); + | ^~~~~~~ +net/bluetooth/hci_core.c:2620:9: note: ‘snprintf’ output between 5 and +14 bytes into a destination of size 8 + 2620 | snprintf(hdev->name, sizeof(hdev->name), "hci%d", id); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + include/net/bluetooth/hci_core.h | 2 +- + net/bluetooth/hci_core.c | 8 +++++--- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index 3da5cfcf84c1d..1f718e91509f4 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -310,7 +310,7 @@ struct hci_dev { + struct list_head list; + struct mutex lock; + +- char name[8]; ++ const char *name; + unsigned long flags; + __u16 id; + __u8 bus; +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index e777ccf76b2b7..b3b597960c562 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -3920,7 +3920,11 @@ int hci_register_dev(struct hci_dev *hdev) + if (id < 0) + return id; + +- snprintf(hdev->name, sizeof(hdev->name), "hci%d", id); ++ error = dev_set_name(&hdev->dev, "hci%u", id); ++ if (error) ++ return error; ++ ++ hdev->name = dev_name(&hdev->dev); + hdev->id = id; + + BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); +@@ -3942,8 +3946,6 @@ int hci_register_dev(struct hci_dev *hdev) + if (!IS_ERR_OR_NULL(bt_debugfs)) + hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); + +- dev_set_name(&hdev->dev, "%s", hdev->name); +- + error = device_add(&hdev->dev); + if (error < 0) + goto err_wqueue; +-- +2.40.1 + diff --git a/queue-5.15/bluetooth-hci_event-fix-using-memcmp-when-comparing-.patch b/queue-5.15/bluetooth-hci_event-fix-using-memcmp-when-comparing-.patch new file mode 100644 index 00000000000..de61c2ce0fe --- /dev/null +++ b/queue-5.15/bluetooth-hci_event-fix-using-memcmp-when-comparing-.patch @@ -0,0 +1,74 @@ +From aecb48fe89a20235bdc1c64fcb126b429d5e1665 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Oct 2023 13:59:59 -0700 +Subject: Bluetooth: hci_event: Fix using memcmp when comparing keys + +From: Luiz Augusto von Dentz + +[ Upstream commit b541260615f601ae1b5d6d0cc54e790de706303b ] + +memcmp is not consider safe to use with cryptographic secrets: + + 'Do not use memcmp() to compare security critical data, such as + cryptographic secrets, because the required CPU time depends on the + number of equal bytes.' + +While usage of memcmp for ZERO_KEY may not be considered a security +critical data, it can lead to more usage of memcmp with pairing keys +which could introduce more security problems. + +Fixes: 455c2ff0a558 ("Bluetooth: Fix BR/EDR out-of-band pairing with only initiator data") +Fixes: 33155c4aae52 ("Bluetooth: hci_event: Ignore NULL link key") +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_event.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c +index d6807c13a9b25..1dd65f13f8930 100644 +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -25,6 +25,8 @@ + /* Bluetooth HCI event handling. */ + + #include ++#include ++#include + + #include + #include +@@ -4184,7 +4186,7 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) + goto unlock; + + /* Ignore NULL link key against CVE-2020-26555 */ +- if (!memcmp(ev->link_key, ZERO_KEY, HCI_LINK_KEY_SIZE)) { ++ if (!crypto_memneq(ev->link_key, ZERO_KEY, HCI_LINK_KEY_SIZE)) { + bt_dev_dbg(hdev, "Ignore NULL link key (ZERO KEY) for %pMR", + &ev->bdaddr); + hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE); +@@ -4696,8 +4698,8 @@ static u8 bredr_oob_data_present(struct hci_conn *conn) + * available, then do not declare that OOB data is + * present. + */ +- if (!memcmp(data->rand256, ZERO_KEY, 16) || +- !memcmp(data->hash256, ZERO_KEY, 16)) ++ if (!crypto_memneq(data->rand256, ZERO_KEY, 16) || ++ !crypto_memneq(data->hash256, ZERO_KEY, 16)) + return 0x00; + + return 0x02; +@@ -4707,8 +4709,8 @@ static u8 bredr_oob_data_present(struct hci_conn *conn) + * not supported by the hardware, then check that if + * P-192 data values are present. + */ +- if (!memcmp(data->rand192, ZERO_KEY, 16) || +- !memcmp(data->hash192, ZERO_KEY, 16)) ++ if (!crypto_memneq(data->rand192, ZERO_KEY, 16) || ++ !crypto_memneq(data->hash192, ZERO_KEY, 16)) + return 0x00; + + return 0x01; +-- +2.40.1 + diff --git a/queue-5.15/btrfs-error-out-when-cowing-block-using-a-stale-tran.patch b/queue-5.15/btrfs-error-out-when-cowing-block-using-a-stale-tran.patch new file mode 100644 index 00000000000..eb38b23693a --- /dev/null +++ b/queue-5.15/btrfs-error-out-when-cowing-block-using-a-stale-tran.patch @@ -0,0 +1,83 @@ +From c488d9cdc20bfe56165ae22c89ba0c03763ca73c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 12:09:21 +0100 +Subject: btrfs: error out when COWing block using a stale transaction + +From: Filipe Manana + +[ Upstream commit 48774f3bf8b4dd3b1a0e155825c9ce48483db14c ] + +At btrfs_cow_block() we have these checks to verify we are not using a +stale transaction (a past transaction with an unblocked state or higher), +and the only thing we do is to trigger a WARN with a message and a stack +trace. This however is a critical problem, highly unexpected and if it +happens it's most likely due to a bug, so we should error out and turn the +fs into error state so that such issue is much more easily noticed if it's +triggered. + +The problem is critical because using such stale transaction will lead to +not persisting the extent buffer used for the COW operation, as allocating +a tree block adds the range of the respective extent buffer to the +->dirty_pages iotree of the transaction, and a stale transaction, in the +unlocked state or higher, will not flush dirty extent buffers anymore, +therefore resulting in not persisting the tree block and resource leaks +(not cleaning the dirty_pages iotree for example). + +So do the following changes: + +1) Return -EUCLEAN if we find a stale transaction; + +2) Turn the fs into error state, with error -EUCLEAN, so that no + transaction can be committed, and generate a stack trace; + +3) Combine both conditions into a single if statement, as both are related + and have the same error message; + +4) Mark the check as unlikely, since this is not expected to ever happen. + +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ctree.c | 24 ++++++++++++++++-------- + 1 file changed, 16 insertions(+), 8 deletions(-) + +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index a648dff2becec..8bc1166215138 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -549,14 +549,22 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, + btrfs_err(fs_info, + "COW'ing blocks on a fs root that's being dropped"); + +- if (trans->transaction != fs_info->running_transaction) +- WARN(1, KERN_CRIT "trans %llu running %llu\n", +- trans->transid, +- fs_info->running_transaction->transid); +- +- if (trans->transid != fs_info->generation) +- WARN(1, KERN_CRIT "trans %llu running %llu\n", +- trans->transid, fs_info->generation); ++ /* ++ * COWing must happen through a running transaction, which always ++ * matches the current fs generation (it's a transaction with a state ++ * less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs ++ * into error state to prevent the commit of any transaction. ++ */ ++ if (unlikely(trans->transaction != fs_info->running_transaction || ++ trans->transid != fs_info->generation)) { ++ btrfs_abort_transaction(trans, -EUCLEAN); ++ btrfs_crit(fs_info, ++"unexpected transaction when attempting to COW block %llu on root %llu, transaction %llu running transaction %llu fs generation %llu", ++ buf->start, btrfs_root_id(root), trans->transid, ++ fs_info->running_transaction->transid, ++ fs_info->generation); ++ return -EUCLEAN; ++ } + + if (!should_cow_block(trans, root, buf)) { + *cow_ret = buf; +-- +2.40.1 + diff --git a/queue-5.15/btrfs-error-out-when-reallocating-block-for-defrag-u.patch b/queue-5.15/btrfs-error-out-when-reallocating-block-for-defrag-u.patch new file mode 100644 index 00000000000..3b6668e513d --- /dev/null +++ b/queue-5.15/btrfs-error-out-when-reallocating-block-for-defrag-u.patch @@ -0,0 +1,78 @@ +From 1327d22e7737d7bd4c75fd1a3b019a2cd20253f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 12:09:23 +0100 +Subject: btrfs: error out when reallocating block for defrag using a stale + transaction + +From: Filipe Manana + +[ Upstream commit e36f94914021e58ee88a8856c7fdf35adf9c7ee1 ] + +At btrfs_realloc_node() we have these checks to verify we are not using a +stale transaction (a past transaction with an unblocked state or higher), +and the only thing we do is to trigger two WARN_ON(). This however is a +critical problem, highly unexpected and if it happens it's most likely due +to a bug, so we should error out and turn the fs into error state so that +such issue is much more easily noticed if it's triggered. + +The problem is critical because in btrfs_realloc_node() we COW tree blocks, +and using such stale transaction will lead to not persisting the extent +buffers used for the COW operations, as allocating tree block adds the +range of the respective extent buffers to the ->dirty_pages iotree of the +transaction, and a stale transaction, in the unlocked state or higher, +will not flush dirty extent buffers anymore, therefore resulting in not +persisting the tree block and resource leaks (not cleaning the dirty_pages +iotree for example). + +So do the following changes: + +1) Return -EUCLEAN if we find a stale transaction; + +2) Turn the fs into error state, with error -EUCLEAN, so that no + transaction can be committed, and generate a stack trace; + +3) Combine both conditions into a single if statement, as both are related + and have the same error message; + +4) Mark the check as unlikely, since this is not expected to ever happen. + +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ctree.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 8fe6aaa7b11fd..8b53313bf3b2c 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -680,8 +680,22 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, + int progress_passed = 0; + struct btrfs_disk_key disk_key; + +- WARN_ON(trans->transaction != fs_info->running_transaction); +- WARN_ON(trans->transid != fs_info->generation); ++ /* ++ * COWing must happen through a running transaction, which always ++ * matches the current fs generation (it's a transaction with a state ++ * less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs ++ * into error state to prevent the commit of any transaction. ++ */ ++ if (unlikely(trans->transaction != fs_info->running_transaction || ++ trans->transid != fs_info->generation)) { ++ btrfs_abort_transaction(trans, -EUCLEAN); ++ btrfs_crit(fs_info, ++"unexpected transaction when attempting to reallocate parent %llu for root %llu, transaction %llu running transaction %llu fs generation %llu", ++ parent->start, btrfs_root_id(root), trans->transid, ++ fs_info->running_transaction->transid, ++ fs_info->generation); ++ return -EUCLEAN; ++ } + + parent_nritems = btrfs_header_nritems(parent); + blocksize = fs_info->nodesize; +-- +2.40.1 + diff --git a/queue-5.15/btrfs-error-when-cowing-block-from-a-root-that-is-be.patch b/queue-5.15/btrfs-error-when-cowing-block-from-a-root-that-is-be.patch new file mode 100644 index 00000000000..ba54cf27615 --- /dev/null +++ b/queue-5.15/btrfs-error-when-cowing-block-from-a-root-that-is-be.patch @@ -0,0 +1,59 @@ +From bb042487f4f980d28a5ce2fa71bdb3183545bf2c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 12:09:22 +0100 +Subject: btrfs: error when COWing block from a root that is being deleted + +From: Filipe Manana + +[ Upstream commit a2caab29884397e583d09be6546259a83ebfbdb1 ] + +At btrfs_cow_block() we check if the block being COWed belongs to a root +that is being deleted and if so we log an error message. However this is +an unexpected case and it indicates a bug somewhere, so we should return +an error and abort the transaction. So change this in the following ways: + +1) Abort the transaction with -EUCLEAN, so that if the issue ever happens + it can easily be noticed; + +2) Change the logged message level from error to critical, and change the + message itself to print the block's logical address and the ID of the + root; + +3) Return -EUCLEAN to the caller; + +4) As this is an unexpected scenario, that should never happen, mark the + check as unlikely, allowing the compiler to potentially generate better + code. + +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ctree.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 8bc1166215138..8fe6aaa7b11fd 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -545,9 +545,13 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, + u64 search_start; + int ret; + +- if (test_bit(BTRFS_ROOT_DELETING, &root->state)) +- btrfs_err(fs_info, +- "COW'ing blocks on a fs root that's being dropped"); ++ if (unlikely(test_bit(BTRFS_ROOT_DELETING, &root->state))) { ++ btrfs_abort_transaction(trans, -EUCLEAN); ++ btrfs_crit(fs_info, ++ "attempt to COW block %llu on root %llu that is being deleted", ++ buf->start, btrfs_root_id(root)); ++ return -EUCLEAN; ++ } + + /* + * COWing must happen through a running transaction, which always +-- +2.40.1 + diff --git a/queue-5.15/btrfs-fix-some-wmaybe-uninitialized-warnings-in-ioct.patch b/queue-5.15/btrfs-fix-some-wmaybe-uninitialized-warnings-in-ioct.patch new file mode 100644 index 00000000000..1aa83b34274 --- /dev/null +++ b/queue-5.15/btrfs-fix-some-wmaybe-uninitialized-warnings-in-ioct.patch @@ -0,0 +1,106 @@ +From 359bdf9c5724a84966fcfea1263a8d266751d726 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 15:47:27 -0400 +Subject: btrfs: fix some -Wmaybe-uninitialized warnings in ioctl.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Josef Bacik + +[ Upstream commit 9147b9ded499d9853bdf0e9804b7eaa99c4429ed ] + +Jens reported the following warnings from -Wmaybe-uninitialized recent +Linus' branch. + + In file included from ./include/asm-generic/rwonce.h:26, + from ./arch/arm64/include/asm/rwonce.h:71, + from ./include/linux/compiler.h:246, + from ./include/linux/export.h:5, + from ./include/linux/linkage.h:7, + from ./include/linux/kernel.h:17, + from fs/btrfs/ioctl.c:6: + In function ‘instrument_copy_from_user_before’, + inlined from ‘_copy_from_user’ at ./include/linux/uaccess.h:148:3, + inlined from ‘copy_from_user’ at ./include/linux/uaccess.h:183:7, + inlined from ‘btrfs_ioctl_space_info’ at fs/btrfs/ioctl.c:2999:6, + inlined from ‘btrfs_ioctl’ at fs/btrfs/ioctl.c:4616:10: + ./include/linux/kasan-checks.h:38:27: warning: ‘space_args’ may be used + uninitialized [-Wmaybe-uninitialized] + 38 | #define kasan_check_write __kasan_check_write + ./include/linux/instrumented.h:129:9: note: in expansion of macro + ‘kasan_check_write’ + 129 | kasan_check_write(to, n); + | ^~~~~~~~~~~~~~~~~ + ./include/linux/kasan-checks.h: In function ‘btrfs_ioctl’: + ./include/linux/kasan-checks.h:20:6: note: by argument 1 of type ‘const + volatile void *’ to ‘__kasan_check_write’ declared here + 20 | bool __kasan_check_write(const volatile void *p, unsigned int + size); + | ^~~~~~~~~~~~~~~~~~~ + fs/btrfs/ioctl.c:2981:39: note: ‘space_args’ declared here + 2981 | struct btrfs_ioctl_space_args space_args; + | ^~~~~~~~~~ + In function ‘instrument_copy_from_user_before’, + inlined from ‘_copy_from_user’ at ./include/linux/uaccess.h:148:3, + inlined from ‘copy_from_user’ at ./include/linux/uaccess.h:183:7, + inlined from ‘_btrfs_ioctl_send’ at fs/btrfs/ioctl.c:4343:9, + inlined from ‘btrfs_ioctl’ at fs/btrfs/ioctl.c:4658:10: + ./include/linux/kasan-checks.h:38:27: warning: ‘args32’ may be used + uninitialized [-Wmaybe-uninitialized] + 38 | #define kasan_check_write __kasan_check_write + ./include/linux/instrumented.h:129:9: note: in expansion of macro + ‘kasan_check_write’ + 129 | kasan_check_write(to, n); + | ^~~~~~~~~~~~~~~~~ + ./include/linux/kasan-checks.h: In function ‘btrfs_ioctl’: + ./include/linux/kasan-checks.h:20:6: note: by argument 1 of type ‘const + volatile void *’ to ‘__kasan_check_write’ declared here + 20 | bool __kasan_check_write(const volatile void *p, unsigned int + size); + | ^~~~~~~~~~~~~~~~~~~ + fs/btrfs/ioctl.c:4341:49: note: ‘args32’ declared here + 4341 | struct btrfs_ioctl_send_args_32 args32; + | ^~~~~~ + +This was due to his config options and having KASAN turned on, +which adds some extra checks around copy_from_user(), which then +triggered the -Wmaybe-uninitialized checker for these cases. + +Fix the warnings by initializing the different structs we're copying +into. + +Reported-by: Jens Axboe +Signed-off-by: Josef Bacik +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ioctl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 33f4557d1a68c..dc9f4f80f90b6 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -3531,7 +3531,7 @@ static void get_block_group_info(struct list_head *groups_list, + static long btrfs_ioctl_space_info(struct btrfs_fs_info *fs_info, + void __user *arg) + { +- struct btrfs_ioctl_space_args space_args; ++ struct btrfs_ioctl_space_args space_args = { 0 }; + struct btrfs_ioctl_space_info space; + struct btrfs_ioctl_space_info *dest; + struct btrfs_ioctl_space_info *dest_orig; +@@ -4867,7 +4867,7 @@ static int _btrfs_ioctl_send(struct file *file, void __user *argp, bool compat) + + if (compat) { + #if defined(CONFIG_64BIT) && defined(CONFIG_COMPAT) +- struct btrfs_ioctl_send_args_32 args32; ++ struct btrfs_ioctl_send_args_32 args32 = { 0 }; + + ret = copy_from_user(&args32, argp, sizeof(args32)); + if (ret) +-- +2.40.1 + diff --git a/queue-5.15/btrfs-initialize-start_slot-in-btrfs_log_prealloc_ex.patch b/queue-5.15/btrfs-initialize-start_slot-in-btrfs_log_prealloc_ex.patch new file mode 100644 index 00000000000..6a2a9282be0 --- /dev/null +++ b/queue-5.15/btrfs-initialize-start_slot-in-btrfs_log_prealloc_ex.patch @@ -0,0 +1,57 @@ +From 4b027f20f28203720029c6411cab5767a0338872 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Sep 2023 12:15:24 -0400 +Subject: btrfs: initialize start_slot in btrfs_log_prealloc_extents +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Josef Bacik + +[ Upstream commit b4c639f699349880b7918b861e1bd360442ec450 ] + +Jens reported a compiler warning when using +CONFIG_CC_OPTIMIZE_FOR_SIZE=y that looks like this + + fs/btrfs/tree-log.c: In function ‘btrfs_log_prealloc_extents’: + fs/btrfs/tree-log.c:4828:23: warning: ‘start_slot’ may be used + uninitialized [-Wmaybe-uninitialized] + 4828 | ret = copy_items(trans, inode, dst_path, path, + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 4829 | start_slot, ins_nr, 1, 0); + | ~~~~~~~~~~~~~~~~~~~~~~~~~ + fs/btrfs/tree-log.c:4725:13: note: ‘start_slot’ was declared here + 4725 | int start_slot; + | ^~~~~~~~~~ + +The compiler is incorrect, as we only use this code when ins_len > 0, +and when ins_len > 0 we have start_slot properly initialized. However +we generally find the -Wmaybe-uninitialized warnings valuable, so +initialize start_slot to get rid of the warning. + +Reported-by: Jens Axboe +Tested-by: Jens Axboe +Signed-off-by: Josef Bacik +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/tree-log.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index 7c0c6fc0c536b..dcf0dd2093f58 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -4446,7 +4446,7 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, + struct extent_buffer *leaf; + int slot; + int ins_nr = 0; +- int start_slot; ++ int start_slot = 0; + int ret; + + if (!(inode->flags & BTRFS_INODE_PREALLOC)) +-- +2.40.1 + diff --git a/queue-5.15/btrfs-return-euclean-for-delayed-tree-ref-with-a-ref.patch b/queue-5.15/btrfs-return-euclean-for-delayed-tree-ref-with-a-ref.patch new file mode 100644 index 00000000000..e5645887f6f --- /dev/null +++ b/queue-5.15/btrfs-return-euclean-for-delayed-tree-ref-with-a-ref.patch @@ -0,0 +1,51 @@ +From 1ba3de289523b68f689dd1c887e73a575ec99a1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Sep 2023 18:20:23 +0100 +Subject: btrfs: return -EUCLEAN for delayed tree ref with a ref count not + equals to 1 + +From: Filipe Manana + +[ Upstream commit 1bf76df3fee56d6637718e267f7c34ed70d0c7dc ] + +When running a delayed tree reference, if we find a ref count different +from 1, we return -EIO. This isn't an IO error, as it indicates either a +bug in the delayed refs code or a memory corruption, so change the error +code from -EIO to -EUCLEAN. Also tag the branch as 'unlikely' as this is +not expected to ever happen, and change the error message to print the +tree block's bytenr without the parenthesis (and there was a missing space +between the 'block' word and the opening parenthesis), for consistency as +that's the style we used everywhere else. + +Reviewed-by: Josef Bacik +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/extent-tree.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 48f2de789b755..a19bdb3597405 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -1674,12 +1674,12 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, + parent = ref->parent; + ref_root = ref->root; + +- if (node->ref_mod != 1) { ++ if (unlikely(node->ref_mod != 1)) { + btrfs_err(trans->fs_info, +- "btree block(%llu) has %d references rather than 1: action %d ref_root %llu parent %llu", ++ "btree block %llu has %d references rather than 1: action %d ref_root %llu parent %llu", + node->bytenr, node->ref_mod, node->action, ref_root, + parent); +- return -EIO; ++ return -EUCLEAN; + } + if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { + BUG_ON(!extent_op || !extent_op->update_flags); +-- +2.40.1 + diff --git a/queue-5.15/devlink-make-devlink_register-to-be-void.patch b/queue-5.15/devlink-make-devlink_register-to-be-void.patch new file mode 100644 index 00000000000..670ae2f208e --- /dev/null +++ b/queue-5.15/devlink-make-devlink_register-to-be-void.patch @@ -0,0 +1,711 @@ +From 3fcd043424744c62b4b710d27b3a845ef1e4225b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Sep 2021 11:58:03 +0300 +Subject: devlink: Make devlink_register to be void + +From: Leon Romanovsky + +[ Upstream commit db4278c55fa53760893266538e86e638330b03bb ] + +devlink_register() can't fail and always returns success, but all drivers +are obligated to check returned status anyway. This adds a lot of boilerplate +code to handle impossible flow. + +Make devlink_register() void and simplify the drivers that use that +API call. + +Signed-off-by: Leon Romanovsky +Acked-by: Simon Horman +Acked-by: Vladimir Oltean # dsa +Reviewed-by: Jiri Pirko +Signed-off-by: David S. Miller +Stable-dep-of: 0288c3e709e5 ("ice: reset first in crash dump kernels") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c | 11 ++--------- + drivers/net/ethernet/cavium/liquidio/lio_main.c | 8 +------- + .../ethernet/freescale/dpaa2/dpaa2-eth-devlink.c | 13 +------------ + .../ethernet/hisilicon/hns3/hns3pf/hclge_devlink.c | 14 +------------- + .../hisilicon/hns3/hns3vf/hclgevf_devlink.c | 14 +------------- + drivers/net/ethernet/huawei/hinic/hinic_devlink.c | 4 ++-- + drivers/net/ethernet/huawei/hinic/hinic_devlink.h | 2 +- + drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 8 +------- + drivers/net/ethernet/intel/ice/ice_devlink.c | 12 ++---------- + drivers/net/ethernet/intel/ice/ice_devlink.h | 2 +- + drivers/net/ethernet/intel/ice/ice_main.c | 6 +----- + .../ethernet/marvell/octeontx2/af/rvu_devlink.c | 8 +------- + .../ethernet/marvell/octeontx2/nic/otx2_devlink.c | 8 +------- + .../ethernet/marvell/prestera/prestera_devlink.c | 6 +----- + drivers/net/ethernet/mellanox/mlx4/main.c | 5 +---- + drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 5 +---- + drivers/net/ethernet/mellanox/mlxsw/core.c | 8 ++------ + drivers/net/ethernet/mscc/ocelot_vsc7514.c | 6 +----- + drivers/net/ethernet/netronome/nfp/nfp_net_main.c | 6 +----- + .../net/ethernet/pensando/ionic/ionic_devlink.c | 7 +------ + drivers/net/ethernet/qlogic/qed/qed_devlink.c | 7 +------ + drivers/net/ethernet/ti/am65-cpsw-nuss.c | 9 +-------- + drivers/net/ethernet/ti/cpsw_new.c | 8 +------- + drivers/net/netdevsim/dev.c | 6 +----- + drivers/ptp/ptp_ocp.c | 7 +------ + drivers/staging/qlge/qlge_main.c | 6 +----- + include/net/devlink.h | 2 +- + net/core/devlink.c | 3 +-- + net/dsa/dsa2.c | 7 +------ + 29 files changed, 33 insertions(+), 175 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +index 2a80882971e3d..dc0851f709f52 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +@@ -805,12 +805,7 @@ int bnxt_dl_register(struct bnxt *bp) + bp->hwrm_spec_code > 0x10803) + bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY; + +- rc = devlink_register(dl); +- if (rc) { +- netdev_warn(bp->dev, "devlink_register failed. rc=%d\n", rc); +- goto err_dl_free; +- } +- ++ devlink_register(dl); + if (!BNXT_PF(bp)) + return 0; + +@@ -822,7 +817,7 @@ int bnxt_dl_register(struct bnxt *bp) + rc = devlink_port_register(dl, &bp->dl_port, bp->pf.port_id); + if (rc) { + netdev_err(bp->dev, "devlink_port_register failed\n"); +- goto err_dl_unreg; ++ goto err_dl_free; + } + + rc = bnxt_dl_params_register(bp); +@@ -833,8 +828,6 @@ int bnxt_dl_register(struct bnxt *bp) + + err_dl_port_unreg: + devlink_port_unregister(&bp->dl_port); +-err_dl_unreg: +- devlink_unregister(dl); + err_dl_free: + devlink_free(dl); + return rc; +diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c +index 443755729d793..cf4a9c6600800 100644 +--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c ++++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c +@@ -3778,13 +3778,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) + lio_devlink = devlink_priv(devlink); + lio_devlink->oct = octeon_dev; + +- if (devlink_register(devlink)) { +- devlink_free(devlink); +- dev_err(&octeon_dev->pci_dev->dev, +- "devlink registration failed\n"); +- goto setup_nic_dev_free; +- } +- ++ devlink_register(devlink); + octeon_dev->devlink = devlink; + octeon_dev->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY; + +diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-devlink.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-devlink.c +index 605a39f892b94..426926fb6fc6e 100644 +--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-devlink.c ++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-devlink.c +@@ -194,7 +194,6 @@ int dpaa2_eth_dl_register(struct dpaa2_eth_priv *priv) + struct net_device *net_dev = priv->net_dev; + struct device *dev = net_dev->dev.parent; + struct dpaa2_eth_devlink_priv *dl_priv; +- int err; + + priv->devlink = + devlink_alloc(&dpaa2_eth_devlink_ops, sizeof(*dl_priv), dev); +@@ -205,18 +204,8 @@ int dpaa2_eth_dl_register(struct dpaa2_eth_priv *priv) + dl_priv = devlink_priv(priv->devlink); + dl_priv->dpaa2_priv = priv; + +- err = devlink_register(priv->devlink); +- if (err) { +- dev_err(dev, "devlink_register() = %d\n", err); +- goto devlink_free; +- } +- ++ devlink_register(priv->devlink); + return 0; +- +-devlink_free: +- devlink_free(priv->devlink); +- +- return err; + } + + void dpaa2_eth_dl_unregister(struct dpaa2_eth_priv *priv) +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_devlink.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_devlink.c +index e4aad695abcc1..59b0ae7d59e01 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_devlink.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_devlink.c +@@ -109,7 +109,6 @@ int hclge_devlink_init(struct hclge_dev *hdev) + struct pci_dev *pdev = hdev->pdev; + struct hclge_devlink_priv *priv; + struct devlink *devlink; +- int ret; + + devlink = devlink_alloc(&hclge_devlink_ops, + sizeof(struct hclge_devlink_priv), &pdev->dev); +@@ -120,20 +119,9 @@ int hclge_devlink_init(struct hclge_dev *hdev) + priv->hdev = hdev; + hdev->devlink = devlink; + +- ret = devlink_register(devlink); +- if (ret) { +- dev_err(&pdev->dev, "failed to register devlink, ret = %d\n", +- ret); +- goto out_reg_fail; +- } +- ++ devlink_register(devlink); + devlink_reload_enable(devlink); +- + return 0; +- +-out_reg_fail: +- devlink_free(devlink); +- return ret; + } + + void hclge_devlink_uninit(struct hclge_dev *hdev) +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_devlink.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_devlink.c +index f478770299c6c..d60cc9426f701 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_devlink.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_devlink.c +@@ -110,7 +110,6 @@ int hclgevf_devlink_init(struct hclgevf_dev *hdev) + struct pci_dev *pdev = hdev->pdev; + struct hclgevf_devlink_priv *priv; + struct devlink *devlink; +- int ret; + + devlink = + devlink_alloc(&hclgevf_devlink_ops, +@@ -122,20 +121,9 @@ int hclgevf_devlink_init(struct hclgevf_dev *hdev) + priv->hdev = hdev; + hdev->devlink = devlink; + +- ret = devlink_register(devlink); +- if (ret) { +- dev_err(&pdev->dev, "failed to register devlink, ret = %d\n", +- ret); +- goto out_reg_fail; +- } +- ++ devlink_register(devlink); + devlink_reload_enable(devlink); +- + return 0; +- +-out_reg_fail: +- devlink_free(devlink); +- return ret; + } + + void hclgevf_devlink_uninit(struct hclgevf_dev *hdev) +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c +index 6e11ee339f12f..60ae8bfc5f69a 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c +@@ -303,11 +303,11 @@ void hinic_devlink_free(struct devlink *devlink) + devlink_free(devlink); + } + +-int hinic_devlink_register(struct hinic_devlink_priv *priv) ++void hinic_devlink_register(struct hinic_devlink_priv *priv) + { + struct devlink *devlink = priv_to_devlink(priv); + +- return devlink_register(devlink); ++ devlink_register(devlink); + } + + void hinic_devlink_unregister(struct hinic_devlink_priv *priv) +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_devlink.h b/drivers/net/ethernet/huawei/hinic/hinic_devlink.h +index 9e315011015c5..46760d607b9b0 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_devlink.h ++++ b/drivers/net/ethernet/huawei/hinic/hinic_devlink.h +@@ -110,7 +110,7 @@ struct host_image_st { + + struct devlink *hinic_devlink_alloc(struct device *dev); + void hinic_devlink_free(struct devlink *devlink); +-int hinic_devlink_register(struct hinic_devlink_priv *priv); ++void hinic_devlink_register(struct hinic_devlink_priv *priv); + void hinic_devlink_unregister(struct hinic_devlink_priv *priv); + + int hinic_health_reporters_create(struct hinic_devlink_priv *priv); +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +index 8b04d133b3c47..536ed7c290c73 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +@@ -753,13 +753,7 @@ static int init_pfhwdev(struct hinic_pfhwdev *pfhwdev) + return err; + } + +- err = hinic_devlink_register(hwdev->devlink_dev); +- if (err) { +- dev_err(&hwif->pdev->dev, "Failed to register devlink\n"); +- hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt); +- return err; +- } +- ++ hinic_devlink_register(hwdev->devlink_dev); + err = hinic_func_to_func_init(hwdev); + if (err) { + dev_err(&hwif->pdev->dev, "Failed to init mailbox\n"); +diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c +index 2ec5d5cb72803..43dca9ab57ec9 100644 +--- a/drivers/net/ethernet/intel/ice/ice_devlink.c ++++ b/drivers/net/ethernet/intel/ice/ice_devlink.c +@@ -499,19 +499,11 @@ struct ice_pf *ice_allocate_pf(struct device *dev) + * + * Return: zero on success or an error code on failure. + */ +-int ice_devlink_register(struct ice_pf *pf) ++void ice_devlink_register(struct ice_pf *pf) + { + struct devlink *devlink = priv_to_devlink(pf); +- struct device *dev = ice_pf_to_dev(pf); +- int err; + +- err = devlink_register(devlink); +- if (err) { +- dev_err(dev, "devlink registration failed: %d\n", err); +- return err; +- } +- +- return 0; ++ devlink_register(devlink); + } + + /** +diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.h b/drivers/net/ethernet/intel/ice/ice_devlink.h +index e30284ccbed4c..b7f9551e4fc44 100644 +--- a/drivers/net/ethernet/intel/ice/ice_devlink.h ++++ b/drivers/net/ethernet/intel/ice/ice_devlink.h +@@ -6,7 +6,7 @@ + + struct ice_pf *ice_allocate_pf(struct device *dev); + +-int ice_devlink_register(struct ice_pf *pf); ++void ice_devlink_register(struct ice_pf *pf); + void ice_devlink_unregister(struct ice_pf *pf); + int ice_devlink_create_pf_port(struct ice_pf *pf); + void ice_devlink_destroy_pf_port(struct ice_pf *pf); +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index d4c29e2562a1c..b742afafd90bb 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -4324,11 +4324,7 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + + pf->msg_enable = netif_msg_init(debug, ICE_DFLT_NETIF_M); + +- err = ice_devlink_register(pf); +- if (err) { +- dev_err(dev, "ice_devlink_register failed: %d\n", err); +- goto err_exit_unroll; +- } ++ ice_devlink_register(pf); + + #ifndef CONFIG_DYNAMIC_DEBUG + if (debug < -1) +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +index 274d3abe30eb4..de9562acd04b6 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +@@ -1510,13 +1510,7 @@ int rvu_register_dl(struct rvu *rvu) + return -ENOMEM; + } + +- err = devlink_register(dl); +- if (err) { +- dev_err(rvu->dev, "devlink register failed with error %d\n", err); +- devlink_free(dl); +- return err; +- } +- ++ devlink_register(dl); + rvu_dl = devlink_priv(dl); + rvu_dl->dl = dl; + rvu_dl->rvu = rvu; +diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c +index 7ac3ef2fa06a2..3de18f9433ae2 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c ++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c +@@ -108,13 +108,7 @@ int otx2_register_dl(struct otx2_nic *pfvf) + return -ENOMEM; + } + +- err = devlink_register(dl); +- if (err) { +- dev_err(pfvf->dev, "devlink register failed with error %d\n", err); +- devlink_free(dl); +- return err; +- } +- ++ devlink_register(dl); + otx2_dl = devlink_priv(dl); + otx2_dl->dl = dl; + otx2_dl->pfvf = pfvf; +diff --git a/drivers/net/ethernet/marvell/prestera/prestera_devlink.c b/drivers/net/ethernet/marvell/prestera/prestera_devlink.c +index 68b442eb6d694..5cca007a3e179 100644 +--- a/drivers/net/ethernet/marvell/prestera/prestera_devlink.c ++++ b/drivers/net/ethernet/marvell/prestera/prestera_devlink.c +@@ -412,11 +412,7 @@ int prestera_devlink_register(struct prestera_switch *sw) + struct devlink *dl = priv_to_devlink(sw); + int err; + +- err = devlink_register(dl); +- if (err) { +- dev_err(prestera_dev(sw), "devlink_register failed: %d\n", err); +- return err; +- } ++ devlink_register(dl); + + err = prestera_devlink_traps_register(sw); + if (err) { +diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c +index 5a6b0fcaf7f8a..27ed4694fbeac 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/main.c ++++ b/drivers/net/ethernet/mellanox/mlx4/main.c +@@ -4015,9 +4015,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) + mutex_init(&dev->persist->interface_state_mutex); + mutex_init(&dev->persist->pci_status_mutex); + +- ret = devlink_register(devlink); +- if (ret) +- goto err_persist_free; ++ devlink_register(devlink); + ret = devlink_params_register(devlink, mlx4_devlink_params, + ARRAY_SIZE(mlx4_devlink_params)); + if (ret) +@@ -4037,7 +4035,6 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) + ARRAY_SIZE(mlx4_devlink_params)); + err_devlink_unregister: + devlink_unregister(devlink); +-err_persist_free: + kfree(dev->persist); + err_devlink_free: + devlink_free(devlink); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +index 7d56a927081d0..b36f721625e45 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +@@ -793,10 +793,7 @@ int mlx5_devlink_register(struct devlink *devlink) + { + int err; + +- err = devlink_register(devlink); +- if (err) +- return err; +- ++ devlink_register(devlink); + err = devlink_params_register(devlink, mlx5_devlink_params, + ARRAY_SIZE(mlx5_devlink_params)); + if (err) +diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c +index f080fab3de2b5..2d5f82be3db0e 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/core.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/core.c +@@ -1974,11 +1974,8 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, + if (err) + goto err_emad_init; + +- if (!reload) { +- err = devlink_register(devlink); +- if (err) +- goto err_devlink_register; +- } ++ if (!reload) ++ devlink_register(devlink); + + if (!reload) { + err = mlxsw_core_params_register(mlxsw_core); +@@ -2038,7 +2035,6 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, + err_register_params: + if (!reload) + devlink_unregister(devlink); +-err_devlink_register: + mlxsw_emad_fini(mlxsw_core); + err_emad_init: + kfree(mlxsw_core->lag.mapping); +diff --git a/drivers/net/ethernet/mscc/ocelot_vsc7514.c b/drivers/net/ethernet/mscc/ocelot_vsc7514.c +index d51f799e4e861..a66e96ab24c71 100644 +--- a/drivers/net/ethernet/mscc/ocelot_vsc7514.c ++++ b/drivers/net/ethernet/mscc/ocelot_vsc7514.c +@@ -1135,10 +1135,7 @@ static int mscc_ocelot_probe(struct platform_device *pdev) + if (err) + goto out_put_ports; + +- err = devlink_register(devlink); +- if (err) +- goto out_ocelot_deinit; +- ++ devlink_register(devlink); + err = mscc_ocelot_init_ports(pdev, ports); + if (err) + goto out_ocelot_devlink_unregister; +@@ -1171,7 +1168,6 @@ static int mscc_ocelot_probe(struct platform_device *pdev) + mscc_ocelot_teardown_devlink_ports(ocelot); + out_ocelot_devlink_unregister: + devlink_unregister(devlink); +-out_ocelot_deinit: + ocelot_deinit(ocelot); + out_put_ports: + of_node_put(ports); +diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c +index 74c4bf4d397d8..6d3edeff1bb33 100644 +--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c ++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c +@@ -701,10 +701,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf) + if (err) + goto err_unmap; + +- err = devlink_register(devlink); +- if (err) +- goto err_app_clean; +- ++ devlink_register(devlink); + err = nfp_shared_buf_register(pf); + if (err) + goto err_devlink_unreg; +@@ -752,7 +749,6 @@ int nfp_net_pci_probe(struct nfp_pf *pf) + err_devlink_unreg: + cancel_work_sync(&pf->port_refresh_work); + devlink_unregister(devlink); +-err_app_clean: + nfp_net_pf_app_clean(pf); + err_unmap: + nfp_net_pci_unmap_mem(pf); +diff --git a/drivers/net/ethernet/pensando/ionic/ionic_devlink.c b/drivers/net/ethernet/pensando/ionic/ionic_devlink.c +index 5c06decc868c4..17b2060405513 100644 +--- a/drivers/net/ethernet/pensando/ionic/ionic_devlink.c ++++ b/drivers/net/ethernet/pensando/ionic/ionic_devlink.c +@@ -84,12 +84,7 @@ int ionic_devlink_register(struct ionic *ionic) + struct devlink_port_attrs attrs = {}; + int err; + +- err = devlink_register(dl); +- if (err) { +- dev_warn(ionic->dev, "devlink_register failed: %d\n", err); +- return err; +- } +- ++ devlink_register(dl); + attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; + devlink_port_attrs_set(&ionic->dl_port, &attrs); + err = devlink_port_register(dl, &ionic->dl_port, 0); +diff --git a/drivers/net/ethernet/qlogic/qed/qed_devlink.c b/drivers/net/ethernet/qlogic/qed/qed_devlink.c +index 78070682f2dff..c51f9590fe193 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_devlink.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_devlink.c +@@ -215,10 +215,7 @@ struct devlink *qed_devlink_register(struct qed_dev *cdev) + qdevlink = devlink_priv(dl); + qdevlink->cdev = cdev; + +- rc = devlink_register(dl); +- if (rc) +- goto err_free; +- ++ devlink_register(dl); + rc = devlink_params_register(dl, qed_devlink_params, + ARRAY_SIZE(qed_devlink_params)); + if (rc) +@@ -238,8 +235,6 @@ struct devlink *qed_devlink_register(struct qed_dev *cdev) + + err_unregister: + devlink_unregister(dl); +- +-err_free: + devlink_free(dl); + + return ERR_PTR(rc); +diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +index 4aa9477ac5977..3cf3befc8576c 100644 +--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c ++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c +@@ -2441,12 +2441,7 @@ static int am65_cpsw_nuss_register_devlink(struct am65_cpsw_common *common) + dl_priv = devlink_priv(common->devlink); + dl_priv->common = common; + +- ret = devlink_register(common->devlink); +- if (ret) { +- dev_err(dev, "devlink reg fail ret:%d\n", ret); +- goto dl_free; +- } +- ++ devlink_register(common->devlink); + /* Provide devlink hook to switch mode when multiple external ports + * are present NUSS switchdev driver is enabled. + */ +@@ -2491,9 +2486,7 @@ static int am65_cpsw_nuss_register_devlink(struct am65_cpsw_common *common) + } + dl_unreg: + devlink_unregister(common->devlink); +-dl_free: + devlink_free(common->devlink); +- + return ret; + } + +diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c +index 0d921f6542d6f..9c87f857e2859 100644 +--- a/drivers/net/ethernet/ti/cpsw_new.c ++++ b/drivers/net/ethernet/ti/cpsw_new.c +@@ -1813,12 +1813,7 @@ static int cpsw_register_devlink(struct cpsw_common *cpsw) + dl_priv = devlink_priv(cpsw->devlink); + dl_priv->cpsw = cpsw; + +- ret = devlink_register(cpsw->devlink); +- if (ret) { +- dev_err(dev, "DL reg fail ret:%d\n", ret); +- goto dl_free; +- } +- ++ devlink_register(cpsw->devlink); + ret = devlink_params_register(cpsw->devlink, cpsw_devlink_params, + ARRAY_SIZE(cpsw_devlink_params)); + if (ret) { +@@ -1831,7 +1826,6 @@ static int cpsw_register_devlink(struct cpsw_common *cpsw) + + dl_unreg: + devlink_unregister(cpsw->devlink); +-dl_free: + devlink_free(cpsw->devlink); + return ret; + } +diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c +index a7279356299af..0c6bfe00b6983 100644 +--- a/drivers/net/netdevsim/dev.c ++++ b/drivers/net/netdevsim/dev.c +@@ -1470,10 +1470,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev) + if (err) + goto err_devlink_free; + +- err = devlink_register(devlink); +- if (err) +- goto err_resources_unregister; +- ++ devlink_register(devlink); + err = devlink_params_register(devlink, nsim_devlink_params, + ARRAY_SIZE(nsim_devlink_params)); + if (err) +@@ -1538,7 +1535,6 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev) + ARRAY_SIZE(nsim_devlink_params)); + err_dl_unregister: + devlink_unregister(devlink); +-err_resources_unregister: + devlink_resources_unregister(devlink, NULL); + err_devlink_free: + devlink_free(devlink); +diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c +index 7a4a06148515a..5120d3d8cca4e 100644 +--- a/drivers/ptp/ptp_ocp.c ++++ b/drivers/ptp/ptp_ocp.c +@@ -1425,10 +1425,7 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id) + return -ENOMEM; + } + +- err = devlink_register(devlink); +- if (err) +- goto out_free; +- ++ devlink_register(devlink); + err = pci_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "pci_enable_device\n"); +@@ -1481,9 +1478,7 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id) + pci_disable_device(pdev); + out_unregister: + devlink_unregister(devlink); +-out_free: + devlink_free(devlink); +- + return err; + } + +diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c +index 8fcdf89da8aa9..33539f6c254d8 100644 +--- a/drivers/staging/qlge/qlge_main.c ++++ b/drivers/staging/qlge/qlge_main.c +@@ -4614,12 +4614,8 @@ static int qlge_probe(struct pci_dev *pdev, + goto netdev_free; + } + +- err = devlink_register(devlink); +- if (err) +- goto netdev_free; +- ++ devlink_register(devlink); + err = qlge_health_create_reporters(qdev); +- + if (err) + goto devlink_unregister; + +diff --git a/include/net/devlink.h b/include/net/devlink.h +index 154cf0dbca372..3c023fd515634 100644 +--- a/include/net/devlink.h ++++ b/include/net/devlink.h +@@ -1566,7 +1566,7 @@ static inline struct devlink *devlink_alloc(const struct devlink_ops *ops, + { + return devlink_alloc_ns(ops, priv_size, &init_net, dev); + } +-int devlink_register(struct devlink *devlink); ++void devlink_register(struct devlink *devlink); + void devlink_unregister(struct devlink *devlink); + void devlink_reload_enable(struct devlink *devlink); + void devlink_reload_disable(struct devlink *devlink); +diff --git a/net/core/devlink.c b/net/core/devlink.c +index db76c55e1a6d7..3ff210c9dc5e1 100644 +--- a/net/core/devlink.c ++++ b/net/core/devlink.c +@@ -8961,13 +8961,12 @@ EXPORT_SYMBOL_GPL(devlink_alloc_ns); + * + * @devlink: devlink + */ +-int devlink_register(struct devlink *devlink) ++void devlink_register(struct devlink *devlink) + { + mutex_lock(&devlink_mutex); + xa_set_mark(&devlinks, devlink->index, DEVLINK_REGISTERED); + devlink_notify(devlink, DEVLINK_CMD_NEW); + mutex_unlock(&devlink_mutex); +- return 0; + } + EXPORT_SYMBOL_GPL(devlink_register); + +diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c +index 34763f575c308..711eeee885f93 100644 +--- a/net/dsa/dsa2.c ++++ b/net/dsa/dsa2.c +@@ -850,10 +850,7 @@ static int dsa_switch_setup(struct dsa_switch *ds) + dl_priv = devlink_priv(ds->devlink); + dl_priv->ds = ds; + +- err = devlink_register(ds->devlink); +- if (err) +- goto free_devlink; +- ++ devlink_register(ds->devlink); + /* Setup devlink port instances now, so that the switch + * setup() can register regions etc, against the ports + */ +@@ -912,10 +909,8 @@ static int dsa_switch_setup(struct dsa_switch *ds) + if (dp->ds == ds) + dsa_port_devlink_teardown(dp); + devlink_unregister(ds->devlink); +-free_devlink: + devlink_free(ds->devlink); + ds->devlink = NULL; +- + return err; + } + +-- +2.40.1 + diff --git a/queue-5.15/drm-atomic-helper-relax-unregistered-connector-check.patch b/queue-5.15/drm-atomic-helper-relax-unregistered-connector-check.patch new file mode 100644 index 00000000000..50e3e14d3da --- /dev/null +++ b/queue-5.15/drm-atomic-helper-relax-unregistered-connector-check.patch @@ -0,0 +1,95 @@ +From 07d5dedb1e7c2b60371560a965a85fa9b0863ca7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Oct 2023 13:16:32 +0000 +Subject: drm/atomic-helper: relax unregistered connector check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Simon Ser + +[ Upstream commit 2b7947bd32e243c52870d54141d3b4ea6775e63d ] + +The driver might pull connectors which weren't submitted by +user-space into the atomic state. For instance, +intel_dp_mst_atomic_master_trans_check() pulls in connectors +sharing the same DP-MST stream. However, if the connector is +unregistered, this later fails with: + + [ 559.425658] i915 0000:00:02.0: [drm:drm_atomic_helper_check_modeset] [CONNECTOR:378:DP-7] is not registered + +Skip the unregistered connector check to allow user-space to turn +off connectors one-by-one. + +See this wlroots issue: +https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3407 + +Previous discussion: +https://lore.kernel.org/intel-gfx/Y6GX7z17WmDSKwta@ideak-desk.fi.intel.com/ + +Signed-off-by: Simon Ser +Cc: stable@vger.kernel.org +Reviewed-by: Ville Syrjälä +Reviewed-by: Lyude Paul +Cc: Jani Nikula +Cc: Imre Deak +Link: https://patchwork.freedesktop.org/patch/msgid/20231005131623.114379-1-contact@emersion.fr +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_atomic_helper.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c +index d0a8c22cbc4b8..070248597d27c 100644 +--- a/drivers/gpu/drm/drm_atomic_helper.c ++++ b/drivers/gpu/drm/drm_atomic_helper.c +@@ -289,7 +289,8 @@ static int + update_connector_routing(struct drm_atomic_state *state, + struct drm_connector *connector, + struct drm_connector_state *old_connector_state, +- struct drm_connector_state *new_connector_state) ++ struct drm_connector_state *new_connector_state, ++ bool added_by_user) + { + const struct drm_connector_helper_funcs *funcs; + struct drm_encoder *new_encoder; +@@ -338,9 +339,13 @@ update_connector_routing(struct drm_atomic_state *state, + * there's a chance the connector may have been destroyed during the + * process, but it's better to ignore that then cause + * drm_atomic_helper_resume() to fail. ++ * ++ * Last, we want to ignore connector registration when the connector ++ * was not pulled in the atomic state by user-space (ie, was pulled ++ * in by the driver, e.g. when updating a DP-MST stream). + */ + if (!state->duplicated && drm_connector_is_unregistered(connector) && +- crtc_state->active) { ++ added_by_user && crtc_state->active) { + drm_dbg_atomic(connector->dev, + "[CONNECTOR:%d:%s] is not registered\n", + connector->base.id, connector->name); +@@ -619,7 +624,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, + struct drm_connector *connector; + struct drm_connector_state *old_connector_state, *new_connector_state; + int i, ret; +- unsigned int connectors_mask = 0; ++ unsigned int connectors_mask = 0, user_connectors_mask = 0; ++ ++ for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) ++ user_connectors_mask |= BIT(i); + + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + bool has_connectors = +@@ -684,7 +692,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, + */ + ret = update_connector_routing(state, connector, + old_connector_state, +- new_connector_state); ++ new_connector_state, ++ BIT(i) & user_connectors_mask); + if (ret) + return ret; + if (old_connector_state->crtc) { +-- +2.40.1 + diff --git a/queue-5.15/drm-get-rid-of-drm_debug_-log-calls-in-drm-core-file.patch b/queue-5.15/drm-get-rid-of-drm_debug_-log-calls-in-drm-core-file.patch new file mode 100644 index 00000000000..9c4b7f197c8 --- /dev/null +++ b/queue-5.15/drm-get-rid-of-drm_debug_-log-calls-in-drm-core-file.patch @@ -0,0 +1,1070 @@ +From d2acead229b0b87efbeaf67e490b7a159c84872e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Nov 2021 11:49:49 +0100 +Subject: drm: get rid of DRM_DEBUG_* log calls in drm core, files drm_a*.c + +From: Claudio Suarez + +[ Upstream commit 6e22dc35837790a84fc040f08e5094b2d5d91477 ] + +DRM_DEBUG_* and DRM_* log calls are deprecated. +Change them to drm_dbg_* / drm_{err,info,...} calls in drm core +files. + +To avoid making a very big patch, this change is split in +smaller patches. This one includes drm_a*.c + +Signed-off-by: Claudio Suarez +Signed-off-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/YaC7zXW119tlzfVh@gineta.localdomain +Stable-dep-of: 2b7947bd32e2 ("drm/atomic-helper: relax unregistered connector check") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_atomic.c | 180 +++++++++++---------- + drivers/gpu/drm/drm_atomic_helper.c | 243 +++++++++++++++------------- + drivers/gpu/drm/drm_atomic_uapi.c | 2 +- + drivers/gpu/drm/drm_auth.c | 12 +- + 4 files changed, 242 insertions(+), 195 deletions(-) + +diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c +index 166d329de9397..e4ed4989a5dba 100644 +--- a/drivers/gpu/drm/drm_atomic.c ++++ b/drivers/gpu/drm/drm_atomic.c +@@ -74,7 +74,7 @@ int drm_crtc_commit_wait(struct drm_crtc_commit *commit) + + ret = wait_for_completion_timeout(&commit->hw_done, timeout); + if (!ret) { +- DRM_ERROR("hw_done timed out\n"); ++ drm_err(commit->crtc->dev, "hw_done timed out\n"); + return -ETIMEDOUT; + } + +@@ -84,7 +84,7 @@ int drm_crtc_commit_wait(struct drm_crtc_commit *commit) + */ + ret = wait_for_completion_timeout(&commit->flip_done, timeout); + if (!ret) { +- DRM_ERROR("flip_done timed out\n"); ++ drm_err(commit->crtc->dev, "flip_done timed out\n"); + return -ETIMEDOUT; + } + +@@ -146,7 +146,7 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state) + drm_dev_get(dev); + state->dev = dev; + +- DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state); ++ drm_dbg_atomic(dev, "Allocated atomic state %p\n", state); + + return 0; + fail: +@@ -197,7 +197,7 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state) + struct drm_mode_config *config = &dev->mode_config; + int i; + +- DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state); ++ drm_dbg_atomic(dev, "Clearing atomic state %p\n", state); + + for (i = 0; i < state->num_connector; i++) { + struct drm_connector *connector = state->connectors[i].ptr; +@@ -308,7 +308,7 @@ void __drm_atomic_state_free(struct kref *ref) + + drm_atomic_state_clear(state); + +- DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state); ++ drm_dbg_atomic(state->dev, "Freeing atomic state %p\n", state); + + if (config->funcs->atomic_state_free) { + config->funcs->atomic_state_free(state); +@@ -367,8 +367,8 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state, + state->crtcs[index].ptr = crtc; + crtc_state->state = state; + +- DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n", +- crtc->base.id, crtc->name, crtc_state, state); ++ drm_dbg_atomic(state->dev, "Added [CRTC:%d:%s] %p state to %p\n", ++ crtc->base.id, crtc->name, crtc_state, state); + + return crtc_state; + } +@@ -388,8 +388,9 @@ static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state, + */ + + if (new_crtc_state->active && !new_crtc_state->enable) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active without enabled\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(crtc->dev, ++ "[CRTC:%d:%s] active without enabled\n", ++ crtc->base.id, crtc->name); + return -EINVAL; + } + +@@ -399,15 +400,17 @@ static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state, + */ + if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) && + WARN_ON(new_crtc_state->enable && !new_crtc_state->mode_blob)) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled without mode blob\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(crtc->dev, ++ "[CRTC:%d:%s] enabled without mode blob\n", ++ crtc->base.id, crtc->name); + return -EINVAL; + } + + if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) && + WARN_ON(!new_crtc_state->enable && new_crtc_state->mode_blob)) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled with mode blob\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(crtc->dev, ++ "[CRTC:%d:%s] disabled with mode blob\n", ++ crtc->base.id, crtc->name); + return -EINVAL; + } + +@@ -423,8 +426,9 @@ static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state, + */ + if (new_crtc_state->event && + !new_crtc_state->active && !old_crtc_state->active) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requesting event but off\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(crtc->dev, ++ "[CRTC:%d:%s] requesting event but off\n", ++ crtc->base.id, crtc->name); + return -EINVAL; + } + +@@ -469,8 +473,9 @@ static int drm_atomic_connector_check(struct drm_connector *connector, + return 0; + + if (writeback_job->fb && !state->crtc) { +- DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] framebuffer without CRTC\n", +- connector->base.id, connector->name); ++ drm_dbg_atomic(connector->dev, ++ "[CONNECTOR:%d:%s] framebuffer without CRTC\n", ++ connector->base.id, connector->name); + return -EINVAL; + } + +@@ -479,16 +484,18 @@ static int drm_atomic_connector_check(struct drm_connector *connector, + state->crtc); + + if (writeback_job->fb && !crtc_state->active) { +- DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] has framebuffer, but [CRTC:%d] is off\n", +- connector->base.id, connector->name, +- state->crtc->base.id); ++ drm_dbg_atomic(connector->dev, ++ "[CONNECTOR:%d:%s] has framebuffer, but [CRTC:%d] is off\n", ++ connector->base.id, connector->name, ++ state->crtc->base.id); + return -EINVAL; + } + + if (!writeback_job->fb) { + if (writeback_job->out_fence) { +- DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] requesting out-fence without framebuffer\n", +- connector->base.id, connector->name); ++ drm_dbg_atomic(connector->dev, ++ "[CONNECTOR:%d:%s] requesting out-fence without framebuffer\n", ++ connector->base.id, connector->name); + return -EINVAL; + } + +@@ -546,8 +553,8 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state, + state->planes[index].new_state = plane_state; + plane_state->state = state; + +- DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n", +- plane->base.id, plane->name, plane_state, state); ++ drm_dbg_atomic(plane->dev, "Added [PLANE:%d:%s] %p state to %p\n", ++ plane->base.id, plane->name, plane_state, state); + + if (plane_state->crtc) { + struct drm_crtc_state *crtc_state; +@@ -603,12 +610,12 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, + + /* either *both* CRTC and FB must be set, or neither */ + if (crtc && !fb) { +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] CRTC set but no FB\n", +- plane->base.id, plane->name); ++ drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no FB\n", ++ plane->base.id, plane->name); + return -EINVAL; + } else if (fb && !crtc) { +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] FB set but no CRTC\n", +- plane->base.id, plane->name); ++ drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] FB set but no CRTC\n", ++ plane->base.id, plane->name); + return -EINVAL; + } + +@@ -618,9 +625,10 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, + + /* Check whether this plane is usable on this CRTC */ + if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) { +- DRM_DEBUG_ATOMIC("Invalid [CRTC:%d:%s] for [PLANE:%d:%s]\n", +- crtc->base.id, crtc->name, +- plane->base.id, plane->name); ++ drm_dbg_atomic(plane->dev, ++ "Invalid [CRTC:%d:%s] for [PLANE:%d:%s]\n", ++ crtc->base.id, crtc->name, ++ plane->base.id, plane->name); + return -EINVAL; + } + +@@ -628,9 +636,10 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, + ret = drm_plane_check_pixel_format(plane, fb->format->format, + fb->modifier); + if (ret) { +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n", +- plane->base.id, plane->name, +- &fb->format->format, fb->modifier); ++ drm_dbg_atomic(plane->dev, ++ "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n", ++ plane->base.id, plane->name, ++ &fb->format->format, fb->modifier); + return ret; + } + +@@ -639,10 +648,11 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, + new_plane_state->crtc_x > INT_MAX - (int32_t) new_plane_state->crtc_w || + new_plane_state->crtc_h > INT_MAX || + new_plane_state->crtc_y > INT_MAX - (int32_t) new_plane_state->crtc_h) { +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid CRTC coordinates %ux%u+%d+%d\n", +- plane->base.id, plane->name, +- new_plane_state->crtc_w, new_plane_state->crtc_h, +- new_plane_state->crtc_x, new_plane_state->crtc_y); ++ drm_dbg_atomic(plane->dev, ++ "[PLANE:%d:%s] invalid CRTC coordinates %ux%u+%d+%d\n", ++ plane->base.id, plane->name, ++ new_plane_state->crtc_w, new_plane_state->crtc_h, ++ new_plane_state->crtc_x, new_plane_state->crtc_y); + return -ERANGE; + } + +@@ -654,18 +664,19 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, + new_plane_state->src_x > fb_width - new_plane_state->src_w || + new_plane_state->src_h > fb_height || + new_plane_state->src_y > fb_height - new_plane_state->src_h) { +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid source coordinates " +- "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n", +- plane->base.id, plane->name, +- new_plane_state->src_w >> 16, +- ((new_plane_state->src_w & 0xffff) * 15625) >> 10, +- new_plane_state->src_h >> 16, +- ((new_plane_state->src_h & 0xffff) * 15625) >> 10, +- new_plane_state->src_x >> 16, +- ((new_plane_state->src_x & 0xffff) * 15625) >> 10, +- new_plane_state->src_y >> 16, +- ((new_plane_state->src_y & 0xffff) * 15625) >> 10, +- fb->width, fb->height); ++ drm_dbg_atomic(plane->dev, ++ "[PLANE:%d:%s] invalid source coordinates " ++ "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n", ++ plane->base.id, plane->name, ++ new_plane_state->src_w >> 16, ++ ((new_plane_state->src_w & 0xffff) * 15625) >> 10, ++ new_plane_state->src_h >> 16, ++ ((new_plane_state->src_h & 0xffff) * 15625) >> 10, ++ new_plane_state->src_x >> 16, ++ ((new_plane_state->src_x & 0xffff) * 15625) >> 10, ++ new_plane_state->src_y >> 16, ++ ((new_plane_state->src_y & 0xffff) * 15625) >> 10, ++ fb->width, fb->height); + return -ENOSPC; + } + +@@ -680,9 +691,10 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, + clips->y1 < 0 || + clips->x2 > fb_width || + clips->y2 > fb_height) { +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid damage clip %d %d %d %d\n", +- plane->base.id, plane->name, clips->x1, +- clips->y1, clips->x2, clips->y2); ++ drm_dbg_atomic(plane->dev, ++ "[PLANE:%d:%s] invalid damage clip %d %d %d %d\n", ++ plane->base.id, plane->name, clips->x1, ++ clips->y1, clips->x2, clips->y2); + return -EINVAL; + } + clips++; +@@ -690,8 +702,9 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state, + } + + if (plane_switching_crtc(old_plane_state, new_plane_state)) { +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] switching CRTC directly\n", +- plane->base.id, plane->name); ++ drm_dbg_atomic(plane->dev, ++ "[PLANE:%d:%s] switching CRTC directly\n", ++ plane->base.id, plane->name); + return -EINVAL; + } + +@@ -855,8 +868,9 @@ drm_atomic_get_private_obj_state(struct drm_atomic_state *state, + + state->num_private_objs = num_objs; + +- DRM_DEBUG_ATOMIC("Added new private object %p state %p to %p\n", +- obj, obj_state, state); ++ drm_dbg_atomic(state->dev, ++ "Added new private object %p state %p to %p\n", ++ obj, obj_state, state); + + return obj_state; + } +@@ -1036,7 +1050,7 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, + state->connectors[index].ptr = connector; + connector_state->state = state; + +- DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d:%s] %p state to %p\n", ++ drm_dbg_atomic(connector->dev, "Added [CONNECTOR:%d:%s] %p state to %p\n", + connector->base.id, connector->name, + connector_state, state); + +@@ -1170,8 +1184,9 @@ drm_atomic_add_encoder_bridges(struct drm_atomic_state *state, + if (!encoder) + return 0; + +- DRM_DEBUG_ATOMIC("Adding all bridges for [encoder:%d:%s] to %p\n", +- encoder->base.id, encoder->name, state); ++ drm_dbg_atomic(encoder->dev, ++ "Adding all bridges for [encoder:%d:%s] to %p\n", ++ encoder->base.id, encoder->name, state); + + drm_for_each_bridge_in_chain(encoder, bridge) { + /* Skip bridges that don't implement the atomic state hooks. */ +@@ -1223,8 +1238,9 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state, + if (ret) + return ret; + +- DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d:%s] to %p\n", +- crtc->base.id, crtc->name, state); ++ drm_dbg_atomic(crtc->dev, ++ "Adding all current connectors for [CRTC:%d:%s] to %p\n", ++ crtc->base.id, crtc->name, state); + + /* + * Changed connectors are already in @state, so only need to look +@@ -1277,8 +1293,9 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state, + + WARN_ON(!drm_atomic_get_new_crtc_state(state, crtc)); + +- DRM_DEBUG_ATOMIC("Adding all current planes for [CRTC:%d:%s] to %p\n", +- crtc->base.id, crtc->name, state); ++ drm_dbg_atomic(crtc->dev, ++ "Adding all current planes for [CRTC:%d:%s] to %p\n", ++ crtc->base.id, crtc->name, state); + + drm_for_each_plane_mask(plane, state->dev, old_crtc_state->plane_mask) { + struct drm_plane_state *plane_state = +@@ -1318,7 +1335,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state) + unsigned int affected_crtc = 0; + int i, ret = 0; + +- DRM_DEBUG_ATOMIC("checking %p\n", state); ++ drm_dbg_atomic(dev, "checking %p\n", state); + + for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { + if (new_crtc_state->enable) +@@ -1328,8 +1345,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state) + for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { + ret = drm_atomic_plane_check(old_plane_state, new_plane_state); + if (ret) { +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic core check failed\n", +- plane->base.id, plane->name); ++ drm_dbg_atomic(dev, "[PLANE:%d:%s] atomic core check failed\n", ++ plane->base.id, plane->name); + return ret; + } + } +@@ -1337,8 +1354,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state) + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + ret = drm_atomic_crtc_check(old_crtc_state, new_crtc_state); + if (ret) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(dev, "[CRTC:%d:%s] atomic core check failed\n", ++ crtc->base.id, crtc->name); + return ret; + } + } +@@ -1346,8 +1363,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state) + for_each_new_connector_in_state(state, conn, conn_state, i) { + ret = drm_atomic_connector_check(conn, conn_state); + if (ret) { +- DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] atomic core check failed\n", +- conn->base.id, conn->name); ++ drm_dbg_atomic(dev, "[CONNECTOR:%d:%s] atomic core check failed\n", ++ conn->base.id, conn->name); + return ret; + } + } +@@ -1356,8 +1373,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state) + ret = config->funcs->atomic_check(state->dev, state); + + if (ret) { +- DRM_DEBUG_ATOMIC("atomic driver check for %p failed: %d\n", +- state, ret); ++ drm_dbg_atomic(dev, "atomic driver check for %p failed: %d\n", ++ state, ret); + return ret; + } + } +@@ -1365,8 +1382,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state) + if (!state->allow_modeset) { + for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { + if (drm_atomic_crtc_needs_modeset(new_crtc_state)) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requires full modeset\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(dev, "[CRTC:%d:%s] requires full modeset\n", ++ crtc->base.id, crtc->name); + return -EINVAL; + } + } +@@ -1388,8 +1405,9 @@ int drm_atomic_check_only(struct drm_atomic_state *state) + * so compositors know what's going on. + */ + if (affected_crtc != requested_crtc) { +- DRM_DEBUG_ATOMIC("driver added CRTC to commit: requested 0x%x, affected 0x%0x\n", +- requested_crtc, affected_crtc); ++ drm_dbg_atomic(dev, ++ "driver added CRTC to commit: requested 0x%x, affected 0x%0x\n", ++ requested_crtc, affected_crtc); + WARN(!state->allow_modeset, "adding CRTC not allowed without modesets: requested 0x%x, affected 0x%0x\n", + requested_crtc, affected_crtc); + } +@@ -1421,7 +1439,7 @@ int drm_atomic_commit(struct drm_atomic_state *state) + if (ret) + return ret; + +- DRM_DEBUG_ATOMIC("committing %p\n", state); ++ drm_dbg_atomic(state->dev, "committing %p\n", state); + + return config->funcs->atomic_commit(state->dev, state, false); + } +@@ -1450,7 +1468,7 @@ int drm_atomic_nonblocking_commit(struct drm_atomic_state *state) + if (ret) + return ret; + +- DRM_DEBUG_ATOMIC("committing %p nonblocking\n", state); ++ drm_dbg_atomic(state->dev, "committing %p nonblocking\n", state); + + return config->funcs->atomic_commit(state->dev, state, true); + } +@@ -1647,11 +1665,11 @@ void drm_atomic_print_new_state(const struct drm_atomic_state *state, + int i; + + if (!p) { +- DRM_ERROR("invalid drm printer\n"); ++ drm_err(state->dev, "invalid drm printer\n"); + return; + } + +- DRM_DEBUG_ATOMIC("checking %p\n", state); ++ drm_dbg_atomic(state->dev, "checking %p\n", state); + + for_each_new_plane_in_state(state, plane, plane_state, i) + drm_atomic_plane_print_state(p, plane_state); +diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c +index 5ba316391381d..d0a8c22cbc4b8 100644 +--- a/drivers/gpu/drm/drm_atomic_helper.c ++++ b/drivers/gpu/drm/drm_atomic_helper.c +@@ -132,9 +132,10 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state, + + if (new_encoder) { + if (encoder_mask & drm_encoder_mask(new_encoder)) { +- DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] on [CONNECTOR:%d:%s] already assigned\n", +- new_encoder->base.id, new_encoder->name, +- connector->base.id, connector->name); ++ drm_dbg_atomic(connector->dev, ++ "[ENCODER:%d:%s] on [CONNECTOR:%d:%s] already assigned\n", ++ new_encoder->base.id, new_encoder->name, ++ connector->base.id, connector->name); + + return -EINVAL; + } +@@ -169,11 +170,12 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state, + continue; + + if (!disable_conflicting_encoders) { +- DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s] by [CONNECTOR:%d:%s]\n", +- encoder->base.id, encoder->name, +- connector->state->crtc->base.id, +- connector->state->crtc->name, +- connector->base.id, connector->name); ++ drm_dbg_atomic(connector->dev, ++ "[ENCODER:%d:%s] in use on [CRTC:%d:%s] by [CONNECTOR:%d:%s]\n", ++ encoder->base.id, encoder->name, ++ connector->state->crtc->base.id, ++ connector->state->crtc->name, ++ connector->base.id, connector->name); + ret = -EINVAL; + goto out; + } +@@ -184,10 +186,11 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state, + goto out; + } + +- DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n", +- encoder->base.id, encoder->name, +- new_conn_state->crtc->base.id, new_conn_state->crtc->name, +- connector->base.id, connector->name); ++ drm_dbg_atomic(connector->dev, ++ "[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n", ++ encoder->base.id, encoder->name, ++ new_conn_state->crtc->base.id, new_conn_state->crtc->name, ++ connector->base.id, connector->name); + + crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc); + +@@ -268,9 +271,10 @@ steal_encoder(struct drm_atomic_state *state, + + encoder_crtc = old_connector_state->crtc; + +- DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n", +- encoder->base.id, encoder->name, +- encoder_crtc->base.id, encoder_crtc->name); ++ drm_dbg_atomic(encoder->dev, ++ "[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n", ++ encoder->base.id, encoder->name, ++ encoder_crtc->base.id, encoder_crtc->name); + + set_best_encoder(state, new_connector_state, NULL); + +@@ -291,9 +295,8 @@ update_connector_routing(struct drm_atomic_state *state, + struct drm_encoder *new_encoder; + struct drm_crtc_state *crtc_state; + +- DRM_DEBUG_ATOMIC("Updating routing for [CONNECTOR:%d:%s]\n", +- connector->base.id, +- connector->name); ++ drm_dbg_atomic(connector->dev, "Updating routing for [CONNECTOR:%d:%s]\n", ++ connector->base.id, connector->name); + + if (old_connector_state->crtc != new_connector_state->crtc) { + if (old_connector_state->crtc) { +@@ -308,9 +311,8 @@ update_connector_routing(struct drm_atomic_state *state, + } + + if (!new_connector_state->crtc) { +- DRM_DEBUG_ATOMIC("Disabling [CONNECTOR:%d:%s]\n", +- connector->base.id, +- connector->name); ++ drm_dbg_atomic(connector->dev, "Disabling [CONNECTOR:%d:%s]\n", ++ connector->base.id, connector->name); + + set_best_encoder(state, new_connector_state, NULL); + +@@ -339,8 +341,9 @@ update_connector_routing(struct drm_atomic_state *state, + */ + if (!state->duplicated && drm_connector_is_unregistered(connector) && + crtc_state->active) { +- DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] is not registered\n", +- connector->base.id, connector->name); ++ drm_dbg_atomic(connector->dev, ++ "[CONNECTOR:%d:%s] is not registered\n", ++ connector->base.id, connector->name); + return -EINVAL; + } + +@@ -354,31 +357,33 @@ update_connector_routing(struct drm_atomic_state *state, + new_encoder = drm_connector_get_single_encoder(connector); + + if (!new_encoder) { +- DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n", +- connector->base.id, +- connector->name); ++ drm_dbg_atomic(connector->dev, ++ "No suitable encoder found for [CONNECTOR:%d:%s]\n", ++ connector->base.id, connector->name); + return -EINVAL; + } + + if (!drm_encoder_crtc_ok(new_encoder, new_connector_state->crtc)) { +- DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] incompatible with [CRTC:%d:%s]\n", +- new_encoder->base.id, +- new_encoder->name, +- new_connector_state->crtc->base.id, +- new_connector_state->crtc->name); ++ drm_dbg_atomic(connector->dev, ++ "[ENCODER:%d:%s] incompatible with [CRTC:%d:%s]\n", ++ new_encoder->base.id, ++ new_encoder->name, ++ new_connector_state->crtc->base.id, ++ new_connector_state->crtc->name); + return -EINVAL; + } + + if (new_encoder == new_connector_state->best_encoder) { + set_best_encoder(state, new_connector_state, new_encoder); + +- DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n", +- connector->base.id, +- connector->name, +- new_encoder->base.id, +- new_encoder->name, +- new_connector_state->crtc->base.id, +- new_connector_state->crtc->name); ++ drm_dbg_atomic(connector->dev, ++ "[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n", ++ connector->base.id, ++ connector->name, ++ new_encoder->base.id, ++ new_encoder->name, ++ new_connector_state->crtc->base.id, ++ new_connector_state->crtc->name); + + return 0; + } +@@ -389,13 +394,14 @@ update_connector_routing(struct drm_atomic_state *state, + + crtc_state->connectors_changed = true; + +- DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d:%s]\n", +- connector->base.id, +- connector->name, +- new_encoder->base.id, +- new_encoder->name, +- new_connector_state->crtc->base.id, +- new_connector_state->crtc->name); ++ drm_dbg_atomic(connector->dev, ++ "[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d:%s]\n", ++ connector->base.id, ++ connector->name, ++ new_encoder->base.id, ++ new_encoder->name, ++ new_connector_state->crtc->base.id, ++ new_connector_state->crtc->name); + + return 0; + } +@@ -443,7 +449,7 @@ mode_fixup(struct drm_atomic_state *state) + new_crtc_state, + new_conn_state); + if (ret) { +- DRM_DEBUG_ATOMIC("Bridge atomic check failed\n"); ++ drm_dbg_atomic(encoder->dev, "Bridge atomic check failed\n"); + return ret; + } + +@@ -451,16 +457,18 @@ mode_fixup(struct drm_atomic_state *state) + ret = funcs->atomic_check(encoder, new_crtc_state, + new_conn_state); + if (ret) { +- DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] check failed\n", +- encoder->base.id, encoder->name); ++ drm_dbg_atomic(encoder->dev, ++ "[ENCODER:%d:%s] check failed\n", ++ encoder->base.id, encoder->name); + return ret; + } + } else if (funcs && funcs->mode_fixup) { + ret = funcs->mode_fixup(encoder, &new_crtc_state->mode, + &new_crtc_state->adjusted_mode); + if (!ret) { +- DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] fixup failed\n", +- encoder->base.id, encoder->name); ++ drm_dbg_atomic(encoder->dev, ++ "[ENCODER:%d:%s] fixup failed\n", ++ encoder->base.id, encoder->name); + return -EINVAL; + } + } +@@ -483,8 +491,8 @@ mode_fixup(struct drm_atomic_state *state) + ret = funcs->mode_fixup(crtc, &new_crtc_state->mode, + &new_crtc_state->adjusted_mode); + if (!ret) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] fixup failed\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(crtc->dev, "[CRTC:%d:%s] fixup failed\n", ++ crtc->base.id, crtc->name); + return -EINVAL; + } + } +@@ -502,8 +510,9 @@ static enum drm_mode_status mode_valid_path(struct drm_connector *connector, + + ret = drm_encoder_mode_valid(encoder, mode); + if (ret != MODE_OK) { +- DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] mode_valid() failed\n", +- encoder->base.id, encoder->name); ++ drm_dbg_atomic(encoder->dev, ++ "[ENCODER:%d:%s] mode_valid() failed\n", ++ encoder->base.id, encoder->name); + return ret; + } + +@@ -511,14 +520,14 @@ static enum drm_mode_status mode_valid_path(struct drm_connector *connector, + ret = drm_bridge_chain_mode_valid(bridge, &connector->display_info, + mode); + if (ret != MODE_OK) { +- DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n"); ++ drm_dbg_atomic(encoder->dev, "[BRIDGE] mode_valid() failed\n"); + return ret; + } + + ret = drm_crtc_mode_valid(crtc, mode); + if (ret != MODE_OK) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode_valid() failed\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(encoder->dev, "[CRTC:%d:%s] mode_valid() failed\n", ++ crtc->base.id, crtc->name); + return ret; + } + +@@ -619,14 +628,14 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, + WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); + + if (!drm_mode_equal(&old_crtc_state->mode, &new_crtc_state->mode)) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode changed\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(dev, "[CRTC:%d:%s] mode changed\n", ++ crtc->base.id, crtc->name); + new_crtc_state->mode_changed = true; + } + + if (old_crtc_state->enable != new_crtc_state->enable) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enable changed\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(dev, "[CRTC:%d:%s] enable changed\n", ++ crtc->base.id, crtc->name); + + /* + * For clarity this assignment is done here, but +@@ -641,14 +650,14 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, + } + + if (old_crtc_state->active != new_crtc_state->active) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active changed\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(dev, "[CRTC:%d:%s] active changed\n", ++ crtc->base.id, crtc->name); + new_crtc_state->active_changed = true; + } + + if (new_crtc_state->enable != has_connectors) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled/connectors mismatch\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(dev, "[CRTC:%d:%s] enabled/connectors mismatch\n", ++ crtc->base.id, crtc->name); + + return -EINVAL; + } +@@ -708,10 +717,11 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, + if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) + continue; + +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] needs all connectors, enable: %c, active: %c\n", +- crtc->base.id, crtc->name, +- new_crtc_state->enable ? 'y' : 'n', +- new_crtc_state->active ? 'y' : 'n'); ++ drm_dbg_atomic(dev, ++ "[CRTC:%d:%s] needs all connectors, enable: %c, active: %c\n", ++ crtc->base.id, crtc->name, ++ new_crtc_state->enable ? 'y' : 'n', ++ new_crtc_state->active ? 'y' : 'n'); + + ret = drm_atomic_add_affected_connectors(state, crtc); + if (ret != 0) +@@ -818,7 +828,8 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, + } + + if (!crtc_state->enable && !can_update_disabled) { +- DRM_DEBUG_KMS("Cannot update plane of a disabled CRTC.\n"); ++ drm_dbg_kms(plane_state->crtc->dev, ++ "Cannot update plane of a disabled CRTC.\n"); + return -EINVAL; + } + +@@ -828,7 +839,8 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, + hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); + vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); + if (hscale < 0 || vscale < 0) { +- DRM_DEBUG_KMS("Invalid scaling of plane\n"); ++ drm_dbg_kms(plane_state->crtc->dev, ++ "Invalid scaling of plane\n"); + drm_rect_debug_print("src: ", &plane_state->src, true); + drm_rect_debug_print("dst: ", &plane_state->dst, false); + return -ERANGE; +@@ -852,7 +864,8 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, + return 0; + + if (!can_position && !drm_rect_equals(dst, &clip)) { +- DRM_DEBUG_KMS("Plane must cover entire CRTC\n"); ++ drm_dbg_kms(plane_state->crtc->dev, ++ "Plane must cover entire CRTC\n"); + drm_rect_debug_print("dst: ", dst, false); + drm_rect_debug_print("clip: ", &clip, false); + return -EINVAL; +@@ -904,8 +917,9 @@ drm_atomic_helper_check_planes(struct drm_device *dev, + + ret = funcs->atomic_check(plane, state); + if (ret) { +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic driver check failed\n", +- plane->base.id, plane->name); ++ drm_dbg_atomic(plane->dev, ++ "[PLANE:%d:%s] atomic driver check failed\n", ++ plane->base.id, plane->name); + return ret; + } + } +@@ -920,8 +934,9 @@ drm_atomic_helper_check_planes(struct drm_device *dev, + + ret = funcs->atomic_check(crtc, state); + if (ret) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check failed\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(crtc->dev, ++ "[CRTC:%d:%s] atomic driver check failed\n", ++ crtc->base.id, crtc->name); + return ret; + } + } +@@ -1059,8 +1074,8 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) + + funcs = encoder->helper_private; + +- DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n", +- encoder->base.id, encoder->name); ++ drm_dbg_atomic(dev, "disabling [ENCODER:%d:%s]\n", ++ encoder->base.id, encoder->name); + + /* + * Each encoder has at most one connector (since we always steal +@@ -1097,8 +1112,8 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) + + funcs = crtc->helper_private; + +- DRM_DEBUG_ATOMIC("disabling [CRTC:%d:%s]\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(dev, "disabling [CRTC:%d:%s]\n", ++ crtc->base.id, crtc->name); + + + /* Right function depends upon target state. */ +@@ -1248,8 +1263,8 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) + funcs = crtc->helper_private; + + if (new_crtc_state->enable && funcs->mode_set_nofb) { +- DRM_DEBUG_ATOMIC("modeset on [CRTC:%d:%s]\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(dev, "modeset on [CRTC:%d:%s]\n", ++ crtc->base.id, crtc->name); + + funcs->mode_set_nofb(crtc); + } +@@ -1273,8 +1288,8 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) + if (!new_crtc_state->mode_changed) + continue; + +- DRM_DEBUG_ATOMIC("modeset on [ENCODER:%d:%s]\n", +- encoder->base.id, encoder->name); ++ drm_dbg_atomic(dev, "modeset on [ENCODER:%d:%s]\n", ++ encoder->base.id, encoder->name); + + /* + * Each encoder has at most one connector (since we always steal +@@ -1376,8 +1391,8 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, + funcs = crtc->helper_private; + + if (new_crtc_state->enable) { +- DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(dev, "enabling [CRTC:%d:%s]\n", ++ crtc->base.id, crtc->name); + if (funcs->atomic_enable) + funcs->atomic_enable(crtc, old_state); + else if (funcs->commit) +@@ -1400,8 +1415,8 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, + encoder = new_conn_state->best_encoder; + funcs = encoder->helper_private; + +- DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n", +- encoder->base.id, encoder->name); ++ drm_dbg_atomic(dev, "enabling [ENCODER:%d:%s]\n", ++ encoder->base.id, encoder->name); + + /* + * Each encoder has at most one connector (since we always steal +@@ -1570,8 +1585,8 @@ void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev, + + ret = wait_for_completion_timeout(&commit->flip_done, 10 * HZ); + if (ret == 0) +- DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n", +- crtc->base.id, crtc->name); ++ drm_err(dev, "[CRTC:%d:%s] flip_done timed out\n", ++ crtc->base.id, crtc->name); + } + + if (old_state->fake_commit) +@@ -1758,8 +1773,9 @@ int drm_atomic_helper_async_check(struct drm_device *dev, + */ + if (old_plane_state->commit && + !try_wait_for_completion(&old_plane_state->commit->hw_done)) { +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] inflight previous commit preventing async commit\n", +- plane->base.id, plane->name); ++ drm_dbg_atomic(dev, ++ "[PLANE:%d:%s] inflight previous commit preventing async commit\n", ++ plane->base.id, plane->name); + return -EBUSY; + } + +@@ -1981,8 +1997,9 @@ static int stall_checks(struct drm_crtc *crtc, bool nonblock) + */ + if (!completed && nonblock) { + spin_unlock(&crtc->commit_lock); +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] busy with a previous commit\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(crtc->dev, ++ "[CRTC:%d:%s] busy with a previous commit\n", ++ crtc->base.id, crtc->name); + + return -EBUSY; + } +@@ -2004,8 +2021,8 @@ static int stall_checks(struct drm_crtc *crtc, bool nonblock) + ret = wait_for_completion_interruptible_timeout(&stall_commit->cleanup_done, + 10*HZ); + if (ret == 0) +- DRM_ERROR("[CRTC:%d:%s] cleanup_done timed out\n", +- crtc->base.id, crtc->name); ++ drm_err(crtc->dev, "[CRTC:%d:%s] cleanup_done timed out\n", ++ crtc->base.id, crtc->name); + + drm_crtc_commit_put(stall_commit); + +@@ -2169,8 +2186,9 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, + */ + if (nonblock && old_conn_state->commit && + !try_wait_for_completion(&old_conn_state->commit->flip_done)) { +- DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] busy with a previous commit\n", +- conn->base.id, conn->name); ++ drm_dbg_atomic(conn->dev, ++ "[CONNECTOR:%d:%s] busy with a previous commit\n", ++ conn->base.id, conn->name); + + return -EBUSY; + } +@@ -2190,8 +2208,9 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, + */ + if (nonblock && old_plane_state->commit && + !try_wait_for_completion(&old_plane_state->commit->flip_done)) { +- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] busy with a previous commit\n", +- plane->base.id, plane->name); ++ drm_dbg_atomic(plane->dev, ++ "[PLANE:%d:%s] busy with a previous commit\n", ++ plane->base.id, plane->name); + + return -EBUSY; + } +@@ -2237,22 +2256,25 @@ void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state) + for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) { + ret = drm_crtc_commit_wait(old_crtc_state->commit); + if (ret) +- DRM_ERROR("[CRTC:%d:%s] commit wait timed out\n", +- crtc->base.id, crtc->name); ++ drm_err(crtc->dev, ++ "[CRTC:%d:%s] commit wait timed out\n", ++ crtc->base.id, crtc->name); + } + + for_each_old_connector_in_state(old_state, conn, old_conn_state, i) { + ret = drm_crtc_commit_wait(old_conn_state->commit); + if (ret) +- DRM_ERROR("[CONNECTOR:%d:%s] commit wait timed out\n", +- conn->base.id, conn->name); ++ drm_err(conn->dev, ++ "[CONNECTOR:%d:%s] commit wait timed out\n", ++ conn->base.id, conn->name); + } + + for_each_old_plane_in_state(old_state, plane, old_plane_state, i) { + ret = drm_crtc_commit_wait(old_plane_state->commit); + if (ret) +- DRM_ERROR("[PLANE:%d:%s] commit wait timed out\n", +- plane->base.id, plane->name); ++ drm_err(plane->dev, ++ "[PLANE:%d:%s] commit wait timed out\n", ++ plane->base.id, plane->name); + } + } + EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies); +@@ -3139,7 +3161,9 @@ void drm_atomic_helper_shutdown(struct drm_device *dev) + + ret = drm_atomic_helper_disable_all(dev, &ctx); + if (ret) +- DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret); ++ drm_err(dev, ++ "Disabling all crtc's during unload failed with %i\n", ++ ret); + + DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + } +@@ -3399,8 +3423,9 @@ static int page_flip_common(struct drm_atomic_state *state, + /* Make sure we don't accidentally do a full modeset. */ + state->allow_modeset = false; + if (!crtc_state->active) { +- DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled, rejecting legacy flip\n", +- crtc->base.id, crtc->name); ++ drm_dbg_atomic(crtc->dev, ++ "[CRTC:%d:%s] disabled, rejecting legacy flip\n", ++ crtc->base.id, crtc->name); + return -EINVAL; + } + +diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c +index f195c70131373..adf6a3c272e72 100644 +--- a/drivers/gpu/drm/drm_atomic_uapi.c ++++ b/drivers/gpu/drm/drm_atomic_uapi.c +@@ -775,7 +775,7 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, + state->scaling_mode = val; + } else if (property == config->content_protection_property) { + if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) { +- DRM_DEBUG_KMS("only drivers can set CP Enabled\n"); ++ drm_dbg_kms(dev, "only drivers can set CP Enabled\n"); + return -EINVAL; + } + state->content_protection = val; +diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c +index 60a6b21474b14..6e433d465f41d 100644 +--- a/drivers/gpu/drm/drm_auth.c ++++ b/drivers/gpu/drm/drm_auth.c +@@ -106,7 +106,7 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) + auth->magic = file_priv->magic; + mutex_unlock(&dev->master_mutex); + +- DRM_DEBUG("%u\n", auth->magic); ++ drm_dbg_core(dev, "%u\n", auth->magic); + + return ret < 0 ? ret : 0; + } +@@ -117,7 +117,7 @@ int drm_authmagic(struct drm_device *dev, void *data, + struct drm_auth *auth = data; + struct drm_file *file; + +- DRM_DEBUG("%u\n", auth->magic); ++ drm_dbg_core(dev, "%u\n", auth->magic); + + mutex_lock(&dev->master_mutex); + file = idr_find(&file_priv->master->magic_map, auth->magic); +@@ -274,7 +274,9 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data, + } + + if (file_priv->master->lessor != NULL) { +- DRM_DEBUG_LEASE("Attempt to set lessee %d as master\n", file_priv->master->lessee_id); ++ drm_dbg_lease(dev, ++ "Attempt to set lessee %d as master\n", ++ file_priv->master->lessee_id); + ret = -EINVAL; + goto out_unlock; + } +@@ -315,7 +317,9 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data, + } + + if (file_priv->master->lessor != NULL) { +- DRM_DEBUG_LEASE("Attempt to drop lessee %d as master\n", file_priv->master->lessee_id); ++ drm_dbg_lease(dev, ++ "Attempt to drop lessee %d as master\n", ++ file_priv->master->lessee_id); + ret = -EINVAL; + goto out_unlock; + } +-- +2.40.1 + diff --git a/queue-5.15/drm-panel-orientation-quirks-add-quirk-for-one-mix-2.patch b/queue-5.15/drm-panel-orientation-quirks-add-quirk-for-one-mix-2.patch new file mode 100644 index 00000000000..5a1105b80ad --- /dev/null +++ b/queue-5.15/drm-panel-orientation-quirks-add-quirk-for-one-mix-2.patch @@ -0,0 +1,59 @@ +From 6e0664bb5b8f0809fba4791958cc36c6b0d7ef76 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 1 Oct 2023 13:47:10 +0200 +Subject: drm: panel-orientation-quirks: Add quirk for One Mix 2S + +From: Kai Uwe Broulik + +[ Upstream commit cbb7eb2dbd9472816e42a1b0fdb51af49abbf812 ] + +The One Mix 2S is a mini laptop with a 1200x1920 portrait screen +mounted in a landscape oriented clamshell case. Because of the too +generic DMI strings this entry is also doing bios-date matching. + +Signed-off-by: Kai Uwe Broulik +Reviewed-by: Hans de Goede +Signed-off-by: Liviu Dudau +Link: https://patchwork.freedesktop.org/patch/msgid/20231001114710.336172-1-foss-linux@broulik.de +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_panel_orientation_quirks.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c +index 6106fa7c43028..43de9dfcba19a 100644 +--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c ++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c +@@ -44,6 +44,14 @@ static const struct drm_dmi_panel_orientation_data gpd_micropc = { + .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, + }; + ++static const struct drm_dmi_panel_orientation_data gpd_onemix2s = { ++ .width = 1200, ++ .height = 1920, ++ .bios_dates = (const char * const []){ "05/21/2018", "10/26/2018", ++ "03/04/2019", NULL }, ++ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, ++}; ++ + static const struct drm_dmi_panel_orientation_data gpd_pocket = { + .width = 1200, + .height = 1920, +@@ -329,6 +337,14 @@ static const struct dmi_system_id orientation_data[] = { + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, ++ }, { /* One Mix 2S (generic strings, also match on bios date) */ ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), ++ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), ++ }, ++ .driver_data = (void *)&gpd_onemix2s, + }, + {} + }; +-- +2.40.1 + diff --git a/queue-5.15/fs-writeback-do-not-requeue-a-clean-inode-having-ski.patch b/queue-5.15/fs-writeback-do-not-requeue-a-clean-inode-having-ski.patch new file mode 100644 index 00000000000..b906f6e57c6 --- /dev/null +++ b/queue-5.15/fs-writeback-do-not-requeue-a-clean-inode-having-ski.patch @@ -0,0 +1,86 @@ +From 91fd6d0b1a881061fa737b9afd5f1a4714d326c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 22:51:31 -0600 +Subject: fs-writeback: do not requeue a clean inode having skipped pages + +From: Chunhai Guo + +[ Upstream commit be049c3a088d512187407b7fd036cecfab46d565 ] + +When writing back an inode and performing an fsync on it concurrently, a +deadlock issue may arise as shown below. In each writeback iteration, a +clean inode is requeued to the wb->b_dirty queue due to non-zero +pages_skipped, without anything actually being written. This causes an +infinite loop and prevents the plug from being flushed, resulting in a +deadlock. We now avoid requeuing the clean inode to prevent this issue. + + wb_writeback fsync (inode-Y) +blk_start_plug(&plug) +for (;;) { + iter i-1: some reqs with page-X added into plug->mq_list // f2fs node page-X with PG_writeback + filemap_fdatawrite + __filemap_fdatawrite_range // write inode-Y with sync_mode WB_SYNC_ALL + do_writepages + f2fs_write_data_pages + __f2fs_write_data_pages // wb_sync_req[DATA]++ for WB_SYNC_ALL + f2fs_write_cache_pages + f2fs_write_single_data_page + f2fs_do_write_data_page + f2fs_outplace_write_data + f2fs_update_data_blkaddr + f2fs_wait_on_page_writeback + wait_on_page_writeback // wait for f2fs node page-X + iter i: + progress = __writeback_inodes_wb(wb, work) + . writeback_sb_inodes + . __writeback_single_inode // write inode-Y with sync_mode WB_SYNC_NONE + . . do_writepages + . . f2fs_write_data_pages + . . . __f2fs_write_data_pages // skip writepages due to (wb_sync_req[DATA]>0) + . . . wbc->pages_skipped += get_dirty_pages(inode) // wbc->pages_skipped = 1 + . if (!(inode->i_state & I_DIRTY_ALL)) // i_state = I_SYNC | I_SYNC_QUEUED + . total_wrote++; // total_wrote = 1 + . requeue_inode // requeue inode-Y to wb->b_dirty queue due to non-zero pages_skipped + if (progress) // progress = 1 + continue; + iter i+1: + queue_io + // similar process with iter i, infinite for-loop ! +} +blk_finish_plug(&plug) // flush plug won't be called + +Signed-off-by: Chunhai Guo +Reviewed-by: Jan Kara +Message-Id: <20230916045131.957929-1-guochunhai@vivo.com> +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/fs-writeback.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c +index c76537a6826a7..5f0abea107e46 100644 +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -1557,10 +1557,15 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb, + + if (wbc->pages_skipped) { + /* +- * writeback is not making progress due to locked +- * buffers. Skip this inode for now. ++ * Writeback is not making progress due to locked buffers. ++ * Skip this inode for now. Although having skipped pages ++ * is odd for clean inodes, it can happen for some ++ * filesystems so handle that gracefully. + */ +- redirty_tail_locked(inode, wb); ++ if (inode->i_state & I_DIRTY_ALL) ++ redirty_tail_locked(inode, wb); ++ else ++ inode_cgwb_move_to_attached(inode, wb); + return; + } + +-- +2.40.1 + diff --git a/queue-5.15/gpio-timberdale-fix-potential-deadlock-on-tgpio-lock.patch b/queue-5.15/gpio-timberdale-fix-potential-deadlock-on-tgpio-lock.patch new file mode 100644 index 00000000000..87217adb871 --- /dev/null +++ b/queue-5.15/gpio-timberdale-fix-potential-deadlock-on-tgpio-lock.patch @@ -0,0 +1,64 @@ +From 60dc47b88da0a8a05fe4404b6a3a33fdc0cc360a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 10:29:14 +0000 +Subject: gpio: timberdale: Fix potential deadlock on &tgpio->lock + +From: Chengfeng Ye + +[ Upstream commit 9e8bc2dda5a7a8e2babc9975f4b11c9a6196e490 ] + +As timbgpio_irq_enable()/timbgpio_irq_disable() callback could be +executed under irq context, it could introduce double locks on +&tgpio->lock if it preempts other execution units requiring +the same locks. + +timbgpio_gpio_set() +--> timbgpio_update_bit() +--> spin_lock(&tgpio->lock) + + --> timbgpio_irq_disable() + --> spin_lock_irqsave(&tgpio->lock) + +This flaw was found by an experimental static analysis tool I am +developing for irq-related deadlock. + +To prevent the potential deadlock, the patch uses spin_lock_irqsave() +on &tgpio->lock inside timbgpio_gpio_set() to prevent the possible +deadlock scenario. + +Signed-off-by: Chengfeng Ye +Reviewed-by: Andy Shevchenko +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-timberdale.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c +index de14949a3fe5a..92c1f2baa4bff 100644 +--- a/drivers/gpio/gpio-timberdale.c ++++ b/drivers/gpio/gpio-timberdale.c +@@ -43,9 +43,10 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, + unsigned offset, bool enabled) + { + struct timbgpio *tgpio = gpiochip_get_data(gpio); ++ unsigned long flags; + u32 reg; + +- spin_lock(&tgpio->lock); ++ spin_lock_irqsave(&tgpio->lock, flags); + reg = ioread32(tgpio->membase + offset); + + if (enabled) +@@ -54,7 +55,7 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, + reg &= ~(1 << index); + + iowrite32(reg, tgpio->membase + offset); +- spin_unlock(&tgpio->lock); ++ spin_unlock_irqrestore(&tgpio->lock, flags); + + return 0; + } +-- +2.40.1 + diff --git a/queue-5.15/hid-holtek-fix-slab-out-of-bounds-write-in-holtek_kb.patch b/queue-5.15/hid-holtek-fix-slab-out-of-bounds-write-in-holtek_kb.patch new file mode 100644 index 00000000000..8f31ca8c17e --- /dev/null +++ b/queue-5.15/hid-holtek-fix-slab-out-of-bounds-write-in-holtek_kb.patch @@ -0,0 +1,40 @@ +From c8c8c775476fa334f5082385957fe2e374a0c43b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 10:40:59 +0800 +Subject: HID: holtek: fix slab-out-of-bounds Write in holtek_kbd_input_event + +From: Ma Ke + +[ Upstream commit ffe3b7837a2bb421df84d0177481db9f52c93a71 ] + +There is a slab-out-of-bounds Write bug in hid-holtek-kbd driver. +The problem is the driver assumes the device must have an input +but some malicious devices violate this assumption. + +Fix this by checking hid_device's input is non-empty before its usage. + +Signed-off-by: Ma Ke +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-holtek-kbd.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/hid/hid-holtek-kbd.c b/drivers/hid/hid-holtek-kbd.c +index 403506b9697e7..b346d68a06f5a 100644 +--- a/drivers/hid/hid-holtek-kbd.c ++++ b/drivers/hid/hid-holtek-kbd.c +@@ -130,6 +130,10 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type, + return -ENODEV; + + boot_hid = usb_get_intfdata(boot_interface); ++ if (list_empty(&boot_hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } + boot_hid_input = list_first_entry(&boot_hid->inputs, + struct hid_input, list); + +-- +2.40.1 + diff --git a/queue-5.15/hid-multitouch-add-required-quirk-for-synaptics-0xcd.patch b/queue-5.15/hid-multitouch-add-required-quirk-for-synaptics-0xcd.patch new file mode 100644 index 00000000000..6ff2860e1c3 --- /dev/null +++ b/queue-5.15/hid-multitouch-add-required-quirk-for-synaptics-0xcd.patch @@ -0,0 +1,39 @@ +From b4e9889e913928badab6c0102977ad8b453b32a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Sep 2023 16:18:43 +0000 +Subject: HID: multitouch: Add required quirk for Synaptics 0xcd7e device + +From: Rahul Rameshbabu + +[ Upstream commit 1437e4547edf41689d7135faaca4222ef0081bc1 ] + +Register the Synaptics device as a special multitouch device with certain +quirks that may improve usability of the touchpad device. + +Reported-by: Rain +Closes: https://lore.kernel.org/linux-input/2bbb8e1d-1793-4df1-810f-cb0137341ff4@app.fastmail.com/ +Signed-off-by: Rahul Rameshbabu +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-multitouch.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index a5bc11750bdc1..4ec8ca06a0bd0 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -2142,6 +2142,10 @@ static const struct hid_device_id mt_devices[] = { + USB_DEVICE_ID_MTP_STM)}, + + /* Synaptics devices */ ++ { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, ++ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, ++ USB_VENDOR_ID_SYNAPTICS, 0xcd7e) }, ++ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_SYNAPTICS, 0xce08) }, +-- +2.40.1 + diff --git a/queue-5.15/i2c-mux-avoid-potential-false-error-message-in-i2c_m.patch b/queue-5.15/i2c-mux-avoid-potential-false-error-message-in-i2c_m.patch new file mode 100644 index 00000000000..5f7376e76bc --- /dev/null +++ b/queue-5.15/i2c-mux-avoid-potential-false-error-message-in-i2c_m.patch @@ -0,0 +1,37 @@ +From 62212437fc153ffd67f9b4ffebfbf696485cdd21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 23 Sep 2023 23:54:06 +0200 +Subject: i2c: mux: Avoid potential false error message in i2c_mux_add_adapter + +From: Heiner Kallweit + +[ Upstream commit b13e59e74ff71a1004e0508107e91e9a84fd7388 ] + +I2C_CLASS_DEPRECATED is a flag and not an actual class. +There's nothing speaking against both, parent and child, having +I2C_CLASS_DEPRECATED set. Therefore exclude it from the check. + +Signed-off-by: Heiner Kallweit +Acked-by: Peter Rosin +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/i2c-mux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c +index 774507b54b57b..c90cec8d9656d 100644 +--- a/drivers/i2c/i2c-mux.c ++++ b/drivers/i2c/i2c-mux.c +@@ -340,7 +340,7 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, + priv->adap.lock_ops = &i2c_parent_lock_ops; + + /* Sanity check on class */ +- if (i2c_mux_parent_classes(parent) & class) ++ if (i2c_mux_parent_classes(parent) & class & ~I2C_CLASS_DEPRECATED) + dev_err(&parent->dev, + "Segment %d behind mux can't share classes with ancestors\n", + chan_id); +-- +2.40.1 + diff --git a/queue-5.15/ice-open-devlink-when-device-is-ready.patch b/queue-5.15/ice-open-devlink-when-device-is-ready.patch new file mode 100644 index 00000000000..6724d7314cd --- /dev/null +++ b/queue-5.15/ice-open-devlink-when-device-is-ready.patch @@ -0,0 +1,68 @@ +From b30dc7ff580d179562951f1b1510fdde6462292c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Sep 2021 14:22:46 +0300 +Subject: ice: Open devlink when device is ready + +From: Leon Romanovsky + +[ Upstream commit 838cefd5e52c4a3bfbc50e6a0194809ce27c759d ] + +Move devlink_registration routine to be the last command, when the +device is fully initialized. + +Signed-off-by: Leon Romanovsky +Signed-off-by: David S. Miller +Stable-dep-of: 0288c3e709e5 ("ice: reset first in crash dump kernels") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_main.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index b742afafd90bb..691c4320b6b1d 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -4324,8 +4324,6 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + + pf->msg_enable = netif_msg_init(debug, ICE_DFLT_NETIF_M); + +- ice_devlink_register(pf); +- + #ifndef CONFIG_DYNAMIC_DEBUG + if (debug < -1) + hw->debug_mask = debug; +@@ -4559,6 +4557,7 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + dev_warn(dev, "RDMA is not supported on this device\n"); + } + ++ ice_devlink_register(pf); + return 0; + + err_init_aux_unroll: +@@ -4582,7 +4581,6 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + ice_devlink_destroy_regions(pf); + ice_deinit_hw(hw); + err_exit_unroll: +- ice_devlink_unregister(pf); + pci_disable_pcie_error_reporting(pdev); + pci_disable_device(pdev); + return err; +@@ -4659,6 +4657,7 @@ static void ice_remove(struct pci_dev *pdev) + struct ice_pf *pf = pci_get_drvdata(pdev); + int i; + ++ ice_devlink_unregister(pf); + for (i = 0; i < ICE_MAX_RESET_WAIT; i++) { + if (!ice_is_reset_in_progress(pf->state)) + break; +@@ -4696,7 +4695,6 @@ static void ice_remove(struct pci_dev *pdev) + ice_deinit_pf(pf); + ice_devlink_destroy_regions(pf); + ice_deinit_hw(&pf->hw); +- ice_devlink_unregister(pf); + + /* Issue a PFR as part of the prescribed driver unload flow. Do not + * do it via ice_schedule_reset() since there is no need to rebuild +-- +2.40.1 + diff --git a/queue-5.15/ice-remove-redundant-pci_enable_pcie_error_reporting.patch b/queue-5.15/ice-remove-redundant-pci_enable_pcie_error_reporting.patch new file mode 100644 index 00000000000..f2346a167bf --- /dev/null +++ b/queue-5.15/ice-remove-redundant-pci_enable_pcie_error_reporting.patch @@ -0,0 +1,65 @@ +From 17dc13c7587cc4f20d5cd4c8e957eb6089c13239 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Jan 2023 17:46:09 -0600 +Subject: ice: Remove redundant pci_enable_pcie_error_reporting() + +From: Bjorn Helgaas + +[ Upstream commit ba153552c18d7eb839ec0bad7d7484e29ba4719c ] + +pci_enable_pcie_error_reporting() enables the device to send ERR_* +Messages. Since f26e58bf6f54 ("PCI/AER: Enable error reporting when AER is +native"), the PCI core does this for all devices during enumeration. + +Remove the redundant pci_enable_pcie_error_reporting() call from the +driver. Also remove the corresponding pci_disable_pcie_error_reporting() +from the driver .remove() path. + +Note that this doesn't control interrupt generation by the Root Port; that +is controlled by the AER Root Error Command register, which is managed by +the AER service driver. + +Signed-off-by: Bjorn Helgaas +Cc: Jesse Brandeburg +Cc: Tony Nguyen +Cc: intel-wired-lan@lists.osuosl.org +Cc: netdev@vger.kernel.org +Tested-by: Gurucharan G (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 0288c3e709e5 ("ice: reset first in crash dump kernels") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_main.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 4aad089ea1f5d..61aaa6b98e199 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -4297,7 +4297,6 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + return err; + } + +- pci_enable_pcie_error_reporting(pdev); + pci_set_master(pdev); + + pf->pdev = pdev; +@@ -4579,7 +4578,6 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + ice_devlink_destroy_regions(pf); + ice_deinit_hw(hw); + err_exit_unroll: +- pci_disable_pcie_error_reporting(pdev); + pci_disable_device(pdev); + return err; + } +@@ -4701,7 +4699,6 @@ static void ice_remove(struct pci_dev *pdev) + ice_reset(&pf->hw, ICE_RESET_PFR); + pci_wait_for_pending_transaction(pdev); + ice_clear_interrupt_scheme(pf); +- pci_disable_pcie_error_reporting(pdev); + pci_disable_device(pdev); + } + +-- +2.40.1 + diff --git a/queue-5.15/ice-remove-useless-dma-32-fallback-configuration.patch b/queue-5.15/ice-remove-useless-dma-32-fallback-configuration.patch new file mode 100644 index 00000000000..5810d7a043c --- /dev/null +++ b/queue-5.15/ice-remove-useless-dma-32-fallback-configuration.patch @@ -0,0 +1,44 @@ +From 6f77725babf0559f90f19df76ff71f7807dff67f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Jan 2022 19:25:05 +0100 +Subject: ice: Remove useless DMA-32 fallback configuration + +From: Christophe JAILLET + +[ Upstream commit 9c3e54a632637f27d98fb0ec0c44f7039925809d ] + +As stated in [1], dma_set_mask() with a 64-bit mask never fails if +dev->dma_mask is non-NULL. +So, if it fails, the 32 bits case will also fail for the same reason. + +Simplify code and remove some dead code accordingly. + +[1]: https://lkml.org/lkml/2021/6/7/398 + +Signed-off-by: Christophe JAILLET +Reviewed-by: Christoph Hellwig +Reviewed-by: Alexander Lobakin +Tested-by: Gurucharan G +Signed-off-by: Tony Nguyen +Stable-dep-of: 0288c3e709e5 ("ice: reset first in crash dump kernels") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_main.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 691c4320b6b1d..4aad089ea1f5d 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -4292,8 +4292,6 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + + /* set up for high or low DMA */ + err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); +- if (err) +- err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (err) { + dev_err(dev, "DMA configuration failed: 0x%x\n", err); + return err; +-- +2.40.1 + diff --git a/queue-5.15/iio-adc-ad7192-correct-reference-voltage.patch b/queue-5.15/iio-adc-ad7192-correct-reference-voltage.patch new file mode 100644 index 00000000000..363170983a4 --- /dev/null +++ b/queue-5.15/iio-adc-ad7192-correct-reference-voltage.patch @@ -0,0 +1,78 @@ +From 6dc31742f152f22496c3860dd9643958e8f6a4df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 18:21:48 +0300 +Subject: iio: adc: ad7192: Correct reference voltage + +From: Alisa-Dariana Roman + +[ Upstream commit 7e7dcab620cd6d34939f615cac63fc0ef7e81c72 ] + +The avdd and the reference voltage are two different sources but the +reference voltage was assigned according to the avdd supply. + +Add vref regulator structure and set the reference voltage according to +the vref supply from the devicetree. + +In case vref supply is missing, reference voltage is set according to +the avdd supply for compatibility with old devicetrees. + +Fixes: b581f748cce0 ("staging: iio: adc: ad7192: move out of staging") +Signed-off-by: Alisa-Dariana Roman +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20230924152149.41884-1-alisadariana@gmail.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/ad7192.c | 29 +++++++++++++++++++++++++---- + 1 file changed, 25 insertions(+), 4 deletions(-) + +diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c +index 6df435e3c4218..31461d46c5941 100644 +--- a/drivers/iio/adc/ad7192.c ++++ b/drivers/iio/adc/ad7192.c +@@ -177,6 +177,7 @@ struct ad7192_state { + const struct ad7192_chip_info *chip_info; + struct regulator *avdd; + struct regulator *dvdd; ++ struct regulator *vref; + struct clk *mclk; + u16 int_vref_mv; + u32 fclk; +@@ -962,10 +963,30 @@ static int ad7192_probe(struct spi_device *spi) + if (ret) + return ret; + +- ret = regulator_get_voltage(st->avdd); +- if (ret < 0) { +- dev_err(&spi->dev, "Device tree error, reference voltage undefined\n"); +- return ret; ++ st->vref = devm_regulator_get_optional(&spi->dev, "vref"); ++ if (IS_ERR(st->vref)) { ++ if (PTR_ERR(st->vref) != -ENODEV) ++ return PTR_ERR(st->vref); ++ ++ ret = regulator_get_voltage(st->avdd); ++ if (ret < 0) ++ return dev_err_probe(&spi->dev, ret, ++ "Device tree error, AVdd voltage undefined\n"); ++ } else { ++ ret = regulator_enable(st->vref); ++ if (ret) { ++ dev_err(&spi->dev, "Failed to enable specified Vref supply\n"); ++ return ret; ++ } ++ ++ ret = devm_add_action_or_reset(&spi->dev, ad7192_reg_disable, st->vref); ++ if (ret) ++ return ret; ++ ++ ret = regulator_get_voltage(st->vref); ++ if (ret < 0) ++ return dev_err_probe(&spi->dev, ret, ++ "Device tree error, Vref voltage undefined\n"); + } + st->int_vref_mv = ret / 1000; + +-- +2.40.1 + diff --git a/queue-5.15/iio-core-hide-read-accesses-to-iio_dev-currentmode.patch b/queue-5.15/iio-core-hide-read-accesses-to-iio_dev-currentmode.patch new file mode 100644 index 00000000000..f4e60beb9ec --- /dev/null +++ b/queue-5.15/iio-core-hide-read-accesses-to-iio_dev-currentmode.patch @@ -0,0 +1,113 @@ +From e23c145faaadcf8dae53747294f055a81e08f0ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Feb 2022 15:38:37 +0100 +Subject: iio: core: Hide read accesses to iio_dev->currentmode + +From: Miquel Raynal + +[ Upstream commit 8c576f87ad7eb639b8bd4472a9bb830e0696dda5 ] + +In order to later move this variable within the opaque structure, let's +create a helper for accessing it in read-only mode. This helper will be +exposed to device drivers and kept accessible for the few that could need +it. The write access to this variable however should be fully reserved to +the core so in a second step we will hide this variable into the opaque +structure. + +Cc: Eugen Hristev +Cc: Nicolas Ferre +Cc: Alexandre Belloni +Cc: Ludovic Desroches +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/r/20220207143840.707510-11-miquel.raynal@bootlin.com +Signed-off-by: Jonathan Cameron +Stable-dep-of: 7771c8c80d62 ("iio: cros_ec: fix an use-after-free in cros_ec_sensors_push_data()") +Signed-off-by: Sasha Levin +--- + drivers/iio/accel/bmc150-accel-core.c | 4 ++-- + drivers/iio/adc/at91-sama5d2_adc.c | 4 ++-- + drivers/iio/industrialio-core.c | 11 +++++++++++ + include/linux/iio/iio.h | 1 + + 4 files changed, 16 insertions(+), 4 deletions(-) + +diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c +index 3af763b4a9737..9eabc4d1dd0f2 100644 +--- a/drivers/iio/accel/bmc150-accel-core.c ++++ b/drivers/iio/accel/bmc150-accel-core.c +@@ -1525,7 +1525,7 @@ static int bmc150_accel_buffer_postenable(struct iio_dev *indio_dev) + struct bmc150_accel_data *data = iio_priv(indio_dev); + int ret = 0; + +- if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) ++ if (iio_device_get_current_mode(indio_dev) == INDIO_BUFFER_TRIGGERED) + return 0; + + mutex_lock(&data->mutex); +@@ -1557,7 +1557,7 @@ static int bmc150_accel_buffer_predisable(struct iio_dev *indio_dev) + { + struct bmc150_accel_data *data = iio_priv(indio_dev); + +- if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) ++ if (iio_device_get_current_mode(indio_dev) == INDIO_BUFFER_TRIGGERED) + return 0; + + mutex_lock(&data->mutex); +diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c +index ecb49bc452ae6..806fdcd79e64d 100644 +--- a/drivers/iio/adc/at91-sama5d2_adc.c ++++ b/drivers/iio/adc/at91-sama5d2_adc.c +@@ -894,7 +894,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev) + return at91_adc_configure_touch(st, true); + + /* if we are not in triggered mode, we cannot enable the buffer. */ +- if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES)) ++ if (!(iio_device_get_current_mode(indio_dev) & INDIO_ALL_TRIGGERED_MODES)) + return -EINVAL; + + /* we continue with the triggered buffer */ +@@ -947,7 +947,7 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev) + return at91_adc_configure_touch(st, false); + + /* if we are not in triggered mode, nothing to do here */ +- if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES)) ++ if (!(iio_device_get_current_mode(indio_dev) & INDIO_ALL_TRIGGERED_MODES)) + return -EINVAL; + + /* +diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c +index f95a95fd9d0a5..6145e6e4f0ffd 100644 +--- a/drivers/iio/industrialio-core.c ++++ b/drivers/iio/industrialio-core.c +@@ -2084,6 +2084,17 @@ void iio_device_release_direct_mode(struct iio_dev *indio_dev) + } + EXPORT_SYMBOL_GPL(iio_device_release_direct_mode); + ++/** ++ * iio_device_get_current_mode() - helper function providing read-only access to ++ * the @currentmode variable ++ * @indio_dev: IIO device structure for device ++ */ ++int iio_device_get_current_mode(struct iio_dev *indio_dev) ++{ ++ return indio_dev->currentmode; ++} ++EXPORT_SYMBOL_GPL(iio_device_get_current_mode); ++ + subsys_initcall(iio_init); + module_exit(iio_exit); + +diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h +index 0346acbbed2ee..0cac05d5ef1c3 100644 +--- a/include/linux/iio/iio.h ++++ b/include/linux/iio/iio.h +@@ -542,6 +542,7 @@ struct iio_dev { + }; + + int iio_device_id(struct iio_dev *indio_dev); ++int iio_device_get_current_mode(struct iio_dev *indio_dev); + bool iio_buffer_enabled(struct iio_dev *indio_dev); + + const struct iio_chan_spec +-- +2.40.1 + diff --git a/queue-5.15/iio-core-introduce-iio_device_-claim-release-_buffer.patch b/queue-5.15/iio-core-introduce-iio_device_-claim-release-_buffer.patch new file mode 100644 index 00000000000..ef451a11ad4 --- /dev/null +++ b/queue-5.15/iio-core-introduce-iio_device_-claim-release-_buffer.patch @@ -0,0 +1,94 @@ +From fccabee084dbdfcf4c6ae3dfd48ece37e52362ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Oct 2022 17:16:17 +0200 +Subject: iio: core: introduce iio_device_{claim|release}_buffer_mode() APIs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nuno Sá + +[ Upstream commit 0a8565425afd8ba0e1a0ea73e21da119ee6dacea ] + +These APIs are analogous to iio_device_claim_direct_mode() and +iio_device_release_direct_mode() but, as the name suggests, with the +logic flipped. While this looks odd enough, it will have at least two +users (in following changes) and it will be important to move the IIO +mlock to the private struct. + +Signed-off-by: Nuno Sá +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20221012151620.1725215-2-nuno.sa@analog.com +Signed-off-by: Jonathan Cameron +Stable-dep-of: 7771c8c80d62 ("iio: cros_ec: fix an use-after-free in cros_ec_sensors_push_data()") +Signed-off-by: Sasha Levin +--- + drivers/iio/industrialio-core.c | 38 +++++++++++++++++++++++++++++++++ + include/linux/iio/iio.h | 2 ++ + 2 files changed, 40 insertions(+) + +diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c +index 6145e6e4f0ffd..78c780d1ab897 100644 +--- a/drivers/iio/industrialio-core.c ++++ b/drivers/iio/industrialio-core.c +@@ -2084,6 +2084,44 @@ void iio_device_release_direct_mode(struct iio_dev *indio_dev) + } + EXPORT_SYMBOL_GPL(iio_device_release_direct_mode); + ++/** ++ * iio_device_claim_buffer_mode - Keep device in buffer mode ++ * @indio_dev: the iio_dev associated with the device ++ * ++ * If the device is in buffer mode it is guaranteed to stay ++ * that way until iio_device_release_buffer_mode() is called. ++ * ++ * Use with iio_device_release_buffer_mode(). ++ * ++ * Returns: 0 on success, -EBUSY on failure. ++ */ ++int iio_device_claim_buffer_mode(struct iio_dev *indio_dev) ++{ ++ mutex_lock(&indio_dev->mlock); ++ ++ if (iio_buffer_enabled(indio_dev)) ++ return 0; ++ ++ mutex_unlock(&indio_dev->mlock); ++ return -EBUSY; ++} ++EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode); ++ ++/** ++ * iio_device_release_buffer_mode - releases claim on buffer mode ++ * @indio_dev: the iio_dev associated with the device ++ * ++ * Release the claim. Device is no longer guaranteed to stay ++ * in buffer mode. ++ * ++ * Use with iio_device_claim_buffer_mode(). ++ */ ++void iio_device_release_buffer_mode(struct iio_dev *indio_dev) ++{ ++ mutex_unlock(&indio_dev->mlock); ++} ++EXPORT_SYMBOL_GPL(iio_device_release_buffer_mode); ++ + /** + * iio_device_get_current_mode() - helper function providing read-only access to + * the @currentmode variable +diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h +index 0cac05d5ef1c3..9b43559e3acfd 100644 +--- a/include/linux/iio/iio.h ++++ b/include/linux/iio/iio.h +@@ -575,6 +575,8 @@ int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev, + int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp); + int iio_device_claim_direct_mode(struct iio_dev *indio_dev); + void iio_device_release_direct_mode(struct iio_dev *indio_dev); ++int iio_device_claim_buffer_mode(struct iio_dev *indio_dev); ++void iio_device_release_buffer_mode(struct iio_dev *indio_dev); + + extern struct bus_type iio_bus_type; + +-- +2.40.1 + diff --git a/queue-5.15/iio-cros_ec-fix-an-use-after-free-in-cros_ec_sensors.patch b/queue-5.15/iio-cros_ec-fix-an-use-after-free-in-cros_ec_sensors.patch new file mode 100644 index 00000000000..51e648c7e76 --- /dev/null +++ b/queue-5.15/iio-cros_ec-fix-an-use-after-free-in-cros_ec_sensors.patch @@ -0,0 +1,73 @@ +From 5a6af070a36f520dd1c477552504741b5a056785 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Aug 2023 11:06:22 +0800 +Subject: iio: cros_ec: fix an use-after-free in cros_ec_sensors_push_data() + +From: Tzung-Bi Shih + +[ Upstream commit 7771c8c80d62ad065637ef74ed2962983f6c5f6d ] + +cros_ec_sensors_push_data() reads `indio_dev->active_scan_mask` and +calls iio_push_to_buffers_with_timestamp() without making sure the +`indio_dev` stays in buffer mode. There is a race if `indio_dev` exits +buffer mode right before cros_ec_sensors_push_data() accesses them. + +An use-after-free on `indio_dev->active_scan_mask` was observed. The +call trace: +[...] + _find_next_bit + cros_ec_sensors_push_data + cros_ec_sensorhub_event + blocking_notifier_call_chain + cros_ec_irq_thread + +It was caused by a race condition: one thread just freed +`active_scan_mask` at [1]; while another thread tried to access the +memory at [2]. + +Fix it by calling iio_device_claim_buffer_mode() to ensure the +`indio_dev` can't exit buffer mode during cros_ec_sensors_push_data(). + +[1]: https://elixir.bootlin.com/linux/v6.5/source/drivers/iio/industrialio-buffer.c#L1189 +[2]: https://elixir.bootlin.com/linux/v6.5/source/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c#L198 + +Cc: stable@vger.kernel.org +Fixes: aa984f1ba4a4 ("iio: cros_ec: Register to cros_ec_sensorhub when EC supports FIFO") +Signed-off-by: Tzung-Bi Shih +Reviewed-by: Guenter Roeck +Reviewed-by: Stephen Boyd +Link: https://lore.kernel.org/r/20230829030622.1571852-1-tzungbi@kernel.org +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +index f529c01ac66b2..a600ad9ed8696 100644 +--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c ++++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +@@ -196,8 +196,11 @@ int cros_ec_sensors_push_data(struct iio_dev *indio_dev, + /* + * Ignore samples if the buffer is not set: it is needed if the ODR is + * set but the buffer is not enabled yet. ++ * ++ * Note: iio_device_claim_buffer_mode() returns -EBUSY if the buffer ++ * is not enabled. + */ +- if (!iio_buffer_enabled(indio_dev)) ++ if (iio_device_claim_buffer_mode(indio_dev) < 0) + return 0; + + out = (s16 *)st->samples; +@@ -216,6 +219,7 @@ int cros_ec_sensors_push_data(struct iio_dev *indio_dev, + iio_push_to_buffers_with_timestamp(indio_dev, st->samples, + timestamp + delta); + ++ iio_device_release_buffer_mode(indio_dev); + return 0; + } + EXPORT_SYMBOL_GPL(cros_ec_sensors_push_data); +-- +2.40.1 + diff --git a/queue-5.15/iio-un-inline-iio_buffer_enabled.patch b/queue-5.15/iio-un-inline-iio_buffer_enabled.patch new file mode 100644 index 00000000000..7535fc54451 --- /dev/null +++ b/queue-5.15/iio-un-inline-iio_buffer_enabled.patch @@ -0,0 +1,86 @@ +From b8227c58ae34b0b1353fc27d9d5685e6517c9d54 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Feb 2022 15:38:36 +0100 +Subject: iio: Un-inline iio_buffer_enabled() + +From: Miquel Raynal + +[ Upstream commit 2f53b4adfede66f1bc1c8bb7efd7ced2bad1191a ] + +As we are going to hide the currentmode inside the opaque structure, +this helper would soon need to call a non-inline function which would +simply drop the benefit of having the helper defined inline in a header. + +One alternative is to move this helper in the core as there is no more +interest in defining it inline in a header. We will pay the minor cost +either way. + +Let's do like the iio_device_id() helper which also refers to the opaque +structure and gets defined in the core. + +Suggested-by: Jonathan Cameron +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/r/20220207143840.707510-10-miquel.raynal@bootlin.com +Signed-off-by: Jonathan Cameron +Stable-dep-of: 7771c8c80d62 ("iio: cros_ec: fix an use-after-free in cros_ec_sensors_push_data()") +Signed-off-by: Sasha Levin +--- + drivers/iio/industrialio-core.c | 12 ++++++++++++ + include/linux/iio/iio.h | 11 +---------- + 2 files changed, 13 insertions(+), 10 deletions(-) + +diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c +index a7f5d432c95d9..f95a95fd9d0a5 100644 +--- a/drivers/iio/industrialio-core.c ++++ b/drivers/iio/industrialio-core.c +@@ -184,6 +184,18 @@ int iio_device_id(struct iio_dev *indio_dev) + } + EXPORT_SYMBOL_GPL(iio_device_id); + ++/** ++ * iio_buffer_enabled() - helper function to test if the buffer is enabled ++ * @indio_dev: IIO device structure for device ++ */ ++bool iio_buffer_enabled(struct iio_dev *indio_dev) ++{ ++ return indio_dev->currentmode ++ & (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE | ++ INDIO_BUFFER_SOFTWARE); ++} ++EXPORT_SYMBOL_GPL(iio_buffer_enabled); ++ + /** + * iio_sysfs_match_string_with_gaps - matches given string in an array with gaps + * @array: array of strings +diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h +index 324561b7a5e86..0346acbbed2ee 100644 +--- a/include/linux/iio/iio.h ++++ b/include/linux/iio/iio.h +@@ -542,6 +542,7 @@ struct iio_dev { + }; + + int iio_device_id(struct iio_dev *indio_dev); ++bool iio_buffer_enabled(struct iio_dev *indio_dev); + + const struct iio_chan_spec + *iio_find_channel_from_si(struct iio_dev *indio_dev, int si); +@@ -671,16 +672,6 @@ struct iio_dev *devm_iio_device_alloc(struct device *parent, int sizeof_priv); + __printf(2, 3) + struct iio_trigger *devm_iio_trigger_alloc(struct device *parent, + const char *fmt, ...); +-/** +- * iio_buffer_enabled() - helper function to test if the buffer is enabled +- * @indio_dev: IIO device structure for device +- **/ +-static inline bool iio_buffer_enabled(struct iio_dev *indio_dev) +-{ +- return indio_dev->currentmode +- & (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE | +- INDIO_BUFFER_SOFTWARE); +-} + + /** + * iio_get_debugfs_dentry() - helper function to get the debugfs_dentry +-- +2.40.1 + diff --git a/queue-5.15/ipv4-fib-send-notify-when-delete-source-address-rout.patch b/queue-5.15/ipv4-fib-send-notify-when-delete-source-address-rout.patch new file mode 100644 index 00000000000..f74660bc5a9 --- /dev/null +++ b/queue-5.15/ipv4-fib-send-notify-when-delete-source-address-rout.patch @@ -0,0 +1,112 @@ +From 83c0d832d995f157ea39c05aae19540ff216ef2b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 15:55:08 +0800 +Subject: ipv4/fib: send notify when delete source address routes + +From: Hangbin Liu + +[ Upstream commit 4b2b606075e50cdae62ab2356b0a1e206947c354 ] + +After deleting an interface address in fib_del_ifaddr(), the function +scans the fib_info list for stray entries and calls fib_flush() and +fib_table_flush(). Then the stray entries will be deleted silently and no +RTM_DELROUTE notification will be sent. + +This lack of notification can make routing daemons, or monitor like +`ip monitor route` miss the routing changes. e.g. + ++ ip link add dummy1 type dummy ++ ip link add dummy2 type dummy ++ ip link set dummy1 up ++ ip link set dummy2 up ++ ip addr add 192.168.5.5/24 dev dummy1 ++ ip route add 7.7.7.0/24 dev dummy2 src 192.168.5.5 ++ ip -4 route +7.7.7.0/24 dev dummy2 scope link src 192.168.5.5 +192.168.5.0/24 dev dummy1 proto kernel scope link src 192.168.5.5 ++ ip monitor route ++ ip addr del 192.168.5.5/24 dev dummy1 +Deleted 192.168.5.0/24 dev dummy1 proto kernel scope link src 192.168.5.5 +Deleted broadcast 192.168.5.255 dev dummy1 table local proto kernel scope link src 192.168.5.5 +Deleted local 192.168.5.5 dev dummy1 table local proto kernel scope host src 192.168.5.5 + +As Ido reminded, fib_table_flush() isn't only called when an address is +deleted, but also when an interface is deleted or put down. The lack of +notification in these cases is deliberate. And commit 7c6bb7d2faaf +("net/ipv6: Add knob to skip DELROUTE message on device down") introduced +a sysctl to make IPv6 behave like IPv4 in this regard. So we can't send +the route delete notify blindly in fib_table_flush(). + +To fix this issue, let's add a new flag in "struct fib_info" to track the +deleted prefer source address routes, and only send notify for them. + +After update: ++ ip monitor route ++ ip addr del 192.168.5.5/24 dev dummy1 +Deleted 192.168.5.0/24 dev dummy1 proto kernel scope link src 192.168.5.5 +Deleted broadcast 192.168.5.255 dev dummy1 table local proto kernel scope link src 192.168.5.5 +Deleted local 192.168.5.5 dev dummy1 table local proto kernel scope host src 192.168.5.5 +Deleted 7.7.7.0/24 dev dummy2 scope link src 192.168.5.5 + +Suggested-by: Thomas Haller +Signed-off-by: Hangbin Liu +Acked-by: Nicolas Dichtel +Reviewed-by: David Ahern +Link: https://lore.kernel.org/r/20230922075508.848925-1-liuhangbin@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + include/net/ip_fib.h | 1 + + net/ipv4/fib_semantics.c | 1 + + net/ipv4/fib_trie.c | 4 ++++ + 3 files changed, 6 insertions(+) + +diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h +index c3324a1949c3a..9f6e2a476dc28 100644 +--- a/include/net/ip_fib.h ++++ b/include/net/ip_fib.h +@@ -151,6 +151,7 @@ struct fib_info { + int fib_nhs; + bool fib_nh_is_v6; + bool nh_updated; ++ bool pfsrc_removed; + struct nexthop *nh; + struct rcu_head rcu; + struct fib_nh fib_nh[]; +diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c +index 91a3d6d338874..735901b8c9f69 100644 +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -1908,6 +1908,7 @@ int fib_sync_down_addr(struct net_device *dev, __be32 local) + continue; + if (fi->fib_prefsrc == local) { + fi->fib_flags |= RTNH_F_DEAD; ++ fi->pfsrc_removed = true; + ret++; + } + } +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index 22531aac0ccbf..0b74debeecbb1 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -2021,6 +2021,7 @@ void fib_table_flush_external(struct fib_table *tb) + int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all) + { + struct trie *t = (struct trie *)tb->tb_data; ++ struct nl_info info = { .nl_net = net }; + struct key_vector *pn = t->kv; + unsigned long cindex = 1; + struct hlist_node *tmp; +@@ -2083,6 +2084,9 @@ int fib_table_flush(struct net *net, struct fib_table *tb, bool flush_all) + + fib_notify_alias_delete(net, n->key, &n->leaf, fa, + NULL); ++ if (fi->pfsrc_removed) ++ rtmsg_fib(RTM_DELROUTE, htonl(n->key), fa, ++ KEYLENGTH - fa->fa_slen, tb->tb_id, &info, 0); + hlist_del_rcu(&fa->fa_list); + fib_release_info(fa->fa_info); + alias_free_mem_rcu(fa); +-- +2.40.1 + diff --git a/queue-5.15/ksmbd-not-allow-to-open-file-if-delelete-on-close-bi.patch b/queue-5.15/ksmbd-not-allow-to-open-file-if-delelete-on-close-bi.patch new file mode 100644 index 00000000000..2e4d8597d35 --- /dev/null +++ b/queue-5.15/ksmbd-not-allow-to-open-file-if-delelete-on-close-bi.patch @@ -0,0 +1,62 @@ +From bdc8d20a06161ea0e7eb02c851024719a5b2f831 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Oct 2023 10:41:36 +0900 +Subject: ksmbd: not allow to open file if delelete on close bit is set +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Namjae Jeon + +[ Upstream commit f43328357defc0dc9d28dbd06dc3361fd2b22e28 ] + +Cthon test fail with the following error. + +check for proper open/unlink operation +nfsjunk files before unlink: + -rwxr-xr-x 1 root root 0 9월 25 11:03 ./nfs2y8Jm9 +./nfs2y8Jm9 open; unlink ret = 0 +nfsjunk files after unlink: + -rwxr-xr-x 1 root root 0 9월 25 11:03 ./nfs2y8Jm9 +data compare ok +nfsjunk files after close: + ls: cannot access './nfs2y8Jm9': No such file or directory +special tests failed + +Cthon expect to second unlink failure when file is already unlinked. +ksmbd can not allow to open file if flags of ksmbd inode is set with +S_DEL_ON_CLS flags. + +Cc: stable@vger.kernel.org +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/ksmbd/vfs_cache.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/ksmbd/vfs_cache.c b/fs/ksmbd/vfs_cache.c +index 0df8467af39af..b67ce2d52ceeb 100644 +--- a/fs/ksmbd/vfs_cache.c ++++ b/fs/ksmbd/vfs_cache.c +@@ -105,7 +105,7 @@ int ksmbd_query_inode_status(struct inode *inode) + ci = __ksmbd_inode_lookup(inode); + if (ci) { + ret = KSMBD_INODE_STATUS_OK; +- if (ci->m_flags & S_DEL_PENDING) ++ if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) + ret = KSMBD_INODE_STATUS_PENDING_DELETE; + atomic_dec(&ci->m_count); + } +@@ -115,7 +115,7 @@ int ksmbd_query_inode_status(struct inode *inode) + + bool ksmbd_inode_pending_delete(struct ksmbd_file *fp) + { +- return (fp->f_ci->m_flags & S_DEL_PENDING); ++ return (fp->f_ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); + } + + void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp) +-- +2.40.1 + diff --git a/queue-5.15/mctp-allow-local-delivery-to-the-null-eid.patch b/queue-5.15/mctp-allow-local-delivery-to-the-null-eid.patch new file mode 100644 index 00000000000..b20b4fafcf0 --- /dev/null +++ b/queue-5.15/mctp-allow-local-delivery-to-the-null-eid.patch @@ -0,0 +1,74 @@ +From 024b1876fc209d4c97e38a74ba548ee32f8c34b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Sep 2021 15:26:06 +0800 +Subject: mctp: Allow local delivery to the null EID + +From: Jeremy Kerr + +[ Upstream commit 1f6c77ac9e6ecef152fd5df94c4b3c346adb197a ] + +We may need to receive packets addressed to the null EID (==0), but +addressed to us at the physical layer. + +This change adds a lookup for local routes when we see a packet +addressed to EID 0, and a local phys address. + +Signed-off-by: Jeremy Kerr +Signed-off-by: David S. Miller +Stable-dep-of: 5093bbfc10ab ("mctp: perform route lookups under a RCU read-side lock") +Signed-off-by: Sasha Levin +--- + net/mctp/route.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/net/mctp/route.c b/net/mctp/route.c +index 89e67399249b4..859f57fd3871f 100644 +--- a/net/mctp/route.c ++++ b/net/mctp/route.c +@@ -480,6 +480,10 @@ static int mctp_alloc_local_tag(struct mctp_sock *msk, + int rc = -EAGAIN; + u8 tagbits; + ++ /* for NULL destination EIDs, we may get a response from any peer */ ++ if (daddr == MCTP_ADDR_NULL) ++ daddr = MCTP_ADDR_ANY; ++ + /* be optimistic, alloc now */ + key = mctp_key_alloc(msk, saddr, daddr, 0, GFP_KERNEL); + if (!key) +@@ -558,6 +562,20 @@ struct mctp_route *mctp_route_lookup(struct net *net, unsigned int dnet, + return rt; + } + ++static struct mctp_route *mctp_route_lookup_null(struct net *net, ++ struct net_device *dev) ++{ ++ struct mctp_route *rt; ++ ++ list_for_each_entry_rcu(rt, &net->mctp.routes, list) { ++ if (rt->dev->dev == dev && rt->type == RTN_LOCAL && ++ refcount_inc_not_zero(&rt->refs)) ++ return rt; ++ } ++ ++ return NULL; ++} ++ + /* sends a skb to rt and releases the route. */ + int mctp_do_route(struct mctp_route *rt, struct sk_buff *skb) + { +@@ -853,6 +871,11 @@ static int mctp_pkttype_receive(struct sk_buff *skb, struct net_device *dev, + rcu_read_unlock(); + + rt = mctp_route_lookup(net, cb->net, mh->dest); ++ ++ /* NULL EID, but addressed to our physical address */ ++ if (!rt && mh->dest == MCTP_ADDR_NULL && skb->pkt_type == PACKET_HOST) ++ rt = mctp_route_lookup_null(net, dev); ++ + if (!rt) + goto err_drop; + +-- +2.40.1 + diff --git a/queue-5.15/mctp-perform-route-lookups-under-a-rcu-read-side-loc.patch b/queue-5.15/mctp-perform-route-lookups-under-a-rcu-read-side-loc.patch new file mode 100644 index 00000000000..cb21cfe9dc8 --- /dev/null +++ b/queue-5.15/mctp-perform-route-lookups-under-a-rcu-read-side-loc.patch @@ -0,0 +1,89 @@ +From 8fc6f7ac730d22db2aac70b2311b67f9a44c9764 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 15:56:45 +0800 +Subject: mctp: perform route lookups under a RCU read-side lock + +From: Jeremy Kerr + +[ Upstream commit 5093bbfc10ab6636b32728e35813cbd79feb063c ] + +Our current route lookups (mctp_route_lookup and mctp_route_lookup_null) +traverse the net's route list without the RCU read lock held. This means +the route lookup is subject to preemption, resulting in an potential +grace period expiry, and so an eventual kfree() while we still have the +route pointer. + +Add the proper read-side critical section locks around the route +lookups, preventing premption and a possible parallel kfree. + +The remaining net->mctp.routes accesses are already under a +rcu_read_lock, or protected by the RTNL for updates. + +Based on an analysis from Sili Luo , where +introducing a delay in the route lookup could cause a UAF on +simultaneous sendmsg() and route deletion. + +Reported-by: Sili Luo +Fixes: 889b7da23abf ("mctp: Add initial routing framework") +Cc: stable@vger.kernel.org +Signed-off-by: Jeremy Kerr +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/29c4b0e67dc1bf3571df3982de87df90cae9b631.1696837310.git.jk@codeconstruct.com.au +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/mctp/route.c | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +diff --git a/net/mctp/route.c b/net/mctp/route.c +index 859f57fd3871f..5ef6b3b0a3d99 100644 +--- a/net/mctp/route.c ++++ b/net/mctp/route.c +@@ -549,6 +549,8 @@ struct mctp_route *mctp_route_lookup(struct net *net, unsigned int dnet, + { + struct mctp_route *tmp, *rt = NULL; + ++ rcu_read_lock(); ++ + list_for_each_entry_rcu(tmp, &net->mctp.routes, list) { + /* TODO: add metrics */ + if (mctp_rt_match_eid(tmp, dnet, daddr)) { +@@ -559,21 +561,29 @@ struct mctp_route *mctp_route_lookup(struct net *net, unsigned int dnet, + } + } + ++ rcu_read_unlock(); ++ + return rt; + } + + static struct mctp_route *mctp_route_lookup_null(struct net *net, + struct net_device *dev) + { +- struct mctp_route *rt; ++ struct mctp_route *tmp, *rt = NULL; + +- list_for_each_entry_rcu(rt, &net->mctp.routes, list) { +- if (rt->dev->dev == dev && rt->type == RTN_LOCAL && +- refcount_inc_not_zero(&rt->refs)) +- return rt; ++ rcu_read_lock(); ++ ++ list_for_each_entry_rcu(tmp, &net->mctp.routes, list) { ++ if (tmp->dev->dev == dev && tmp->type == RTN_LOCAL && ++ refcount_inc_not_zero(&tmp->refs)) { ++ rt = tmp; ++ break; ++ } + } + +- return NULL; ++ rcu_read_unlock(); ++ ++ return rt; + } + + /* sends a skb to rt and releases the route. */ +-- +2.40.1 + diff --git a/queue-5.15/net-fix-ifname-in-netlink-ntf-during-netns-move.patch b/queue-5.15/net-fix-ifname-in-netlink-ntf-during-netns-move.patch new file mode 100644 index 00000000000..3a6fa018f63 --- /dev/null +++ b/queue-5.15/net-fix-ifname-in-netlink-ntf-during-netns-move.patch @@ -0,0 +1,129 @@ +From 70fce1ea300904393991baa2ee0e8dc1610a34c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 18:38:13 -0700 +Subject: net: fix ifname in netlink ntf during netns move + +From: Jakub Kicinski + +[ Upstream commit 311cca40661f428b7aa114fb5af578cfdbe3e8b6 ] + +dev_get_valid_name() overwrites the netdev's name on success. +This makes it hard to use in prepare-commit-like fashion, +where we do validation first, and "commit" to the change +later. + +Factor out a helper which lets us save the new name to a buffer. +Use it to fix the problem of notification on netns move having +incorrect name: + + 5: eth0: mtu 1500 qdisc noop state DOWN group default + link/ether be:4d:58:f9:d5:40 brd ff:ff:ff:ff:ff:ff + 6: eth1: mtu 1500 qdisc noop state DOWN group default + link/ether 1e:4a:34:36:e3:cd brd ff:ff:ff:ff:ff:ff + + [ ~]# ip link set dev eth0 netns 1 name eth1 + +ip monitor inside netns: + Deleted inet eth0 + Deleted inet6 eth0 + Deleted 5: eth1: mtu 1500 qdisc noop state DOWN group default + link/ether be:4d:58:f9:d5:40 brd ff:ff:ff:ff:ff:ff new-netnsid 0 new-ifindex 7 + +Name is reported as eth1 in old netns for ifindex 5, already renamed. + +Fixes: d90310243fd7 ("net: device name allocation cleanups") +Signed-off-by: Jakub Kicinski +Reviewed-by: Jiri Pirko +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/core/dev.c | 44 +++++++++++++++++++++++++++++++------------- + 1 file changed, 31 insertions(+), 13 deletions(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index af0e0ce53ca52..8f4f355a963f8 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1151,6 +1151,26 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) + return -ENFILE; + } + ++static int dev_prep_valid_name(struct net *net, struct net_device *dev, ++ const char *want_name, char *out_name) ++{ ++ int ret; ++ ++ if (!dev_valid_name(want_name)) ++ return -EINVAL; ++ ++ if (strchr(want_name, '%')) { ++ ret = __dev_alloc_name(net, want_name, out_name); ++ return ret < 0 ? ret : 0; ++ } else if (netdev_name_in_use(net, want_name)) { ++ return -EEXIST; ++ } else if (out_name != want_name) { ++ strscpy(out_name, want_name, IFNAMSIZ); ++ } ++ ++ return 0; ++} ++ + static int dev_alloc_name_ns(struct net *net, + struct net_device *dev, + const char *name) +@@ -1188,19 +1208,13 @@ EXPORT_SYMBOL(dev_alloc_name); + static int dev_get_valid_name(struct net *net, struct net_device *dev, + const char *name) + { +- BUG_ON(!net); +- +- if (!dev_valid_name(name)) +- return -EINVAL; +- +- if (strchr(name, '%')) +- return dev_alloc_name_ns(net, dev, name); +- else if (netdev_name_in_use(net, name)) +- return -EEXIST; +- else if (dev->name != name) +- strscpy(dev->name, name, IFNAMSIZ); ++ char buf[IFNAMSIZ]; ++ int ret; + +- return 0; ++ ret = dev_prep_valid_name(net, dev, name, buf); ++ if (ret >= 0) ++ strscpy(dev->name, buf, IFNAMSIZ); ++ return ret; + } + + /** +@@ -11154,6 +11168,7 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net, + const char *pat, int new_ifindex) + { + struct net *net_old = dev_net(dev); ++ char new_name[IFNAMSIZ] = {}; + int err, new_nsid; + + ASSERT_RTNL(); +@@ -11180,7 +11195,7 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net, + /* We get here if we can't use the current device name */ + if (!pat) + goto out; +- err = dev_get_valid_name(net, dev, pat); ++ err = dev_prep_valid_name(net, dev, pat, new_name); + if (err < 0) + goto out; + } +@@ -11248,6 +11263,9 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net, + kobject_uevent(&dev->dev.kobj, KOBJ_ADD); + netdev_adjacent_add_links(dev); + ++ if (new_name[0]) /* Rename the netdev to prepared name */ ++ strscpy(dev->name, new_name, IFNAMSIZ); ++ + /* Fixup kobjects */ + err = device_rename(&dev->dev, dev->name); + WARN_ON(err); +-- +2.40.1 + diff --git a/queue-5.15/net-introduce-a-function-to-check-if-a-netdev-name-i.patch b/queue-5.15/net-introduce-a-function-to-check-if-a-netdev-name-i.patch new file mode 100644 index 00000000000..f303a6ed681 --- /dev/null +++ b/queue-5.15/net-introduce-a-function-to-check-if-a-netdev-name-i.patch @@ -0,0 +1,97 @@ +From b0994db2200c5f54ab2b494a45201e2cb3925b12 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Oct 2021 18:16:50 +0200 +Subject: net: introduce a function to check if a netdev name is in use + +From: Antoine Tenart + +[ Upstream commit 75ea27d0d62281c31ee259c872dfdeb072cf5e39 ] + +__dev_get_by_name is currently used to either retrieve a net device +reference using its name or to check if a name is already used by a +registered net device (per ns). In the later case there is no need to +return a reference to a net device. + +Introduce a new helper, netdev_name_in_use, to check if a name is +currently used by a registered net device without leaking a reference +the corresponding net device. This helper uses netdev_name_node_lookup +instead of __dev_get_by_name as we don't need the extra logic retrieving +a reference to the corresponding net device. + +Signed-off-by: Antoine Tenart +Signed-off-by: David S. Miller +Stable-dep-of: 311cca40661f ("net: fix ifname in netlink ntf during netns move") +Signed-off-by: Sasha Levin +--- + include/linux/netdevice.h | 1 + + net/core/dev.c | 14 ++++++++++---- + 2 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index b5df2e59a51d3..132f4344fee9f 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2978,6 +2978,7 @@ struct net_device *__dev_get_by_flags(struct net *net, unsigned short flags, + struct net_device *dev_get_by_name(struct net *net, const char *name); + struct net_device *dev_get_by_name_rcu(struct net *net, const char *name); + struct net_device *__dev_get_by_name(struct net *net, const char *name); ++bool netdev_name_in_use(struct net *net, const char *name); + int dev_alloc_name(struct net_device *dev, const char *name); + int dev_open(struct net_device *dev, struct netlink_ext_ack *extack); + void dev_close(struct net_device *dev); +diff --git a/net/core/dev.c b/net/core/dev.c +index 4d698ccf41726..d269c1760fa45 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -303,6 +303,12 @@ static struct netdev_name_node *netdev_name_node_lookup_rcu(struct net *net, + return NULL; + } + ++bool netdev_name_in_use(struct net *net, const char *name) ++{ ++ return netdev_name_node_lookup(net, name); ++} ++EXPORT_SYMBOL(netdev_name_in_use); ++ + int netdev_name_node_alt_create(struct net_device *dev, const char *name) + { + struct netdev_name_node *name_node; +@@ -1135,7 +1141,7 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) + } + + snprintf(buf, IFNAMSIZ, name, i); +- if (!__dev_get_by_name(net, buf)) ++ if (!netdev_name_in_use(net, buf)) + return i; + + /* It is possible to run out of possible slots +@@ -1189,7 +1195,7 @@ static int dev_get_valid_name(struct net *net, struct net_device *dev, + + if (strchr(name, '%')) + return dev_alloc_name_ns(net, dev, name); +- else if (__dev_get_by_name(net, name)) ++ else if (netdev_name_in_use(net, name)) + return -EEXIST; + else if (dev->name != name) + strlcpy(dev->name, name, IFNAMSIZ); +@@ -11170,7 +11176,7 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net, + * we can use it in the destination network namespace. + */ + err = -EEXIST; +- if (__dev_get_by_name(net, dev->name)) { ++ if (netdev_name_in_use(net, dev->name)) { + /* We get here if we can't use the current device name */ + if (!pat) + goto out; +@@ -11522,7 +11528,7 @@ static void __net_exit default_device_exit(struct net *net) + + /* Push remaining network devices to init_net */ + snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex); +- if (__dev_get_by_name(&init_net, fb_name)) ++ if (netdev_name_in_use(&init_net, fb_name)) + snprintf(fb_name, IFNAMSIZ, "dev%%d"); + err = dev_change_net_namespace(dev, &init_net, fb_name); + if (err) { +-- +2.40.1 + diff --git a/queue-5.15/net-mlx5-handle-fw-tracer-change-ownership-event-bas.patch b/queue-5.15/net-mlx5-handle-fw-tracer-change-ownership-event-bas.patch new file mode 100644 index 00000000000..627fa124357 --- /dev/null +++ b/queue-5.15/net-mlx5-handle-fw-tracer-change-ownership-event-bas.patch @@ -0,0 +1,50 @@ +From e71fe90b0c0377c18d6cd27c644c1769b50f038a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 21:48:30 +0300 +Subject: net/mlx5: Handle fw tracer change ownership event based on MTRC + +From: Maher Sanalla + +[ Upstream commit 92fd39634541eb0a11bf1bafbc8ba92d6ddb8dba ] + +Currently, whenever fw issues a change ownership event, the PF that owns +the fw tracer drops its ownership directly and the other PFs try to pick +up the ownership via what MTRC register suggests. + +In some cases, driver releases the ownership of the tracer and reacquires +it later on. Whenever the driver releases ownership of the tracer, fw +issues a change ownership event. This event can be delayed and come after +driver has reacquired ownership of the tracer. Thus the late event will +trigger the tracer owner PF to release the ownership again and lead to a +scenario where no PF is owning the tracer. + +To prevent the scenario described above, when handling a change +ownership event, do not drop ownership of the tracer directly, instead +read the fw MTRC register to retrieve the up-to-date owner of the tracer +and set it accordingly in driver level. + +Fixes: f53aaa31cce7 ("net/mlx5: FW tracer, implement tracer logic") +Signed-off-by: Maher Sanalla +Reviewed-by: Shay Drory +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +index 958cdb9755598..b69ab30ecf03b 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +@@ -821,7 +821,7 @@ static void mlx5_fw_tracer_ownership_change(struct work_struct *work) + + mlx5_core_dbg(tracer->dev, "FWTracer: ownership changed, current=(%d)\n", tracer->owner); + if (tracer->owner) { +- tracer->owner = false; ++ mlx5_fw_tracer_ownership_acquire(tracer); + return; + } + +-- +2.40.1 + diff --git a/queue-5.15/net-move-from-strlcpy-with-unused-retval-to-strscpy.patch b/queue-5.15/net-move-from-strlcpy-with-unused-retval-to-strscpy.patch new file mode 100644 index 00000000000..b6a36c1eb40 --- /dev/null +++ b/queue-5.15/net-move-from-strlcpy-with-unused-retval-to-strscpy.patch @@ -0,0 +1,85 @@ +From 739e8ae2fe127bf74b5f3dda7ab55b9861dd77e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Aug 2022 23:02:15 +0200 +Subject: net: move from strlcpy with unused retval to strscpy + +From: Wolfram Sang + +[ Upstream commit 70986397a15bf337d4ca3215a65e30bbe95e5d3c ] + +Follow the advice of the below link and prefer 'strscpy' in this +subsystem. Conversion is 1:1 because the return value is not used. +Generated by a coccinelle script. + +Link: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw@mail.gmail.com/ +Signed-off-by: Wolfram Sang +Link: https://lore.kernel.org/r/20220818210215.8395-1-wsa+renesas@sang-engineering.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 311cca40661f ("net: fix ifname in netlink ntf during netns move") +Signed-off-by: Sasha Levin +--- + net/core/dev.c | 4 ++-- + net/core/drop_monitor.c | 2 +- + net/core/netpoll.c | 4 ++-- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index d269c1760fa45..af0e0ce53ca52 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1161,7 +1161,7 @@ static int dev_alloc_name_ns(struct net *net, + BUG_ON(!net); + ret = __dev_alloc_name(net, name, buf); + if (ret >= 0) +- strlcpy(dev->name, buf, IFNAMSIZ); ++ strscpy(dev->name, buf, IFNAMSIZ); + return ret; + } + +@@ -1198,7 +1198,7 @@ static int dev_get_valid_name(struct net *net, struct net_device *dev, + else if (netdev_name_in_use(net, name)) + return -EEXIST; + else if (dev->name != name) +- strlcpy(dev->name, name, IFNAMSIZ); ++ strscpy(dev->name, name, IFNAMSIZ); + + return 0; + } +diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c +index 78202141930f4..22015ebc1dd56 100644 +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -473,7 +473,7 @@ net_dm_hw_trap_summary_probe(void *ignore, const struct devlink *devlink, + goto out; + + hw_entry = &hw_entries->entries[hw_entries->num_entries]; +- strlcpy(hw_entry->trap_name, metadata->trap_name, ++ strscpy(hw_entry->trap_name, metadata->trap_name, + NET_DM_MAX_HW_TRAP_NAME_LEN - 1); + hw_entry->count = 1; + hw_entries->num_entries++; +diff --git a/net/core/netpoll.c b/net/core/netpoll.c +index bd750863959f2..47a86da6ab980 100644 +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -573,7 +573,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt) + if ((delim = strchr(cur, ',')) == NULL) + goto parse_failed; + *delim = 0; +- strlcpy(np->dev_name, cur, sizeof(np->dev_name)); ++ strscpy(np->dev_name, cur, sizeof(np->dev_name)); + cur = delim; + } + cur++; +@@ -627,7 +627,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev) + int err; + + np->dev = ndev; +- strlcpy(np->dev_name, ndev->name, IFNAMSIZ); ++ strscpy(np->dev_name, ndev->name, IFNAMSIZ); + + if (ndev->priv_flags & IFF_DISABLE_NETPOLL) { + np_err(np, "%s doesn't support polling, aborting\n", +-- +2.40.1 + diff --git a/queue-5.15/netfilter-nf_tables-do-not-remove-elements-if-set-ba.patch b/queue-5.15/netfilter-nf_tables-do-not-remove-elements-if-set-ba.patch new file mode 100644 index 00000000000..dbe79367fad --- /dev/null +++ b/queue-5.15/netfilter-nf_tables-do-not-remove-elements-if-set-ba.patch @@ -0,0 +1,42 @@ +From 0099073d67d434c3e9140697d9c99182ce276fa3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 13:12:58 +0200 +Subject: netfilter: nf_tables: do not remove elements if set backend + implements .abort + +From: Pablo Neira Ayuso + +[ Upstream commit ebd032fa881882fef2acb9da1bbde48d8233241d ] + +pipapo set backend maintains two copies of the datastructure, removing +the elements from the copy that is going to be discarded slows down +the abort path significantly, from several minutes to few seconds after +this patch. + +Fixes: 212ed75dc5fb ("netfilter: nf_tables: integrate pipapo into commit protocol") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 8a4cd1c16e0e4..cd4318cbcaa39 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -9713,7 +9713,10 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) + break; + } + te = (struct nft_trans_elem *)trans->data; +- nft_setelem_remove(net, te->set, &te->elem); ++ if (!te->set->ops->abort || ++ nft_setelem_is_catchall(te->set, &te->elem)) ++ nft_setelem_remove(net, te->set, &te->elem); ++ + if (!nft_setelem_is_catchall(te->set, &te->elem)) + atomic_dec(&te->set->nelems); + +-- +2.40.1 + diff --git a/queue-5.15/netfilter-nf_tables-revert-do-not-remove-elements-if.patch b/queue-5.15/netfilter-nf_tables-revert-do-not-remove-elements-if.patch new file mode 100644 index 00000000000..89668e54848 --- /dev/null +++ b/queue-5.15/netfilter-nf_tables-revert-do-not-remove-elements-if.patch @@ -0,0 +1,41 @@ +From 50d86f272bb83ac65b42c1925af2837f619e8804 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Oct 2023 13:18:39 +0200 +Subject: netfilter: nf_tables: revert do not remove elements if set backend + implements .abort + +From: Pablo Neira Ayuso + +[ Upstream commit f86fb94011aeb3b26337fc22204ca726aeb8bc24 ] + +nf_tables_abort_release() path calls nft_set_elem_destroy() for +NFT_MSG_NEWSETELEM which releases the element, however, a reference to +the element still remains in the working copy. + +Fixes: ebd032fa8818 ("netfilter: nf_tables: do not remove elements if set backend implements .abort") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_tables_api.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index cd4318cbcaa39..8a4cd1c16e0e4 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -9713,10 +9713,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) + break; + } + te = (struct nft_trans_elem *)trans->data; +- if (!te->set->ops->abort || +- nft_setelem_is_catchall(te->set, &te->elem)) +- nft_setelem_remove(net, te->set, &te->elem); +- ++ nft_setelem_remove(net, te->set, &te->elem); + if (!nft_setelem_is_catchall(te->set, &te->elem)) + atomic_dec(&te->set->nelems); + +-- +2.40.1 + diff --git a/queue-5.15/nfp-flower-avoid-rmmod-nfp-crash-issues.patch b/queue-5.15/nfp-flower-avoid-rmmod-nfp-crash-issues.patch new file mode 100644 index 00000000000..b05494e9101 --- /dev/null +++ b/queue-5.15/nfp-flower-avoid-rmmod-nfp-crash-issues.patch @@ -0,0 +1,283 @@ +From 4a865a31a23fda1be2131b0972910ef16a28d2cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 13:21:55 +0200 +Subject: nfp: flower: avoid rmmod nfp crash issues +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Yanguo Li + +[ Upstream commit 14690995c14109852c7ba6e316045c02e4254272 ] + +When there are CT table entries, and you rmmod nfp, the following +events can happen: + +task1: + nfp_net_pci_remove + ↓ + nfp_flower_stop->(asynchronous)tcf_ct_flow_table_cleanup_work(3) + ↓ + nfp_zone_table_entry_destroy(1) + +task2: + nfp_fl_ct_handle_nft_flow(2) + +When the execution order is (1)->(2)->(3), it will crash. Therefore, in +the function nfp_fl_ct_del_flow, nf_flow_table_offload_del_cb needs to +be executed synchronously. + +At the same time, in order to solve the deadlock problem and the problem +of rtnl_lock sometimes failing, replace rtnl_lock with the private +nfp_fl_lock. + +Fixes: 7cc93d888df7 ("nfp: flower-ct: remove callback delete deadlock") +Cc: stable@vger.kernel.org +Signed-off-by: Yanguo Li +Signed-off-by: Louis Peens +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../net/ethernet/netronome/nfp/flower/cmsg.c | 10 ++++---- + .../ethernet/netronome/nfp/flower/conntrack.c | 19 ++++++++++----- + .../net/ethernet/netronome/nfp/flower/main.h | 2 ++ + .../ethernet/netronome/nfp/flower/metadata.c | 2 ++ + .../ethernet/netronome/nfp/flower/offload.c | 24 ++++++++++++++----- + .../ethernet/netronome/nfp/flower/qos_conf.c | 20 ++++++++++------ + 6 files changed, 54 insertions(+), 23 deletions(-) + +diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c +index f21cf1f40f987..153533cd8f086 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c ++++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c +@@ -210,6 +210,7 @@ nfp_flower_cmsg_merge_hint_rx(struct nfp_app *app, struct sk_buff *skb) + unsigned int msg_len = nfp_flower_cmsg_get_data_len(skb); + struct nfp_flower_cmsg_merge_hint *msg; + struct nfp_fl_payload *sub_flows[2]; ++ struct nfp_flower_priv *priv; + int err, i, flow_cnt; + + msg = nfp_flower_cmsg_get_data(skb); +@@ -228,14 +229,15 @@ nfp_flower_cmsg_merge_hint_rx(struct nfp_app *app, struct sk_buff *skb) + return; + } + +- rtnl_lock(); ++ priv = app->priv; ++ mutex_lock(&priv->nfp_fl_lock); + for (i = 0; i < flow_cnt; i++) { + u32 ctx = be32_to_cpu(msg->flow[i].host_ctx); + + sub_flows[i] = nfp_flower_get_fl_payload_from_ctx(app, ctx); + if (!sub_flows[i]) { + nfp_flower_cmsg_warn(app, "Invalid flow in merge hint\n"); +- goto err_rtnl_unlock; ++ goto err_mutex_unlock; + } + } + +@@ -244,8 +246,8 @@ nfp_flower_cmsg_merge_hint_rx(struct nfp_app *app, struct sk_buff *skb) + if (err == -ENOMEM) + nfp_flower_cmsg_warn(app, "Flow merge memory fail.\n"); + +-err_rtnl_unlock: +- rtnl_unlock(); ++err_mutex_unlock: ++ mutex_unlock(&priv->nfp_fl_lock); + } + + static void +diff --git a/drivers/net/ethernet/netronome/nfp/flower/conntrack.c b/drivers/net/ethernet/netronome/nfp/flower/conntrack.c +index 7e9fcc16286e2..fc17e9b11d19d 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/conntrack.c ++++ b/drivers/net/ethernet/netronome/nfp/flower/conntrack.c +@@ -1665,8 +1665,6 @@ nfp_fl_ct_offload_nft_flow(struct nfp_fl_ct_zone_entry *zt, struct flow_cls_offl + struct nfp_fl_ct_flow_entry *ct_entry; + struct netlink_ext_ack *extack = NULL; + +- ASSERT_RTNL(); +- + extack = flow->common.extack; + switch (flow->command) { + case FLOW_CLS_REPLACE: +@@ -1709,9 +1707,13 @@ int nfp_fl_ct_handle_nft_flow(enum tc_setup_type type, void *type_data, void *cb + + switch (type) { + case TC_SETUP_CLSFLOWER: +- rtnl_lock(); ++ while (!mutex_trylock(&zt->priv->nfp_fl_lock)) { ++ if (!zt->nft) /* avoid deadlock */ ++ return err; ++ msleep(20); ++ } + err = nfp_fl_ct_offload_nft_flow(zt, flow); +- rtnl_unlock(); ++ mutex_unlock(&zt->priv->nfp_fl_lock); + break; + default: + return -EOPNOTSUPP; +@@ -1739,6 +1741,7 @@ int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent) + struct nfp_fl_ct_flow_entry *ct_entry; + struct nfp_fl_ct_zone_entry *zt; + struct rhashtable *m_table; ++ struct nf_flowtable *nft; + + if (!ct_map_ent) + return -ENOENT; +@@ -1755,8 +1758,12 @@ int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent) + nfp_fl_ct_clean_flow_entry(ct_entry); + kfree(ct_map_ent); + +- if (!zt->pre_ct_count) { +- zt->nft = NULL; ++ if (!zt->pre_ct_count && zt->nft) { ++ nft = zt->nft; ++ zt->nft = NULL; /* avoid deadlock */ ++ nf_flow_table_offload_del_cb(nft, ++ nfp_fl_ct_handle_nft_flow, ++ zt); + nfp_fl_ct_clean_nft_entries(zt); + } + break; +diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h +index 917c450a7aadd..f5222e3c8ce56 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/main.h ++++ b/drivers/net/ethernet/netronome/nfp/flower/main.h +@@ -196,6 +196,7 @@ struct nfp_fl_internal_ports { + * @ct_zone_table: Hash table used to store the different zones + * @ct_zone_wc: Special zone entry for wildcarded zone matches + * @ct_map_table: Hash table used to referennce ct flows ++ * @nfp_fl_lock: Lock to protect the flow offload operation + */ + struct nfp_flower_priv { + struct nfp_app *app; +@@ -233,6 +234,7 @@ struct nfp_flower_priv { + struct rhashtable ct_zone_table; + struct nfp_fl_ct_zone_entry *ct_zone_wc; + struct rhashtable ct_map_table; ++ struct mutex nfp_fl_lock; /* Protect the flow operation */ + }; + + /** +diff --git a/drivers/net/ethernet/netronome/nfp/flower/metadata.c b/drivers/net/ethernet/netronome/nfp/flower/metadata.c +index 2af9faee96c5c..a515bd89defea 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/metadata.c ++++ b/drivers/net/ethernet/netronome/nfp/flower/metadata.c +@@ -530,6 +530,8 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, + if (err) + goto err_free_stats_ctx_table; + ++ mutex_init(&priv->nfp_fl_lock); ++ + err = rhashtable_init(&priv->ct_zone_table, &nfp_zone_table_params); + if (err) + goto err_free_merge_table; +diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c +index 64c0ef57ad426..d165098c457e7 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c ++++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c +@@ -1009,8 +1009,6 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, + u64 parent_ctx = 0; + int err; + +- ASSERT_RTNL(); +- + if (sub_flow1 == sub_flow2 || + nfp_flower_is_merge_flow(sub_flow1) || + nfp_flower_is_merge_flow(sub_flow2)) +@@ -1662,19 +1660,30 @@ static int + nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev, + struct flow_cls_offload *flower) + { ++ struct nfp_flower_priv *priv = app->priv; ++ int ret; ++ + if (!eth_proto_is_802_3(flower->common.protocol)) + return -EOPNOTSUPP; + ++ mutex_lock(&priv->nfp_fl_lock); + switch (flower->command) { + case FLOW_CLS_REPLACE: +- return nfp_flower_add_offload(app, netdev, flower); ++ ret = nfp_flower_add_offload(app, netdev, flower); ++ break; + case FLOW_CLS_DESTROY: +- return nfp_flower_del_offload(app, netdev, flower); ++ ret = nfp_flower_del_offload(app, netdev, flower); ++ break; + case FLOW_CLS_STATS: +- return nfp_flower_get_stats(app, netdev, flower); ++ ret = nfp_flower_get_stats(app, netdev, flower); ++ break; + default: +- return -EOPNOTSUPP; ++ ret = -EOPNOTSUPP; ++ break; + } ++ mutex_unlock(&priv->nfp_fl_lock); ++ ++ return ret; + } + + static int nfp_flower_setup_tc_block_cb(enum tc_setup_type type, +@@ -1713,6 +1722,7 @@ static int nfp_flower_setup_tc_block(struct net_device *netdev, + repr_priv = repr->app_priv; + repr_priv->block_shared = f->block_shared; + f->driver_block_list = &nfp_block_cb_list; ++ f->unlocked_driver_cb = true; + + switch (f->command) { + case FLOW_BLOCK_BIND: +@@ -1811,6 +1821,8 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct Qdisc *sch, str + nfp_flower_internal_port_can_offload(app, netdev))) + return -EOPNOTSUPP; + ++ f->unlocked_driver_cb = true; ++ + switch (f->command) { + case FLOW_BLOCK_BIND: + cb_priv = nfp_flower_indr_block_cb_priv_lookup(app, netdev); +diff --git a/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c b/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c +index 784c6dbf8bc47..577a7a534b472 100644 +--- a/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c ++++ b/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c +@@ -421,23 +421,29 @@ int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev, + { + struct netlink_ext_ack *extack = flow->common.extack; + struct nfp_flower_priv *fl_priv = app->priv; ++ int ret; + + if (!(fl_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM)) { + NL_SET_ERR_MSG_MOD(extack, "unsupported offload: loaded firmware does not support qos rate limit offload"); + return -EOPNOTSUPP; + } + ++ mutex_lock(&fl_priv->nfp_fl_lock); + switch (flow->command) { + case TC_CLSMATCHALL_REPLACE: +- return nfp_flower_install_rate_limiter(app, netdev, flow, +- extack); ++ ret = nfp_flower_install_rate_limiter(app, netdev, flow, extack); ++ break; + case TC_CLSMATCHALL_DESTROY: +- return nfp_flower_remove_rate_limiter(app, netdev, flow, +- extack); ++ ret = nfp_flower_remove_rate_limiter(app, netdev, flow, extack); ++ break; + case TC_CLSMATCHALL_STATS: +- return nfp_flower_stats_rate_limiter(app, netdev, flow, +- extack); ++ ret = nfp_flower_stats_rate_limiter(app, netdev, flow, extack); ++ break; + default: +- return -EOPNOTSUPP; ++ ret = -EOPNOTSUPP; ++ break; + } ++ mutex_unlock(&fl_priv->nfp_fl_lock); ++ ++ return ret; + } +-- +2.40.1 + diff --git a/queue-5.15/overlayfs-set-ctime-when-setting-mtime-and-atime.patch b/queue-5.15/overlayfs-set-ctime-when-setting-mtime-and-atime.patch new file mode 100644 index 00000000000..52477cdfe8a --- /dev/null +++ b/queue-5.15/overlayfs-set-ctime-when-setting-mtime-and-atime.patch @@ -0,0 +1,47 @@ +From 93b9230676ee229274d8ad7526e3b1ae38c93bd9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 09:33:12 -0400 +Subject: overlayfs: set ctime when setting mtime and atime + +From: Jeff Layton + +[ Upstream commit 03dbab3bba5f009d053635c729d1244f2c8bad38 ] + +Nathan reported that he was seeing the new warning in +setattr_copy_mgtime pop when starting podman containers. Overlayfs is +trying to set the atime and mtime via notify_change without also +setting the ctime. + +POSIX states that when the atime and mtime are updated via utimes() that +we must also update the ctime to the current time. The situation with +overlayfs copy-up is analogies, so add ATTR_CTIME to the bitmask. +notify_change will fill in the value. + +Reported-by: Nathan Chancellor +Signed-off-by: Jeff Layton +Tested-by: Nathan Chancellor +Acked-by: Christian Brauner +Acked-by: Amir Goldstein +Message-Id: <20230913-ctime-v1-1-c6bc509cbc27@kernel.org> +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/overlayfs/copy_up.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index 864e821c3910b..0ed70eff9cb9e 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -306,7 +306,7 @@ static int ovl_set_timestamps(struct dentry *upperdentry, struct kstat *stat) + { + struct iattr attr = { + .ia_valid = +- ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET, ++ ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_CTIME, + .ia_atime = stat->atime, + .ia_mtime = stat->mtime, + }; +-- +2.40.1 + diff --git a/queue-5.15/perf-add-irq-and-exception-return-branch-types.patch b/queue-5.15/perf-add-irq-and-exception-return-branch-types.patch new file mode 100644 index 00000000000..0f082578343 --- /dev/null +++ b/queue-5.15/perf-add-irq-and-exception-return-branch-types.patch @@ -0,0 +1,87 @@ +From dabd4a12a648ce114c7d936bdb479201ad3cb043 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Feb 2022 11:06:54 +0530 +Subject: perf: Add irq and exception return branch types + +From: Anshuman Khandual + +[ Upstream commit cedd3614e5d9c80908099c19f8716714ce0610b1 ] + +This expands generic branch type classification by adding two more entries +there in i.e irq and exception return. Also updates the x86 implementation +to process X86_BR_IRET and X86_BR_IRQ records as appropriate. This changes +branch types reported to user space on x86 platform but it should not be a +problem. The possible scenarios and impacts are enumerated here. + +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/1645681014-3346-1-git-send-email-anshuman.khandual@arm.com +Stable-dep-of: e53899771a02 ("perf/x86/lbr: Filter vsyscall addresses") +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/lbr.c | 4 ++-- + include/uapi/linux/perf_event.h | 2 ++ + tools/include/uapi/linux/perf_event.h | 2 ++ + tools/perf/util/branch.c | 4 +++- + 4 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c +index b3f92255cbd2d..bc3e40184719f 100644 +--- a/arch/x86/events/intel/lbr.c ++++ b/arch/x86/events/intel/lbr.c +@@ -1352,10 +1352,10 @@ static int branch_map[X86_BR_TYPE_MAP_MAX] = { + PERF_BR_SYSCALL, /* X86_BR_SYSCALL */ + PERF_BR_SYSRET, /* X86_BR_SYSRET */ + PERF_BR_UNKNOWN, /* X86_BR_INT */ +- PERF_BR_UNKNOWN, /* X86_BR_IRET */ ++ PERF_BR_ERET, /* X86_BR_IRET */ + PERF_BR_COND, /* X86_BR_JCC */ + PERF_BR_UNCOND, /* X86_BR_JMP */ +- PERF_BR_UNKNOWN, /* X86_BR_IRQ */ ++ PERF_BR_IRQ, /* X86_BR_IRQ */ + PERF_BR_IND_CALL, /* X86_BR_IND_CALL */ + PERF_BR_UNKNOWN, /* X86_BR_ABORT */ + PERF_BR_UNKNOWN, /* X86_BR_IN_TX */ +diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h +index f92880a15645a..a7fb8d2b77096 100644 +--- a/include/uapi/linux/perf_event.h ++++ b/include/uapi/linux/perf_event.h +@@ -251,6 +251,8 @@ enum { + PERF_BR_SYSRET = 8, /* syscall return */ + PERF_BR_COND_CALL = 9, /* conditional function call */ + PERF_BR_COND_RET = 10, /* conditional function return */ ++ PERF_BR_ERET = 11, /* exception return */ ++ PERF_BR_IRQ = 12, /* irq */ + PERF_BR_MAX, + }; + +diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h +index f92880a15645a..a7fb8d2b77096 100644 +--- a/tools/include/uapi/linux/perf_event.h ++++ b/tools/include/uapi/linux/perf_event.h +@@ -251,6 +251,8 @@ enum { + PERF_BR_SYSRET = 8, /* syscall return */ + PERF_BR_COND_CALL = 9, /* conditional function call */ + PERF_BR_COND_RET = 10, /* conditional function return */ ++ PERF_BR_ERET = 11, /* exception return */ ++ PERF_BR_IRQ = 12, /* irq */ + PERF_BR_MAX, + }; + +diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c +index 2285b1eb3128d..a9a909db8cc7f 100644 +--- a/tools/perf/util/branch.c ++++ b/tools/perf/util/branch.c +@@ -49,7 +49,9 @@ const char *branch_type_name(int type) + "SYSCALL", + "SYSRET", + "COND_CALL", +- "COND_RET" ++ "COND_RET", ++ "ERET", ++ "IRQ" + }; + + if (type >= 0 && type < PERF_BR_MAX) +-- +2.40.1 + diff --git a/queue-5.15/perf-x86-lbr-filter-vsyscall-addresses.patch b/queue-5.15/perf-x86-lbr-filter-vsyscall-addresses.patch new file mode 100644 index 00000000000..4f229579b42 --- /dev/null +++ b/queue-5.15/perf-x86-lbr-filter-vsyscall-addresses.patch @@ -0,0 +1,76 @@ +From 1b6b74d0627690ac8c01e5f783c57230c6e5439f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Oct 2023 11:57:26 -0700 +Subject: perf/x86/lbr: Filter vsyscall addresses + +From: JP Kobryn + +[ Upstream commit e53899771a02f798d436655efbd9d4b46c0f9265 ] + +We found that a panic can occur when a vsyscall is made while LBR sampling +is active. If the vsyscall is interrupted (NMI) for perf sampling, this +call sequence can occur (most recent at top): + + __insn_get_emulate_prefix() + insn_get_emulate_prefix() + insn_get_prefixes() + insn_get_opcode() + decode_branch_type() + get_branch_type() + intel_pmu_lbr_filter() + intel_pmu_handle_irq() + perf_event_nmi_handler() + +Within __insn_get_emulate_prefix() at frame 0, a macro is called: + + peek_nbyte_next(insn_byte_t, insn, i) + +Within this macro, this dereference occurs: + + (insn)->next_byte + +Inspecting registers at this point, the value of the next_byte field is the +address of the vsyscall made, for example the location of the vsyscall +version of gettimeofday() at 0xffffffffff600000. The access to an address +in the vsyscall region will trigger an oops due to an unhandled page fault. + +To fix the bug, filtering for vsyscalls can be done when +determining the branch type. This patch will return +a "none" branch if a kernel address if found to lie in the +vsyscall region. + +Suggested-by: Alexei Starovoitov +Signed-off-by: JP Kobryn +Signed-off-by: Ingo Molnar +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +--- + arch/x86/events/utils.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/events/utils.c b/arch/x86/events/utils.c +index a32368945462f..b30508b88bf22 100644 +--- a/arch/x86/events/utils.c ++++ b/arch/x86/events/utils.c +@@ -1,5 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 + #include ++#include + + #include "perf_event.h" + +@@ -58,9 +59,9 @@ int branch_type(unsigned long from, unsigned long to, int abort) + * The LBR logs any address in the IP, even if the IP just + * faulted. This means userspace can control the from address. + * Ensure we don't blindly read any address by validating it is +- * a known text address. ++ * a known text address and not a vsyscall address. + */ +- if (kernel_text_address(from)) { ++ if (kernel_text_address(from) && !in_gate_area_no_mm(from)) { + addr = (void *)from; + /* + * Assume we can get the maximum possible size +-- +2.40.1 + diff --git a/queue-5.15/perf-x86-move-branch-classifier.patch b/queue-5.15/perf-x86-move-branch-classifier.patch new file mode 100644 index 00000000000..31aa4949862 --- /dev/null +++ b/queue-5.15/perf-x86-move-branch-classifier.patch @@ -0,0 +1,636 @@ +From e2cbcdee081ecc866276c390853d26b925284b03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Aug 2022 17:59:56 +0530 +Subject: perf/x86: Move branch classifier + +From: Sandipan Das + +[ Upstream commit 4462fbfe6ec1bfe2196b977010f6ce7b43a32f2c ] + +Commit 3e702ff6d1ea ("perf/x86: Add LBR software filter support for Intel +CPUs") introduces a software branch filter which complements the hardware +branch filter and adds an x86 branch classifier. + +Move the branch classifier to arch/x86/events/ so that it can be utilized +by other vendors for branch record filtering. + +Signed-off-by: Sandipan Das +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/bae5b95470d6bd49f40954bd379f414f5afcb965.1660211399.git.sandipan.das@amd.com +Stable-dep-of: e53899771a02 ("perf/x86/lbr: Filter vsyscall addresses") +Signed-off-by: Sasha Levin +--- + arch/x86/events/Makefile | 2 +- + arch/x86/events/intel/lbr.c | 273 ----------------------------------- + arch/x86/events/perf_event.h | 62 ++++++++ + arch/x86/events/utils.c | 216 +++++++++++++++++++++++++++ + 4 files changed, 279 insertions(+), 274 deletions(-) + create mode 100644 arch/x86/events/utils.c + +diff --git a/arch/x86/events/Makefile b/arch/x86/events/Makefile +index 9933c0e8e97a9..86a76efa8bb6d 100644 +--- a/arch/x86/events/Makefile ++++ b/arch/x86/events/Makefile +@@ -1,5 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0-only +-obj-y += core.o probe.o ++obj-y += core.o probe.o utils.o + obj-$(CONFIG_PERF_EVENTS_INTEL_RAPL) += rapl.o + obj-y += amd/ + obj-$(CONFIG_X86_LOCAL_APIC) += msr.o +diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c +index bc3e40184719f..e8c6575cf65ea 100644 +--- a/arch/x86/events/intel/lbr.c ++++ b/arch/x86/events/intel/lbr.c +@@ -4,7 +4,6 @@ + + #include + #include +-#include + + #include "../perf_event.h" + +@@ -73,65 +72,6 @@ static const enum { + + #define LBR_FROM_SIGNEXT_2MSB (BIT_ULL(60) | BIT_ULL(59)) + +-/* +- * x86control flow change classification +- * x86control flow changes include branches, interrupts, traps, faults +- */ +-enum { +- X86_BR_NONE = 0, /* unknown */ +- +- X86_BR_USER = 1 << 0, /* branch target is user */ +- X86_BR_KERNEL = 1 << 1, /* branch target is kernel */ +- +- X86_BR_CALL = 1 << 2, /* call */ +- X86_BR_RET = 1 << 3, /* return */ +- X86_BR_SYSCALL = 1 << 4, /* syscall */ +- X86_BR_SYSRET = 1 << 5, /* syscall return */ +- X86_BR_INT = 1 << 6, /* sw interrupt */ +- X86_BR_IRET = 1 << 7, /* return from interrupt */ +- X86_BR_JCC = 1 << 8, /* conditional */ +- X86_BR_JMP = 1 << 9, /* jump */ +- X86_BR_IRQ = 1 << 10,/* hw interrupt or trap or fault */ +- X86_BR_IND_CALL = 1 << 11,/* indirect calls */ +- X86_BR_ABORT = 1 << 12,/* transaction abort */ +- X86_BR_IN_TX = 1 << 13,/* in transaction */ +- X86_BR_NO_TX = 1 << 14,/* not in transaction */ +- X86_BR_ZERO_CALL = 1 << 15,/* zero length call */ +- X86_BR_CALL_STACK = 1 << 16,/* call stack */ +- X86_BR_IND_JMP = 1 << 17,/* indirect jump */ +- +- X86_BR_TYPE_SAVE = 1 << 18,/* indicate to save branch type */ +- +-}; +- +-#define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL) +-#define X86_BR_ANYTX (X86_BR_NO_TX | X86_BR_IN_TX) +- +-#define X86_BR_ANY \ +- (X86_BR_CALL |\ +- X86_BR_RET |\ +- X86_BR_SYSCALL |\ +- X86_BR_SYSRET |\ +- X86_BR_INT |\ +- X86_BR_IRET |\ +- X86_BR_JCC |\ +- X86_BR_JMP |\ +- X86_BR_IRQ |\ +- X86_BR_ABORT |\ +- X86_BR_IND_CALL |\ +- X86_BR_IND_JMP |\ +- X86_BR_ZERO_CALL) +- +-#define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY) +- +-#define X86_BR_ANY_CALL \ +- (X86_BR_CALL |\ +- X86_BR_IND_CALL |\ +- X86_BR_ZERO_CALL |\ +- X86_BR_SYSCALL |\ +- X86_BR_IRQ |\ +- X86_BR_INT) +- + /* + * Intel LBR_CTL bits + * +@@ -1168,219 +1108,6 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event) + return ret; + } + +-/* +- * return the type of control flow change at address "from" +- * instruction is not necessarily a branch (in case of interrupt). +- * +- * The branch type returned also includes the priv level of the +- * target of the control flow change (X86_BR_USER, X86_BR_KERNEL). +- * +- * If a branch type is unknown OR the instruction cannot be +- * decoded (e.g., text page not present), then X86_BR_NONE is +- * returned. +- */ +-static int branch_type(unsigned long from, unsigned long to, int abort) +-{ +- struct insn insn; +- void *addr; +- int bytes_read, bytes_left; +- int ret = X86_BR_NONE; +- int ext, to_plm, from_plm; +- u8 buf[MAX_INSN_SIZE]; +- int is64 = 0; +- +- to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER; +- from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER; +- +- /* +- * maybe zero if lbr did not fill up after a reset by the time +- * we get a PMU interrupt +- */ +- if (from == 0 || to == 0) +- return X86_BR_NONE; +- +- if (abort) +- return X86_BR_ABORT | to_plm; +- +- if (from_plm == X86_BR_USER) { +- /* +- * can happen if measuring at the user level only +- * and we interrupt in a kernel thread, e.g., idle. +- */ +- if (!current->mm) +- return X86_BR_NONE; +- +- /* may fail if text not present */ +- bytes_left = copy_from_user_nmi(buf, (void __user *)from, +- MAX_INSN_SIZE); +- bytes_read = MAX_INSN_SIZE - bytes_left; +- if (!bytes_read) +- return X86_BR_NONE; +- +- addr = buf; +- } else { +- /* +- * The LBR logs any address in the IP, even if the IP just +- * faulted. This means userspace can control the from address. +- * Ensure we don't blindly read any address by validating it is +- * a known text address. +- */ +- if (kernel_text_address(from)) { +- addr = (void *)from; +- /* +- * Assume we can get the maximum possible size +- * when grabbing kernel data. This is not +- * _strictly_ true since we could possibly be +- * executing up next to a memory hole, but +- * it is very unlikely to be a problem. +- */ +- bytes_read = MAX_INSN_SIZE; +- } else { +- return X86_BR_NONE; +- } +- } +- +- /* +- * decoder needs to know the ABI especially +- * on 64-bit systems running 32-bit apps +- */ +-#ifdef CONFIG_X86_64 +- is64 = kernel_ip((unsigned long)addr) || any_64bit_mode(current_pt_regs()); +-#endif +- insn_init(&insn, addr, bytes_read, is64); +- if (insn_get_opcode(&insn)) +- return X86_BR_ABORT; +- +- switch (insn.opcode.bytes[0]) { +- case 0xf: +- switch (insn.opcode.bytes[1]) { +- case 0x05: /* syscall */ +- case 0x34: /* sysenter */ +- ret = X86_BR_SYSCALL; +- break; +- case 0x07: /* sysret */ +- case 0x35: /* sysexit */ +- ret = X86_BR_SYSRET; +- break; +- case 0x80 ... 0x8f: /* conditional */ +- ret = X86_BR_JCC; +- break; +- default: +- ret = X86_BR_NONE; +- } +- break; +- case 0x70 ... 0x7f: /* conditional */ +- ret = X86_BR_JCC; +- break; +- case 0xc2: /* near ret */ +- case 0xc3: /* near ret */ +- case 0xca: /* far ret */ +- case 0xcb: /* far ret */ +- ret = X86_BR_RET; +- break; +- case 0xcf: /* iret */ +- ret = X86_BR_IRET; +- break; +- case 0xcc ... 0xce: /* int */ +- ret = X86_BR_INT; +- break; +- case 0xe8: /* call near rel */ +- if (insn_get_immediate(&insn) || insn.immediate1.value == 0) { +- /* zero length call */ +- ret = X86_BR_ZERO_CALL; +- break; +- } +- fallthrough; +- case 0x9a: /* call far absolute */ +- ret = X86_BR_CALL; +- break; +- case 0xe0 ... 0xe3: /* loop jmp */ +- ret = X86_BR_JCC; +- break; +- case 0xe9 ... 0xeb: /* jmp */ +- ret = X86_BR_JMP; +- break; +- case 0xff: /* call near absolute, call far absolute ind */ +- if (insn_get_modrm(&insn)) +- return X86_BR_ABORT; +- +- ext = (insn.modrm.bytes[0] >> 3) & 0x7; +- switch (ext) { +- case 2: /* near ind call */ +- case 3: /* far ind call */ +- ret = X86_BR_IND_CALL; +- break; +- case 4: +- case 5: +- ret = X86_BR_IND_JMP; +- break; +- } +- break; +- default: +- ret = X86_BR_NONE; +- } +- /* +- * interrupts, traps, faults (and thus ring transition) may +- * occur on any instructions. Thus, to classify them correctly, +- * we need to first look at the from and to priv levels. If they +- * are different and to is in the kernel, then it indicates +- * a ring transition. If the from instruction is not a ring +- * transition instr (syscall, systenter, int), then it means +- * it was a irq, trap or fault. +- * +- * we have no way of detecting kernel to kernel faults. +- */ +- if (from_plm == X86_BR_USER && to_plm == X86_BR_KERNEL +- && ret != X86_BR_SYSCALL && ret != X86_BR_INT) +- ret = X86_BR_IRQ; +- +- /* +- * branch priv level determined by target as +- * is done by HW when LBR_SELECT is implemented +- */ +- if (ret != X86_BR_NONE) +- ret |= to_plm; +- +- return ret; +-} +- +-#define X86_BR_TYPE_MAP_MAX 16 +- +-static int branch_map[X86_BR_TYPE_MAP_MAX] = { +- PERF_BR_CALL, /* X86_BR_CALL */ +- PERF_BR_RET, /* X86_BR_RET */ +- PERF_BR_SYSCALL, /* X86_BR_SYSCALL */ +- PERF_BR_SYSRET, /* X86_BR_SYSRET */ +- PERF_BR_UNKNOWN, /* X86_BR_INT */ +- PERF_BR_ERET, /* X86_BR_IRET */ +- PERF_BR_COND, /* X86_BR_JCC */ +- PERF_BR_UNCOND, /* X86_BR_JMP */ +- PERF_BR_IRQ, /* X86_BR_IRQ */ +- PERF_BR_IND_CALL, /* X86_BR_IND_CALL */ +- PERF_BR_UNKNOWN, /* X86_BR_ABORT */ +- PERF_BR_UNKNOWN, /* X86_BR_IN_TX */ +- PERF_BR_UNKNOWN, /* X86_BR_NO_TX */ +- PERF_BR_CALL, /* X86_BR_ZERO_CALL */ +- PERF_BR_UNKNOWN, /* X86_BR_CALL_STACK */ +- PERF_BR_IND, /* X86_BR_IND_JMP */ +-}; +- +-static int +-common_branch_type(int type) +-{ +- int i; +- +- type >>= 2; /* skip X86_BR_USER and X86_BR_KERNEL */ +- +- if (type) { +- i = __ffs(type); +- if (i < X86_BR_TYPE_MAP_MAX) +- return branch_map[i]; +- } +- +- return PERF_BR_UNKNOWN; +-} +- + enum { + ARCH_LBR_BR_TYPE_JCC = 0, + ARCH_LBR_BR_TYPE_NEAR_IND_JMP = 1, +diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h +index e3ac05c97b5e5..9b4d51c0e0ad4 100644 +--- a/arch/x86/events/perf_event.h ++++ b/arch/x86/events/perf_event.h +@@ -1181,6 +1181,68 @@ static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip) + regs->ip = ip; + } + ++/* ++ * x86control flow change classification ++ * x86control flow changes include branches, interrupts, traps, faults ++ */ ++enum { ++ X86_BR_NONE = 0, /* unknown */ ++ ++ X86_BR_USER = 1 << 0, /* branch target is user */ ++ X86_BR_KERNEL = 1 << 1, /* branch target is kernel */ ++ ++ X86_BR_CALL = 1 << 2, /* call */ ++ X86_BR_RET = 1 << 3, /* return */ ++ X86_BR_SYSCALL = 1 << 4, /* syscall */ ++ X86_BR_SYSRET = 1 << 5, /* syscall return */ ++ X86_BR_INT = 1 << 6, /* sw interrupt */ ++ X86_BR_IRET = 1 << 7, /* return from interrupt */ ++ X86_BR_JCC = 1 << 8, /* conditional */ ++ X86_BR_JMP = 1 << 9, /* jump */ ++ X86_BR_IRQ = 1 << 10,/* hw interrupt or trap or fault */ ++ X86_BR_IND_CALL = 1 << 11,/* indirect calls */ ++ X86_BR_ABORT = 1 << 12,/* transaction abort */ ++ X86_BR_IN_TX = 1 << 13,/* in transaction */ ++ X86_BR_NO_TX = 1 << 14,/* not in transaction */ ++ X86_BR_ZERO_CALL = 1 << 15,/* zero length call */ ++ X86_BR_CALL_STACK = 1 << 16,/* call stack */ ++ X86_BR_IND_JMP = 1 << 17,/* indirect jump */ ++ ++ X86_BR_TYPE_SAVE = 1 << 18,/* indicate to save branch type */ ++ ++}; ++ ++#define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL) ++#define X86_BR_ANYTX (X86_BR_NO_TX | X86_BR_IN_TX) ++ ++#define X86_BR_ANY \ ++ (X86_BR_CALL |\ ++ X86_BR_RET |\ ++ X86_BR_SYSCALL |\ ++ X86_BR_SYSRET |\ ++ X86_BR_INT |\ ++ X86_BR_IRET |\ ++ X86_BR_JCC |\ ++ X86_BR_JMP |\ ++ X86_BR_IRQ |\ ++ X86_BR_ABORT |\ ++ X86_BR_IND_CALL |\ ++ X86_BR_IND_JMP |\ ++ X86_BR_ZERO_CALL) ++ ++#define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY) ++ ++#define X86_BR_ANY_CALL \ ++ (X86_BR_CALL |\ ++ X86_BR_IND_CALL |\ ++ X86_BR_ZERO_CALL |\ ++ X86_BR_SYSCALL |\ ++ X86_BR_IRQ |\ ++ X86_BR_INT) ++ ++int common_branch_type(int type); ++int branch_type(unsigned long from, unsigned long to, int abort); ++ + ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event); + ssize_t intel_event_sysfs_show(char *page, u64 config); + +diff --git a/arch/x86/events/utils.c b/arch/x86/events/utils.c +new file mode 100644 +index 0000000000000..a32368945462f +--- /dev/null ++++ b/arch/x86/events/utils.c +@@ -0,0 +1,216 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include ++ ++#include "perf_event.h" ++ ++/* ++ * return the type of control flow change at address "from" ++ * instruction is not necessarily a branch (in case of interrupt). ++ * ++ * The branch type returned also includes the priv level of the ++ * target of the control flow change (X86_BR_USER, X86_BR_KERNEL). ++ * ++ * If a branch type is unknown OR the instruction cannot be ++ * decoded (e.g., text page not present), then X86_BR_NONE is ++ * returned. ++ */ ++int branch_type(unsigned long from, unsigned long to, int abort) ++{ ++ struct insn insn; ++ void *addr; ++ int bytes_read, bytes_left; ++ int ret = X86_BR_NONE; ++ int ext, to_plm, from_plm; ++ u8 buf[MAX_INSN_SIZE]; ++ int is64 = 0; ++ ++ to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER; ++ from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER; ++ ++ /* ++ * maybe zero if lbr did not fill up after a reset by the time ++ * we get a PMU interrupt ++ */ ++ if (from == 0 || to == 0) ++ return X86_BR_NONE; ++ ++ if (abort) ++ return X86_BR_ABORT | to_plm; ++ ++ if (from_plm == X86_BR_USER) { ++ /* ++ * can happen if measuring at the user level only ++ * and we interrupt in a kernel thread, e.g., idle. ++ */ ++ if (!current->mm) ++ return X86_BR_NONE; ++ ++ /* may fail if text not present */ ++ bytes_left = copy_from_user_nmi(buf, (void __user *)from, ++ MAX_INSN_SIZE); ++ bytes_read = MAX_INSN_SIZE - bytes_left; ++ if (!bytes_read) ++ return X86_BR_NONE; ++ ++ addr = buf; ++ } else { ++ /* ++ * The LBR logs any address in the IP, even if the IP just ++ * faulted. This means userspace can control the from address. ++ * Ensure we don't blindly read any address by validating it is ++ * a known text address. ++ */ ++ if (kernel_text_address(from)) { ++ addr = (void *)from; ++ /* ++ * Assume we can get the maximum possible size ++ * when grabbing kernel data. This is not ++ * _strictly_ true since we could possibly be ++ * executing up next to a memory hole, but ++ * it is very unlikely to be a problem. ++ */ ++ bytes_read = MAX_INSN_SIZE; ++ } else { ++ return X86_BR_NONE; ++ } ++ } ++ ++ /* ++ * decoder needs to know the ABI especially ++ * on 64-bit systems running 32-bit apps ++ */ ++#ifdef CONFIG_X86_64 ++ is64 = kernel_ip((unsigned long)addr) || any_64bit_mode(current_pt_regs()); ++#endif ++ insn_init(&insn, addr, bytes_read, is64); ++ if (insn_get_opcode(&insn)) ++ return X86_BR_ABORT; ++ ++ switch (insn.opcode.bytes[0]) { ++ case 0xf: ++ switch (insn.opcode.bytes[1]) { ++ case 0x05: /* syscall */ ++ case 0x34: /* sysenter */ ++ ret = X86_BR_SYSCALL; ++ break; ++ case 0x07: /* sysret */ ++ case 0x35: /* sysexit */ ++ ret = X86_BR_SYSRET; ++ break; ++ case 0x80 ... 0x8f: /* conditional */ ++ ret = X86_BR_JCC; ++ break; ++ default: ++ ret = X86_BR_NONE; ++ } ++ break; ++ case 0x70 ... 0x7f: /* conditional */ ++ ret = X86_BR_JCC; ++ break; ++ case 0xc2: /* near ret */ ++ case 0xc3: /* near ret */ ++ case 0xca: /* far ret */ ++ case 0xcb: /* far ret */ ++ ret = X86_BR_RET; ++ break; ++ case 0xcf: /* iret */ ++ ret = X86_BR_IRET; ++ break; ++ case 0xcc ... 0xce: /* int */ ++ ret = X86_BR_INT; ++ break; ++ case 0xe8: /* call near rel */ ++ if (insn_get_immediate(&insn) || insn.immediate1.value == 0) { ++ /* zero length call */ ++ ret = X86_BR_ZERO_CALL; ++ break; ++ } ++ fallthrough; ++ case 0x9a: /* call far absolute */ ++ ret = X86_BR_CALL; ++ break; ++ case 0xe0 ... 0xe3: /* loop jmp */ ++ ret = X86_BR_JCC; ++ break; ++ case 0xe9 ... 0xeb: /* jmp */ ++ ret = X86_BR_JMP; ++ break; ++ case 0xff: /* call near absolute, call far absolute ind */ ++ if (insn_get_modrm(&insn)) ++ return X86_BR_ABORT; ++ ++ ext = (insn.modrm.bytes[0] >> 3) & 0x7; ++ switch (ext) { ++ case 2: /* near ind call */ ++ case 3: /* far ind call */ ++ ret = X86_BR_IND_CALL; ++ break; ++ case 4: ++ case 5: ++ ret = X86_BR_IND_JMP; ++ break; ++ } ++ break; ++ default: ++ ret = X86_BR_NONE; ++ } ++ /* ++ * interrupts, traps, faults (and thus ring transition) may ++ * occur on any instructions. Thus, to classify them correctly, ++ * we need to first look at the from and to priv levels. If they ++ * are different and to is in the kernel, then it indicates ++ * a ring transition. If the from instruction is not a ring ++ * transition instr (syscall, systenter, int), then it means ++ * it was a irq, trap or fault. ++ * ++ * we have no way of detecting kernel to kernel faults. ++ */ ++ if (from_plm == X86_BR_USER && to_plm == X86_BR_KERNEL ++ && ret != X86_BR_SYSCALL && ret != X86_BR_INT) ++ ret = X86_BR_IRQ; ++ ++ /* ++ * branch priv level determined by target as ++ * is done by HW when LBR_SELECT is implemented ++ */ ++ if (ret != X86_BR_NONE) ++ ret |= to_plm; ++ ++ return ret; ++} ++ ++#define X86_BR_TYPE_MAP_MAX 16 ++ ++static int branch_map[X86_BR_TYPE_MAP_MAX] = { ++ PERF_BR_CALL, /* X86_BR_CALL */ ++ PERF_BR_RET, /* X86_BR_RET */ ++ PERF_BR_SYSCALL, /* X86_BR_SYSCALL */ ++ PERF_BR_SYSRET, /* X86_BR_SYSRET */ ++ PERF_BR_UNKNOWN, /* X86_BR_INT */ ++ PERF_BR_ERET, /* X86_BR_IRET */ ++ PERF_BR_COND, /* X86_BR_JCC */ ++ PERF_BR_UNCOND, /* X86_BR_JMP */ ++ PERF_BR_IRQ, /* X86_BR_IRQ */ ++ PERF_BR_IND_CALL, /* X86_BR_IND_CALL */ ++ PERF_BR_UNKNOWN, /* X86_BR_ABORT */ ++ PERF_BR_UNKNOWN, /* X86_BR_IN_TX */ ++ PERF_BR_UNKNOWN, /* X86_BR_NO_TX */ ++ PERF_BR_CALL, /* X86_BR_ZERO_CALL */ ++ PERF_BR_UNKNOWN, /* X86_BR_CALL_STACK */ ++ PERF_BR_IND, /* X86_BR_IND_JMP */ ++}; ++ ++int common_branch_type(int type) ++{ ++ int i; ++ ++ type >>= 2; /* skip X86_BR_USER and X86_BR_KERNEL */ ++ ++ if (type) { ++ i = __ffs(type); ++ if (i < X86_BR_TYPE_MAP_MAX) ++ return branch_map[i]; ++ } ++ ++ return PERF_BR_UNKNOWN; ++} +-- +2.40.1 + diff --git a/queue-5.15/platform-x86-touchscreen_dmi-add-info-for-the-positi.patch b/queue-5.15/platform-x86-touchscreen_dmi-add-info-for-the-positi.patch new file mode 100644 index 00000000000..133707e1b10 --- /dev/null +++ b/queue-5.15/platform-x86-touchscreen_dmi-add-info-for-the-positi.patch @@ -0,0 +1,65 @@ +From e4eea38431b1c285d185920c4bc81d769ea425c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 19:59:00 -0400 +Subject: platform/x86: touchscreen_dmi: Add info for the Positivo C4128B + +From: Renan Guilherme Lebre Ramos + +[ Upstream commit aa7dcba3bae6869122828b144a3cfd231718089d ] + +Add information for the Positivo C4128B, a notebook/tablet convertible. + +Link: https://github.com/onitake/gsl-firmware/pull/217 +Signed-off-by: Renan Guilherme Lebre Ramos +Link: https://lore.kernel.org/r/20231004235900.426240-1-japareaggae@gmail.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/touchscreen_dmi.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index 90aee8b87bbe0..f129e29b295d9 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -743,6 +743,21 @@ static const struct ts_dmi_data pipo_w11_data = { + .properties = pipo_w11_props, + }; + ++static const struct property_entry positivo_c4128b_props[] = { ++ PROPERTY_ENTRY_U32("touchscreen-min-x", 4), ++ PROPERTY_ENTRY_U32("touchscreen-min-y", 13), ++ PROPERTY_ENTRY_U32("touchscreen-size-x", 1915), ++ PROPERTY_ENTRY_U32("touchscreen-size-y", 1269), ++ PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-positivo-c4128b.fw"), ++ PROPERTY_ENTRY_U32("silead,max-fingers", 10), ++ { } ++}; ++ ++static const struct ts_dmi_data positivo_c4128b_data = { ++ .acpi_name = "MSSL1680:00", ++ .properties = positivo_c4128b_props, ++}; ++ + static const struct property_entry pov_mobii_wintab_p800w_v20_props[] = { + PROPERTY_ENTRY_U32("touchscreen-min-x", 32), + PROPERTY_ENTRY_U32("touchscreen-min-y", 16), +@@ -1442,6 +1457,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_BIOS_VERSION, "MOMO.G.WI71C.MABMRBA02"), + }, + }, ++ { ++ /* Positivo C4128B */ ++ .driver_data = (void *)&positivo_c4128b_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "C4128B-1"), ++ }, ++ }, + { + /* Point of View mobii wintab p800w (v2.0) */ + .driver_data = (void *)&pov_mobii_wintab_p800w_v20_data, +-- +2.40.1 + diff --git a/queue-5.15/powerpc-32s-do-kuep_lock-and-kuep_unlock-in-assembly.patch b/queue-5.15/powerpc-32s-do-kuep_lock-and-kuep_unlock-in-assembly.patch new file mode 100644 index 00000000000..51232d32bab --- /dev/null +++ b/queue-5.15/powerpc-32s-do-kuep_lock-and-kuep_unlock-in-assembly.patch @@ -0,0 +1,354 @@ +From a81572b85f663d9a604802959a4137857f53cecb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Oct 2021 09:29:17 +0200 +Subject: powerpc/32s: Do kuep_lock() and kuep_unlock() in assembly + +From: Christophe Leroy + +[ Upstream commit 526d4a4c77aedf1b7df1133e5cced29c70232e6e ] + +When interrupt and syscall entries where converted to C, KUEP locking +and unlocking was also converted. It improved performance by unrolling +the loop, and allowed easily implementing boot time deactivation of +KUEP. + +However, null_syscall selftest shows that KUEP is still heavy +(361 cycles with KUEP, 212 cycles without). + +A way to improve more is to group 'mtsr's together, instead of +repeating 'addi' + 'mtsr' several times. + +In order to do that, more registers need to be available. In C, GCC +will always be able to provide the requested number of registers, but +at the cost of saving some data on the stack, which is counter +performant here. + +So let's do it in assembly, when we have full control of which +register can be used. It also has the advantage of locking earlier +and unlocking later and it helps GCC generating less tricky code. +The only drawback is to make boot time deactivation less straight +forward and require 'hand' instruction patching. + +Group 'mtsr's by 4. + +With this change, null_syscall selftest reports 336 cycles. Without +the change it was 361 cycles, that's a 7% reduction. + +Signed-off-by: Christophe Leroy +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/115cb279e9b9948dfd93a065e047081c59e3a2a6.1634627931.git.christophe.leroy@csgroup.eu +Stable-dep-of: f0eee815babe ("powerpc/47x: Fix 47x syscall return crash") +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/book3s/32/kup.h | 34 -------- + arch/powerpc/include/asm/book3s/32/mmu-hash.h | 77 ++++++++++++++++++- + arch/powerpc/include/asm/interrupt.h | 6 +- + arch/powerpc/include/asm/kup.h | 5 -- + arch/powerpc/kernel/entry_32.S | 31 ++++++++ + arch/powerpc/kernel/head_32.h | 6 ++ + arch/powerpc/kernel/head_book3s_32.S | 4 + + arch/powerpc/kernel/interrupt.c | 3 - + arch/powerpc/mm/book3s32/kuep.c | 2 - + 9 files changed, 119 insertions(+), 49 deletions(-) + +diff --git a/arch/powerpc/include/asm/book3s/32/kup.h b/arch/powerpc/include/asm/book3s/32/kup.h +index fb6c39225dd19..e3db5ed4b255e 100644 +--- a/arch/powerpc/include/asm/book3s/32/kup.h ++++ b/arch/powerpc/include/asm/book3s/32/kup.h +@@ -23,40 +23,6 @@ static __always_inline bool kuep_is_disabled(void) + return !IS_ENABLED(CONFIG_PPC_KUEP); + } + +-static inline void kuep_lock(void) +-{ +- if (kuep_is_disabled()) +- return; +- +- update_user_segments(mfsr(0) | SR_NX); +- /* +- * This isync() shouldn't be necessary as the kernel is not excepted to +- * run any instruction in userspace soon after the update of segments, +- * but hash based cores (at least G3) seem to exhibit a random +- * behaviour when the 'isync' is not there. 603 cores don't have this +- * behaviour so don't do the 'isync' as it saves several CPU cycles. +- */ +- if (mmu_has_feature(MMU_FTR_HPTE_TABLE)) +- isync(); /* Context sync required after mtsr() */ +-} +- +-static inline void kuep_unlock(void) +-{ +- if (kuep_is_disabled()) +- return; +- +- update_user_segments(mfsr(0) & ~SR_NX); +- /* +- * This isync() shouldn't be necessary as a 'rfi' will soon be executed +- * to return to userspace, but hash based cores (at least G3) seem to +- * exhibit a random behaviour when the 'isync' is not there. 603 cores +- * don't have this behaviour so don't do the 'isync' as it saves several +- * CPU cycles. +- */ +- if (mmu_has_feature(MMU_FTR_HPTE_TABLE)) +- isync(); /* Context sync required after mtsr() */ +-} +- + #ifdef CONFIG_PPC_KUAP + + #include +diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h +index 94ad7acfd0565..d4bf2a67396be 100644 +--- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h ++++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h +@@ -64,7 +64,82 @@ struct ppc_bat { + #define SR_KP 0x20000000 /* User key */ + #define SR_KS 0x40000000 /* Supervisor key */ + +-#ifndef __ASSEMBLY__ ++#ifdef __ASSEMBLY__ ++ ++#include ++ ++.macro uus_addi sr reg1 reg2 imm ++ .if NUM_USER_SEGMENTS > \sr ++ addi \reg1,\reg2,\imm ++ .endif ++.endm ++ ++.macro uus_mtsr sr reg1 ++ .if NUM_USER_SEGMENTS > \sr ++ mtsr \sr, \reg1 ++ .endif ++.endm ++ ++/* ++ * This isync() shouldn't be necessary as the kernel is not excepted to run ++ * any instruction in userspace soon after the update of segments and 'rfi' ++ * instruction is used to return to userspace, but hash based cores ++ * (at least G3) seem to exhibit a random behaviour when the 'isync' is not ++ * there. 603 cores don't have this behaviour so don't do the 'isync' as it ++ * saves several CPU cycles. ++ */ ++.macro uus_isync ++#ifdef CONFIG_PPC_BOOK3S_604 ++BEGIN_MMU_FTR_SECTION ++ isync ++END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) ++#endif ++.endm ++ ++.macro update_user_segments_by_4 tmp1 tmp2 tmp3 tmp4 ++ uus_addi 1, \tmp2, \tmp1, 0x111 ++ uus_addi 2, \tmp3, \tmp1, 0x222 ++ uus_addi 3, \tmp4, \tmp1, 0x333 ++ ++ uus_mtsr 0, \tmp1 ++ uus_mtsr 1, \tmp2 ++ uus_mtsr 2, \tmp3 ++ uus_mtsr 3, \tmp4 ++ ++ uus_addi 4, \tmp1, \tmp1, 0x444 ++ uus_addi 5, \tmp2, \tmp2, 0x444 ++ uus_addi 6, \tmp3, \tmp3, 0x444 ++ uus_addi 7, \tmp4, \tmp4, 0x444 ++ ++ uus_mtsr 4, \tmp1 ++ uus_mtsr 5, \tmp2 ++ uus_mtsr 6, \tmp3 ++ uus_mtsr 7, \tmp4 ++ ++ uus_addi 8, \tmp1, \tmp1, 0x444 ++ uus_addi 9, \tmp2, \tmp2, 0x444 ++ uus_addi 10, \tmp3, \tmp3, 0x444 ++ uus_addi 11, \tmp4, \tmp4, 0x444 ++ ++ uus_mtsr 8, \tmp1 ++ uus_mtsr 9, \tmp2 ++ uus_mtsr 10, \tmp3 ++ uus_mtsr 11, \tmp4 ++ ++ uus_addi 12, \tmp1, \tmp1, 0x444 ++ uus_addi 13, \tmp2, \tmp2, 0x444 ++ uus_addi 14, \tmp3, \tmp3, 0x444 ++ uus_addi 15, \tmp4, \tmp4, 0x444 ++ ++ uus_mtsr 12, \tmp1 ++ uus_mtsr 13, \tmp2 ++ uus_mtsr 14, \tmp3 ++ uus_mtsr 15, \tmp4 ++ ++ uus_isync ++.endm ++ ++#else + + /* + * This macro defines the mapping from contexts to VSIDs (virtual +diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h +index a07960066b5fa..e592e65e7665c 100644 +--- a/arch/powerpc/include/asm/interrupt.h ++++ b/arch/powerpc/include/asm/interrupt.h +@@ -139,12 +139,10 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup + if (!arch_irq_disabled_regs(regs)) + trace_hardirqs_off(); + +- if (user_mode(regs)) { +- kuep_lock(); ++ if (user_mode(regs)) + account_cpu_user_entry(); +- } else { ++ else + kuap_save_and_lock(regs); +- } + #endif + + #ifdef CONFIG_PPC64 +diff --git a/arch/powerpc/include/asm/kup.h b/arch/powerpc/include/asm/kup.h +index 1df763002726a..34ff86e3686ea 100644 +--- a/arch/powerpc/include/asm/kup.h ++++ b/arch/powerpc/include/asm/kup.h +@@ -38,11 +38,6 @@ void setup_kuep(bool disabled); + static inline void setup_kuep(bool disabled) { } + #endif /* CONFIG_PPC_KUEP */ + +-#ifndef CONFIG_PPC_BOOK3S_32 +-static inline void kuep_lock(void) { } +-static inline void kuep_unlock(void) { } +-#endif +- + #ifdef CONFIG_PPC_KUAP + void setup_kuap(bool disabled); + #else +diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S +index c62dd98159653..0756829b2f7fa 100644 +--- a/arch/powerpc/kernel/entry_32.S ++++ b/arch/powerpc/kernel/entry_32.S +@@ -73,6 +73,34 @@ prepare_transfer_to_handler: + _ASM_NOKPROBE_SYMBOL(prepare_transfer_to_handler) + #endif /* CONFIG_PPC_BOOK3S_32 || CONFIG_E500 */ + ++#if defined(CONFIG_PPC_KUEP) && defined(CONFIG_PPC_BOOK3S_32) ++ .globl __kuep_lock ++__kuep_lock: ++ mfsr r9,0 ++ rlwinm r9,r9,0,8,3 ++ oris r9,r9,SR_NX@h ++ update_user_segments_by_4 r9, r10, r11, r12 ++ blr ++ ++__kuep_unlock: ++ mfsr r9,0 ++ rlwinm r9,r9,0,8,2 ++ update_user_segments_by_4 r9, r10, r11, r12 ++ blr ++ ++.macro kuep_lock ++ bl __kuep_lock ++.endm ++.macro kuep_unlock ++ bl __kuep_unlock ++.endm ++#else ++.macro kuep_lock ++.endm ++.macro kuep_unlock ++.endm ++#endif ++ + .globl transfer_to_syscall + transfer_to_syscall: + stw r11, GPR1(r1) +@@ -93,6 +121,7 @@ transfer_to_syscall: + SAVE_GPRS(3, 8, r1) + addi r2,r10,-THREAD + SAVE_NVGPRS(r1) ++ kuep_lock + + /* Calling convention has r9 = orig r0, r10 = regs */ + addi r10,r1,STACK_FRAME_OVERHEAD +@@ -109,6 +138,7 @@ ret_from_syscall: + cmplwi cr0,r5,0 + bne- 2f + #endif /* CONFIG_PPC_47x */ ++ kuep_unlock + lwz r4,_LINK(r1) + lwz r5,_CCR(r1) + mtlr r4 +@@ -272,6 +302,7 @@ interrupt_return: + beq .Lkernel_interrupt_return + bl interrupt_exit_user_prepare + cmpwi r3,0 ++ kuep_unlock + bne- .Lrestore_nvgprs + + .Lfast_user_interrupt_return: +diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h +index 261c79bdbe53f..c3286260a7d1c 100644 +--- a/arch/powerpc/kernel/head_32.h ++++ b/arch/powerpc/kernel/head_32.h +@@ -135,6 +135,12 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt) + andi. r12,r9,MSR_PR + bne 777f + bl prepare_transfer_to_handler ++#ifdef CONFIG_PPC_KUEP ++ b 778f ++777: ++ bl __kuep_lock ++778: ++#endif + 777: + #endif + .endm +diff --git a/arch/powerpc/kernel/head_book3s_32.S b/arch/powerpc/kernel/head_book3s_32.S +index 68e5c0a7e99d1..fa84744d6b248 100644 +--- a/arch/powerpc/kernel/head_book3s_32.S ++++ b/arch/powerpc/kernel/head_book3s_32.S +@@ -931,7 +931,11 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) + _GLOBAL(load_segment_registers) + li r0, NUM_USER_SEGMENTS /* load up user segment register values */ + mtctr r0 /* for context 0 */ ++#ifdef CONFIG_PPC_KUEP ++ lis r3, SR_NX@h /* Kp = 0, Ks = 0, VSID = 0 */ ++#else + li r3, 0 /* Kp = 0, Ks = 0, VSID = 0 */ ++#endif + li r4, 0 + 3: mtsrin r3, r4 + addi r3, r3, 0x111 /* increment VSID */ +diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c +index e93f67c3af76b..c53725a598e5b 100644 +--- a/arch/powerpc/kernel/interrupt.c ++++ b/arch/powerpc/kernel/interrupt.c +@@ -83,8 +83,6 @@ notrace long system_call_exception(long r3, long r4, long r5, + { + syscall_fn f; + +- kuep_lock(); +- + regs->orig_gpr3 = r3; + + if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) +@@ -408,7 +406,6 @@ interrupt_exit_user_prepare_main(unsigned long ret, struct pt_regs *regs) + + /* Restore user access locks last */ + kuap_user_restore(regs); +- kuep_unlock(); + + return ret; + } +diff --git a/arch/powerpc/mm/book3s32/kuep.c b/arch/powerpc/mm/book3s32/kuep.c +index 8474edce3df9a..bac1420d028b6 100644 +--- a/arch/powerpc/mm/book3s32/kuep.c ++++ b/arch/powerpc/mm/book3s32/kuep.c +@@ -5,8 +5,6 @@ + + void setup_kuep(bool disabled) + { +- kuep_lock(); +- + if (smp_processor_id() != boot_cpuid) + return; + +-- +2.40.1 + diff --git a/queue-5.15/powerpc-32s-remove-capability-to-disable-kuep-at-boo.patch b/queue-5.15/powerpc-32s-remove-capability-to-disable-kuep-at-boo.patch new file mode 100644 index 00000000000..860548b629d --- /dev/null +++ b/queue-5.15/powerpc-32s-remove-capability-to-disable-kuep-at-boo.patch @@ -0,0 +1,73 @@ +From 10ea835ab61d34200c05e870d69b6b6fcaf26993 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Oct 2021 09:29:16 +0200 +Subject: powerpc/32s: Remove capability to disable KUEP at boottime + +From: Christophe Leroy + +[ Upstream commit df415cd758261bceff27f34a145dd8328bbfb018 ] + +Disabling KUEP at boottime makes things unnecessarily complex. + +Still allow disabling KUEP at build time, but when it's built-in +it is always there. + +Signed-off-by: Christophe Leroy +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/96f583f82423a29a4205c60b9721079111b35567.1634627931.git.christophe.leroy@csgroup.eu +Stable-dep-of: f0eee815babe ("powerpc/47x: Fix 47x syscall return crash") +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/book3s/32/kup.h | 3 +-- + arch/powerpc/mm/book3s32/kuep.c | 10 ++-------- + 2 files changed, 3 insertions(+), 10 deletions(-) + +diff --git a/arch/powerpc/include/asm/book3s/32/kup.h b/arch/powerpc/include/asm/book3s/32/kup.h +index 9f38040f0641d..fb6c39225dd19 100644 +--- a/arch/powerpc/include/asm/book3s/32/kup.h ++++ b/arch/powerpc/include/asm/book3s/32/kup.h +@@ -12,7 +12,6 @@ + #include + + extern struct static_key_false disable_kuap_key; +-extern struct static_key_false disable_kuep_key; + + static __always_inline bool kuap_is_disabled(void) + { +@@ -21,7 +20,7 @@ static __always_inline bool kuap_is_disabled(void) + + static __always_inline bool kuep_is_disabled(void) + { +- return !IS_ENABLED(CONFIG_PPC_KUEP) || static_branch_unlikely(&disable_kuep_key); ++ return !IS_ENABLED(CONFIG_PPC_KUEP); + } + + static inline void kuep_lock(void) +diff --git a/arch/powerpc/mm/book3s32/kuep.c b/arch/powerpc/mm/book3s32/kuep.c +index c20733d6e02cb..8474edce3df9a 100644 +--- a/arch/powerpc/mm/book3s32/kuep.c ++++ b/arch/powerpc/mm/book3s32/kuep.c +@@ -3,18 +3,12 @@ + #include + #include + +-struct static_key_false disable_kuep_key; +- + void setup_kuep(bool disabled) + { +- if (!disabled) +- kuep_lock(); ++ kuep_lock(); + + if (smp_processor_id() != boot_cpuid) + return; + +- if (disabled) +- static_branch_enable(&disable_kuep_key); +- else +- pr_info("Activating Kernel Userspace Execution Prevention\n"); ++ pr_info("Activating Kernel Userspace Execution Prevention\n"); + } +-- +2.40.1 + diff --git a/queue-5.15/powerpc-47x-fix-47x-syscall-return-crash.patch b/queue-5.15/powerpc-47x-fix-47x-syscall-return-crash.patch new file mode 100644 index 00000000000..2ca4a5eef19 --- /dev/null +++ b/queue-5.15/powerpc-47x-fix-47x-syscall-return-crash.patch @@ -0,0 +1,100 @@ +From e8d03c211ca2194013114187bafd96fc44cbdde8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 22:47:50 +1100 +Subject: powerpc/47x: Fix 47x syscall return crash +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michael Ellerman + +[ Upstream commit f0eee815babed70a749d2496a7678be5b45b4c14 ] + +Eddie reported that newer kernels were crashing during boot on his 476 +FSP2 system: + + kernel tried to execute user page (b7ee2000) - exploit attempt? (uid: 0) + BUG: Unable to handle kernel instruction fetch + Faulting instruction address: 0xb7ee2000 + Oops: Kernel access of bad area, sig: 11 [#1] + BE PAGE_SIZE=4K FSP-2 + Modules linked in: + CPU: 0 PID: 61 Comm: mount Not tainted 6.1.55-d23900f.ppcnf-fsp2 #1 + Hardware name: ibm,fsp2 476fpe 0x7ff520c0 FSP-2 + NIP:  b7ee2000 LR: 8c008000 CTR: 00000000 + REGS: bffebd83 TRAP: 0400   Not tainted (6.1.55-d23900f.ppcnf-fs p2) + MSR:  00000030   CR: 00001000  XER: 20000000 + GPR00: c00110ac bffebe63 bffebe7e bffebe88 8c008000 00001000 00000d12 b7ee2000 + GPR08: 00000033 00000000 00000000 c139df10 48224824 1016c314 10160000 00000000 + GPR16: 10160000 10160000 00000008 00000000 10160000 00000000 10160000 1017f5b0 + GPR24: 1017fa50 1017f4f0 1017fa50 1017f740 1017f630 00000000 00000000 1017f4f0 + NIP [b7ee2000] 0xb7ee2000 + LR [8c008000] 0x8c008000 + Call Trace: + Instruction dump: + XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX + XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX + ---[ end trace 0000000000000000 ]--- + +The problem is in ret_from_syscall where the check for +icache_44x_need_flush is done. When the flush is needed the code jumps +out-of-line to do the flush, and then intends to jump back to continue +the syscall return. + +However the branch back to label 1b doesn't return to the correct +location, instead branching back just prior to the return to userspace, +causing bogus register values to be used by the rfi. + +The breakage was introduced by commit 6f76a01173cc +("powerpc/syscall: implement system call entry/exit logic in C for PPC32") which +inadvertently removed the "1" label and reused it elsewhere. + +Fix it by adding named local labels in the correct locations. Note that +the return label needs to be outside the ifdef so that CONFIG_PPC_47x=n +compiles. + +Fixes: 6f76a01173cc ("powerpc/syscall: implement system call entry/exit logic in C for PPC32") +Cc: stable@vger.kernel.org # v5.12+ +Reported-by: Eddie James +Tested-by: Eddie James +Link: https://lore.kernel.org/linuxppc-dev/fdaadc46-7476-9237-e104-1d2168526e72@linux.ibm.com/ +Signed-off-by: Michael Ellerman +Reviewed-by: Christophe Leroy +Link: https://msgid.link/20231010114750.847794-1-mpe@ellerman.id.au +Signed-off-by: Sasha Levin +--- + arch/powerpc/kernel/entry_32.S | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S +index 0756829b2f7fa..3eb3c74e402b5 100644 +--- a/arch/powerpc/kernel/entry_32.S ++++ b/arch/powerpc/kernel/entry_32.S +@@ -136,8 +136,9 @@ ret_from_syscall: + lis r4,icache_44x_need_flush@ha + lwz r5,icache_44x_need_flush@l(r4) + cmplwi cr0,r5,0 +- bne- 2f ++ bne- .L44x_icache_flush + #endif /* CONFIG_PPC_47x */ ++.L44x_icache_flush_return: + kuep_unlock + lwz r4,_LINK(r1) + lwz r5,_CCR(r1) +@@ -173,10 +174,11 @@ syscall_exit_finish: + b 1b + + #ifdef CONFIG_44x +-2: li r7,0 ++.L44x_icache_flush: ++ li r7,0 + iccci r0,r0 + stw r7,icache_44x_need_flush@l(r4) +- b 1b ++ b .L44x_icache_flush_return + #endif /* CONFIG_44x */ + + .globl ret_from_fork +-- +2.40.1 + diff --git a/queue-5.15/regulator-core-revert-fix-kobject-release-warning-an.patch b/queue-5.15/regulator-core-revert-fix-kobject-release-warning-an.patch new file mode 100644 index 00000000000..dd6b99f0879 --- /dev/null +++ b/queue-5.15/regulator-core-revert-fix-kobject-release-warning-an.patch @@ -0,0 +1,50 @@ +From b190c42af4cc4a690afcbcc6e0ae82252655b05a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 00:50:27 +0200 +Subject: regulator/core: Revert "fix kobject release warning and memory leak + in regulator_register()" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michał Mirosław + +[ Upstream commit 6e800968f6a715c0661716d2ec5e1f56ed9f9c08 ] + +This reverts commit 5f4b204b6b8153923d5be8002c5f7082985d153f. + +Since rdev->dev now has a release() callback, the proper way of freeing +the initialized device can be restored. + +Signed-off-by: Michał Mirosław +Link: https://lore.kernel.org/r/d7f469f3f7b1f0e1d52f9a7ede3f3c5703382090.1695077303.git.mirq-linux@rere.qmqm.pl +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index ebde10e744343..8ad50dc8fb356 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -5649,15 +5649,11 @@ regulator_register(const struct regulator_desc *regulator_desc, + mutex_lock(®ulator_list_mutex); + regulator_ena_gpio_free(rdev); + mutex_unlock(®ulator_list_mutex); +- put_device(&rdev->dev); +- rdev = NULL; + clean: + if (dangling_of_gpiod) + gpiod_put(config->ena_gpiod); +- if (rdev && rdev->dev.of_node) +- of_node_put(rdev->dev.of_node); +- kfree(rdev); + kfree(config); ++ put_device(&rdev->dev); + rinse: + if (dangling_cfg_gpiod) + gpiod_put(cfg->ena_gpiod); +-- +2.40.1 + diff --git a/queue-5.15/selftests-mm-fix-awk-usage-in-charge_reserved_hugetl.patch b/queue-5.15/selftests-mm-fix-awk-usage-in-charge_reserved_hugetl.patch new file mode 100644 index 00000000000..5625e1a77fe --- /dev/null +++ b/queue-5.15/selftests-mm-fix-awk-usage-in-charge_reserved_hugetl.patch @@ -0,0 +1,77 @@ +From f239591b5989f42d86ebcd53ecbb2ecf3e7910f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 02:19:44 +0800 +Subject: selftests/mm: fix awk usage in charge_reserved_hugetlb.sh and + hugetlb_reparenting_test.sh that may cause error + +From: Juntong Deng + +[ Upstream commit bbe246f875d064ecfb872fe4f66152e743dfd22d ] + +According to the awk manual, the -e option does not need to be specified +in front of 'program' (unless you need to mix program-file). + +The redundant -e option can cause error when users use awk tools other +than gawk (for example, mawk does not support the -e option). + +Error Example: +awk: not an option: -e + +Link: https://lkml.kernel.org/r/VI1P193MB075228810591AF2FDD7D42C599C3A@VI1P193MB0752.EURP193.PROD.OUTLOOK.COM +Signed-off-by: Juntong Deng +Cc: Shuah Khan +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/vm/charge_reserved_hugetlb.sh | 4 ++-- + tools/testing/selftests/vm/hugetlb_reparenting_test.sh | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/testing/selftests/vm/charge_reserved_hugetlb.sh b/tools/testing/selftests/vm/charge_reserved_hugetlb.sh +index a5cb4b09a46c4..0899019a7fcb4 100644 +--- a/tools/testing/selftests/vm/charge_reserved_hugetlb.sh ++++ b/tools/testing/selftests/vm/charge_reserved_hugetlb.sh +@@ -25,7 +25,7 @@ if [[ "$1" == "-cgroup-v2" ]]; then + fi + + if [[ $cgroup2 ]]; then +- cgroup_path=$(mount -t cgroup2 | head -1 | awk -e '{print $3}') ++ cgroup_path=$(mount -t cgroup2 | head -1 | awk '{print $3}') + if [[ -z "$cgroup_path" ]]; then + cgroup_path=/dev/cgroup/memory + mount -t cgroup2 none $cgroup_path +@@ -33,7 +33,7 @@ if [[ $cgroup2 ]]; then + fi + echo "+hugetlb" >$cgroup_path/cgroup.subtree_control + else +- cgroup_path=$(mount -t cgroup | grep ",hugetlb" | awk -e '{print $3}') ++ cgroup_path=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}') + if [[ -z "$cgroup_path" ]]; then + cgroup_path=/dev/cgroup/memory + mount -t cgroup memory,hugetlb $cgroup_path +diff --git a/tools/testing/selftests/vm/hugetlb_reparenting_test.sh b/tools/testing/selftests/vm/hugetlb_reparenting_test.sh +index bf2d2a684edfd..14d26075c8635 100644 +--- a/tools/testing/selftests/vm/hugetlb_reparenting_test.sh ++++ b/tools/testing/selftests/vm/hugetlb_reparenting_test.sh +@@ -20,7 +20,7 @@ fi + + + if [[ $cgroup2 ]]; then +- CGROUP_ROOT=$(mount -t cgroup2 | head -1 | awk -e '{print $3}') ++ CGROUP_ROOT=$(mount -t cgroup2 | head -1 | awk '{print $3}') + if [[ -z "$CGROUP_ROOT" ]]; then + CGROUP_ROOT=/dev/cgroup/memory + mount -t cgroup2 none $CGROUP_ROOT +@@ -28,7 +28,7 @@ if [[ $cgroup2 ]]; then + fi + echo "+hugetlb +memory" >$CGROUP_ROOT/cgroup.subtree_control + else +- CGROUP_ROOT=$(mount -t cgroup | grep ",hugetlb" | awk -e '{print $3}') ++ CGROUP_ROOT=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}') + if [[ -z "$CGROUP_ROOT" ]]; then + CGROUP_ROOT=/dev/cgroup/memory + mount -t cgroup memory,hugetlb $CGROUP_ROOT +-- +2.40.1 + diff --git a/queue-5.15/serial-8250-omap-fix-imprecise-external-abort-for-om.patch b/queue-5.15/serial-8250-omap-fix-imprecise-external-abort-for-om.patch new file mode 100644 index 00000000000..f090a4139e9 --- /dev/null +++ b/queue-5.15/serial-8250-omap-fix-imprecise-external-abort-for-om.patch @@ -0,0 +1,260 @@ +From 162c2c230f3172f1f8356abd122638cb8bba1119 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 May 2023 11:20:12 +0300 +Subject: serial: 8250: omap: Fix imprecise external abort for omap_8250_pm() + +From: Tony Lindgren + +[ Upstream commit 398cecc24846e867b9f90a0bd22730e3df6b05be ] + +We must idle the uart only after serial8250_unregister_port(). Otherwise +unbinding the uart via sysfs while doing cat on the port produces an +imprecise external abort: + +mem_serial_in from omap_8250_pm+0x44/0xf4 +omap_8250_pm from uart_hangup+0xe0/0x194 +uart_hangup from __tty_hangup.part.0+0x37c/0x3a8 +__tty_hangup.part.0 from uart_remove_one_port+0x9c/0x22c +uart_remove_one_port from serial8250_unregister_port+0x60/0xe8 +serial8250_unregister_port from omap8250_remove+0x6c/0xd0 +omap8250_remove from platform_remove+0x28/0x54 + +Turns out the driver needs to have runtime PM functional before the +driver probe calls serial8250_register_8250_port(). And it needs +runtime PM after driver remove calls serial8250_unregister_port(). + +On probe, we need to read registers before registering the port in +omap_serial_fill_features_erratas(). We do that with custom uart_read() +already. + +On remove, after serial8250_unregister_port(), we need to write to the +uart registers to idle the device. Let's add a custom uart_write() for +that. + +Currently the uart register access depends on port->membase to be +initialized, which won't work after serial8250_unregister_port(). +Let's use priv->membase instead, and use it for runtime PM related +functions to remove the dependency to port->membase for early and +late register access. + +Note that during use, we need to check for a valid port in the runtime PM +related functions. This is needed for the optional wakeup configuration. +We now need to set the drvdata a bit earlier so it's available for the +runtime PM functions. + +With the port checks in runtime PM functions, the old checks for priv in +omap8250_runtime_suspend() and omap8250_runtime_resume() functions are no +longer needed and are removed. + +Signed-off-by: Tony Lindgren +Link: https://lore.kernel.org/r/20230508082014.23083-3-tony@atomide.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 560706eff7c8 ("serial: 8250_omap: Fix errors with no_console_suspend") +Signed-off-by: Sasha Levin +--- + drivers/tty/serial/8250/8250_omap.c | 70 ++++++++++++++++------------- + 1 file changed, 38 insertions(+), 32 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c +index a6b374c026a87..2454c903c97d5 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -32,6 +32,7 @@ + #include "8250.h" + + #define DEFAULT_CLK_SPEED 48000000 ++#define OMAP_UART_REGSHIFT 2 + + #define UART_ERRATA_i202_MDR1_ACCESS (1 << 0) + #define OMAP_UART_WER_HAS_TX_WAKEUP (1 << 1) +@@ -109,6 +110,7 @@ + #define UART_OMAP_RX_LVL 0x19 + + struct omap8250_priv { ++ void __iomem *membase; + int line; + u8 habit; + u8 mdr1; +@@ -152,9 +154,14 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p); + static inline void omap_8250_rx_dma_flush(struct uart_8250_port *p) { } + #endif + +-static u32 uart_read(struct uart_8250_port *up, u32 reg) ++static u32 uart_read(struct omap8250_priv *priv, u32 reg) + { +- return readl(up->port.membase + (reg << up->port.regshift)); ++ return readl(priv->membase + (reg << OMAP_UART_REGSHIFT)); ++} ++ ++static void uart_write(struct omap8250_priv *priv, u32 reg, u32 val) ++{ ++ writel(val, priv->membase + (reg << OMAP_UART_REGSHIFT)); + } + + /* +@@ -552,7 +559,7 @@ static void omap_serial_fill_features_erratas(struct uart_8250_port *up, + u32 mvr, scheme; + u16 revision, major, minor; + +- mvr = uart_read(up, UART_OMAP_MVER); ++ mvr = uart_read(priv, UART_OMAP_MVER); + + /* Check revision register scheme */ + scheme = mvr >> OMAP_UART_MVR_SCHEME_SHIFT; +@@ -1336,7 +1343,7 @@ static int omap8250_probe(struct platform_device *pdev) + UPF_HARD_FLOW; + up.port.private_data = priv; + +- up.port.regshift = 2; ++ up.port.regshift = OMAP_UART_REGSHIFT; + up.port.fifosize = 64; + up.tx_loadsz = 64; + up.capabilities = UART_CAP_FIFO; +@@ -1397,6 +1404,8 @@ static int omap8250_probe(struct platform_device *pdev) + DEFAULT_CLK_SPEED); + } + ++ priv->membase = membase; ++ priv->line = -ENODEV; + priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; + priv->calc_latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; + cpu_latency_qos_add_request(&priv->pm_qos_request, priv->latency); +@@ -1404,6 +1413,8 @@ static int omap8250_probe(struct platform_device *pdev) + + spin_lock_init(&priv->rx_dma_lock); + ++ platform_set_drvdata(pdev, priv); ++ + device_init_wakeup(&pdev->dev, true); + pm_runtime_enable(&pdev->dev); + pm_runtime_use_autosuspend(&pdev->dev); +@@ -1465,7 +1476,6 @@ static int omap8250_probe(struct platform_device *pdev) + goto err; + } + priv->line = ret; +- platform_set_drvdata(pdev, priv); + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); + return 0; +@@ -1487,11 +1497,12 @@ static int omap8250_remove(struct platform_device *pdev) + if (err) + return err; + ++ serial8250_unregister_port(priv->line); ++ priv->line = -ENODEV; + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_put_sync(&pdev->dev); + flush_work(&priv->qos_work); + pm_runtime_disable(&pdev->dev); +- serial8250_unregister_port(priv->line); + cpu_latency_qos_remove_request(&priv->pm_qos_request); + device_init_wakeup(&pdev->dev, false); + return 0; +@@ -1577,7 +1588,6 @@ static int omap8250_lost_context(struct uart_8250_port *up) + static int omap8250_soft_reset(struct device *dev) + { + struct omap8250_priv *priv = dev_get_drvdata(dev); +- struct uart_8250_port *up = serial8250_get_port(priv->line); + int timeout = 100; + int sysc; + int syss; +@@ -1591,20 +1601,20 @@ static int omap8250_soft_reset(struct device *dev) + * needing omap8250_soft_reset() quirk. Do it in two writes as + * recommended in the comment for omap8250_update_scr(). + */ +- serial_out(up, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1); +- serial_out(up, UART_OMAP_SCR, ++ uart_write(priv, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1); ++ uart_write(priv, UART_OMAP_SCR, + OMAP_UART_SCR_DMAMODE_1 | OMAP_UART_SCR_DMAMODE_CTL); + +- sysc = serial_in(up, UART_OMAP_SYSC); ++ sysc = uart_read(priv, UART_OMAP_SYSC); + + /* softreset the UART */ + sysc |= OMAP_UART_SYSC_SOFTRESET; +- serial_out(up, UART_OMAP_SYSC, sysc); ++ uart_write(priv, UART_OMAP_SYSC, sysc); + + /* By experiments, 1us enough for reset complete on AM335x */ + do { + udelay(1); +- syss = serial_in(up, UART_OMAP_SYSS); ++ syss = uart_read(priv, UART_OMAP_SYSS); + } while (--timeout && !(syss & OMAP_UART_SYSS_RESETDONE)); + + if (!timeout) { +@@ -1618,13 +1628,10 @@ static int omap8250_soft_reset(struct device *dev) + static int omap8250_runtime_suspend(struct device *dev) + { + struct omap8250_priv *priv = dev_get_drvdata(dev); +- struct uart_8250_port *up; +- +- /* In case runtime-pm tries this before we are setup */ +- if (!priv) +- return 0; ++ struct uart_8250_port *up = NULL; + +- up = serial8250_get_port(priv->line); ++ if (priv->line >= 0) ++ up = serial8250_get_port(priv->line); + /* + * When using 'no_console_suspend', the console UART must not be + * suspended. Since driver suspend is managed by runtime suspend, +@@ -1632,7 +1639,7 @@ static int omap8250_runtime_suspend(struct device *dev) + * active during suspend. + */ + if (priv->is_suspending && !console_suspend_enabled) { +- if (uart_console(&up->port)) ++ if (up && uart_console(&up->port)) + return -EBUSY; + } + +@@ -1643,13 +1650,15 @@ static int omap8250_runtime_suspend(struct device *dev) + if (ret) + return ret; + +- /* Restore to UART mode after reset (for wakeup) */ +- omap8250_update_mdr1(up, priv); +- /* Restore wakeup enable register */ +- serial_out(up, UART_OMAP_WER, priv->wer); ++ if (up) { ++ /* Restore to UART mode after reset (for wakeup) */ ++ omap8250_update_mdr1(up, priv); ++ /* Restore wakeup enable register */ ++ serial_out(up, UART_OMAP_WER, priv->wer); ++ } + } + +- if (up->dma && up->dma->rxchan) ++ if (up && up->dma && up->dma->rxchan) + omap_8250_rx_dma_flush(up); + + priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; +@@ -1661,18 +1670,15 @@ static int omap8250_runtime_suspend(struct device *dev) + static int omap8250_runtime_resume(struct device *dev) + { + struct omap8250_priv *priv = dev_get_drvdata(dev); +- struct uart_8250_port *up; +- +- /* In case runtime-pm tries this before we are setup */ +- if (!priv) +- return 0; ++ struct uart_8250_port *up = NULL; + +- up = serial8250_get_port(priv->line); ++ if (priv->line >= 0) ++ up = serial8250_get_port(priv->line); + +- if (omap8250_lost_context(up)) ++ if (up && omap8250_lost_context(up)) + omap8250_restore_regs(up); + +- if (up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) ++ if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2)) + omap_8250_rx_dma(up); + + priv->latency = priv->calc_latency; +-- +2.40.1 + diff --git a/queue-5.15/serial-8250_omap-fix-errors-with-no_console_suspend.patch b/queue-5.15/serial-8250_omap-fix-errors-with-no_console_suspend.patch new file mode 100644 index 00000000000..31f5df490f1 --- /dev/null +++ b/queue-5.15/serial-8250_omap-fix-errors-with-no_console_suspend.patch @@ -0,0 +1,97 @@ +From c9767b9c2788a4341f1bd7dbb827b0c2598c882c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Sep 2023 09:13:17 +0300 +Subject: serial: 8250_omap: Fix errors with no_console_suspend + +From: Tony Lindgren + +[ Upstream commit 560706eff7c8e5621b0d63afe0866e0e1906e87e ] + +We now get errors on system suspend if no_console_suspend is set as +reported by Thomas. The errors started with commit 20a41a62618d ("serial: +8250_omap: Use force_suspend and resume for system suspend"). + +Let's fix the issue by checking for console_suspend_enabled in the system +suspend and resume path. + +Note that with this fix the checks for console_suspend_enabled in +omap8250_runtime_suspend() become useless. We now keep runtime PM usage +count for an attached kernel console starting with commit bedb404e91bb +("serial: 8250_port: Don't use power management for kernel console"). + +Fixes: 20a41a62618d ("serial: 8250_omap: Use force_suspend and resume for system suspend") +Cc: stable +Cc: Udit Kumar +Reported-by: Thomas Richard +Signed-off-by: Tony Lindgren +Tested-by: Thomas Richard +Reviewed-by: Dhruva Gole +Link: https://lore.kernel.org/r/20230926061319.15140-1-tony@atomide.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/tty/serial/8250/8250_omap.c | 25 ++++++++++--------------- + 1 file changed, 10 insertions(+), 15 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c +index 2454c903c97d5..94629d2c84893 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -1532,7 +1532,7 @@ static int omap8250_suspend(struct device *dev) + { + struct omap8250_priv *priv = dev_get_drvdata(dev); + struct uart_8250_port *up = serial8250_get_port(priv->line); +- int err; ++ int err = 0; + + serial8250_suspend_port(priv->line); + +@@ -1542,7 +1542,8 @@ static int omap8250_suspend(struct device *dev) + if (!device_may_wakeup(dev)) + priv->wer = 0; + serial_out(up, UART_OMAP_WER, priv->wer); +- err = pm_runtime_force_suspend(dev); ++ if (uart_console(&up->port) && console_suspend_enabled) ++ err = pm_runtime_force_suspend(dev); + flush_work(&priv->qos_work); + + return err; +@@ -1551,11 +1552,15 @@ static int omap8250_suspend(struct device *dev) + static int omap8250_resume(struct device *dev) + { + struct omap8250_priv *priv = dev_get_drvdata(dev); ++ struct uart_8250_port *up = serial8250_get_port(priv->line); + int err; + +- err = pm_runtime_force_resume(dev); +- if (err) +- return err; ++ if (uart_console(&up->port) && console_suspend_enabled) { ++ err = pm_runtime_force_resume(dev); ++ if (err) ++ return err; ++ } ++ + serial8250_resume_port(priv->line); + /* Paired with pm_runtime_resume_and_get() in omap8250_suspend() */ + pm_runtime_mark_last_busy(dev); +@@ -1632,16 +1637,6 @@ static int omap8250_runtime_suspend(struct device *dev) + + if (priv->line >= 0) + up = serial8250_get_port(priv->line); +- /* +- * When using 'no_console_suspend', the console UART must not be +- * suspended. Since driver suspend is managed by runtime suspend, +- * preventing runtime suspend (by returning error) will keep device +- * active during suspend. +- */ +- if (priv->is_suspending && !console_suspend_enabled) { +- if (up && uart_console(&up->port)) +- return -EBUSY; +- } + + if (priv->habit & UART_ERRATA_CLOCK_DISABLE) { + int ret; +-- +2.40.1 + diff --git a/queue-5.15/series b/queue-5.15/series index b49b059b6f1..5e2b96faf3f 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -49,3 +49,63 @@ netfilter-nft_set_rbtree-.deactivate-fails-if-element-has-expired.patch netfilter-nf_tables-do-not-remove-elements-if-set-backend-implements-.abort.patch netfilter-nf_tables-revert-do-not-remove-elements-if-set-backend-implements-.abort.patch net-pktgen-fix-interface-flags-printing.patch +selftests-mm-fix-awk-usage-in-charge_reserved_hugetl.patch +serial-8250-omap-fix-imprecise-external-abort-for-om.patch +serial-8250_omap-fix-errors-with-no_console_suspend.patch +iio-un-inline-iio_buffer_enabled.patch +iio-core-hide-read-accesses-to-iio_dev-currentmode.patch +iio-core-introduce-iio_device_-claim-release-_buffer.patch +iio-cros_ec-fix-an-use-after-free-in-cros_ec_sensors.patch +iio-adc-ad7192-correct-reference-voltage.patch +perf-add-irq-and-exception-return-branch-types.patch +perf-x86-move-branch-classifier.patch +perf-x86-lbr-filter-vsyscall-addresses.patch +drm-get-rid-of-drm_debug_-log-calls-in-drm-core-file.patch +drm-atomic-helper-relax-unregistered-connector-check.patch +powerpc-32s-remove-capability-to-disable-kuep-at-boo.patch +powerpc-32s-do-kuep_lock-and-kuep_unlock-in-assembly.patch +powerpc-47x-fix-47x-syscall-return-crash.patch +mctp-allow-local-delivery-to-the-null-eid.patch +mctp-perform-route-lookups-under-a-rcu-read-side-loc.patch +nfp-flower-avoid-rmmod-nfp-crash-issues.patch +ksmbd-not-allow-to-open-file-if-delelete-on-close-bi.patch +arm-dts-ti-omap-fix-noisy-serial-with-overrun-thrott.patch +fs-writeback-do-not-requeue-a-clean-inode-having-ski.patch +btrfs-return-euclean-for-delayed-tree-ref-with-a-ref.patch +btrfs-initialize-start_slot-in-btrfs_log_prealloc_ex.patch +i2c-mux-avoid-potential-false-error-message-in-i2c_m.patch +overlayfs-set-ctime-when-setting-mtime-and-atime.patch +gpio-timberdale-fix-potential-deadlock-on-tgpio-lock.patch +ata-libata-core-fix-compilation-warning-in-ata_dev_c.patch +ata-libata-eh-fix-compilation-warning-in-ata_eh_link.patch +tracing-relax-trace_event_eval_update-execution-with.patch +wifi-mwifiex-sanity-check-tlv_len-and-tlv_bitmap_len.patch +wifi-iwlwifi-ensure-ack-flag-is-properly-cleared.patch +hid-holtek-fix-slab-out-of-bounds-write-in-holtek_kb.patch +bluetooth-btusb-add-shutdown-function-for-qca6174.patch +bluetooth-avoid-redundant-authentication.patch +bluetooth-hci_core-fix-build-warnings.patch +wifi-cfg80211-fix-6ghz-scan-configuration.patch +wifi-mac80211-allow-transmitting-eapol-frames-with-t.patch +wifi-cfg80211-avoid-leaking-stack-data-into-trace.patch +regulator-core-revert-fix-kobject-release-warning-an.patch +sky2-make-sure-there-is-at-least-one-frag_addr-avail.patch +ipv4-fib-send-notify-when-delete-source-address-rout.patch +drm-panel-orientation-quirks-add-quirk-for-one-mix-2.patch +btrfs-fix-some-wmaybe-uninitialized-warnings-in-ioct.patch +btrfs-error-out-when-cowing-block-using-a-stale-tran.patch +btrfs-error-when-cowing-block-from-a-root-that-is-be.patch +btrfs-error-out-when-reallocating-block-for-defrag-u.patch +hid-multitouch-add-required-quirk-for-synaptics-0xcd.patch +platform-x86-touchscreen_dmi-add-info-for-the-positi.patch +netfilter-nf_tables-do-not-remove-elements-if-set-ba.patch +net-mlx5-handle-fw-tracer-change-ownership-event-bas.patch +devlink-make-devlink_register-to-be-void.patch +ice-open-devlink-when-device-is-ready.patch +ice-remove-useless-dma-32-fallback-configuration.patch +ice-remove-redundant-pci_enable_pcie_error_reporting.patch +bluetooth-hci_event-fix-using-memcmp-when-comparing-.patch +netfilter-nf_tables-revert-do-not-remove-elements-if.patch +net-introduce-a-function-to-check-if-a-netdev-name-i.patch +net-move-from-strlcpy-with-unused-retval-to-strscpy.patch +net-fix-ifname-in-netlink-ntf-during-netns-move.patch diff --git a/queue-5.15/sky2-make-sure-there-is-at-least-one-frag_addr-avail.patch b/queue-5.15/sky2-make-sure-there-is-at-least-one-frag_addr-avail.patch new file mode 100644 index 00000000000..179f8f9ca79 --- /dev/null +++ b/queue-5.15/sky2-make-sure-there-is-at-least-one-frag_addr-avail.patch @@ -0,0 +1,73 @@ +From 8a2eabe9402e695a0d61b4ecc87eb00f49b837b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Sep 2023 09:50:39 -0700 +Subject: sky2: Make sure there is at least one frag_addr available + +From: Kees Cook + +[ Upstream commit 6a70e5cbedaf8ad10528ac9ac114f3ec20f422df ] + +In the pathological case of building sky2 with 16k PAGE_SIZE, the +frag_addr[] array would never be used, so the original code was correct +that size should be 0. But the compiler now gets upset with 0 size arrays +in places where it hasn't eliminated the code that might access such an +array (it can't figure out that in this case an rx skb with fragments +would never be created). To keep the compiler happy, make sure there is +at least 1 frag_addr in struct rx_ring_info: + + In file included from include/linux/skbuff.h:28, + from include/net/net_namespace.h:43, + from include/linux/netdevice.h:38, + from drivers/net/ethernet/marvell/sky2.c:18: + drivers/net/ethernet/marvell/sky2.c: In function 'sky2_rx_unmap_skb': + include/linux/dma-mapping.h:416:36: warning: array subscript i is outside array bounds of 'dma_addr_t[0]' {aka 'long long unsigned int[]'} [-Warray-bounds=] + 416 | #define dma_unmap_page(d, a, s, r) dma_unmap_page_attrs(d, a, s, r, 0) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + drivers/net/ethernet/marvell/sky2.c:1257:17: note: in expansion of macro 'dma_unmap_page' + 1257 | dma_unmap_page(&pdev->dev, re->frag_addr[i], + | ^~~~~~~~~~~~~~ + In file included from drivers/net/ethernet/marvell/sky2.c:41: + drivers/net/ethernet/marvell/sky2.h:2198:25: note: while referencing 'frag_addr' + 2198 | dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; + | ^~~~~~~~~ + +With CONFIG_PAGE_SIZE_16KB=y, PAGE_SHIFT == 14, so: + + #define ETH_JUMBO_MTU 9000 + +causes "ETH_JUMBO_MTU >> PAGE_SHIFT" to be 0. Use "?: 1" to solve this build warning. + +Cc: Mirko Lindner +Cc: Stephen Hemminger +Cc: "David S. Miller" +Cc: Eric Dumazet +Cc: Jakub Kicinski +Cc: Paolo Abeni +Cc: netdev@vger.kernel.org +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202309191958.UBw1cjXk-lkp@intel.com/ +Reviewed-by: Alexander Lobakin +Signed-off-by: Kees Cook +Reviewed-by: Gustavo A. R. Silva +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/sky2.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h +index ddec1627f1a7b..8d0bacf4e49cc 100644 +--- a/drivers/net/ethernet/marvell/sky2.h ++++ b/drivers/net/ethernet/marvell/sky2.h +@@ -2195,7 +2195,7 @@ struct rx_ring_info { + struct sk_buff *skb; + dma_addr_t data_addr; + DEFINE_DMA_UNMAP_LEN(data_size); +- dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; ++ dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT ?: 1]; + }; + + enum flow_control { +-- +2.40.1 + diff --git a/queue-5.15/tracing-relax-trace_event_eval_update-execution-with.patch b/queue-5.15/tracing-relax-trace_event_eval_update-execution-with.patch new file mode 100644 index 00000000000..4599e61e66a --- /dev/null +++ b/queue-5.15/tracing-relax-trace_event_eval_update-execution-with.patch @@ -0,0 +1,55 @@ +From 4b04c476512267b2d02d2007bba81798e87b5e6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 21:16:37 +0200 +Subject: tracing: relax trace_event_eval_update() execution with + cond_resched() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Clément Léger + +[ Upstream commit 23cce5f25491968b23fb9c399bbfb25f13870cd9 ] + +When kernel is compiled without preemption, the eval_map_work_func() +(which calls trace_event_eval_update()) will not be preempted up to its +complete execution. This can actually cause a problem since if another +CPU call stop_machine(), the call will have to wait for the +eval_map_work_func() function to finish executing in the workqueue +before being able to be scheduled. This problem was observe on a SMP +system at boot time, when the CPU calling the initcalls executed +clocksource_done_booting() which in the end calls stop_machine(). We +observed a 1 second delay because one CPU was executing +eval_map_work_func() and was not preempted by the stop_machine() task. + +Adding a call to cond_resched() in trace_event_eval_update() allows +other tasks to be executed and thus continue working asynchronously +like before without blocking any pending task at boot time. + +Link: https://lore.kernel.org/linux-trace-kernel/20230929191637.416931-1-cleger@rivosinc.com + +Cc: Masami Hiramatsu +Signed-off-by: Clément Léger +Tested-by: Atish Patra +Reviewed-by: Atish Patra +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Sasha Levin +--- + kernel/trace/trace_events.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index c626d02776a54..f8af4a15c3a88 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -2753,6 +2753,7 @@ void trace_event_eval_update(struct trace_eval_map **map, int len) + update_event_fields(call, map[i]); + } + } ++ cond_resched(); + } + up_write(&trace_event_sem); + } +-- +2.40.1 + diff --git a/queue-5.15/wifi-cfg80211-avoid-leaking-stack-data-into-trace.patch b/queue-5.15/wifi-cfg80211-avoid-leaking-stack-data-into-trace.patch new file mode 100644 index 00000000000..997fa7a455b --- /dev/null +++ b/queue-5.15/wifi-cfg80211-avoid-leaking-stack-data-into-trace.patch @@ -0,0 +1,38 @@ +From 7bda3069aa4617ebe6caaa39a58b84cd49542728 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 17:18:56 +0200 +Subject: wifi: cfg80211: avoid leaking stack data into trace + +From: Benjamin Berg + +[ Upstream commit 334bf33eec5701a1e4e967bcb7cc8611a998334b ] + +If the structure is not initialized then boolean types might be copied +into the tracing data without being initialised. This causes data from +the stack to leak into the trace and also triggers a UBSAN failure which +can easily be avoided here. + +Signed-off-by: Benjamin Berg +Link: https://lore.kernel.org/r/20230925171855.a9271ef53b05.I8180bae663984c91a3e036b87f36a640ba409817@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/nl80211.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index ed3ec7e320ced..82b93380afec4 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -7664,7 +7664,7 @@ static int nl80211_update_mesh_config(struct sk_buff *skb, + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; +- struct mesh_config cfg; ++ struct mesh_config cfg = {}; + u32 mask; + int err; + +-- +2.40.1 + diff --git a/queue-5.15/wifi-cfg80211-fix-6ghz-scan-configuration.patch b/queue-5.15/wifi-cfg80211-fix-6ghz-scan-configuration.patch new file mode 100644 index 00000000000..b6b5155af12 --- /dev/null +++ b/queue-5.15/wifi-cfg80211-fix-6ghz-scan-configuration.patch @@ -0,0 +1,40 @@ +From 78c8ae94e0cfb28b9462b98ee495aeb4cfd046f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 14:10:54 +0300 +Subject: wifi: cfg80211: Fix 6GHz scan configuration + +From: Ilan Peer + +[ Upstream commit 0914468adf92296c4cba8a2134e06e3dea150f2e ] + +When the scan request includes a non broadcast BSSID, when adding the +scan parameters for 6GHz collocated scanning, do not include entries +that do not match the given BSSID. + +Signed-off-by: Ilan Peer +Signed-off-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230918140607.6d31d2a96baf.I6c4e3e3075d1d1878ee41f45190fdc6b86f18708@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/scan.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/wireless/scan.c b/net/wireless/scan.c +index c7192d7bcbd76..4decdc2c601fc 100644 +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -874,6 +874,10 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev) + !cfg80211_find_ssid_match(ap, request)) + continue; + ++ if (!is_broadcast_ether_addr(request->bssid) && ++ !ether_addr_equal(request->bssid, ap->bssid)) ++ continue; ++ + if (!request->n_ssids && ap->multi_bss && !ap->transmitted_bssid) + continue; + +-- +2.40.1 + diff --git a/queue-5.15/wifi-iwlwifi-ensure-ack-flag-is-properly-cleared.patch b/queue-5.15/wifi-iwlwifi-ensure-ack-flag-is-properly-cleared.patch new file mode 100644 index 00000000000..10ada3891f3 --- /dev/null +++ b/queue-5.15/wifi-iwlwifi-ensure-ack-flag-is-properly-cleared.patch @@ -0,0 +1,46 @@ +From 8f1217979516ffdc29eb4759f926280ca6c014e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Aug 2023 13:56:05 -0700 +Subject: wifi: iwlwifi: Ensure ack flag is properly cleared. + +From: Ben Greear + +[ Upstream commit e8fbe99e87877f0412655f40d7c45bf8471470ac ] + +Debugging indicates that nothing else is clearing the info->flags, +so some frames were flagged as ACKed when they should not be. +Explicitly clear the ack flag to ensure this does not happen. + +Signed-off-by: Ben Greear +Acked-by: Gregory Greenman +Link: https://lore.kernel.org/r/20230808205605.4105670-1-greearb@candelatech.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +index e354918c2480f..b127e0b527ce0 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -1445,6 +1445,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, + iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); + + memset(&info->status, 0, sizeof(info->status)); ++ info->flags &= ~(IEEE80211_TX_STAT_ACK | IEEE80211_TX_STAT_TX_FILTERED); + + /* inform mac80211 about what happened with the frame */ + switch (status & TX_STATUS_MSK) { +@@ -1790,6 +1791,8 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid, + */ + if (!is_flush) + info->flags |= IEEE80211_TX_STAT_ACK; ++ else ++ info->flags &= ~IEEE80211_TX_STAT_ACK; + } + + /* +-- +2.40.1 + diff --git a/queue-5.15/wifi-mac80211-allow-transmitting-eapol-frames-with-t.patch b/queue-5.15/wifi-mac80211-allow-transmitting-eapol-frames-with-t.patch new file mode 100644 index 00000000000..29aec0ab38f --- /dev/null +++ b/queue-5.15/wifi-mac80211-allow-transmitting-eapol-frames-with-t.patch @@ -0,0 +1,110 @@ +From 1f787ea208230eed42ba0175cb639d6e6a1f7f27 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Aug 2023 02:47:51 -0400 +Subject: wifi: mac80211: allow transmitting EAPOL frames with tainted key + +From: Wen Gong + +[ Upstream commit 61304336c67358d49a989e5e0060d8c99bad6ca8 ] + +Lower layer device driver stop/wake TX by calling ieee80211_stop_queue()/ +ieee80211_wake_queue() while hw scan. Sometimes hw scan and PTK rekey are +running in parallel, when M4 sent from wpa_supplicant arrive while the TX +queue is stopped, then the M4 will pending send, and then new key install +from wpa_supplicant. After TX queue wake up by lower layer device driver, +the M4 will be dropped by below call stack. + +When key install started, the current key flag is set KEY_FLAG_TAINTED in +ieee80211_pairwise_rekey(), and then mac80211 wait key install complete by +lower layer device driver. Meanwhile ieee80211_tx_h_select_key() will return +TX_DROP for the M4 in step 12 below, and then ieee80211_free_txskb() called +by ieee80211_tx_dequeue(), so the M4 will not send and free, then the rekey +process failed becaue AP not receive M4. Please see details in steps below. + +There are a interval between KEY_FLAG_TAINTED set for current key flag and +install key complete by lower layer device driver, the KEY_FLAG_TAINTED is +set in this interval, all packet including M4 will be dropped in this +interval, the interval is step 8~13 as below. + +issue steps: + TX thread install key thread +1. stop_queue -idle- +2. sending M4 -idle- +3. M4 pending -idle- +4. -idle- starting install key from wpa_supplicant +5. -idle- =>ieee80211_key_replace() +6. -idle- =>ieee80211_pairwise_rekey() and set + currently key->flags |= KEY_FLAG_TAINTED +7. -idle- =>ieee80211_key_enable_hw_accel() +8. -idle- =>drv_set_key() and waiting key install + complete from lower layer device driver +9. wake_queue -waiting state- +10. re-sending M4 -waiting state- +11. =>ieee80211_tx_h_select_key() -waiting state- +12. drop M4 by KEY_FLAG_TAINTED -waiting state- +13. -idle- install key complete with success/fail + success: clear flag KEY_FLAG_TAINTED + fail: start disconnect + +Hence add check in step 11 above to allow the EAPOL send out in the +interval. If lower layer device driver use the old key/cipher to encrypt +the M4, then AP received/decrypt M4 correctly, after M4 send out, lower +layer device driver install the new key/cipher to hardware and return +success. + +If lower layer device driver use new key/cipher to send the M4, then AP +will/should drop the M4, then it is same result with this issue, AP will/ +should kick out station as well as this issue. + +issue log: +kworker/u16:4-5238 [000] 6456.108926: stop_queue: phy1 queue:0, reason:0 +wpa_supplicant-961 [003] 6456.119737: rdev_tx_control_port: wiphy_name=phy1 name=wlan0 ifindex=6 dest=ARRAY[9e, 05, 31, 20, 9b, d0] proto=36488 unencrypted=0 +wpa_supplicant-961 [003] 6456.119839: rdev_return_int_cookie: phy1, returned 0, cookie: 504 +wpa_supplicant-961 [003] 6456.120287: rdev_add_key: phy1, netdev:wlan0(6), key_index: 0, mode: 0, pairwise: true, mac addr: 9e:05:31:20:9b:d0 +wpa_supplicant-961 [003] 6456.120453: drv_set_key: phy1 vif:wlan0(2) sta:9e:05:31:20:9b:d0 cipher:0xfac04, flags=0x9, keyidx=0, hw_key_idx=0 +kworker/u16:9-3829 [001] 6456.168240: wake_queue: phy1 queue:0, reason:0 +kworker/u16:9-3829 [001] 6456.168255: drv_wake_tx_queue: phy1 vif:wlan0(2) sta:9e:05:31:20:9b:d0 ac:0 tid:7 +kworker/u16:9-3829 [001] 6456.168305: cfg80211_control_port_tx_status: wdev(1), cookie: 504, ack: false +wpa_supplicant-961 [003] 6459.167982: drv_return_int: phy1 - -110 + +issue call stack: +nl80211_frame_tx_status+0x230/0x340 [cfg80211] +cfg80211_control_port_tx_status+0x1c/0x28 [cfg80211] +ieee80211_report_used_skb+0x374/0x3e8 [mac80211] +ieee80211_free_txskb+0x24/0x40 [mac80211] +ieee80211_tx_dequeue+0x644/0x954 [mac80211] +ath10k_mac_tx_push_txq+0xac/0x238 [ath10k_core] +ath10k_mac_op_wake_tx_queue+0xac/0xe0 [ath10k_core] +drv_wake_tx_queue+0x80/0x168 [mac80211] +__ieee80211_wake_txqs+0xe8/0x1c8 [mac80211] +_ieee80211_wake_txqs+0xb4/0x120 [mac80211] +ieee80211_wake_txqs+0x48/0x80 [mac80211] +tasklet_action_common+0xa8/0x254 +tasklet_action+0x2c/0x38 +__do_softirq+0xdc/0x384 + +Signed-off-by: Wen Gong +Link: https://lore.kernel.org/r/20230801064751.25803-1-quic_wgong@quicinc.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/tx.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c +index 8f8dc2625d535..d5c89c6758f2c 100644 +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -644,7 +644,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) + } + + if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED && +- !ieee80211_is_deauth(hdr->frame_control))) ++ !ieee80211_is_deauth(hdr->frame_control)) && ++ tx->skb->protocol != tx->sdata->control_port_protocol) + return TX_DROP; + + if (!skip_hw && tx->key && +-- +2.40.1 + diff --git a/queue-5.15/wifi-mwifiex-sanity-check-tlv_len-and-tlv_bitmap_len.patch b/queue-5.15/wifi-mwifiex-sanity-check-tlv_len-and-tlv_bitmap_len.patch new file mode 100644 index 00000000000..33a3343ebe4 --- /dev/null +++ b/queue-5.15/wifi-mwifiex-sanity-check-tlv_len-and-tlv_bitmap_len.patch @@ -0,0 +1,62 @@ +From 5c2f2de97b7322b31c0dda1d8a018ce1f109c8f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Aug 2023 21:10:45 -0600 +Subject: wifi: mwifiex: Sanity check tlv_len and tlv_bitmap_len + +From: Gustavo A. R. Silva + +[ Upstream commit d5a93b7d2877aae4ba7590ad6cb65f8d33079489 ] + +Add sanity checks for both `tlv_len` and `tlv_bitmap_len` before +decoding data from `event_buf`. + +This prevents any malicious or buggy firmware from overflowing +`event_buf` through large values for `tlv_len` and `tlv_bitmap_len`. + +Suggested-by: Dan Williams +Signed-off-by: Gustavo A. R. Silva +Reviewed-by: Kees Cook +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/d4f8780527d551552ee96f17a0229e02e1c200d1.1692931954.git.gustavoars@kernel.org +Signed-off-by: Sasha Levin +--- + .../net/wireless/marvell/mwifiex/11n_rxreorder.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +index cbe4a200e4eaf..e5f34805c92cc 100644 +--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c ++++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +@@ -933,6 +933,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv, + while (tlv_buf_left >= sizeof(*tlv_rxba)) { + tlv_type = le16_to_cpu(tlv_rxba->header.type); + tlv_len = le16_to_cpu(tlv_rxba->header.len); ++ if (size_add(sizeof(tlv_rxba->header), tlv_len) > tlv_buf_left) { ++ mwifiex_dbg(priv->adapter, WARN, ++ "TLV size (%zu) overflows event_buf buf_left=%d\n", ++ size_add(sizeof(tlv_rxba->header), tlv_len), ++ tlv_buf_left); ++ return; ++ } ++ + if (tlv_type != TLV_TYPE_RXBA_SYNC) { + mwifiex_dbg(priv->adapter, ERROR, + "Wrong TLV id=0x%x\n", tlv_type); +@@ -941,6 +949,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv, + + tlv_seq_num = le16_to_cpu(tlv_rxba->seq_num); + tlv_bitmap_len = le16_to_cpu(tlv_rxba->bitmap_len); ++ if (size_add(sizeof(*tlv_rxba), tlv_bitmap_len) > tlv_buf_left) { ++ mwifiex_dbg(priv->adapter, WARN, ++ "TLV size (%zu) overflows event_buf buf_left=%d\n", ++ size_add(sizeof(*tlv_rxba), tlv_bitmap_len), ++ tlv_buf_left); ++ return; ++ } ++ + mwifiex_dbg(priv->adapter, INFO, + "%pM tid=%d seq_num=%d bitmap_len=%d\n", + tlv_rxba->mac, tlv_rxba->tid, tlv_seq_num, +-- +2.40.1 +