From d5e3bcff9b43d228c0a1b46b75908cbc3d29ceb3 Mon Sep 17 00:00:00 2001 From: Fabio Porcedda Date: Thu, 10 Jul 2025 14:16:38 +0200 Subject: [PATCH 001/404] USB: serial: option: add Telit Cinterion FE910C04 (ECM) composition commit 252f4ac08cd2f16ecd20e4c5e41ac2a17dd86942 upstream. Add Telit Cinterion FE910C04 (ECM) composition: 0x10c7: ECM + tty (AT) + tty (AT) + tty (diag) usb-devices output: T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 7 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1bc7 ProdID=10c7 Rev=05.15 S: Manufacturer=Telit Cinterion S: Product=FE910 S: SerialNumber=f71b8b32 C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether E: Ad=82(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms Cc: stable@vger.kernel.org Signed-off-by: Fabio Porcedda Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 08d70256e72e..42d7602f6b6b 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1415,6 +1415,9 @@ static const struct usb_device_id option_ids[] = { .driver_info = NCTRL(5) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d0, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d0, 0xff, 0xff, 0x60) }, + { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10c7, 0xff, 0xff, 0x30), /* Telit FE910C04 (ECM) */ + .driver_info = NCTRL(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10c7, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d1, 0xff, 0xff, 0x30), /* Telit FN990B (MBIM) */ .driver_info = NCTRL(6) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d1, 0xff, 0xff, 0x40) }, From aad2f69c55bea357a77d4e6581b3042b4fe8d358 Mon Sep 17 00:00:00 2001 From: Slark Xiao Date: Fri, 20 Jun 2025 11:57:21 +0800 Subject: [PATCH 002/404] USB: serial: option: add Foxconn T99W640 commit 08f49cdb71f3759368fded4dbc9dde35a404ec2b upstream. T99W640 is designed based on Qualconn SDX72 chip. There are 3 serial ports to be enumerated: Diag, NMEA and AT. Test evidence as below: T: Bus=04 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0 D: Ver= 3.20 Cls=ef(misc ) Sub=02 Prot=01 MxPS= 9 #Cfgs= 1 P: Vendor=0489 ProdID=e167 Rev=05.15 S: Manufacturer=QCOM S: Product=SDXPINNL USB WWAN Adapter S: SerialNumber=cc1f1d92 C: #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=896mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=02(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 3 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=85(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=03(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=04(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=88(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms 0&1: MBIM, 2:Modem, 3:GNSS(non-serial port), 4: NMEA, 5:Diag Signed-off-by: Slark Xiao Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 42d7602f6b6b..70c70461655a 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -2346,6 +2346,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = RSVD(3) }, { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe145, 0xff), /* Foxconn T99W651 RNDIS */ .driver_info = RSVD(5) | RSVD(6) }, + { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe167, 0xff), /* Foxconn T99W640 MBIM */ + .driver_info = RSVD(3) }, { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */ .driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, { USB_DEVICE(0x1782, 0x4d10) }, /* Fibocom L610 (AT mode) */ From bc5c5490062a5a0900f69e6e88905337b08fe40b Mon Sep 17 00:00:00 2001 From: "Ryan Mann (NDI)" Date: Thu, 10 Jul 2025 13:08:00 +0000 Subject: [PATCH 003/404] USB: serial: ftdi_sio: add support for NDI EMGUIDE GEMINI commit c980666b6958d9a841597331b38115a29a32250e upstream. NDI (Northern Digital Inc.) is introducing a new product called the EMGUIDE GEMINI that will use an FTDI chip for USB serial communications. Add the NDI EMGUIDE GEMINI product ID that uses the NDI Vendor ID rather than the FTDI Vendor ID, unlike older products. Signed-off-by: Ryan Mann Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio_ids.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index d13b8e35ce33..ee01061b413c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -781,6 +781,8 @@ static const struct usb_device_id id_table_combined[] = { .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, + { USB_DEVICE(FTDI_NDI_VID, FTDI_NDI_EMGUIDE_GEMINI_PID), + .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, { USB_DEVICE(NOVITUS_VID, NOVITUS_BONO_E_PID) }, { USB_DEVICE(FTDI_VID, RTSYSTEMS_USB_VX8_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 9c95ca876bae..324065cc352c 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -197,6 +197,9 @@ #define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ #define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ +#define FTDI_NDI_VID 0x23F2 +#define FTDI_NDI_EMGUIDE_GEMINI_PID 0x0003 /* NDI Emguide Gemini */ + /* * ChamSys Limited (www.chamsys.co.uk) USB wing/interface product IDs */ From 78b41148cfea2a3f04d87adf3a71b21735820a37 Mon Sep 17 00:00:00 2001 From: Xinyu Liu <1171169449@qq.com> Date: Wed, 9 Jul 2025 11:55:33 +0800 Subject: [PATCH 004/404] usb: gadget: configfs: Fix OOB read on empty string write commit 3014168731b7930300aab656085af784edc861f6 upstream. When writing an empty string to either 'qw_sign' or 'landingPage' sysfs attributes, the store functions attempt to access page[l - 1] before validating that the length 'l' is greater than zero. This patch fixes the vulnerability by adding a check at the beginning of os_desc_qw_sign_store() and webusb_landingPage_store() to handle the zero-length input case gracefully by returning immediately. Signed-off-by: Xinyu Liu Cc: stable Link: https://lore.kernel.org/r/tencent_B1C9481688D0E95E7362AB2E999DE8048207@qq.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/configfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 87657e0ca5fc..476a22728e8d 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -824,6 +824,8 @@ static ssize_t os_desc_qw_sign_store(struct config_item *item, const char *page, struct gadget_info *gi = os_desc_item_to_gadget_info(item); int res, l; + if (!len) + return len; l = min((int)len, OS_STRING_QW_SIGN_LEN >> 1); if (page[l - 1] == '\n') --l; From e64ec9509c1ed56080063f3e976764503717e7c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Le=20Goffic?= Date: Fri, 4 Jul 2025 10:39:14 +0200 Subject: [PATCH 005/404] i2c: stm32: fix the device used for the DMA map MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit c870cbbd71fccda71d575f0acd4a8d2b7cd88861 upstream. If the DMA mapping failed, it produced an error log with the wrong device name: "stm32-dma3 40400000.dma-controller: rejecting DMA map of vmalloc memory" Fix this issue by replacing the dev with the I2C dev. Fixes: bb8822cbbc53 ("i2c: i2c-stm32: Add generic DMA API") Signed-off-by: Clément Le Goffic Cc: # v4.18+ Acked-by: Alain Volmat Signed-off-by: Andi Shyti Link: https://lore.kernel.org/r/20250704-i2c-upstream-v4-1-84a095a2c728@foss.st.com Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-stm32.c | 8 +++----- drivers/i2c/busses/i2c-stm32f7.c | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-stm32.c b/drivers/i2c/busses/i2c-stm32.c index 1da347e6a358..4878729f3322 100644 --- a/drivers/i2c/busses/i2c-stm32.c +++ b/drivers/i2c/busses/i2c-stm32.c @@ -98,7 +98,6 @@ int stm32_i2c_prep_dma_xfer(struct device *dev, struct stm32_i2c_dma *dma, void *dma_async_param) { struct dma_async_tx_descriptor *txdesc; - struct device *chan_dev; int ret; if (rd_wr) { @@ -112,11 +111,10 @@ int stm32_i2c_prep_dma_xfer(struct device *dev, struct stm32_i2c_dma *dma, } dma->dma_len = len; - chan_dev = dma->chan_using->device->dev; - dma->dma_buf = dma_map_single(chan_dev, buf, dma->dma_len, + dma->dma_buf = dma_map_single(dev, buf, dma->dma_len, dma->dma_data_dir); - if (dma_mapping_error(chan_dev, dma->dma_buf)) { + if (dma_mapping_error(dev, dma->dma_buf)) { dev_err(dev, "DMA mapping failed\n"); return -EINVAL; } @@ -146,7 +144,7 @@ int stm32_i2c_prep_dma_xfer(struct device *dev, struct stm32_i2c_dma *dma, return 0; err: - dma_unmap_single(chan_dev, dma->dma_buf, dma->dma_len, + dma_unmap_single(dev, dma->dma_buf, dma->dma_len, dma->dma_data_dir); return ret; } diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 02f0f9eeb59f..c8d15d0f194e 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -632,10 +632,10 @@ static void stm32f7_i2c_dma_callback(void *arg) { struct stm32f7_i2c_dev *i2c_dev = (struct stm32f7_i2c_dev *)arg; struct stm32_i2c_dma *dma = i2c_dev->dma; - struct device *dev = dma->chan_using->device->dev; stm32f7_i2c_disable_dma_req(i2c_dev); - dma_unmap_single(dev, dma->dma_buf, dma->dma_len, dma->dma_data_dir); + dma_unmap_single(i2c_dev->dev, dma->dma_buf, dma->dma_len, + dma->dma_data_dir); complete(&dma->dma_complete); } From d3aae77584d38a618be33ea304484eb3a3ba2af0 Mon Sep 17 00:00:00 2001 From: Nilton Perim Neto Date: Sat, 19 Jul 2025 22:07:36 -0700 Subject: [PATCH 006/404] Input: xpad - set correct controller type for Acer NGR200 commit bcce05041b21888f10b80ea903dcfe51a25c586e upstream. The controller should have been set as XTYPE_XBOX360 and not XTYPE_XBOX. Also the entry is in the wrong place. Fix it. Reported-by: Vicki Pfau Signed-off-by: Nilton Perim Neto Link: https://lore.kernel.org/r/20250708033126.26216-2-niltonperimneto@gmail.com Fixes: 22c69d786ef8 ("Input: xpad - support Acer NGR 200 Controller") Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/input/joystick/xpad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index a0362201b5d3..31f7d09c71dc 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -142,12 +142,12 @@ static const struct xpad_device { { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX }, { 0x046d, 0xca8a, "Logitech Precision Vibration Feedback Wheel", 0, XTYPE_XBOX }, { 0x046d, 0xcaa3, "Logitech DriveFx Racing Wheel", 0, XTYPE_XBOX360 }, + { 0x0502, 0x1305, "Acer NGR200", 0, XTYPE_XBOX360 }, { 0x056e, 0x2004, "Elecom JC-U3613M", 0, XTYPE_XBOX360 }, { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX }, { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX }, { 0x05fe, 0x3030, "Chic Controller", 0, XTYPE_XBOX }, { 0x05fe, 0x3031, "Chic Controller", 0, XTYPE_XBOX }, - { 0x0502, 0x1305, "Acer NGR200", 0, XTYPE_XBOX }, { 0x062a, 0x0020, "Logic3 Xbox GamePad", 0, XTYPE_XBOX }, { 0x062a, 0x0033, "Competition Pro Steering Wheel", 0, XTYPE_XBOX }, { 0x06a3, 0x0200, "Saitek Racing Wheel", 0, XTYPE_XBOX }, From fe96b632ad43841309d6bca3853107d60bd7e985 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Tue, 1 Jul 2025 13:34:52 +0200 Subject: [PATCH 007/404] pch_uart: Fix dma_sync_sg_for_device() nents value commit 6c0e9f05c9d7875995b0e92ace71be947f280bbd upstream. The dma_sync_sg_for_device() functions should be called with the same nents as the dma_map_sg(), not the value the map function returned according to the documentation in Documentation/core-api/dma-api.rst:450: With the sync_sg API, all the parameters must be the same as those passed into the sg mapping API. Fixes: da3564ee027e ("pch_uart: add multi-scatter processing") Cc: stable Signed-off-by: Thomas Fourier Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20250701113452.18590-2-fourier.thomas@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 317067184bfa..15e6c56258b4 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1025,7 +1025,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) __func__); return 0; } - dma_sync_sg_for_device(port->dev, priv->sg_tx_p, nent, DMA_TO_DEVICE); + dma_sync_sg_for_device(port->dev, priv->sg_tx_p, num, DMA_TO_DEVICE); priv->desc_tx = desc; desc->callback = pch_dma_tx_complete; desc->callback_param = priv; From 7228e36c7875e4b035374cf68ca5e44dffa596b2 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 10 Jul 2025 16:01:33 +0200 Subject: [PATCH 008/404] HID: core: ensure the allocated report buffer can contain the reserved report ID commit 4f15ee98304b96e164ff2340e1dfd6181c3f42aa upstream. When the report ID is not used, the low level transport drivers expect the first byte to be 0. However, currently the allocated buffer not account for that extra byte, meaning that instead of having 8 guaranteed bytes for implement to be working, we only have 7. Reported-by: Alan Stern Closes: https://lore.kernel.org/linux-input/c75433e0-9b47-4072-bbe8-b1d14ea97b13@rowland.harvard.edu/ Cc: stable@vger.kernel.org Suggested-by: Alan Stern Link: https://patch.msgid.link/20250710-report-size-null-v2-1-ccf922b7c4e5@kernel.org Signed-off-by: Benjamin Tissoires Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index ad0c5b353c16..8a8ea5f91288 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1655,9 +1655,12 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags) /* * 7 extra bytes are necessary to achieve proper functionality * of implement() working on 8 byte chunks + * 1 extra byte for the report ID if it is null (not used) so + * we can reserve that extra byte in the first position of the buffer + * when sending it to .raw_request() */ - u32 len = hid_report_len(report) + 7; + u32 len = hid_report_len(report) + 7 + (report->id == 0); return kzalloc(len, flags); } From 964affcebe53d162c821e7636b3b109705a3040b Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 10 Jul 2025 16:01:34 +0200 Subject: [PATCH 009/404] HID: core: ensure __hid_request reserves the report ID as the first byte commit 0d0777ccaa2d46609d05b66ba0096802a2746193 upstream. The low level transport driver expects the first byte to be the report ID, even when the report ID is not use (in which case they just shift the buffer). However, __hid_request() whas not offsetting the buffer it used by one in this case, meaning that the raw_request() callback emitted by the transport driver would be stripped of the first byte. Note: this changes the API for uhid devices when a request is made through hid_hw_request. However, several considerations makes me think this is fine: - every request to a HID device made through hid_hw_request() would see that change, but every request made through hid_hw_raw_request() already has the new behaviour. So that means that the users are already facing situations where they might have or not the first byte being the null report ID when it is 0. We are making things more straightforward in the end. - uhid is mainly used for BLE devices - uhid is also used for testing, but I don't see that change a big issue - for BLE devices, we can check which kernel module is calling hid_hw_request() - and in those modules, we can check which are using a Bluetooth device - and then we can check if the command is used with a report ID or not. - surprise: none of the kernel module are using a report ID 0 - and finally, bluez, in its function set_report()[0], does the same shift if the report ID is 0 and the given buffer has a size > 0. [0] https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/profiles/input/hog-lib.c#n879 Reported-by: Alan Stern Closes: https://lore.kernel.org/linux-input/c75433e0-9b47-4072-bbe8-b1d14ea97b13@rowland.harvard.edu/ Reported-by: syzbot+8258d5439c49d4c35f43@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=8258d5439c49d4c35f43 Tested-by: syzbot+8258d5439c49d4c35f43@syzkaller.appspotmail.com Fixes: 4fa5a7f76cc7 ("HID: core: implement generic .request()") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250710-report-size-null-v2-2-ccf922b7c4e5@kernel.org Signed-off-by: Benjamin Tissoires Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 8a8ea5f91288..6b26565393ef 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1723,7 +1723,7 @@ static struct hid_report *hid_get_report(struct hid_report_enum *report_enum, int __hid_request(struct hid_device *hid, struct hid_report *report, int reqtype) { - char *buf; + char *buf, *data_buf; int ret; u32 len; @@ -1731,10 +1731,17 @@ int __hid_request(struct hid_device *hid, struct hid_report *report, if (!buf) return -ENOMEM; + data_buf = buf; len = hid_report_len(report); + if (report->id == 0) { + /* reserve the first byte for the report ID */ + data_buf++; + len++; + } + if (reqtype == HID_REQ_SET_REPORT) - hid_output_report(report, buf); + hid_output_report(report, data_buf); ret = hid->ll_driver->raw_request(hid, report->id, buf, len, report->type, reqtype); From dd8e8314f2ce225dade5248dcfb9e2ac0edda624 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 10 Jul 2025 16:01:35 +0200 Subject: [PATCH 010/404] HID: core: do not bypass hid_hw_raw_request commit c2ca42f190b6714d6c481dfd3d9b62ea091c946b upstream. hid_hw_raw_request() is actually useful to ensure the provided buffer and length are valid. Directly calling in the low level transport driver function bypassed those checks and allowed invalid paramto be used. Reported-by: Alan Stern Closes: https://lore.kernel.org/linux-input/c75433e0-9b47-4072-bbe8-b1d14ea97b13@rowland.harvard.edu/ Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250710-report-size-null-v2-3-ccf922b7c4e5@kernel.org Signed-off-by: Benjamin Tissoires Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 6b26565393ef..dd718bdb3ade 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1743,8 +1743,7 @@ int __hid_request(struct hid_device *hid, struct hid_report *report, if (reqtype == HID_REQ_SET_REPORT) hid_output_report(report, data_buf); - ret = hid->ll_driver->raw_request(hid, report->id, buf, len, - report->type, reqtype); + ret = hid_hw_raw_request(hid, report->id, buf, len, report->type, reqtype); if (ret < 0) { dbg_hid("unable to complete request: %d\n", ret); goto out; From 02c153c61fdc6565b7d7fde834c6c008fd243df5 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 15 Jul 2025 16:15:40 -0700 Subject: [PATCH 011/404] phonet/pep: Move call to pn_skb_get_dst_sockaddr() earlier in pep_sock_accept() commit 17ba793f381eb813596d6de1cc6820bcbda5ed8b upstream. A new warning in clang [1] points out a place in pep_sock_accept() where dst is uninitialized then passed as a const pointer to pep_find_pipe(): net/phonet/pep.c:829:37: error: variable 'dst' is uninitialized when passed as a const pointer argument here [-Werror,-Wuninitialized-const-pointer] 829 | newsk = pep_find_pipe(&pn->hlist, &dst, pipe_handle); | ^~~: Move the call to pn_skb_get_dst_sockaddr(), which initializes dst, to before the call to pep_find_pipe(), so that dst is consistently used initialized throughout the function. Cc: stable@vger.kernel.org Fixes: f7ae8d59f661 ("Phonet: allocate sock from accept syscall rather than soft IRQ") Link: https://github.com/llvm/llvm-project/commit/00dacf8c22f065cb52efb14cd091d441f19b319e [1] Closes: https://github.com/ClangBuiltLinux/linux/issues/2101 Signed-off-by: Nathan Chancellor Link: https://patch.msgid.link/20250715-net-phonet-fix-uninit-const-pointer-v1-1-8efd1bd188b3@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/phonet/pep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 0c5d0f7b8b4b..83d435e274e9 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -825,6 +825,7 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp, } /* Check for duplicate pipe handle */ + pn_skb_get_dst_sockaddr(skb, &dst); newsk = pep_find_pipe(&pn->hlist, &dst, pipe_handle); if (unlikely(newsk)) { __sock_put(newsk); @@ -849,7 +850,6 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp, newsk->sk_destruct = pipe_destruct; newpn = pep_sk(newsk); - pn_skb_get_dst_sockaddr(skb, &dst); pn_skb_get_src_sockaddr(skb, &src); newpn->pn_sk.sobject = pn_sockaddr_get_object(&dst); newpn->pn_sk.dobject = pn_sockaddr_get_object(&src); From aabd21a25a0218bd42e43cbf9ca59403ca863799 Mon Sep 17 00:00:00 2001 From: Yun Lu Date: Fri, 11 Jul 2025 17:32:59 +0800 Subject: [PATCH 012/404] af_packet: fix the SO_SNDTIMEO constraint not effective on tpacked_snd() commit c1ba3c0cbdb5e53a8ec5d708e99cd4c497028a13 upstream. Due to the changes in commit 581073f626e3 ("af_packet: do not call packet_read_pending() from tpacket_destruct_skb()"), every time tpacket_destruct_skb() is executed, the skb_completion is marked as completed. When wait_for_completion_interruptible_timeout() returns completed, the pending_refcnt has not yet been reduced to zero. Therefore, when ph is NULL, the wait function may need to be called multiple times until packet_read_pending() finally returns zero. We should call sock_sndtimeo() only once, otherwise the SO_SNDTIMEO constraint could be way off. Fixes: 581073f626e3 ("af_packet: do not call packet_read_pending() from tpacket_destruct_skb()") Cc: stable@kernel.org Suggested-by: Eric Dumazet Signed-off-by: Yun Lu Reviewed-by: Eric Dumazet Reviewed-by: Willem de Bruijn Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/packet/af_packet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index b1cf6a069e63..3e66b7890c12 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2713,7 +2713,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) int len_sum = 0; int status = TP_STATUS_AVAILABLE; int hlen, tlen, copylen = 0; - long timeo = 0; + long timeo; mutex_lock(&po->pg_vec_lock); @@ -2767,6 +2767,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) if ((size_max > dev->mtu + reserve + VLAN_HLEN) && !po->has_vnet_hdr) size_max = dev->mtu + reserve + VLAN_HLEN; + timeo = sock_sndtimeo(&po->sk, msg->msg_flags & MSG_DONTWAIT); reinit_completion(&po->skb_completion); do { @@ -2774,7 +2775,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) TP_STATUS_SEND_REQUEST); if (unlikely(ph == NULL)) { if (need_wait && skb) { - timeo = sock_sndtimeo(&po->sk, msg->msg_flags & MSG_DONTWAIT); timeo = wait_for_completion_interruptible_timeout(&po->skb_completion, timeo); if (timeo <= 0) { err = !timeo ? -ETIMEDOUT : -ERESTARTSYS; From 36031c3f0fae156c33c42aa3955e2c1982183c45 Mon Sep 17 00:00:00 2001 From: Yun Lu Date: Fri, 11 Jul 2025 17:33:00 +0800 Subject: [PATCH 013/404] af_packet: fix soft lockup issue caused by tpacket_snd() commit 55f0bfc0370539213202f4ce1a07615327ac4713 upstream. When MSG_DONTWAIT is not set, the tpacket_snd operation will wait for pending_refcnt to decrement to zero before returning. The pending_refcnt is decremented by 1 when the skb->destructor function is called, indicating that the skb has been successfully sent and needs to be destroyed. If an error occurs during this process, the tpacket_snd() function will exit and return error, but pending_refcnt may not yet have decremented to zero. Assuming the next send operation is executed immediately, but there are no available frames to be sent in tx_ring (i.e., packet_current_frame returns NULL), and skb is also NULL, the function will not execute wait_for_completion_interruptible_timeout() to yield the CPU. Instead, it will enter a do-while loop, waiting for pending_refcnt to be zero. Even if the previous skb has completed transmission, the skb->destructor function can only be invoked in the ksoftirqd thread (assuming NAPI threading is enabled). When both the ksoftirqd thread and the tpacket_snd operation happen to run on the same CPU, and the CPU trapped in the do-while loop without yielding, the ksoftirqd thread will not get scheduled to run. As a result, pending_refcnt will never be reduced to zero, and the do-while loop cannot exit, eventually leading to a CPU soft lockup issue. In fact, skb is true for all but the first iterations of that loop, and as long as pending_refcnt is not zero, even if incremented by a previous call, wait_for_completion_interruptible_timeout() should be executed to yield the CPU, allowing the ksoftirqd thread to be scheduled. Therefore, the execution condition of this function should be modified to check if pending_refcnt is not zero, instead of check skb. - if (need_wait && skb) { + if (need_wait && packet_read_pending(&po->tx_ring)) { As a result, the judgment conditions are duplicated with the end code of the while loop, and packet_read_pending() is a very expensive function. Actually, this loop can only exit when ph is NULL, so the loop condition can be changed to while (1), and in the "ph = NULL" branch, if the subsequent condition of if is not met, the loop can break directly. Now, the loop logic remains the same as origin but is clearer and more obvious. Fixes: 89ed5b519004 ("af_packet: Block execution of tasks waiting for transmit to complete in AF_PACKET") Cc: stable@kernel.org Suggested-by: LongJun Tang Signed-off-by: Yun Lu Reviewed-by: Willem de Bruijn Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/packet/af_packet.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 3e66b7890c12..d9799310ef0d 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2774,15 +2774,21 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ph = packet_current_frame(po, &po->tx_ring, TP_STATUS_SEND_REQUEST); if (unlikely(ph == NULL)) { - if (need_wait && skb) { + /* Note: packet_read_pending() might be slow if we + * have to call it as it's per_cpu variable, but in + * fast-path we don't have to call it, only when ph + * is NULL, we need to check the pending_refcnt. + */ + if (need_wait && packet_read_pending(&po->tx_ring)) { timeo = wait_for_completion_interruptible_timeout(&po->skb_completion, timeo); if (timeo <= 0) { err = !timeo ? -ETIMEDOUT : -ERESTARTSYS; goto out_put; } - } - /* check for additional frames */ - continue; + /* check for additional frames */ + continue; + } else + break; } skb = NULL; @@ -2872,14 +2878,7 @@ tpacket_error: } packet_increment_head(&po->tx_ring); len_sum += tp_len; - } while (likely((ph != NULL) || - /* Note: packet_read_pending() might be slow if we have - * to call it as it's per_cpu variable, but in fast-path - * we already short-circuit the loop with the first - * condition, and luckily don't have to go that path - * anyway. - */ - (need_wait && packet_read_pending(&po->tx_ring)))); + } while (1); err = len_sum; goto out_put; From 84fff8e6f11b9af1407e273995b5257d99ff0cff Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 1 Jul 2025 17:31:40 -0500 Subject: [PATCH 014/404] dmaengine: nbpfaxi: Fix memory corruption in probe() commit 188c6ba1dd925849c5d94885c8bbdeb0b3dcf510 upstream. The nbpf->chan[] array is allocated earlier in the nbpf_probe() function and it has "num_channels" elements. These three loops iterate one element farther than they should and corrupt memory. The changes to the second loop are more involved. In this case, we're copying data from the irqbuf[] array into the nbpf->chan[] array. If the data in irqbuf[i] is the error IRQ then we skip it, so the iterators are not in sync. I added a check to ensure that we don't go beyond the end of the irqbuf[] array. I'm pretty sure this can't happen, but it seemed harmless to add a check. On the other hand, after the loop has ended there is a check to ensure that the "chan" iterator is where we expect it to be. In the original code we went one element beyond the end of the array so the iterator wasn't in the correct place and it would always return -EINVAL. However, now it will always be in the correct place. I deleted the check since we know the result. Cc: stable@vger.kernel.org Fixes: b45b262cefd5 ("dmaengine: add a driver for AMBA AXI NBPF DMAC IP cores") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/b13c5225-7eff-448c-badc-a2c98e9bcaca@sabinyo.mountain Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman --- drivers/dma/nbpfaxi.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c index 594409a6e975..b9a36a6a3852 100644 --- a/drivers/dma/nbpfaxi.c +++ b/drivers/dma/nbpfaxi.c @@ -1349,7 +1349,7 @@ static int nbpf_probe(struct platform_device *pdev) if (irqs == 1) { eirq = irqbuf[0]; - for (i = 0; i <= num_channels; i++) + for (i = 0; i < num_channels; i++) nbpf->chan[i].irq = irqbuf[0]; } else { eirq = platform_get_irq_byname(pdev, "error"); @@ -1359,16 +1359,15 @@ static int nbpf_probe(struct platform_device *pdev) if (irqs == num_channels + 1) { struct nbpf_channel *chan; - for (i = 0, chan = nbpf->chan; i <= num_channels; + for (i = 0, chan = nbpf->chan; i < num_channels; i++, chan++) { /* Skip the error IRQ */ if (irqbuf[i] == eirq) i++; + if (i >= ARRAY_SIZE(irqbuf)) + return -EINVAL; chan->irq = irqbuf[i]; } - - if (chan != nbpf->chan + num_channels) - return -EINVAL; } else { /* 2 IRQs and more than one channel */ if (irqbuf[0] == eirq) @@ -1376,7 +1375,7 @@ static int nbpf_probe(struct platform_device *pdev) else irq = irqbuf[0]; - for (i = 0; i <= num_channels; i++) + for (i = 0; i < num_channels; i++) nbpf->chan[i].irq = irq; } } From b4c2fd8d7400273408ba76b80011f29915db8f53 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 9 Jul 2025 11:55:46 +0200 Subject: [PATCH 015/404] isofs: Verify inode mode when loading from disk commit 0a9e7405131380b57e155f10242b2e25d2e51852 upstream. Verify that the inode mode is sane when loading it from the disk to avoid complaints from VFS about setting up invalid inodes. Reported-by: syzbot+895c23f6917da440ed0d@syzkaller.appspotmail.com CC: stable@vger.kernel.org Signed-off-by: Jan Kara Link: https://lore.kernel.org/20250709095545.31062-2-jack@suse.cz Acked-by: Christian Brauner Signed-off-by: Christian Brauner Signed-off-by: Greg Kroah-Hartman --- fs/isofs/inode.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 95c08f3c4b35..ce3848720a8d 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -1499,9 +1499,16 @@ static int isofs_read_inode(struct inode *inode, int relocated) inode->i_op = &page_symlink_inode_operations; inode_nohighmem(inode); inode->i_data.a_ops = &isofs_symlink_aops; - } else + } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || + S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { /* XXX - parse_rock_ridge_inode() had already set i_rdev. */ init_special_inode(inode, inode->i_mode, inode->i_rdev); + } else { + printk(KERN_DEBUG "ISOFS: Invalid file type 0%04o for inode %lu.\n", + inode->i_mode, inode->i_ino); + ret = -EIO; + goto fail; + } ret = 0; out: From 6894d179bd0a97c37f3f7459c066483f3c94d885 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 15 Jul 2025 15:56:05 -0700 Subject: [PATCH 016/404] memstick: core: Zero initialize id_reg in h_memstick_read_dev_id() commit 21b34a3a204ed616373a12ec17dc127ebe51eab3 upstream. A new warning in clang [1] points out that id_reg is uninitialized then passed to memstick_init_req() as a const pointer: drivers/memstick/core/memstick.c:330:59: error: variable 'id_reg' is uninitialized when passed as a const pointer argument here [-Werror,-Wuninitialized-const-pointer] 330 | memstick_init_req(&card->current_mrq, MS_TPC_READ_REG, &id_reg, | ^~~~~~ Commit de182cc8e882 ("drivers/memstick/core/memstick.c: avoid -Wnonnull warning") intentionally passed this variable uninitialized to avoid an -Wnonnull warning from a NULL value that was previously there because id_reg is never read from the call to memstick_init_req() in h_memstick_read_dev_id(). Just zero initialize id_reg to avoid the warning, which is likely happening in the majority of builds using modern compilers that support '-ftrivial-auto-var-init=zero'. Cc: stable@vger.kernel.org Fixes: de182cc8e882 ("drivers/memstick/core/memstick.c: avoid -Wnonnull warning") Link: https://github.com/llvm/llvm-project/commit/00dacf8c22f065cb52efb14cd091d441f19b319e [1] Closes: https://github.com/ClangBuiltLinux/linux/issues/2105 Signed-off-by: Nathan Chancellor Link: https://lore.kernel.org/r/20250715-memstick-fix-uninit-const-pointer-v1-1-f6753829c27a@kernel.org Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/memstick/core/memstick.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index 1c7a9dcfed65..e03118b8d1c4 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -324,7 +324,7 @@ EXPORT_SYMBOL(memstick_init_req); static int h_memstick_read_dev_id(struct memstick_dev *card, struct memstick_request **mrq) { - struct ms_id_register id_reg; + struct ms_id_register id_reg = {}; if (!(*mrq)) { memstick_init_req(&card->current_mrq, MS_TPC_READ_REG, &id_reg, From 25ca57629f5ad15c2946c3855d6118cf6133d16c Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Mon, 30 Jun 2025 11:35:07 +0200 Subject: [PATCH 017/404] mmc: bcm2835: Fix dma_unmap_sg() nents value commit ff09b71bf9daeca4f21d6e5e449641c9fad75b53 upstream. The dma_unmap_sg() functions should be called with the same nents as the dma_map_sg(), not the value the map function returned. Fixes: 2f5da678351f ("mmc: bcm2835: Properly handle dmaengine_prep_slave_sg") Signed-off-by: Thomas Fourier Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250630093510.82871-2-fourier.thomas@gmail.com Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/bcm2835.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c index d20943e43312..8a9912219e5e 100644 --- a/drivers/mmc/host/bcm2835.c +++ b/drivers/mmc/host/bcm2835.c @@ -507,7 +507,8 @@ void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data) DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { - dma_unmap_sg(dma_chan->device->dev, data->sg, sg_len, dir_data); + dma_unmap_sg(dma_chan->device->dev, data->sg, data->sg_len, + dir_data); return; } From 43b52cb40d88df52bd1efe10ce745c03beac50d6 Mon Sep 17 00:00:00 2001 From: Edson Juliano Drosdeck Date: Thu, 26 Jun 2025 08:24:42 -0300 Subject: [PATCH 018/404] mmc: sdhci-pci: Quirk for broken command queuing on Intel GLK-based Positivo models commit 50c78f398e92fafa1cbba3469c95fe04b2e4206d upstream. Disable command queuing on Intel GLK-based Positivo models. Without this quirk, CQE (Command Queuing Engine) causes instability or I/O errors during operation. Disabling it ensures stable operation on affected devices. Signed-off-by: Edson Juliano Drosdeck Fixes: bedf9fc01ff1 ("mmc: sdhci: Workaround broken command queuing on Intel GLK") Cc: stable@vger.kernel.org Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/20250626112442.9791-1-edson.drosdeck@gmail.com Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/sdhci-pci-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 22978057b94a..e75dbc0cfda1 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -972,7 +972,8 @@ static bool glk_broken_cqhci(struct sdhci_pci_slot *slot) { return slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_GLK_EMMC && (dmi_match(DMI_BIOS_VENDOR, "LENOVO") || - dmi_match(DMI_SYS_VENDOR, "IRBIS")); + dmi_match(DMI_SYS_VENDOR, "IRBIS") || + dmi_match(DMI_SYS_VENDOR, "Positivo Tecnologia SA")); } static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot) From 5a6714244947295b03b2e7faa7a1fb1a50be86f9 Mon Sep 17 00:00:00 2001 From: Judith Mendez Date: Thu, 26 Jun 2025 18:14:52 -0500 Subject: [PATCH 019/404] mmc: sdhci_am654: Workaround for Errata i2312 commit 6d0b1c01847fedd7c85a5cdf59b8cfc7d14512e6 upstream. Errata i2312 [0] for K3 silicon mentions the maximum obtainable timeout through MMC host controller is 700ms. And for commands taking longer than 700ms, hardware timeout should be disabled and software timeout should be used. The workaround for Errata i2312 can be achieved by adding SDHCI_QUIRK2_DISABLE_HW_TIMEOUT quirk in sdhci_am654. [0] https://www.ti.com/lit/pdf/sprz487 Signed-off-by: Judith Mendez Acked-by: Adrian Hunter Fixes: 41fd4caeb00b ("mmc: sdhci_am654: Add Initial Support for AM654 SDHCI driver") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250626231452.3460987-1-jm@ti.com Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/sdhci_am654.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c index 987626ffdb6f..3ac3f9d840ff 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c @@ -264,7 +264,8 @@ static struct sdhci_ops sdhci_am654_ops = { static const struct sdhci_pltfm_data sdhci_am654_pdata = { .ops = &sdhci_am654_ops, .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_DISABLE_HW_TIMEOUT, }; static const struct sdhci_am654_driver_data sdhci_am654_drvdata = { @@ -286,7 +287,8 @@ static struct sdhci_ops sdhci_j721e_8bit_ops = { static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = { .ops = &sdhci_j721e_8bit_ops, .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_DISABLE_HW_TIMEOUT, }; static const struct sdhci_am654_driver_data sdhci_j721e_8bit_drvdata = { @@ -308,7 +310,8 @@ static struct sdhci_ops sdhci_j721e_4bit_ops = { static const struct sdhci_pltfm_data sdhci_j721e_4bit_pdata = { .ops = &sdhci_j721e_4bit_ops, .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_DISABLE_HW_TIMEOUT, }; static const struct sdhci_am654_driver_data sdhci_j721e_4bit_drvdata = { From e4e4798204a34a7a010d3bb208fe39f25e6eef62 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Mon, 16 Jun 2025 22:43:38 +0930 Subject: [PATCH 020/404] soc: aspeed: lpc-snoop: Cleanup resources in stack-order commit 8481d59be606d2338dbfe14b04cdbd1a3402c150 upstream. Free the kfifo after unregistering the miscdev in aspeed_lpc_disable_snoop() as the kfifo is initialised before the miscdev in aspeed_lpc_enable_snoop(). Fixes: 3772e5da4454 ("drivers/misc: Aspeed LPC snoop output using misc chardev") Cc: stable@vger.kernel.org Cc: Jean Delvare Acked-by: Jean Delvare Link: https://patch.msgid.link/20250616-aspeed-lpc-snoop-fixes-v2-1-3cdd59c934d3@codeconstruct.com.au Signed-off-by: Andrew Jeffery Signed-off-by: Greg Kroah-Hartman --- drivers/soc/aspeed/aspeed-lpc-snoop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c index 43e30937fc9d..f0fc72e1e74d 100644 --- a/drivers/soc/aspeed/aspeed-lpc-snoop.c +++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c @@ -265,8 +265,8 @@ static void aspeed_lpc_disable_snoop(struct aspeed_lpc_snoop *lpc_snoop, return; } - kfifo_free(&lpc_snoop->chan[channel].fifo); misc_deregister(&lpc_snoop->chan[channel].miscdev); + kfifo_free(&lpc_snoop->chan[channel].fifo); } static int aspeed_lpc_snoop_probe(struct platform_device *pdev) From 62e51f51d97477ea4e78c82e7076a171dac86c75 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Mon, 16 Jun 2025 22:43:39 +0930 Subject: [PATCH 021/404] soc: aspeed: lpc-snoop: Don't disable channels that aren't enabled commit 56448e78a6bb4e1a8528a0e2efe94eff0400c247 upstream. Mitigate e.g. the following: # echo 1e789080.lpc-snoop > /sys/bus/platform/drivers/aspeed-lpc-snoop/unbind ... [ 120.363594] Unable to handle kernel NULL pointer dereference at virtual address 00000004 when write [ 120.373866] [00000004] *pgd=00000000 [ 120.377910] Internal error: Oops: 805 [#1] SMP ARM [ 120.383306] CPU: 1 UID: 0 PID: 315 Comm: sh Not tainted 6.15.0-rc1-00009-g926217bc7d7d-dirty #20 NONE ... [ 120.679543] Call trace: [ 120.679559] misc_deregister from aspeed_lpc_snoop_remove+0x84/0xac [ 120.692462] aspeed_lpc_snoop_remove from platform_remove+0x28/0x38 [ 120.700996] platform_remove from device_release_driver_internal+0x188/0x200 ... Fixes: 9f4f9ae81d0a ("drivers/misc: add Aspeed LPC snoop driver") Cc: stable@vger.kernel.org Cc: Jean Delvare Acked-by: Jean Delvare Link: https://patch.msgid.link/20250616-aspeed-lpc-snoop-fixes-v2-2-3cdd59c934d3@codeconstruct.com.au Signed-off-by: Andrew Jeffery Signed-off-by: Greg Kroah-Hartman --- drivers/soc/aspeed/aspeed-lpc-snoop.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c index f0fc72e1e74d..f3462ce22a0b 100644 --- a/drivers/soc/aspeed/aspeed-lpc-snoop.c +++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c @@ -60,6 +60,7 @@ struct aspeed_lpc_snoop_model_data { }; struct aspeed_lpc_snoop_channel { + bool enabled; struct kfifo fifo; wait_queue_head_t wq; struct miscdevice miscdev; @@ -192,6 +193,9 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop, const struct aspeed_lpc_snoop_model_data *model_data = of_device_get_match_data(dev); + if (WARN_ON(lpc_snoop->chan[channel].enabled)) + return -EBUSY; + init_waitqueue_head(&lpc_snoop->chan[channel].wq); /* Create FIFO datastructure */ rc = kfifo_alloc(&lpc_snoop->chan[channel].fifo, @@ -238,6 +242,8 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop, regmap_update_bits(lpc_snoop->regmap, HICRB, hicrb_en, hicrb_en); + lpc_snoop->chan[channel].enabled = true; + return 0; err_misc_deregister: @@ -250,6 +256,9 @@ err_free_fifo: static void aspeed_lpc_disable_snoop(struct aspeed_lpc_snoop *lpc_snoop, int channel) { + if (!lpc_snoop->chan[channel].enabled) + return; + switch (channel) { case 0: regmap_update_bits(lpc_snoop->regmap, HICR5, @@ -265,6 +274,8 @@ static void aspeed_lpc_disable_snoop(struct aspeed_lpc_snoop *lpc_snoop, return; } + lpc_snoop->chan[channel].enabled = false; + /* Consider improving safety wrt concurrent reader(s) */ misc_deregister(&lpc_snoop->chan[channel].miscdev); kfifo_free(&lpc_snoop->chan[channel].fifo); } From 016f13e0ad2a9372db932e770042fb5d23cb8fd6 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 16 May 2025 14:38:59 -0300 Subject: [PATCH 022/404] iio: adc: max1363: Fix MAX1363_4X_CHANS/MAX1363_8X_CHANS[] commit 6d21f2c2dd843bceefd9455f2919f6bb526797f0 upstream. Since commit 2718f15403fb ("iio: sanity check available_scan_masks array"), booting a board populated with a MAX11601 results in a flood of warnings: max1363 1-0064: available_scan_mask 8 subset of 0. Never used max1363 1-0064: available_scan_mask 9 subset of 0. Never used max1363 1-0064: available_scan_mask 10 subset of 0. Never used max1363 1-0064: available_scan_mask 11 subset of 0. Never used max1363 1-0064: available_scan_mask 12 subset of 0. Never used max1363 1-0064: available_scan_mask 13 subset of 0. Never used ... These warnings are caused by incorrect offsets used for differential channels in the MAX1363_4X_CHANS() and MAX1363_8X_CHANS() macros. The max1363_mode_table[] defines the differential channel mappings as follows: MAX1363_MODE_DIFF_SINGLE(0, 1, 1 << 12), MAX1363_MODE_DIFF_SINGLE(2, 3, 1 << 13), MAX1363_MODE_DIFF_SINGLE(4, 5, 1 << 14), MAX1363_MODE_DIFF_SINGLE(6, 7, 1 << 15), MAX1363_MODE_DIFF_SINGLE(8, 9, 1 << 16), MAX1363_MODE_DIFF_SINGLE(10, 11, 1 << 17), MAX1363_MODE_DIFF_SINGLE(1, 0, 1 << 18), MAX1363_MODE_DIFF_SINGLE(3, 2, 1 << 19), MAX1363_MODE_DIFF_SINGLE(5, 4, 1 << 20), MAX1363_MODE_DIFF_SINGLE(7, 6, 1 << 21), MAX1363_MODE_DIFF_SINGLE(9, 8, 1 << 22), MAX1363_MODE_DIFF_SINGLE(11, 10, 1 << 23), Update the macros to follow this same pattern, ensuring that the scan masks are valid and preventing the warnings. Cc: stable@vger.kernel.org Suggested-by: Jonathan Cameron Signed-off-by: Fabio Estevam Acked-by: Matti Vaittinen Link: https://patch.msgid.link/20250516173900.677821-1-festevam@gmail.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/max1363.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 5c2cc61b666e..9bc0a8be5605 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -505,10 +505,10 @@ static const struct iio_event_spec max1363_events[] = { MAX1363_CHAN_U(1, _s1, 1, bits, ev_spec, num_ev_spec), \ MAX1363_CHAN_U(2, _s2, 2, bits, ev_spec, num_ev_spec), \ MAX1363_CHAN_U(3, _s3, 3, bits, ev_spec, num_ev_spec), \ - MAX1363_CHAN_B(0, 1, d0m1, 4, bits, ev_spec, num_ev_spec), \ - MAX1363_CHAN_B(2, 3, d2m3, 5, bits, ev_spec, num_ev_spec), \ - MAX1363_CHAN_B(1, 0, d1m0, 6, bits, ev_spec, num_ev_spec), \ - MAX1363_CHAN_B(3, 2, d3m2, 7, bits, ev_spec, num_ev_spec), \ + MAX1363_CHAN_B(0, 1, d0m1, 12, bits, ev_spec, num_ev_spec), \ + MAX1363_CHAN_B(2, 3, d2m3, 13, bits, ev_spec, num_ev_spec), \ + MAX1363_CHAN_B(1, 0, d1m0, 18, bits, ev_spec, num_ev_spec), \ + MAX1363_CHAN_B(3, 2, d3m2, 19, bits, ev_spec, num_ev_spec), \ IIO_CHAN_SOFT_TIMESTAMP(8) \ } @@ -603,14 +603,14 @@ static const enum max1363_modes max11608_mode_list[] = { MAX1363_CHAN_U(5, _s5, 5, bits, NULL, 0), \ MAX1363_CHAN_U(6, _s6, 6, bits, NULL, 0), \ MAX1363_CHAN_U(7, _s7, 7, bits, NULL, 0), \ - MAX1363_CHAN_B(0, 1, d0m1, 8, bits, NULL, 0), \ - MAX1363_CHAN_B(2, 3, d2m3, 9, bits, NULL, 0), \ - MAX1363_CHAN_B(4, 5, d4m5, 10, bits, NULL, 0), \ - MAX1363_CHAN_B(6, 7, d6m7, 11, bits, NULL, 0), \ - MAX1363_CHAN_B(1, 0, d1m0, 12, bits, NULL, 0), \ - MAX1363_CHAN_B(3, 2, d3m2, 13, bits, NULL, 0), \ - MAX1363_CHAN_B(5, 4, d5m4, 14, bits, NULL, 0), \ - MAX1363_CHAN_B(7, 6, d7m6, 15, bits, NULL, 0), \ + MAX1363_CHAN_B(0, 1, d0m1, 12, bits, NULL, 0), \ + MAX1363_CHAN_B(2, 3, d2m3, 13, bits, NULL, 0), \ + MAX1363_CHAN_B(4, 5, d4m5, 14, bits, NULL, 0), \ + MAX1363_CHAN_B(6, 7, d6m7, 15, bits, NULL, 0), \ + MAX1363_CHAN_B(1, 0, d1m0, 18, bits, NULL, 0), \ + MAX1363_CHAN_B(3, 2, d3m2, 19, bits, NULL, 0), \ + MAX1363_CHAN_B(5, 4, d5m4, 20, bits, NULL, 0), \ + MAX1363_CHAN_B(7, 6, d7m6, 21, bits, NULL, 0), \ IIO_CHAN_SOFT_TIMESTAMP(16) \ } static const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8); From 14760b52482f08a7e87b2278da992b34f28804c1 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 16 May 2025 14:39:00 -0300 Subject: [PATCH 023/404] iio: adc: max1363: Reorder mode_list[] entries commit 8d8d7c1dbc46aa07a76acab7336a42ddd900be10 upstream. The IIO core issues warnings when a scan mask is a subset of a previous entry in the available_scan_masks array. On a board using a MAX11601, the following warning is observed: max1363 1-0064: available_scan_mask 7 subset of 6. Never used This occurs because the entries in the max11607_mode_list[] array are not ordered correctly. To fix this, reorder the entries so that no scan mask is a subset of an earlier one. While at it, reorder the mode_list[] arrays for other supported chips as well, to prevent similar warnings on different variants. Note fixes tag dropped as these were introduced over many commits a long time back and the side effect until recently was a reduction in sampling rate due to reading too many channels when only a few were desired. Now we have a sanity check that reports this error but that is not where the issue was introduced. Cc: stable@vger.kernel.org Signed-off-by: Fabio Estevam Acked-by: Matti Vaittinen Link: https://patch.msgid.link/20250516173900.677821-2-festevam@gmail.com Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/max1363.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 9bc0a8be5605..2ad0a6f4c336 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -526,23 +526,23 @@ static const struct iio_chan_spec max1363_channels[] = /* Applies to max1236, max1237 */ static const enum max1363_modes max1236_mode_list[] = { _s0, _s1, _s2, _s3, - s0to1, s0to2, s0to3, + s0to1, s0to2, s2to3, s0to3, d0m1, d2m3, d1m0, d3m2, d0m1to2m3, d1m0to3m2, - s2to3, }; /* Applies to max1238, max1239 */ static const enum max1363_modes max1238_mode_list[] = { _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, + s6to7, s6to8, s6to9, s6to10, s6to11, s0to7, s0to8, s0to9, s0to10, s0to11, d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, - d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11, - d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10, - s6to7, s6to8, s6to9, s6to10, s6to11, - d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10, + d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9, + d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2, + d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8, + d7m6to11m10, d1m0to11m10, }; #define MAX1363_12X_CHANS(bits) { \ @@ -578,16 +578,15 @@ static const struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12); static const enum max1363_modes max11607_mode_list[] = { _s0, _s1, _s2, _s3, - s0to1, s0to2, s0to3, - s2to3, + s0to1, s0to2, s2to3, + s0to3, d0m1, d2m3, d1m0, d3m2, d0m1to2m3, d1m0to3m2, }; static const enum max1363_modes max11608_mode_list[] = { _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, - s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s0to7, - s6to7, + s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s6to7, s0to7, d0m1, d2m3, d4m5, d6m7, d1m0, d3m2, d5m4, d7m6, d0m1to2m3, d0m1to4m5, d0m1to6m7, From fedfd16c297bf6bcb78c20686dc98658b171cc3b Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Thu, 15 May 2025 16:31:01 +0800 Subject: [PATCH 024/404] iio: adc: stm32-adc: Fix race in installing chained IRQ handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e8ad595064f6ebd5d2d1a5d5d7ebe0efce623091 upstream. Fix a race where a pending interrupt could be received and the handler called before the handler's data has been setup, by converting to irq_set_chained_handler_and_data(). Fixes: 1add69880240 ("iio: adc: Add support for STM32 ADC core") Signed-off-by: Chen Ni Reviewed-by: Nuno Sá Tested-by: Fabrice Gasnier Reviewed-by: Fabrice Gasnier Link: https://patch.msgid.link/20250515083101.3811350-1-nichen@iscas.ac.cn Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/stm32-adc-core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index 0ecec5a15fbf..ab07b12124fa 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c @@ -393,10 +393,9 @@ static int stm32_adc_irq_probe(struct platform_device *pdev, return -ENOMEM; } - for (i = 0; i < priv->cfg->num_irqs; i++) { - irq_set_chained_handler(priv->irq[i], stm32_adc_irq_handler); - irq_set_handler_data(priv->irq[i], priv); - } + for (i = 0; i < priv->cfg->num_irqs; i++) + irq_set_chained_handler_and_data(priv->irq[i], + stm32_adc_irq_handler, priv); return 0; } From 374d9b3eb4b08407997ef1fce96119d31e0c0bc4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 7 Jul 2025 14:34:29 +0100 Subject: [PATCH 025/404] comedi: pcl812: Fix bit shift out of bounds commit b14b076ce593f72585412fc7fd3747e03a5e3632 upstream. When checking for a supported IRQ number, the following test is used: if ((1 << it->options[1]) & board->irq_bits) { However, `it->options[i]` is an unchecked `int` value from userspace, so the shift amount could be negative or out of bounds. Fix the test by requiring `it->options[1]` to be within bounds before proceeding with the original test. Valid `it->options[1]` values that select the IRQ will be in the range [1,15]. The value 0 explicitly disables the use of interrupts. Reported-by: syzbot+32de323b0addb9e114ff@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=32de323b0addb9e114ff Fixes: fcdb427bc7cf ("Staging: comedi: add pcl821 driver") Cc: stable@vger.kernel.org # 5.13+ Signed-off-by: Ian Abbott Link: https://lore.kernel.org/r/20250707133429.73202-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl812.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index aefc1b849cf7..98112c79e2d7 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -1151,7 +1151,8 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!dev->pacer) return -ENOMEM; - if ((1 << it->options[1]) & board->irq_bits) { + if (it->options[1] > 0 && it->options[1] < 16 && + (1 << it->options[1]) & board->irq_bits) { ret = request_irq(it->options[1], pcl812_interrupt, 0, dev->board_name, dev); if (ret == 0) From a88692245c315bf8e225f205297a6f4b13d6856a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 7 Jul 2025 14:46:22 +0100 Subject: [PATCH 026/404] comedi: aio_iiro_16: Fix bit shift out of bounds commit 66acb1586737a22dd7b78abc63213b1bcaa100e4 upstream. When checking for a supported IRQ number, the following test is used: if ((1 << it->options[1]) & 0xdcfc) { However, `it->options[i]` is an unchecked `int` value from userspace, so the shift amount could be negative or out of bounds. Fix the test by requiring `it->options[1]` to be within bounds before proceeding with the original test. Valid `it->options[1]` values that select the IRQ will be in the range [1,15]. The value 0 explicitly disables the use of interrupts. Fixes: ad7a370c8be4 ("staging: comedi: aio_iiro_16: add command support for change of state detection") Cc: stable@vger.kernel.org # 5.13+ Signed-off-by: Ian Abbott Link: https://lore.kernel.org/r/20250707134622.75403-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/aio_iiro_16.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index 41c9c56816ef..68be0ab0b80b 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -178,7 +178,8 @@ static int aio_iiro_16_attach(struct comedi_device *dev, * Digital input change of state interrupts are optionally supported * using IRQ 2-7, 10-12, 14, or 15. */ - if ((1 << it->options[1]) & 0xdcfc) { + if (it->options[1] > 0 && it->options[1] < 16 && + (1 << it->options[1]) & 0xdcfc) { ret = request_irq(it->options[1], aio_iiro_16_cos, 0, dev->board_name, dev); if (ret == 0) From 539bdff832adac9ea653859fa0b6bc62e743329c Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 7 Jul 2025 14:09:08 +0100 Subject: [PATCH 027/404] comedi: das16m1: Fix bit shift out of bounds commit ed93c6f68a3be06e4e0c331c6e751f462dee3932 upstream. When checking for a supported IRQ number, the following test is used: /* only irqs 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, and 15 are valid */ if ((1 << it->options[1]) & 0xdcfc) { However, `it->options[i]` is an unchecked `int` value from userspace, so the shift amount could be negative or out of bounds. Fix the test by requiring `it->options[1]` to be within bounds before proceeding with the original test. Reported-by: syzbot+c52293513298e0fd9a94@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=c52293513298e0fd9a94 Fixes: 729988507680 ("staging: comedi: das16m1: tidy up the irq support in das16m1_attach()") Tested-by: syzbot+c52293513298e0fd9a94@syzkaller.appspotmail.com Suggested-by: "Enju, Kohei" Cc: stable@vger.kernel.org # 5.13+ Signed-off-by: Ian Abbott Link: https://lore.kernel.org/r/20250707130908.70758-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16m1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index 4e36377b592a..16e4c1637d0b 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -523,7 +523,8 @@ static int das16m1_attach(struct comedi_device *dev, devpriv->extra_iobase = dev->iobase + DAS16M1_8255_IOBASE; /* only irqs 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, and 15 are valid */ - if ((1 << it->options[1]) & 0xdcfc) { + if (it->options[1] >= 2 && it->options[1] <= 15 && + (1 << it->options[1]) & 0xdcfc) { ret = request_irq(it->options[1], das16m1_interrupt, 0, dev->board_name, dev); if (ret == 0) From a15e9c175f783298c4ee48146be6841335400406 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 7 Jul 2025 14:57:37 +0100 Subject: [PATCH 028/404] comedi: das6402: Fix bit shift out of bounds commit 70f2b28b5243df557f51c054c20058ae207baaac upstream. When checking for a supported IRQ number, the following test is used: /* IRQs 2,3,5,6,7, 10,11,15 are valid for "enhanced" mode */ if ((1 << it->options[1]) & 0x8cec) { However, `it->options[i]` is an unchecked `int` value from userspace, so the shift amount could be negative or out of bounds. Fix the test by requiring `it->options[1]` to be within bounds before proceeding with the original test. Valid `it->options[1]` values that select the IRQ will be in the range [1,15]. The value 0 explicitly disables the use of interrupts. Fixes: 79e5e6addbb1 ("staging: comedi: das6402: rewrite broken driver") Cc: stable@vger.kernel.org # 5.13+ Signed-off-by: Ian Abbott Link: https://lore.kernel.org/r/20250707135737.77448-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das6402.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index 0034005bdf8f..0cd5d1b1ffde 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -569,7 +569,8 @@ static int das6402_attach(struct comedi_device *dev, das6402_reset(dev); /* IRQs 2,3,5,6,7, 10,11,15 are valid for "enhanced" mode */ - if ((1 << it->options[1]) & 0x8cec) { + if (it->options[1] > 0 && it->options[1] < 16 && + (1 << it->options[1]) & 0x8cec) { ret = request_irq(it->options[1], das6402_interrupt, 0, dev->board_name, dev); if (ret == 0) { From c1a1ddba35dd1d869ea6e3b5f508f4ff0b38b997 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 7 Jul 2025 13:15:55 +0100 Subject: [PATCH 029/404] comedi: Fix some signed shift left operations commit ab705c8c35e18652abc6239c07cf3441f03e2cda upstream. Correct some left shifts of the signed integer constant 1 by some unsigned number less than 32. Change the constant to 1U to avoid shifting a 1 into the sign bit. The corrected functions are comedi_dio_insn_config(), comedi_dio_update_state(), and __comedi_device_postconfig(). Fixes: e523c6c86232 ("staging: comedi: drivers: introduce comedi_dio_insn_config()") Fixes: 05e60b13a36b ("staging: comedi: drivers: introduce comedi_dio_update_state()") Fixes: 09567cb4373e ("staging: comedi: initialize subdevice s->io_bits in postconfig") Cc: stable@vger.kernel.org # 5.13+ Signed-off-by: Ian Abbott Link: https://lore.kernel.org/r/20250707121555.65424-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 750a6ff3c03c..6bb7b8a1e75d 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -339,10 +339,10 @@ int comedi_dio_insn_config(struct comedi_device *dev, unsigned int *data, unsigned int mask) { - unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec); + unsigned int chan = CR_CHAN(insn->chanspec); - if (!mask) - mask = chan_mask; + if (!mask && chan < 32) + mask = 1U << chan; switch (data[0]) { case INSN_CONFIG_DIO_INPUT: @@ -382,7 +382,7 @@ EXPORT_SYMBOL_GPL(comedi_dio_insn_config); unsigned int comedi_dio_update_state(struct comedi_subdevice *s, unsigned int *data) { - unsigned int chanmask = (s->n_chan < 32) ? ((1 << s->n_chan) - 1) + unsigned int chanmask = (s->n_chan < 32) ? ((1U << s->n_chan) - 1) : 0xffffffff; unsigned int mask = data[0] & chanmask; unsigned int bits = data[1]; @@ -625,8 +625,8 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, if (insn->insn == INSN_WRITE) { if (!(s->subdev_flags & SDF_WRITABLE)) return -EINVAL; - _data[0] = 1 << (chan - base_chan); /* mask */ - _data[1] = data[0] ? (1 << (chan - base_chan)) : 0; /* bits */ + _data[0] = 1U << (chan - base_chan); /* mask */ + _data[1] = data[0] ? (1U << (chan - base_chan)) : 0; /* bits */ } ret = s->insn_bits(dev, s, &_insn, _data); @@ -709,7 +709,7 @@ static int __comedi_device_postconfig(struct comedi_device *dev) if (s->type == COMEDI_SUBD_DO) { if (s->n_chan < 32) - s->io_bits = (1 << s->n_chan) - 1; + s->io_bits = (1U << s->n_chan) - 1; else s->io_bits = 0xffffffff; } From 4c2981bf30401adfcdbfece4ab6f411f7c5875a1 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 7 Jul 2025 16:33:54 +0100 Subject: [PATCH 030/404] comedi: Fix use of uninitialized data in insn_rw_emulate_bits() commit e9cb26291d009243a4478a7ffb37b3a9175bfce9 upstream. For Comedi `INSN_READ` and `INSN_WRITE` instructions on "digital" subdevices (subdevice types `COMEDI_SUBD_DI`, `COMEDI_SUBD_DO`, and `COMEDI_SUBD_DIO`), it is common for the subdevice driver not to have `insn_read` and `insn_write` handler functions, but to have an `insn_bits` handler function for handling Comedi `INSN_BITS` instructions. In that case, the subdevice's `insn_read` and/or `insn_write` function handler pointers are set to point to the `insn_rw_emulate_bits()` function by `__comedi_device_postconfig()`. For `INSN_WRITE`, `insn_rw_emulate_bits()` currently assumes that the supplied `data[0]` value is a valid copy from user memory. It will at least exist because `do_insnlist_ioctl()` and `do_insn_ioctl()` in "comedi_fops.c" ensure at lease `MIN_SAMPLES` (16) elements are allocated. However, if `insn->n` is 0 (which is allowable for `INSN_READ` and `INSN_WRITE` instructions, then `data[0]` may contain uninitialized data, and certainly contains invalid data, possibly from a different instruction in the array of instructions handled by `do_insnlist_ioctl()`. This will result in an incorrect value being written to the digital output channel (or to the digital input/output channel if configured as an output), and may be reflected in the internal saved state of the channel. Fix it by returning 0 early if `insn->n` is 0, before reaching the code that accesses `data[0]`. Previously, the function always returned 1 on success, but it is supposed to be the number of data samples actually read or written up to `insn->n`, which is 0 in this case. Reported-by: syzbot+cb96ec476fb4914445c9@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=cb96ec476fb4914445c9 Fixes: ed9eccbe8970 ("Staging: add comedi core") Cc: stable@vger.kernel.org # 5.13+ Signed-off-by: Ian Abbott Link: https://lore.kernel.org/r/20250707153355.82474-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 6bb7b8a1e75d..ced660663f0d 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -615,6 +615,9 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, unsigned int _data[2]; int ret; + if (insn->n == 0) + return 0; + memset(_data, 0, sizeof(_data)); memset(&_insn, 0, sizeof(_insn)); _insn.insn = INSN_BITS; From 04d49e2bc19870e3f7d1d18afe951bb6293a63a0 Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Thu, 10 Jul 2025 10:38:46 -0700 Subject: [PATCH 031/404] net: emaclite: Fix missing pointer increment in aligned_read() [ Upstream commit 7727ec1523d7973defa1dff8f9c0aad288d04008 ] Add missing post-increment operators for byte pointers in the loop that copies remaining bytes in xemaclite_aligned_read(). Without the increment, the same byte was written repeatedly to the destination. This update aligns with xemaclite_aligned_write() Fixes: bb81b2ddfa19 ("net: add Xilinx emac lite device driver") Signed-off-by: Alok Tiwari Link: https://patch.msgid.link/20250710173849.2381003-1-alok.a.tiwari@oracle.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/xilinx/xilinx_emaclite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 951482d899f9..a834a0c7f770 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -293,7 +293,7 @@ static void xemaclite_aligned_read(u32 *src_ptr, u8 *dest_ptr, /* Read the remaining data */ for (; length > 0; length--) - *to_u8_ptr = *from_u8_ptr; + *to_u8_ptr++ = *from_u8_ptr++; } } From aa7a22c4d678bf649fd3a1d27debec583563414d Mon Sep 17 00:00:00 2001 From: Xiang Mei Date: Thu, 10 Jul 2025 03:09:42 -0700 Subject: [PATCH 032/404] net/sched: sch_qfq: Fix race condition on qfq_aggregate [ Upstream commit 5e28d5a3f774f118896aec17a3a20a9c5c9dfc64 ] A race condition can occur when 'agg' is modified in qfq_change_agg (called during qfq_enqueue) while other threads access it concurrently. For example, qfq_dump_class may trigger a NULL dereference, and qfq_delete_class may cause a use-after-free. This patch addresses the issue by: 1. Moved qfq_destroy_class into the critical section. 2. Added sch_tree_lock protection to qfq_dump_class and qfq_dump_class_stats. Fixes: 462dbc9101ac ("pkt_sched: QFQ Plus: fair-queueing service at DRR cost") Signed-off-by: Xiang Mei Reviewed-by: Cong Wang Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/sched/sch_qfq.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index c466d255f786..2a4331a08494 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -408,7 +408,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, bool existing = false; struct nlattr *tb[TCA_QFQ_MAX + 1]; struct qfq_aggregate *new_agg = NULL; - u32 weight, lmax, inv_w; + u32 weight, lmax, inv_w, old_weight, old_lmax; int err; int delta_w; @@ -444,12 +444,16 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, inv_w = ONE_FP / weight; weight = ONE_FP / inv_w; - if (cl != NULL && - lmax == cl->agg->lmax && - weight == cl->agg->class_weight) - return 0; /* nothing to change */ + if (cl != NULL) { + sch_tree_lock(sch); + old_weight = cl->agg->class_weight; + old_lmax = cl->agg->lmax; + sch_tree_unlock(sch); + if (lmax == old_lmax && weight == old_weight) + return 0; /* nothing to change */ + } - delta_w = weight - (cl ? cl->agg->class_weight : 0); + delta_w = weight - (cl ? old_weight : 0); if (q->wsum + delta_w > QFQ_MAX_WSUM) { pr_notice("qfq: total weight out of range (%d + %u)\n", @@ -550,10 +554,10 @@ static int qfq_delete_class(struct Qdisc *sch, unsigned long arg) qdisc_purge_queue(cl->qdisc); qdisc_class_hash_remove(&q->clhash, &cl->common); + qfq_destroy_class(sch, cl); sch_tree_unlock(sch); - qfq_destroy_class(sch, cl); return 0; } @@ -620,6 +624,7 @@ static int qfq_dump_class(struct Qdisc *sch, unsigned long arg, { struct qfq_class *cl = (struct qfq_class *)arg; struct nlattr *nest; + u32 class_weight, lmax; tcm->tcm_parent = TC_H_ROOT; tcm->tcm_handle = cl->common.classid; @@ -628,8 +633,13 @@ static int qfq_dump_class(struct Qdisc *sch, unsigned long arg, nest = nla_nest_start_noflag(skb, TCA_OPTIONS); if (nest == NULL) goto nla_put_failure; - if (nla_put_u32(skb, TCA_QFQ_WEIGHT, cl->agg->class_weight) || - nla_put_u32(skb, TCA_QFQ_LMAX, cl->agg->lmax)) + + sch_tree_lock(sch); + class_weight = cl->agg->class_weight; + lmax = cl->agg->lmax; + sch_tree_unlock(sch); + if (nla_put_u32(skb, TCA_QFQ_WEIGHT, class_weight) || + nla_put_u32(skb, TCA_QFQ_LMAX, lmax)) goto nla_put_failure; return nla_nest_end(skb, nest); @@ -646,8 +656,10 @@ static int qfq_dump_class_stats(struct Qdisc *sch, unsigned long arg, memset(&xstats, 0, sizeof(xstats)); + sch_tree_lock(sch); xstats.weight = cl->agg->class_weight; xstats.lmax = cl->agg->lmax; + sch_tree_unlock(sch); if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), d, NULL, &cl->bstats) < 0 || From 0a263ccb905b4ae2af381cd4280bd8d2477b98b8 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 14 Jul 2025 13:12:56 +0200 Subject: [PATCH 033/404] usb: net: sierra: check for no status endpoint [ Upstream commit 4c4ca3c46167518f8534ed70f6e3b4bf86c4d158 ] The driver checks for having three endpoints and having bulk in and out endpoints, but not that the third endpoint is interrupt input. Rectify the omission. Reported-by: syzbot+3f89ec3d1d0842e95d50@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-usb/686d5a9f.050a0220.1ffab7.0017.GAE@google.com/ Tested-by: syzbot+3f89ec3d1d0842e95d50@syzkaller.appspotmail.com Fixes: eb4fd8cd355c8 ("net/usb: add sierra_net.c driver") Signed-off-by: Oliver Neukum Link: https://patch.msgid.link/20250714111326.258378-1-oneukum@suse.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/usb/sierra_net.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index 6f9ec5ce61dc..a8f8134fab36 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -694,6 +694,10 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) status); return -ENODEV; } + if (!dev->status) { + dev_err(&dev->udev->dev, "No status endpoint found"); + return -ENODEV; + } /* Initialize sierra private data */ priv = kzalloc(sizeof *priv, GFP_KERNEL); if (!priv) From 262cd18f5f7ede6a586580cadc5d0799e52e2e7c Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 7 Jul 2025 19:28:29 +0000 Subject: [PATCH 034/404] Bluetooth: Fix null-ptr-deref in l2cap_sock_resume_cb() [ Upstream commit a0075accbf0d76c2dad1ad3993d2e944505d99a0 ] syzbot reported null-ptr-deref in l2cap_sock_resume_cb(). [0] l2cap_sock_resume_cb() has a similar problem that was fixed by commit 1bff51ea59a9 ("Bluetooth: fix use-after-free error in lock_sock_nested()"). Since both l2cap_sock_kill() and l2cap_sock_resume_cb() are executed under l2cap_sock_resume_cb(), we can avoid the issue simply by checking if chan->data is NULL. Let's not access to the killed socket in l2cap_sock_resume_cb(). [0]: BUG: KASAN: null-ptr-deref in instrument_atomic_write include/linux/instrumented.h:82 [inline] BUG: KASAN: null-ptr-deref in clear_bit include/asm-generic/bitops/instrumented-atomic.h:41 [inline] BUG: KASAN: null-ptr-deref in l2cap_sock_resume_cb+0xb4/0x17c net/bluetooth/l2cap_sock.c:1711 Write of size 8 at addr 0000000000000570 by task kworker/u9:0/52 CPU: 1 UID: 0 PID: 52 Comm: kworker/u9:0 Not tainted 6.16.0-rc4-syzkaller-g7482bb149b9f #0 PREEMPT Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025 Workqueue: hci0 hci_rx_work Call trace: show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:501 (C) __dump_stack+0x30/0x40 lib/dump_stack.c:94 dump_stack_lvl+0xd8/0x12c lib/dump_stack.c:120 print_report+0x58/0x84 mm/kasan/report.c:524 kasan_report+0xb0/0x110 mm/kasan/report.c:634 check_region_inline mm/kasan/generic.c:-1 [inline] kasan_check_range+0x264/0x2a4 mm/kasan/generic.c:189 __kasan_check_write+0x20/0x30 mm/kasan/shadow.c:37 instrument_atomic_write include/linux/instrumented.h:82 [inline] clear_bit include/asm-generic/bitops/instrumented-atomic.h:41 [inline] l2cap_sock_resume_cb+0xb4/0x17c net/bluetooth/l2cap_sock.c:1711 l2cap_security_cfm+0x524/0xea0 net/bluetooth/l2cap_core.c:7357 hci_auth_cfm include/net/bluetooth/hci_core.h:2092 [inline] hci_auth_complete_evt+0x2e8/0xa4c net/bluetooth/hci_event.c:3514 hci_event_func net/bluetooth/hci_event.c:7511 [inline] hci_event_packet+0x650/0xe9c net/bluetooth/hci_event.c:7565 hci_rx_work+0x320/0xb18 net/bluetooth/hci_core.c:4070 process_one_work+0x7e8/0x155c kernel/workqueue.c:3238 process_scheduled_works kernel/workqueue.c:3321 [inline] worker_thread+0x958/0xed8 kernel/workqueue.c:3402 kthread+0x5fc/0x75c kernel/kthread.c:464 ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:847 Fixes: d97c899bde33 ("Bluetooth: Introduce L2CAP channel callback for resuming") Reported-by: syzbot+e4d73b165c3892852d22@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/686c12bd.a70a0220.29fe6c.0b13.GAE@google.com/ Signed-off-by: Kuniyuki Iwashima Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/l2cap_sock.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index e6d93501e106..93df53f2b76e 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1488,6 +1488,9 @@ static void l2cap_sock_resume_cb(struct l2cap_chan *chan) { struct sock *sk = chan->data; + if (!sk) + return; + if (test_and_clear_bit(FLAG_PENDING_SECURITY, &chan->flags)) { sk->sk_state = BT_CONNECTED; chan->state = BT_CONNECTED; From 24a855e2bb6fe0a894e06972f8d0a1c034fb4e11 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 30 Jun 2025 14:42:23 -0400 Subject: [PATCH 035/404] Bluetooth: SMP: If an unallowed command is received consider it a failure [ Upstream commit fe4840df0bdf341f376885271b7680764fe6b34e ] If a command is received while a bonding is ongoing consider it a pairing failure so the session is cleanup properly and the device is disconnected immediately instead of continuing with other commands that may result in the session to get stuck without ever completing such as the case bellow: > ACL Data RX: Handle 2048 flags 0x02 dlen 21 SMP: Identity Information (0x08) len 16 Identity resolving key[16]: d7e08edef97d3e62cd2331f82d8073b0 > ACL Data RX: Handle 2048 flags 0x02 dlen 21 SMP: Signing Information (0x0a) len 16 Signature key[16]: 1716c536f94e843a9aea8b13ffde477d Bluetooth: hci0: unexpected SMP command 0x0a from XX:XX:XX:XX:XX:XX > ACL Data RX: Handle 2048 flags 0x02 dlen 12 SMP: Identity Address Information (0x09) len 7 Address: XX:XX:XX:XX:XX:XX (Intel Corporate) While accourding to core spec 6.1 the expected order is always BD_ADDR first first then CSRK: When using LE legacy pairing, the keys shall be distributed in the following order: LTK by the Peripheral EDIV and Rand by the Peripheral IRK by the Peripheral BD_ADDR by the Peripheral CSRK by the Peripheral LTK by the Central EDIV and Rand by the Central IRK by the Central BD_ADDR by the Central CSRK by the Central When using LE Secure Connections, the keys shall be distributed in the following order: IRK by the Peripheral BD_ADDR by the Peripheral CSRK by the Peripheral IRK by the Central BD_ADDR by the Central CSRK by the Central According to the Core 6.1 for commands used for key distribution "Key Rejected" can be used: '3.6.1. Key distribution and generation A device may reject a distributed key by sending the Pairing Failed command with the reason set to "Key Rejected". Fixes: b28b4943660f ("Bluetooth: Add strict checks for allowed SMP PDUs") Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/smp.c | 19 ++++++++++++++++++- net/bluetooth/smp.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 4d5ba9778885..3227956eb741 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -2908,8 +2908,25 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) if (code > SMP_CMD_MAX) goto drop; - if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) + if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) { + /* If there is a context and the command is not allowed consider + * it a failure so the session is cleanup properly. + */ + switch (code) { + case SMP_CMD_IDENT_INFO: + case SMP_CMD_IDENT_ADDR_INFO: + case SMP_CMD_SIGN_INFO: + /* 3.6.1. Key distribution and generation + * + * A device may reject a distributed key by sending the + * Pairing Failed command with the reason set to + * "Key Rejected". + */ + smp_failure(conn, SMP_KEY_REJECTED); + break; + } goto drop; + } /* If we don't have a context the only allowed commands are * pairing request and security request. diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 121edadd5f8d..f17de3d9778d 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h @@ -138,6 +138,7 @@ struct smp_cmd_keypress_notify { #define SMP_NUMERIC_COMP_FAILED 0x0c #define SMP_BREDR_PAIRING_IN_PROGRESS 0x0d #define SMP_CROSS_TRANSP_NOT_ALLOWED 0x0e +#define SMP_KEY_REJECTED 0x0f #define SMP_MIN_ENC_KEY_SIZE 7 #define SMP_MAX_ENC_KEY_SIZE 16 From 9adf57c0d4780986aed20636ae971f181026b85b Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 2 Jul 2025 11:53:40 -0400 Subject: [PATCH 036/404] Bluetooth: SMP: Fix using HCI_ERROR_REMOTE_USER_TERM on timeout [ Upstream commit 6ef99c917688a8510259e565bd1b168b7146295a ] This replaces the usage of HCI_ERROR_REMOTE_USER_TERM, which as the name suggest is to indicate a regular disconnection initiated by an user, with HCI_ERROR_AUTH_FAILURE to indicate the session has timeout thus any pairing shall be considered as failed. Fixes: 1e91c29eb60c ("Bluetooth: Use hci_disconnect for immediate disconnection from SMP") Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 3227956eb741..65035d89af98 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1368,7 +1368,7 @@ static void smp_timeout(struct work_struct *work) BT_DBG("conn %p", conn); - hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM); + hci_disconnect(conn->hcon, HCI_ERROR_AUTH_FAILURE); } static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) From 8d3dd53f92e3f3b6f4f71bc66e9c612acf85eb5e Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 16 Jul 2025 09:40:49 -0400 Subject: [PATCH 037/404] Bluetooth: L2CAP: Fix attempting to adjust outgoing MTU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit d24e4a7fedae121d33fb32ad785b87046527eedb ] Configuration request only configure the incoming direction of the peer initiating the request, so using the MTU is the other direction shall not be used, that said the spec allows the peer responding to adjust: Bluetooth Core 6.1, Vol 3, Part A, Section 4.5 'Each configuration parameter value (if any is present) in an L2CAP_CONFIGURATION_RSP packet reflects an ‘adjustment’ to a configuration parameter value that has been sent (or, in case of default values, implied) in the corresponding L2CAP_CONFIGURATION_REQ packet.' That said adjusting the MTU in the response shall be limited to ERTM channels only as for older modes the remote stack may not be able to detect the adjustment causing it to silently drop packets. Link: https://github.com/bluez/bluez/issues/1422 Link: https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/issues/149 Link: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4793 Fixes: 042bb9603c44 ("Bluetooth: L2CAP: Fix L2CAP MTU negotiation") Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- net/bluetooth/l2cap_core.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 4939152f6adc..1272ad73e401 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3484,12 +3484,28 @@ done: /* Configure output options and let the other side know * which ones we don't like. */ - /* If MTU is not provided in configure request, use the most recently - * explicitly or implicitly accepted value for the other direction, - * or the default value. + /* If MTU is not provided in configure request, try adjusting it + * to the current output MTU if it has been set + * + * Bluetooth Core 6.1, Vol 3, Part A, Section 4.5 + * + * Each configuration parameter value (if any is present) in an + * L2CAP_CONFIGURATION_RSP packet reflects an ‘adjustment’ to a + * configuration parameter value that has been sent (or, in case + * of default values, implied) in the corresponding + * L2CAP_CONFIGURATION_REQ packet. */ - if (mtu == 0) - mtu = chan->imtu ? chan->imtu : L2CAP_DEFAULT_MTU; + if (!mtu) { + /* Only adjust for ERTM channels as for older modes the + * remote stack may not be able to detect that the + * adjustment causing it to silently drop packets. + */ + if (chan->mode == L2CAP_MODE_ERTM && + chan->omtu && chan->omtu != L2CAP_DEFAULT_MTU) + mtu = chan->omtu; + else + mtu = L2CAP_DEFAULT_MTU; + } if (mtu < L2CAP_DEFAULT_MIN_MTU) result = L2CAP_CONF_UNACCEPT; From ba48d3993af23753e1f1f01c8d592de9c7785f24 Mon Sep 17 00:00:00 2001 From: Dong Chenchen Date: Wed, 16 Jul 2025 11:45:03 +0800 Subject: [PATCH 038/404] net: vlan: fix VLAN 0 refcount imbalance of toggling filtering during runtime [ Upstream commit 579d4f9ca9a9a605184a9b162355f6ba131f678d ] Assuming the "rx-vlan-filter" feature is enabled on a net device, the 8021q module will automatically add or remove VLAN 0 when the net device is put administratively up or down, respectively. There are a couple of problems with the above scheme. The first problem is a memory leak that can happen if the "rx-vlan-filter" feature is disabled while the device is running: # ip link add bond1 up type bond mode 0 # ethtool -K bond1 rx-vlan-filter off # ip link del dev bond1 When the device is put administratively down the "rx-vlan-filter" feature is disabled, so the 8021q module will not remove VLAN 0 and the memory will be leaked [1]. Another problem that can happen is that the kernel can automatically delete VLAN 0 when the device is put administratively down despite not adding it when the device was put administratively up since during that time the "rx-vlan-filter" feature was disabled. null-ptr-unref or bug_on[2] will be triggered by unregister_vlan_dev() for refcount imbalance if toggling filtering during runtime: $ ip link add bond0 type bond mode 0 $ ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q $ ethtool -K bond0 rx-vlan-filter off $ ifconfig bond0 up $ ethtool -K bond0 rx-vlan-filter on $ ifconfig bond0 down $ ip link del vlan0 Root cause is as below: step1: add vlan0 for real_dev, such as bond, team. register_vlan_dev vlan_vid_add(real_dev,htons(ETH_P_8021Q),0) //refcnt=1 step2: disable vlan filter feature and enable real_dev step3: change filter from 0 to 1 vlan_device_event vlan_filter_push_vids ndo_vlan_rx_add_vid //No refcnt added to real_dev vlan0 step4: real_dev down vlan_device_event vlan_vid_del(dev, htons(ETH_P_8021Q), 0); //refcnt=0 vlan_info_rcu_free //free vlan0 step5: delete vlan0 unregister_vlan_dev BUG_ON(!vlan_info); //vlan_info is null Fix both problems by noting in the VLAN info whether VLAN 0 was automatically added upon NETDEV_UP and based on that decide whether it should be deleted upon NETDEV_DOWN, regardless of the state of the "rx-vlan-filter" feature. [1] unreferenced object 0xffff8880068e3100 (size 256): comm "ip", pid 384, jiffies 4296130254 hex dump (first 32 bytes): 00 20 30 0d 80 88 ff ff 00 00 00 00 00 00 00 00 . 0............. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace (crc 81ce31fa): __kmalloc_cache_noprof+0x2b5/0x340 vlan_vid_add+0x434/0x940 vlan_device_event.cold+0x75/0xa8 notifier_call_chain+0xca/0x150 __dev_notify_flags+0xe3/0x250 rtnl_configure_link+0x193/0x260 rtnl_newlink_create+0x383/0x8e0 __rtnl_newlink+0x22c/0xa40 rtnl_newlink+0x627/0xb00 rtnetlink_rcv_msg+0x6fb/0xb70 netlink_rcv_skb+0x11f/0x350 netlink_unicast+0x426/0x710 netlink_sendmsg+0x75a/0xc20 __sock_sendmsg+0xc1/0x150 ____sys_sendmsg+0x5aa/0x7b0 ___sys_sendmsg+0xfc/0x180 [2] kernel BUG at net/8021q/vlan.c:99! Oops: invalid opcode: 0000 [#1] SMP KASAN PTI CPU: 0 UID: 0 PID: 382 Comm: ip Not tainted 6.16.0-rc3 #61 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 RIP: 0010:unregister_vlan_dev (net/8021q/vlan.c:99 (discriminator 1)) RSP: 0018:ffff88810badf310 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff88810da84000 RCX: ffffffffb47ceb9a RDX: dffffc0000000000 RSI: 0000000000000008 RDI: ffff88810e8b43c8 RBP: 0000000000000000 R08: 0000000000000000 R09: fffffbfff6cefe80 R10: ffffffffb677f407 R11: ffff88810badf3c0 R12: ffff88810e8b4000 R13: 0000000000000000 R14: ffff88810642a5c0 R15: 000000000000017e FS: 00007f1ff68c20c0(0000) GS:ffff888163a24000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f1ff5dad240 CR3: 0000000107e56000 CR4: 00000000000006f0 Call Trace: rtnl_dellink (net/core/rtnetlink.c:3511 net/core/rtnetlink.c:3553) rtnetlink_rcv_msg (net/core/rtnetlink.c:6945) netlink_rcv_skb (net/netlink/af_netlink.c:2535) netlink_unicast (net/netlink/af_netlink.c:1314 net/netlink/af_netlink.c:1339) netlink_sendmsg (net/netlink/af_netlink.c:1883) ____sys_sendmsg (net/socket.c:712 net/socket.c:727 net/socket.c:2566) ___sys_sendmsg (net/socket.c:2622) __sys_sendmsg (net/socket.c:2652) do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94) Fixes: ad1afb003939 ("vlan_dev: VLAN 0 should be treated as "no vlan tag" (802.1p packet)") Reported-by: syzbot+a8b046e462915c65b10b@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=a8b046e462915c65b10b Suggested-by: Ido Schimmel Signed-off-by: Dong Chenchen Reviewed-by: Ido Schimmel Link: https://patch.msgid.link/20250716034504.2285203-2-dongchenchen2@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/8021q/vlan.c | 42 +++++++++++++++++++++++++++++++++--------- net/8021q/vlan.h | 1 + 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index c75fca3eed49..14244445f944 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -354,6 +354,35 @@ static int __vlan_device_event(struct net_device *dev, unsigned long event) return err; } +static void vlan_vid0_add(struct net_device *dev) +{ + struct vlan_info *vlan_info; + int err; + + if (!(dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) + return; + + pr_info("adding VLAN 0 to HW filter on device %s\n", dev->name); + + err = vlan_vid_add(dev, htons(ETH_P_8021Q), 0); + if (err) + return; + + vlan_info = rtnl_dereference(dev->vlan_info); + vlan_info->auto_vid0 = true; +} + +static void vlan_vid0_del(struct net_device *dev) +{ + struct vlan_info *vlan_info = rtnl_dereference(dev->vlan_info); + + if (!vlan_info || !vlan_info->auto_vid0) + return; + + vlan_info->auto_vid0 = false; + vlan_vid_del(dev, htons(ETH_P_8021Q), 0); +} + static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr) { @@ -375,15 +404,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, return notifier_from_errno(err); } - if ((event == NETDEV_UP) && - (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) { - pr_info("adding VLAN 0 to HW filter on device %s\n", - dev->name); - vlan_vid_add(dev, htons(ETH_P_8021Q), 0); - } - if (event == NETDEV_DOWN && - (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) - vlan_vid_del(dev, htons(ETH_P_8021Q), 0); + if (event == NETDEV_UP) + vlan_vid0_add(dev); + else if (event == NETDEV_DOWN) + vlan_vid0_del(dev); vlan_info = rtnl_dereference(dev->vlan_info); if (!vlan_info) diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 6728d1593929..f0d78018b0d2 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -33,6 +33,7 @@ struct vlan_info { struct vlan_group grp; struct list_head vid_list; unsigned int nr_vids; + bool auto_vid0; struct rcu_head rcu; }; From fed3570e548a6c9f95c5f4c9e1a7afc1679fd90d Mon Sep 17 00:00:00 2001 From: William Liu Date: Thu, 17 Jul 2025 02:28:38 +0000 Subject: [PATCH 039/404] net/sched: Return NULL when htb_lookup_leaf encounters an empty rbtree [ Upstream commit 0e1d5d9b5c5966e2e42e298670808590db5ed628 ] htb_lookup_leaf has a BUG_ON that can trigger with the following: tc qdisc del dev lo root tc qdisc add dev lo root handle 1: htb default 1 tc class add dev lo parent 1: classid 1:1 htb rate 64bit tc qdisc add dev lo parent 1:1 handle 2: netem tc qdisc add dev lo parent 2:1 handle 3: blackhole ping -I lo -c1 -W0.001 127.0.0.1 The root cause is the following: 1. htb_dequeue calls htb_dequeue_tree which calls the dequeue handler on the selected leaf qdisc 2. netem_dequeue calls enqueue on the child qdisc 3. blackhole_enqueue drops the packet and returns a value that is not just NET_XMIT_SUCCESS 4. Because of this, netem_dequeue calls qdisc_tree_reduce_backlog, and since qlen is now 0, it calls htb_qlen_notify -> htb_deactivate -> htb_deactiviate_prios -> htb_remove_class_from_row -> htb_safe_rb_erase 5. As this is the only class in the selected hprio rbtree, __rb_change_child in __rb_erase_augmented sets the rb_root pointer to NULL 6. Because blackhole_dequeue returns NULL, netem_dequeue returns NULL, which causes htb_dequeue_tree to call htb_lookup_leaf with the same hprio rbtree, and fail the BUG_ON The function graph for this scenario is shown here: 0) | htb_enqueue() { 0) + 13.635 us | netem_enqueue(); 0) 4.719 us | htb_activate_prios(); 0) # 2249.199 us | } 0) | htb_dequeue() { 0) 2.355 us | htb_lookup_leaf(); 0) | netem_dequeue() { 0) + 11.061 us | blackhole_enqueue(); 0) | qdisc_tree_reduce_backlog() { 0) | qdisc_lookup_rcu() { 0) 1.873 us | qdisc_match_from_root(); 0) 6.292 us | } 0) 1.894 us | htb_search(); 0) | htb_qlen_notify() { 0) 2.655 us | htb_deactivate_prios(); 0) 6.933 us | } 0) + 25.227 us | } 0) 1.983 us | blackhole_dequeue(); 0) + 86.553 us | } 0) # 2932.761 us | qdisc_warn_nonwc(); 0) | htb_lookup_leaf() { 0) | BUG_ON(); ------------------------------------------ The full original bug report can be seen here [1]. We can fix this just by returning NULL instead of the BUG_ON, as htb_dequeue_tree returns NULL when htb_lookup_leaf returns NULL. [1] https://lore.kernel.org/netdev/pF5XOOIim0IuEfhI-SOxTgRvNoDwuux7UHKnE_Y5-zVd4wmGvNk2ceHjKb8ORnzw0cGwfmVu42g9dL7XyJLf1NEzaztboTWcm0Ogxuojoeo=@willsroot.io/ Fixes: 512bb43eb542 ("pkt_sched: sch_htb: Optimize WARN_ONs in htb_dequeue_tree() etc.") Signed-off-by: William Liu Signed-off-by: Savino Dicanosa Link: https://patch.msgid.link/20250717022816.221364-1-will@willsroot.io Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_htb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index c618aae25b09..2562219ccca4 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -776,7 +776,9 @@ static struct htb_class *htb_lookup_leaf(struct htb_prio *hprio, const int prio) u32 *pid; } stk[TC_HTB_MAXDEPTH], *sp = stk; - BUG_ON(!hprio->row.rb_node); + if (unlikely(!hprio->row.rb_node)) + return NULL; + sp->root = hprio->row.rb_node; sp->pptr = &hprio->ptr; sp->pid = &hprio->last_ptr_id; From 4ea93e0eb91ffa0073a41e47599757766e06b3eb Mon Sep 17 00:00:00 2001 From: Drew Hamilton Date: Tue, 1 Jul 2025 11:41:26 -0400 Subject: [PATCH 040/404] usb: musb: fix gadget state on disconnect commit 67a59f82196c8c4f50c83329f0577acfb1349b50 upstream. When unplugging the USB cable or disconnecting a gadget in usb peripheral mode with echo "" > /sys/kernel/config/usb_gadget//UDC, /sys/class/udc/musb-hdrc.0/state does not change from USB_STATE_CONFIGURED. Testing on dwc2/3 shows they both update the state to USB_STATE_NOTATTACHED. Add calls to usb_gadget_set_state in musb_g_disconnect and musb_gadget_stop to fix both cases. Fixes: 49401f4169c0 ("usb: gadget: introduce gadget state tracking") Cc: stable@vger.kernel.org Co-authored-by: Yehowshua Immanuel Signed-off-by: Yehowshua Immanuel Signed-off-by: Drew Hamilton Link: https://lore.kernel.org/r/20250701154126.8543-1-drew.hamilton@zetier.com [ replaced musb_set_state() call with direct otg state assignment ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_gadget.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index b8fc818c154a..efb70b5c9e8e 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1910,6 +1910,7 @@ static int musb_gadget_stop(struct usb_gadget *g) * gadget driver here and have everything work; * that currently misbehaves. */ + usb_gadget_set_state(g, USB_STATE_NOTATTACHED); /* Force check of devctl register for PM runtime */ schedule_delayed_work(&musb->irq_work, 0); @@ -2018,6 +2019,7 @@ void musb_g_disconnect(struct musb *musb) case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_IDLE: musb->xceiv->otg->state = OTG_STATE_B_IDLE; + usb_gadget_set_state(&musb->g, USB_STATE_NOTATTACHED); break; case OTG_STATE_B_SRP_INIT: break; From 3451944a8cdedcd22e4211462639eb99b1dc8688 Mon Sep 17 00:00:00 2001 From: Krishna Kurapati Date: Wed, 9 Jul 2025 18:59:00 +0530 Subject: [PATCH 041/404] usb: dwc3: qcom: Don't leave BCR asserted commit ef8abc0ba49ce717e6bc4124e88e59982671f3b5 upstream. Leaving the USB BCR asserted prevents the associated GDSC to turn on. This blocks any subsequent attempts of probing the device, e.g. after a probe deferral, with the following showing in the log: [ 1.332226] usb30_prim_gdsc status stuck at 'off' Leave the BCR deasserted when exiting the driver to avoid this issue. Cc: stable Fixes: a4333c3a6ba9 ("usb: dwc3: Add Qualcomm DWC3 glue driver") Acked-by: Thinh Nguyen Reviewed-by: Konrad Dybcio Signed-off-by: Krishna Kurapati Link: https://lore.kernel.org/r/20250709132900.3408752-1-krishna.kurapati@oss.qualcomm.com [ adapted to individual clock management API instead of bulk clock operations ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/dwc3-qcom.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index 742be1e07a01..8be05c7fc98b 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -615,13 +615,13 @@ static int dwc3_qcom_probe(struct platform_device *pdev) ret = reset_control_deassert(qcom->resets); if (ret) { dev_err(&pdev->dev, "failed to deassert resets, err=%d\n", ret); - goto reset_assert; + return ret; } ret = dwc3_qcom_clk_init(qcom, of_clk_get_parent_count(np)); if (ret) { dev_err(dev, "failed to get clocks\n"); - goto reset_assert; + return ret; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -700,8 +700,6 @@ clk_disable: clk_disable_unprepare(qcom->clks[i]); clk_put(qcom->clks[i]); } -reset_assert: - reset_control_assert(qcom->resets); return ret; } @@ -725,8 +723,6 @@ static int dwc3_qcom_remove(struct platform_device *pdev) } qcom->num_clocks = 0; - reset_control_assert(qcom->resets); - pm_runtime_allow(dev); pm_runtime_disable(dev); From 5e45c136ca473fc79c4f231466de0e0ca06c1aac Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Thu, 26 Jun 2025 09:08:25 -0400 Subject: [PATCH 042/404] ASoC: fsl_sai: Force a software reset when starting in consumer mode commit dc78f7e59169d3f0e6c3c95d23dc8e55e95741e2 upstream. On an imx8mm platform with an external clock provider, when running the receiver (arecord) and triggering an xrun with xrun_injection, we see a channel swap/offset. This happens sometimes when running only the receiver, but occurs reliably if a transmitter (aplay) is also concurrently running. It seems that the SAI loses track of frame sync during the trigger stop -> trigger start cycle that occurs during an xrun. Doing just a FIFO reset in this case does not suffice, and only a software reset seems to get it back on track. This looks like the same h/w bug that is already handled for the producer case, so we now do the reset unconditionally on config disable. Signed-off-by: Arun Raghavan Reported-by: Pieterjan Camerlynck Fixes: 3e3f8bd56955 ("ASoC: fsl_sai: fix no frame clk in master mode") Cc: stable@vger.kernel.org Reviewed-by: Fabio Estevam Link: https://patch.msgid.link/20250626130858.163825-1-arun@arunraghavan.net Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- sound/soc/fsl/fsl_sai.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index fdbfaedda4ce..219c4133d26e 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -565,13 +565,15 @@ static void fsl_sai_config_disable(struct fsl_sai *sai, int dir) * anymore. Add software reset to fix this issue. * This is a hardware bug, and will be fix in the * next sai version. + * + * In consumer mode, this can happen even after a + * single open/close, especially if both tx and rx + * are running concurrently. */ - if (!sai->is_slave_mode) { - /* Software Reset */ - regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), FSL_SAI_CSR_SR); - /* Clear SR bit to finish the reset */ - regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), 0); - } + /* Software Reset */ + regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), FSL_SAI_CSR_SR); + /* Clear SR bit to finish the reset */ + regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), 0); } static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, From 773e95c268b5d859f51f7547559734fd2a57660c Mon Sep 17 00:00:00 2001 From: Bui Quang Minh Date: Mon, 30 Jun 2025 21:42:10 +0700 Subject: [PATCH 043/404] virtio-net: ensure the received length does not exceed allocated size commit 315dbdd7cdf6aa533829774caaf4d25f1fd20e73 upstream. In xdp_linearize_page, when reading the following buffers from the ring, we forget to check the received length with the true allocate size. This can lead to an out-of-bound read. This commit adds that missing check. Cc: Fixes: 4941d472bf95 ("virtio-net: do not reset during XDP set") Signed-off-by: Bui Quang Minh Acked-by: Jason Wang Link: https://patch.msgid.link/20250630144212.48471-2-minhquangbui99@gmail.com Signed-off-by: Paolo Abeni [ adapted virtqueue_get_buf() to virtqueue_get_buf_ctx() ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/virtio_net.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 215c546bf50a..6f82338c617e 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -394,6 +394,26 @@ static unsigned int mergeable_ctx_to_truesize(void *mrg_ctx) return (unsigned long)mrg_ctx & ((1 << MRG_CTX_HEADER_SHIFT) - 1); } +static int check_mergeable_len(struct net_device *dev, void *mrg_ctx, + unsigned int len) +{ + unsigned int headroom, tailroom, room, truesize; + + truesize = mergeable_ctx_to_truesize(mrg_ctx); + headroom = mergeable_ctx_to_headroom(mrg_ctx); + tailroom = headroom ? sizeof(struct skb_shared_info) : 0; + room = SKB_DATA_ALIGN(headroom + tailroom); + + if (len > truesize - room) { + pr_debug("%s: rx error: len %u exceeds truesize %lu\n", + dev->name, len, (unsigned long)(truesize - room)); + dev->stats.rx_length_errors++; + return -1; + } + + return 0; +} + /* Called from bottom half context */ static struct sk_buff *page_to_skb(struct virtnet_info *vi, struct receive_queue *rq, @@ -639,7 +659,8 @@ static unsigned int virtnet_get_headroom(struct virtnet_info *vi) * across multiple buffers (num_buf > 1), and we make sure buffers * have enough headroom. */ -static struct page *xdp_linearize_page(struct receive_queue *rq, +static struct page *xdp_linearize_page(struct net_device *dev, + struct receive_queue *rq, u16 *num_buf, struct page *p, int offset, @@ -659,18 +680,27 @@ static struct page *xdp_linearize_page(struct receive_queue *rq, memcpy(page_address(page) + page_off, page_address(p) + offset, *len); page_off += *len; + /* Only mergeable mode can go inside this while loop. In small mode, + * *num_buf == 1, so it cannot go inside. + */ while (--*num_buf) { unsigned int buflen; void *buf; + void *ctx; int off; - buf = virtqueue_get_buf(rq->vq, &buflen); + buf = virtqueue_get_buf_ctx(rq->vq, &buflen, &ctx); if (unlikely(!buf)) goto err_buf; p = virt_to_head_page(buf); off = buf - page_address(p); + if (check_mergeable_len(dev, ctx, buflen)) { + put_page(p); + goto err_buf; + } + /* guard against a misconfigured or uncooperative backend that * is sending packet larger than the MTU. */ @@ -745,7 +775,7 @@ static struct sk_buff *receive_small(struct net_device *dev, headroom = vi->hdr_len + header_offset; buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - xdp_page = xdp_linearize_page(rq, &num_buf, page, + xdp_page = xdp_linearize_page(dev, rq, &num_buf, page, offset, header_offset, &tlen); if (!xdp_page) @@ -910,7 +940,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, if (unlikely(num_buf > 1 || headroom < virtnet_get_headroom(vi))) { /* linearize data for XDP */ - xdp_page = xdp_linearize_page(rq, &num_buf, + xdp_page = xdp_linearize_page(dev, rq, &num_buf, page, offset, VIRTIO_XDP_HEADROOM, &len); From c7e68db993c2fa03b22ad7a072e49428a59af770 Mon Sep 17 00:00:00 2001 From: Hongyu Xie Date: Fri, 27 Jun 2025 17:41:20 +0300 Subject: [PATCH 044/404] xhci: Disable stream for xHC controller with XHCI_BROKEN_STREAMS commit cd65ee81240e8bc3c3119b46db7f60c80864b90b upstream. Disable stream for platform xHC controller with broken stream. Fixes: 14aec589327a6 ("storage: accept some UAS devices if streams are unavailable") Cc: stable Signed-off-by: Hongyu Xie Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20250627144127.3889714-3-mathias.nyman@linux.intel.com [ removed xhci_get_usb3_hcd() call ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index fa320006b04d..73570b392282 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -333,7 +333,8 @@ static int xhci_plat_probe(struct platform_device *pdev) if (ret) goto disable_usb_phy; - if (HCC_MAX_PSA(xhci->hcc_params) >= 4) + if (HCC_MAX_PSA(xhci->hcc_params) >= 4 && + !(xhci->quirks & XHCI_BROKEN_STREAMS)) xhci->shared_hcd->can_do_streams = 1; ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); From b23879eadc617f375d087f9a777197ac97286541 Mon Sep 17 00:00:00 2001 From: Dinghao Liu Date: Mon, 21 Jul 2025 17:18:44 +0530 Subject: [PATCH 045/404] power: supply: bq24190_charger: Fix runtime PM imbalance on error [ Upstream commit 1a37a039711610dd53ec03d8cab9e81875338225 ] pm_runtime_get_sync() increments the runtime PM usage counter even it returns an error code. Thus a pairing decrement is needed on the error handling path to keep the counter balanced. Signed-off-by: Dinghao Liu Reviewed-by: Rafael J. Wysocki Signed-off-by: Sebastian Reichel Stable-dep-of: 47c29d692129 ("power: supply: bq24190: Fix use after free bug in bq24190_remove due to race condition") Signed-off-by: Shubham Kulkarni Signed-off-by: Greg Kroah-Hartman --- drivers/power/supply/bq24190_charger.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index f912284b2e55..446b6f13dc8a 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c @@ -484,8 +484,10 @@ static ssize_t bq24190_sysfs_store(struct device *dev, return ret; ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(bdi->dev); return ret; + } ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v); if (ret) From 38af1d0e43998b2a2c40b3d62894d7e51c8d5b4c Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Mon, 21 Jul 2025 17:18:45 +0530 Subject: [PATCH 046/404] power: supply: bq24190_charger: using pm_runtime_resume_and_get instead of pm_runtime_get_sync [ Upstream commit d96a89407e5f682d1cb22569d91784506c784863 ] Using pm_runtime_resume_and_get is more appropriate for simplifing code Reported-by: Zeal Robot Signed-off-by: Minghao Chi Signed-off-by: Sebastian Reichel [ skulkarni: Minor changes in hunk #3/12 wrt the mainline commit ] Stable-dep-of: 47c29d692129 ("power: supply: bq24190: Fix use after free bug in bq24190_remove due to race condition") Signed-off-by: Shubham Kulkarni Signed-off-by: Greg Kroah-Hartman --- drivers/power/supply/bq24190_charger.c | 63 +++++++++----------------- 1 file changed, 21 insertions(+), 42 deletions(-) diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index 446b6f13dc8a..0107b43ff554 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c @@ -448,11 +448,9 @@ static ssize_t bq24190_sysfs_show(struct device *dev, if (!info) return -EINVAL; - ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) { - pm_runtime_put_noidle(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) return ret; - } ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v); if (ret) @@ -483,11 +481,9 @@ static ssize_t bq24190_sysfs_store(struct device *dev, if (ret < 0) return ret; - ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) { - pm_runtime_put_noidle(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) return ret; - } ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v); if (ret) @@ -506,10 +502,9 @@ static int bq24190_set_charge_mode(struct regulator_dev *dev, u8 val) struct bq24190_dev_info *bdi = rdev_get_drvdata(dev); int ret; - ret = pm_runtime_get_sync(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); if (ret < 0) { dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret); - pm_runtime_put_noidle(bdi->dev); return ret; } @@ -539,10 +534,9 @@ static int bq24190_vbus_is_enabled(struct regulator_dev *dev) int ret; u8 val; - ret = pm_runtime_get_sync(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); if (ret < 0) { dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret); - pm_runtime_put_noidle(bdi->dev); return ret; } @@ -1083,11 +1077,9 @@ static int bq24190_charger_get_property(struct power_supply *psy, dev_dbg(bdi->dev, "prop: %d\n", psp); - ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) { - pm_runtime_put_noidle(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) return ret; - } switch (psp) { case POWER_SUPPLY_PROP_CHARGE_TYPE: @@ -1157,11 +1149,9 @@ static int bq24190_charger_set_property(struct power_supply *psy, dev_dbg(bdi->dev, "prop: %d\n", psp); - ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) { - pm_runtime_put_noidle(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) return ret; - } switch (psp) { case POWER_SUPPLY_PROP_ONLINE: @@ -1431,11 +1421,9 @@ static int bq24190_battery_get_property(struct power_supply *psy, dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n"); dev_dbg(bdi->dev, "prop: %d\n", psp); - ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) { - pm_runtime_put_noidle(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) return ret; - } switch (psp) { case POWER_SUPPLY_PROP_STATUS: @@ -1479,11 +1467,9 @@ static int bq24190_battery_set_property(struct power_supply *psy, dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n"); dev_dbg(bdi->dev, "prop: %d\n", psp); - ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) { - pm_runtime_put_noidle(bdi->dev); + ret = pm_runtime_resume_and_get(bdi->dev); + if (ret < 0) return ret; - } switch (psp) { case POWER_SUPPLY_PROP_ONLINE: @@ -1637,10 +1623,9 @@ static irqreturn_t bq24190_irq_handler_thread(int irq, void *data) int error; bdi->irq_event = true; - error = pm_runtime_get_sync(bdi->dev); + error = pm_runtime_resume_and_get(bdi->dev); if (error < 0) { dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); - pm_runtime_put_noidle(bdi->dev); return IRQ_NONE; } bq24190_check_status(bdi); @@ -1860,11 +1845,9 @@ static int bq24190_remove(struct i2c_client *client) struct bq24190_dev_info *bdi = i2c_get_clientdata(client); int error; - error = pm_runtime_get_sync(bdi->dev); - if (error < 0) { + error = pm_runtime_resume_and_get(bdi->dev); + if (error < 0) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); - pm_runtime_put_noidle(bdi->dev); - } bq24190_register_reset(bdi); if (bdi->battery) @@ -1913,11 +1896,9 @@ static __maybe_unused int bq24190_pm_suspend(struct device *dev) struct bq24190_dev_info *bdi = i2c_get_clientdata(client); int error; - error = pm_runtime_get_sync(bdi->dev); - if (error < 0) { + error = pm_runtime_resume_and_get(bdi->dev); + if (error < 0) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); - pm_runtime_put_noidle(bdi->dev); - } bq24190_register_reset(bdi); @@ -1938,11 +1919,9 @@ static __maybe_unused int bq24190_pm_resume(struct device *dev) bdi->f_reg = 0; bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ - error = pm_runtime_get_sync(bdi->dev); - if (error < 0) { + error = pm_runtime_resume_and_get(bdi->dev); + if (error < 0) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); - pm_runtime_put_noidle(bdi->dev); - } bq24190_register_reset(bdi); bq24190_set_config(bdi); From 4a1b82ee331903aa56f4aeea33fb1244e63355f3 Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Mon, 21 Jul 2025 17:18:46 +0530 Subject: [PATCH 047/404] power: supply: bq24190: Fix use after free bug in bq24190_remove due to race condition [ Upstream commit 47c29d69212911f50bdcdd0564b5999a559010d4 ] In bq24190_probe, &bdi->input_current_limit_work is bound with bq24190_input_current_limit_work. When external power changed, it will call bq24190_charger_external_power_changed to start the work. If we remove the module which will call bq24190_remove to make cleanup, there may be a unfinished work. The possible sequence is as follows: CPU0 CPUc1 |bq24190_input_current_limit_work bq24190_remove | power_supply_unregister | device_unregister | power_supply_dev_release| kfree(psy) | | | power_supply_get_property_from_supplier | //use Fix it by finishing the work before cleanup in the bq24190_remove Fixes: 97774672573a ("power_supply: Initialize changed_work before calling device_add") Signed-off-by: Zheng Wang Signed-off-by: Sebastian Reichel Signed-off-by: Shubham Kulkarni Signed-off-by: Greg Kroah-Hartman --- drivers/power/supply/bq24190_charger.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index 0107b43ff554..34f570ccbe47 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c @@ -1845,6 +1845,7 @@ static int bq24190_remove(struct i2c_client *client) struct bq24190_dev_info *bdi = i2c_get_clientdata(client); int error; + cancel_delayed_work_sync(&bdi->input_current_limit_work); error = pm_runtime_resume_and_get(bdi->dev); if (error < 0) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); From 74d5d2575f0e06e2cdbaaf208d0648f05a57197f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 17 Jul 2025 05:45:51 -0700 Subject: [PATCH 048/404] net_sched: sch_sfq: annotate data-races around q->perturb_period [ Upstream commit a17ef9e6c2c1cf0fc6cd6ca6a9ce525c67d1da7f ] sfq_perturbation() reads q->perturb_period locklessly. Add annotations to fix potential issues. Signed-off-by: Eric Dumazet Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20240430180015.3111398-1-edumazet@google.com Signed-off-by: Jakub Kicinski [ Harshit: Backport to 5.4.y, conflicts resolved due to missing commit: d636fc5dd692 ("net: sched: add rcu annotations around qdisc->qdisc_sleeping")in 5.4.y ] Signed-off-by: Harshit Mogalapalli Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_sfq.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index acda65371028..7ca33cfbd03b 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -611,6 +611,7 @@ static void sfq_perturbation(struct timer_list *t) struct Qdisc *sch = q->sch; spinlock_t *root_lock = qdisc_lock(qdisc_root_sleeping(sch)); siphash_key_t nkey; + int period; get_random_bytes(&nkey, sizeof(nkey)); spin_lock(root_lock); @@ -619,8 +620,12 @@ static void sfq_perturbation(struct timer_list *t) sfq_rehash(sch); spin_unlock(root_lock); - if (q->perturb_period) - mod_timer(&q->perturb_timer, jiffies + q->perturb_period); + /* q->perturb_period can change under us from + * sfq_change() and sfq_destroy(). + */ + period = READ_ONCE(q->perturb_period); + if (period) + mod_timer(&q->perturb_timer, jiffies + period); } static int sfq_change(struct Qdisc *sch, struct nlattr *opt) @@ -662,7 +667,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) q->quantum = ctl->quantum; q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum); } - q->perturb_period = ctl->perturb_period * HZ; + WRITE_ONCE(q->perturb_period, ctl->perturb_period * HZ); if (ctl->flows) q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS); if (ctl->divisor) { @@ -724,7 +729,7 @@ static void sfq_destroy(struct Qdisc *sch) struct sfq_sched_data *q = qdisc_priv(sch); tcf_block_put(q->block); - q->perturb_period = 0; + WRITE_ONCE(q->perturb_period, 0); del_timer_sync(&q->perturb_timer); sfq_free(q->ht); sfq_free(q->slots); From 843cacb88f42f426973f1ed11c6fb562558efb27 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 17 Jul 2025 05:45:52 -0700 Subject: [PATCH 049/404] net_sched: sch_sfq: handle bigger packets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit e4650d7ae4252f67e997a632adfae0dd74d3a99a ] SFQ has an assumption on dealing with packets smaller than 64KB. Even before BIG TCP, TCA_STAB can provide arbitrary big values in qdisc_pkt_len(skb) It is time to switch (struct sfq_slot)->allot to a 32bit field. sizeof(struct sfq_slot) is now 64 bytes, giving better cache locality. Signed-off-by: Eric Dumazet Reviewed-by: Toke Høiland-Jørgensen Link: https://patch.msgid.link/20241008111603.653140-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Harshit Mogalapalli Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_sfq.c | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 7ca33cfbd03b..69e7d01c8518 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -77,12 +77,6 @@ #define SFQ_EMPTY_SLOT 0xffff #define SFQ_DEFAULT_HASH_DIVISOR 1024 -/* We use 16 bits to store allot, and want to handle packets up to 64K - * Scale allot by 8 (1<<3) so that no overflow occurs. - */ -#define SFQ_ALLOT_SHIFT 3 -#define SFQ_ALLOT_SIZE(X) DIV_ROUND_UP(X, 1 << SFQ_ALLOT_SHIFT) - /* This type should contain at least SFQ_MAX_DEPTH + 1 + SFQ_MAX_FLOWS values */ typedef u16 sfq_index; @@ -104,7 +98,7 @@ struct sfq_slot { sfq_index next; /* next slot in sfq RR chain */ struct sfq_head dep; /* anchor in dep[] chains */ unsigned short hash; /* hash value (index in ht[]) */ - short allot; /* credit for this slot */ + int allot; /* credit for this slot */ unsigned int backlog; struct red_vars vars; @@ -120,7 +114,6 @@ struct sfq_sched_data { siphash_key_t perturbation; u8 cur_depth; /* depth of longest slot */ u8 flags; - unsigned short scaled_quantum; /* SFQ_ALLOT_SIZE(quantum) */ struct tcf_proto __rcu *filter_list; struct tcf_block *block; sfq_index *ht; /* Hash table ('divisor' slots) */ @@ -459,7 +452,7 @@ enqueue: */ q->tail = slot; /* We could use a bigger initial quantum for new flows */ - slot->allot = q->scaled_quantum; + slot->allot = q->quantum; } if (++sch->q.qlen <= q->limit) return NET_XMIT_SUCCESS; @@ -496,7 +489,7 @@ next_slot: slot = &q->slots[a]; if (slot->allot <= 0) { q->tail = slot; - slot->allot += q->scaled_quantum; + slot->allot += q->quantum; goto next_slot; } skb = slot_dequeue_head(slot); @@ -515,7 +508,7 @@ next_slot: } q->tail->next = next_a; } else { - slot->allot -= SFQ_ALLOT_SIZE(qdisc_pkt_len(skb)); + slot->allot -= qdisc_pkt_len(skb); } return skb; } @@ -598,7 +591,7 @@ drop: q->tail->next = x; } q->tail = slot; - slot->allot = q->scaled_quantum; + slot->allot = q->quantum; } } sch->q.qlen -= dropped; @@ -628,7 +621,8 @@ static void sfq_perturbation(struct timer_list *t) mod_timer(&q->perturb_timer, jiffies + period); } -static int sfq_change(struct Qdisc *sch, struct nlattr *opt) +static int sfq_change(struct Qdisc *sch, struct nlattr *opt, + struct netlink_ext_ack *extack) { struct sfq_sched_data *q = qdisc_priv(sch); struct tc_sfq_qopt *ctl = nla_data(opt); @@ -646,14 +640,10 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) (!is_power_of_2(ctl->divisor) || ctl->divisor > 65536)) return -EINVAL; - /* slot->allot is a short, make sure quantum is not too big. */ - if (ctl->quantum) { - unsigned int scaled = SFQ_ALLOT_SIZE(ctl->quantum); - - if (scaled <= 0 || scaled > SHRT_MAX) - return -EINVAL; + if ((int)ctl->quantum < 0) { + NL_SET_ERR_MSG_MOD(extack, "invalid quantum"); + return -EINVAL; } - if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, ctl_v1->Wlog, ctl_v1->Scell_log, NULL)) return -EINVAL; @@ -663,10 +653,8 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) return -ENOMEM; } sch_tree_lock(sch); - if (ctl->quantum) { + if (ctl->quantum) q->quantum = ctl->quantum; - q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum); - } WRITE_ONCE(q->perturb_period, ctl->perturb_period * HZ); if (ctl->flows) q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS); @@ -762,12 +750,11 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt, q->divisor = SFQ_DEFAULT_HASH_DIVISOR; q->maxflows = SFQ_DEFAULT_FLOWS; q->quantum = psched_mtu(qdisc_dev(sch)); - q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum); q->perturb_period = 0; get_random_bytes(&q->perturbation, sizeof(q->perturbation)); if (opt) { - int err = sfq_change(sch, opt); + int err = sfq_change(sch, opt, extack); if (err) return err; } @@ -878,7 +865,7 @@ static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl, if (idx != SFQ_EMPTY_SLOT) { const struct sfq_slot *slot = &q->slots[idx]; - xstats.allot = slot->allot << SFQ_ALLOT_SHIFT; + xstats.allot = slot->allot; qs.qlen = slot->qlen; qs.backlog = slot->backlog; } From e12f6013d0a69660e8b99bfe381b9546ae667328 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Thu, 17 Jul 2025 05:45:53 -0700 Subject: [PATCH 050/404] net_sched: sch_sfq: don't allow 1 packet limit [ Upstream commit 10685681bafce6febb39770f3387621bf5d67d0b ] The current implementation does not work correctly with a limit of 1. iproute2 actually checks for this and this patch adds the check in kernel as well. This fixes the following syzkaller reported crash: UBSAN: array-index-out-of-bounds in net/sched/sch_sfq.c:210:6 index 65535 is out of range for type 'struct sfq_head[128]' CPU: 0 PID: 2569 Comm: syz-executor101 Not tainted 5.10.0-smp-DEV #1 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 Call Trace: __dump_stack lib/dump_stack.c:79 [inline] dump_stack+0x125/0x19f lib/dump_stack.c:120 ubsan_epilogue lib/ubsan.c:148 [inline] __ubsan_handle_out_of_bounds+0xed/0x120 lib/ubsan.c:347 sfq_link net/sched/sch_sfq.c:210 [inline] sfq_dec+0x528/0x600 net/sched/sch_sfq.c:238 sfq_dequeue+0x39b/0x9d0 net/sched/sch_sfq.c:500 sfq_reset+0x13/0x50 net/sched/sch_sfq.c:525 qdisc_reset+0xfe/0x510 net/sched/sch_generic.c:1026 tbf_reset+0x3d/0x100 net/sched/sch_tbf.c:319 qdisc_reset+0xfe/0x510 net/sched/sch_generic.c:1026 dev_reset_queue+0x8c/0x140 net/sched/sch_generic.c:1296 netdev_for_each_tx_queue include/linux/netdevice.h:2350 [inline] dev_deactivate_many+0x6dc/0xc20 net/sched/sch_generic.c:1362 __dev_close_many+0x214/0x350 net/core/dev.c:1468 dev_close_many+0x207/0x510 net/core/dev.c:1506 unregister_netdevice_many+0x40f/0x16b0 net/core/dev.c:10738 unregister_netdevice_queue+0x2be/0x310 net/core/dev.c:10695 unregister_netdevice include/linux/netdevice.h:2893 [inline] __tun_detach+0x6b6/0x1600 drivers/net/tun.c:689 tun_detach drivers/net/tun.c:705 [inline] tun_chr_close+0x104/0x1b0 drivers/net/tun.c:3640 __fput+0x203/0x840 fs/file_table.c:280 task_work_run+0x129/0x1b0 kernel/task_work.c:185 exit_task_work include/linux/task_work.h:33 [inline] do_exit+0x5ce/0x2200 kernel/exit.c:931 do_group_exit+0x144/0x310 kernel/exit.c:1046 __do_sys_exit_group kernel/exit.c:1057 [inline] __se_sys_exit_group kernel/exit.c:1055 [inline] __x64_sys_exit_group+0x3b/0x40 kernel/exit.c:1055 do_syscall_64+0x6c/0xd0 entry_SYSCALL_64_after_hwframe+0x61/0xcb RIP: 0033:0x7fe5e7b52479 Code: Unable to access opcode bytes at RIP 0x7fe5e7b5244f. RSP: 002b:00007ffd3c800398 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fe5e7b52479 RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000000 RBP: 00007fe5e7bcd2d0 R08: ffffffffffffffb8 R09: 0000000000000014 R10: 0000000000000000 R11: 0000000000000246 R12: 00007fe5e7bcd2d0 R13: 0000000000000000 R14: 00007fe5e7bcdd20 R15: 00007fe5e7b24270 The crash can be also be reproduced with the following (with a tc recompiled to allow for sfq limits of 1): tc qdisc add dev dummy0 handle 1: root tbf rate 1Kbit burst 100b lat 1s ../iproute2-6.9.0/tc/tc qdisc add dev dummy0 handle 2: parent 1:10 sfq limit 1 ifconfig dummy0 up ping -I dummy0 -f -c2 -W0.1 8.8.8.8 sleep 1 Scenario that triggers the crash: * the first packet is sent and queued in TBF and SFQ; qdisc qlen is 1 * TBF dequeues: it peeks from SFQ which moves the packet to the gso_skb list and keeps qdisc qlen set to 1. TBF is out of tokens so it schedules itself for later. * the second packet is sent and TBF tries to queues it to SFQ. qdisc qlen is now 2 and because the SFQ limit is 1 the packet is dropped by SFQ. At this point qlen is 1, and all of the SFQ slots are empty, however q->tail is not NULL. At this point, assuming no more packets are queued, when sch_dequeue runs again it will decrement the qlen for the current empty slot causing an underflow and the subsequent out of bounds access. Reported-by: syzbot Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Octavian Purdila Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20241204030520.2084663-2-tavip@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Harshit Mogalapalli Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_sfq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 69e7d01c8518..aac1a4783f11 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -652,6 +652,10 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt, if (!p) return -ENOMEM; } + if (ctl->limit == 1) { + NL_SET_ERR_MSG_MOD(extack, "invalid limit"); + return -EINVAL; + } sch_tree_lock(sch); if (ctl->quantum) q->quantum = ctl->quantum; From 7bb9498f3dc8e04a2efa9d902aa2b65930ad1e4d Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Thu, 17 Jul 2025 05:45:54 -0700 Subject: [PATCH 051/404] net_sched: sch_sfq: use a temporary work area for validating configuration [ Upstream commit 8c0cea59d40cf6dd13c2950437631dd614fbade6 ] Many configuration parameters have influence on others (e.g. divisor -> flows -> limit, depth -> limit) and so it is difficult to correctly do all of the validation before applying the configuration. And if a validation error is detected late it is difficult to roll back a partially applied configuration. To avoid these issues use a temporary work area to update and validate the configuration and only then apply the configuration to the internal state. Signed-off-by: Octavian Purdila Acked-by: Cong Wang Signed-off-by: David S. Miller Signed-off-by: Harshit Mogalapalli Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_sfq.c | 56 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index aac1a4783f11..d49edcb9729e 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -631,6 +631,15 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt, struct red_parms *p = NULL; struct sk_buff *to_free = NULL; struct sk_buff *tail = NULL; + unsigned int maxflows; + unsigned int quantum; + unsigned int divisor; + int perturb_period; + u8 headdrop; + u8 maxdepth; + int limit; + u8 flags; + if (opt->nla_len < nla_attr_size(sizeof(*ctl))) return -EINVAL; @@ -656,36 +665,59 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt, NL_SET_ERR_MSG_MOD(extack, "invalid limit"); return -EINVAL; } + sch_tree_lock(sch); + + limit = q->limit; + divisor = q->divisor; + headdrop = q->headdrop; + maxdepth = q->maxdepth; + maxflows = q->maxflows; + perturb_period = q->perturb_period; + quantum = q->quantum; + flags = q->flags; + + /* update and validate configuration */ if (ctl->quantum) - q->quantum = ctl->quantum; - WRITE_ONCE(q->perturb_period, ctl->perturb_period * HZ); + quantum = ctl->quantum; + perturb_period = ctl->perturb_period * HZ; if (ctl->flows) - q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS); + maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS); if (ctl->divisor) { - q->divisor = ctl->divisor; - q->maxflows = min_t(u32, q->maxflows, q->divisor); + divisor = ctl->divisor; + maxflows = min_t(u32, maxflows, divisor); } if (ctl_v1) { if (ctl_v1->depth) - q->maxdepth = min_t(u32, ctl_v1->depth, SFQ_MAX_DEPTH); + maxdepth = min_t(u32, ctl_v1->depth, SFQ_MAX_DEPTH); if (p) { - swap(q->red_parms, p); - red_set_parms(q->red_parms, + red_set_parms(p, ctl_v1->qth_min, ctl_v1->qth_max, ctl_v1->Wlog, ctl_v1->Plog, ctl_v1->Scell_log, NULL, ctl_v1->max_P); } - q->flags = ctl_v1->flags; - q->headdrop = ctl_v1->headdrop; + flags = ctl_v1->flags; + headdrop = ctl_v1->headdrop; } if (ctl->limit) { - q->limit = min_t(u32, ctl->limit, q->maxdepth * q->maxflows); - q->maxflows = min_t(u32, q->maxflows, q->limit); + limit = min_t(u32, ctl->limit, maxdepth * maxflows); + maxflows = min_t(u32, maxflows, limit); } + /* commit configuration */ + q->limit = limit; + q->divisor = divisor; + q->headdrop = headdrop; + q->maxdepth = maxdepth; + q->maxflows = maxflows; + WRITE_ONCE(q->perturb_period, perturb_period); + q->quantum = quantum; + q->flags = flags; + if (p) + swap(q->red_parms, p); + qlen = sch->q.qlen; while (sch->q.qlen > q->limit) { dropped += sfq_drop(sch, &to_free); From 8fadc871a42933aacb7f1ce9ed9a96485e2c9cf4 Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Thu, 17 Jul 2025 05:45:55 -0700 Subject: [PATCH 052/404] net_sched: sch_sfq: move the limit validation [ Upstream commit b3bf8f63e6179076b57c9de660c9f80b5abefe70 ] It is not sufficient to directly validate the limit on the data that the user passes as it can be updated based on how the other parameters are changed. Move the check at the end of the configuration update process to also catch scenarios where the limit is indirectly updated, for example with the following configurations: tc qdisc add dev dummy0 handle 1: root sfq limit 2 flows 1 depth 1 tc qdisc add dev dummy0 handle 1: root sfq limit 2 flows 1 divisor 1 This fixes the following syzkaller reported crash: ------------[ cut here ]------------ UBSAN: array-index-out-of-bounds in net/sched/sch_sfq.c:203:6 index 65535 is out of range for type 'struct sfq_head[128]' CPU: 1 UID: 0 PID: 3037 Comm: syz.2.16 Not tainted 6.14.0-rc2-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 12/27/2024 Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x201/0x300 lib/dump_stack.c:120 ubsan_epilogue lib/ubsan.c:231 [inline] __ubsan_handle_out_of_bounds+0xf5/0x120 lib/ubsan.c:429 sfq_link net/sched/sch_sfq.c:203 [inline] sfq_dec+0x53c/0x610 net/sched/sch_sfq.c:231 sfq_dequeue+0x34e/0x8c0 net/sched/sch_sfq.c:493 sfq_reset+0x17/0x60 net/sched/sch_sfq.c:518 qdisc_reset+0x12e/0x600 net/sched/sch_generic.c:1035 tbf_reset+0x41/0x110 net/sched/sch_tbf.c:339 qdisc_reset+0x12e/0x600 net/sched/sch_generic.c:1035 dev_reset_queue+0x100/0x1b0 net/sched/sch_generic.c:1311 netdev_for_each_tx_queue include/linux/netdevice.h:2590 [inline] dev_deactivate_many+0x7e5/0xe70 net/sched/sch_generic.c:1375 Reported-by: syzbot Fixes: 10685681bafc ("net_sched: sch_sfq: don't allow 1 packet limit") Signed-off-by: Octavian Purdila Acked-by: Cong Wang Signed-off-by: David S. Miller Signed-off-by: Harshit Mogalapalli Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_sfq.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index d49edcb9729e..9e8601e64508 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -661,10 +661,6 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt, if (!p) return -ENOMEM; } - if (ctl->limit == 1) { - NL_SET_ERR_MSG_MOD(extack, "invalid limit"); - return -EINVAL; - } sch_tree_lock(sch); @@ -705,6 +701,12 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt, limit = min_t(u32, ctl->limit, maxdepth * maxflows); maxflows = min_t(u32, maxflows, limit); } + if (limit == 1) { + sch_tree_unlock(sch); + kfree(p); + NL_SET_ERR_MSG_MOD(extack, "invalid limit"); + return -EINVAL; + } /* commit configuration */ q->limit = limit; From e0936ff56be4e08ad5b60ec26971eae0c40af305 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 17 Jul 2025 05:45:56 -0700 Subject: [PATCH 053/404] net_sched: sch_sfq: reject invalid perturb period [ Upstream commit 7ca52541c05c832d32b112274f81a985101f9ba8 ] Gerrard Tai reported that SFQ perturb_period has no range check yet, and this can be used to trigger a race condition fixed in a separate patch. We want to make sure ctl->perturb_period * HZ will not overflow and is positive. Tested: tc qd add dev lo root sfq perturb -10 # negative value : error Error: sch_sfq: invalid perturb period. tc qd add dev lo root sfq perturb 1000000000 # too big : error Error: sch_sfq: invalid perturb period. tc qd add dev lo root sfq perturb 2000000 # acceptable value tc -s -d qd sh dev lo qdisc sfq 8005: root refcnt 2 limit 127p quantum 64Kb depth 127 flows 128 divisor 1024 perturb 2000000sec Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: Gerrard Tai Signed-off-by: Eric Dumazet Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250611083501.1810459-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Harshit Mogalapalli Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_sfq.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 9e8601e64508..eaaa5d0e17a7 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -653,6 +653,14 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt, NL_SET_ERR_MSG_MOD(extack, "invalid quantum"); return -EINVAL; } + + if (ctl->perturb_period < 0 || + ctl->perturb_period > INT_MAX / HZ) { + NL_SET_ERR_MSG_MOD(extack, "invalid perturb period"); + return -EINVAL; + } + perturb_period = ctl->perturb_period * HZ; + if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, ctl_v1->Wlog, ctl_v1->Scell_log, NULL)) return -EINVAL; @@ -669,14 +677,12 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt, headdrop = q->headdrop; maxdepth = q->maxdepth; maxflows = q->maxflows; - perturb_period = q->perturb_period; quantum = q->quantum; flags = q->flags; /* update and validate configuration */ if (ctl->quantum) quantum = ctl->quantum; - perturb_period = ctl->perturb_period * HZ; if (ctl->flows) maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS); if (ctl->divisor) { From 042959e9b479502a921109224c3abcc3d3cf09a1 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Wed, 11 Jun 2025 14:24:41 +0300 Subject: [PATCH 054/404] usb: hub: fix detection of high tier USB3 devices behind suspended hubs commit 8f5b7e2bec1c36578fdaa74a6951833541103e27 upstream. USB3 devices connected behind several external suspended hubs may not be detected when plugged in due to aggressive hub runtime pm suspend. The hub driver immediately runtime-suspends hubs if there are no active children or port activity. There is a delay between the wake signal causing hub resume, and driver visible port activity on the hub downstream facing ports. Most of the LFPS handshake, resume signaling and link training done on the downstream ports is not visible to the hub driver until completed, when device then will appear fully enabled and running on the port. This delay between wake signal and detectable port change is even more significant with chained suspended hubs where the wake signal will propagate upstream first. Suspended hubs will only start resuming downstream ports after upstream facing port resumes. The hub driver may resume a USB3 hub, read status of all ports, not yet see any activity, and runtime suspend back the hub before any port activity is visible. This exact case was seen when conncting USB3 devices to a suspended Thunderbolt dock. USB3 specification defines a 100ms tU3WakeupRetryDelay, indicating USB3 devices expect to be resumed within 100ms after signaling wake. if not then device will resend the wake signal. Give the USB3 hubs twice this time (200ms) to detect any port changes after resume, before allowing hub to runtime suspend again. Cc: stable Fixes: 2839f5bcfcfc ("USB: Turn on auto-suspend for USB 3.0 hubs.") Acked-by: Alan Stern Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20250611112441.2267883-1-mathias.nyman@linux.intel.com [ replaced hub_get/hub_put wrapper functions with direct kref_get/kref_put calls ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 585375817f5e..e14bf25a14a6 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -51,6 +51,12 @@ #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */ #define USB_PING_RESPONSE_TIME 400 /* ns */ +/* + * Give SS hubs 200ms time after wake to train downstream links before + * assuming no port activity and allowing hub to runtime suspend back. + */ +#define USB_SS_PORT_U0_WAKE_TIME 200 /* ms */ + /* Protect struct usb_device->state and ->children members * Note: Both are also protected by ->dev.sem, except that ->state can * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ @@ -1024,11 +1030,12 @@ int usb_remove_device(struct usb_device *udev) enum hub_activation_type { HUB_INIT, HUB_INIT2, HUB_INIT3, /* INITs must come first */ - HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME, + HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME, HUB_POST_RESUME, }; static void hub_init_func2(struct work_struct *ws); static void hub_init_func3(struct work_struct *ws); +static void hub_post_resume(struct work_struct *ws); static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) { @@ -1051,6 +1058,13 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) goto init2; goto init3; } + + if (type == HUB_POST_RESUME) { + usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); + kref_put(&hub->kref, hub_release); + return; + } + kref_get(&hub->kref); /* The superspeed hub except for root hub has to use Hub Depth @@ -1299,6 +1313,16 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) device_unlock(&hdev->dev); } + if (type == HUB_RESUME && hub_is_superspeed(hub->hdev)) { + /* give usb3 downstream links training time after hub resume */ + INIT_DELAYED_WORK(&hub->init_work, hub_post_resume); + queue_delayed_work(system_power_efficient_wq, &hub->init_work, + msecs_to_jiffies(USB_SS_PORT_U0_WAKE_TIME)); + usb_autopm_get_interface_no_resume( + to_usb_interface(hub->intfdev)); + return; + } + kref_put(&hub->kref, hub_release); } @@ -1317,6 +1341,13 @@ static void hub_init_func3(struct work_struct *ws) hub_activate(hub, HUB_INIT3); } +static void hub_post_resume(struct work_struct *ws) +{ + struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work); + + hub_activate(hub, HUB_POST_RESUME); +} + enum hub_quiescing_type { HUB_DISCONNECT, HUB_PRE_RESET, HUB_SUSPEND }; From c72cd4c92e06d4f342fba290010d23bce8ff7438 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 26 Jun 2025 16:01:02 +0300 Subject: [PATCH 055/404] usb: hub: Fix flushing and scheduling of delayed work that tunes runtime pm commit a49e1e2e785fb3621f2d748581881b23a364998a upstream. Delayed work to prevent USB3 hubs from runtime-suspending immediately after resume was added in commit 8f5b7e2bec1c ("usb: hub: fix detection of high tier USB3 devices behind suspended hubs"). This delayed work needs be flushed if system suspends, or hub needs to be quiesced for other reasons right after resume. Not flushing it triggered issues on QC SC8280XP CRD board during suspend/resume testing. Fix it by flushing the delayed resume work in hub_quiesce() The delayed work item that allow hub runtime suspend is also scheduled just before calling autopm get. Alan pointed out there is a small risk that work is run before autopm get, which would call autopm put before get, and mess up the runtime pm usage order. Swap the order of work sheduling and calling autopm get to solve this. Cc: stable Fixes: 8f5b7e2bec1c ("usb: hub: fix detection of high tier USB3 devices behind suspended hubs") Reported-by: Konrad Dybcio Closes: https://lore.kernel.org/linux-usb/acaaa928-832c-48ca-b0ea-d202d5cd3d6c@oss.qualcomm.com Reported-by: Alan Stern Closes: https://lore.kernel.org/linux-usb/c73fbead-66d7-497a-8fa1-75ea4761090a@rowland.harvard.edu Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20250626130102.3639861-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index e14bf25a14a6..a854fed13165 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1315,11 +1315,12 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) if (type == HUB_RESUME && hub_is_superspeed(hub->hdev)) { /* give usb3 downstream links training time after hub resume */ + usb_autopm_get_interface_no_resume( + to_usb_interface(hub->intfdev)); + INIT_DELAYED_WORK(&hub->init_work, hub_post_resume); queue_delayed_work(system_power_efficient_wq, &hub->init_work, msecs_to_jiffies(USB_SS_PORT_U0_WAKE_TIME)); - usb_autopm_get_interface_no_resume( - to_usb_interface(hub->intfdev)); return; } @@ -1373,6 +1374,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) /* Stop hub_wq and related activity */ del_timer_sync(&hub->irq_urb_retry); + flush_delayed_work(&hub->init_work); usb_kill_urb(hub->urb); if (hub->has_indicators) cancel_delayed_work_sync(&hub->leds); From 7574892e259bbb16262ebfb4b65a2054a5e03a49 Mon Sep 17 00:00:00 2001 From: Alessandro Carminati Date: Thu, 26 Jun 2025 08:38:09 +0000 Subject: [PATCH 056/404] regulator: core: fix NULL dereference on unbind due to stale coupling data [ Upstream commit ca46946a482238b0cdea459fb82fc837fb36260e ] Failing to reset coupling_desc.n_coupled after freeing coupled_rdevs can lead to NULL pointer dereference when regulators are accessed post-unbind. This can happen during runtime PM or other regulator operations that rely on coupling metadata. For example, on ridesx4, unbinding the 'reg-dummy' platform device triggers a panic in regulator_lock_recursive() due to stale coupling state. Ensure n_coupled is set to 0 to prevent access to invalid pointers. Signed-off-by: Alessandro Carminati Link: https://patch.msgid.link/20250626083809.314842-1-acarmina@redhat.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/regulator/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index a01a769b2f2d..e5ce97dc3215 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -5062,6 +5062,7 @@ static void regulator_remove_coupling(struct regulator_dev *rdev) err); } + rdev->coupling_desc.n_coupled = 0; kfree(rdev->coupling_desc.coupled_rdevs); rdev->coupling_desc.coupled_rdevs = NULL; } From 8b36f61da77f53572dd84826867854b773668e23 Mon Sep 17 00:00:00 2001 From: Maor Gottlieb Date: Mon, 16 Jun 2025 11:26:21 +0300 Subject: [PATCH 057/404] RDMA/core: Rate limit GID cache warning messages [ Upstream commit 333e4d79316c9ed5877d7aac8b8ed22efc74e96d ] The GID cache warning messages can flood the kernel log when there are multiple failed attempts to add GIDs. This can happen when creating many virtual interfaces without having enough space for their GIDs in the GID table. Change pr_warn to pr_warn_ratelimited to prevent log flooding while still maintaining visibility of the issue. Link: https://patch.msgid.link/r/fd45ed4a1078e743f498b234c3ae816610ba1b18.1750062357.git.leon@kernel.org Signed-off-by: Maor Gottlieb Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin --- drivers/infiniband/core/cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index 7affe6b4ae21..641e537a0069 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c @@ -578,8 +578,8 @@ static int __ib_cache_gid_add(struct ib_device *ib_dev, u8 port, out_unlock: mutex_unlock(&table->lock); if (ret) - pr_warn("%s: unable to add gid %pI6 error=%d\n", - __func__, gid->raw, ret); + pr_warn_ratelimited("%s: unable to add gid %pI6 error=%d\n", + __func__, gid->raw, ret); return ret; } From 7dc69383be04c0fb4bb2f28bdd22175b6033471e Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Wed, 28 Oct 2020 01:55:27 +0100 Subject: [PATCH 058/404] net: appletalk: fix kerneldoc warnings [ Upstream commit 709565ae14aa2670d6b480be46720856e804af41 ] net/appletalk/aarp.c:68: warning: Function parameter or member 'dev' not described in 'aarp_entry' net/appletalk/aarp.c:68: warning: Function parameter or member 'expires_at' not described in 'aarp_entry' net/appletalk/aarp.c:68: warning: Function parameter or member 'hwaddr' not described in 'aarp_entry' net/appletalk/aarp.c:68: warning: Function parameter or member 'last_sent' not described in 'aarp_entry' net/appletalk/aarp.c:68: warning: Function parameter or member 'next' not described in 'aarp_entry' net/appletalk/aarp.c:68: warning: Function parameter or member 'packet_queue' not described in 'aarp_entry' net/appletalk/aarp.c:68: warning: Function parameter or member 'status' not described in 'aarp_entry' net/appletalk/aarp.c:68: warning: Function parameter or member 'target_addr' not described in 'aarp_entry' net/appletalk/aarp.c:68: warning: Function parameter or member 'xmit_count' not described in 'aarp_entry' net/appletalk/ddp.c:1422: warning: Function parameter or member 'dev' not described in 'atalk_rcv' net/appletalk/ddp.c:1422: warning: Function parameter or member 'orig_dev' not described in 'atalk_rcv' net/appletalk/ddp.c:1422: warning: Function parameter or member 'pt' not described in 'atalk_rcv' net/appletalk/ddp.c:1422: warning: Function parameter or member 'skb' not described in 'atalk_rcv' Signed-off-by: Andrew Lunn Link: https://lore.kernel.org/r/20201028005527.930388-1-andrew@lunn.ch Signed-off-by: Jakub Kicinski Stable-dep-of: 6c4a92d07b08 ("net: appletalk: Fix use-after-free in AARP proxy probe") Signed-off-by: Sasha Levin --- net/appletalk/aarp.c | 18 +++++++++--------- net/appletalk/ddp.c | 7 ++++--- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index 45f584171de7..be18af481d7d 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -44,15 +44,15 @@ int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; /* Lists of aarp entries */ /** * struct aarp_entry - AARP entry - * @last_sent - Last time we xmitted the aarp request - * @packet_queue - Queue of frames wait for resolution - * @status - Used for proxy AARP - * expires_at - Entry expiry time - * target_addr - DDP Address - * dev - Device to use - * hwaddr - Physical i/f address of target/router - * xmit_count - When this hits 10 we give up - * next - Next entry in chain + * @last_sent: Last time we xmitted the aarp request + * @packet_queue: Queue of frames wait for resolution + * @status: Used for proxy AARP + * @expires_at: Entry expiry time + * @target_addr: DDP Address + * @dev: Device to use + * @hwaddr: Physical i/f address of target/router + * @xmit_count: When this hits 10 we give up + * @next: Next entry in chain */ struct aarp_entry { /* These first two are only used for unresolved entries */ diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 46ca0f1354fd..01170c4e9c6d 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1400,9 +1400,10 @@ drop: /** * atalk_rcv - Receive a packet (in skb) from device dev - * @skb - packet received - * @dev - network device where the packet comes from - * @pt - packet type + * @skb: packet received + * @dev: network device where the packet comes from + * @pt: packet type + * @orig_dev: the original receive net device * * Receive a packet (in skb) from device dev. This has come from the SNAP * decoder, and on entry skb->transport_header is the DDP header, skb->len From b35694ffabb2af308a1f725d70f60fd8a47d1f3e Mon Sep 17 00:00:00 2001 From: "Kito Xu (veritas501)" Date: Thu, 17 Jul 2025 01:28:43 +0000 Subject: [PATCH 059/404] net: appletalk: Fix use-after-free in AARP proxy probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 6c4a92d07b0850342d3becf2e608f805e972467c ] The AARP proxy‐probe routine (aarp_proxy_probe_network) sends a probe, releases the aarp_lock, sleeps, then re-acquires the lock. During that window an expire timer thread (__aarp_expire_timer) can remove and kfree() the same entry, leading to a use-after-free. race condition: cpu 0 | cpu 1 atalk_sendmsg() | atif_proxy_probe_device() aarp_send_ddp() | aarp_proxy_probe_network() mod_timer() | lock(aarp_lock) // LOCK!! timeout around 200ms | alloc(aarp_entry) and then call | proxies[hash] = aarp_entry aarp_expire_timeout() | aarp_send_probe() | unlock(aarp_lock) // UNLOCK!! lock(aarp_lock) // LOCK!! | msleep(100); __aarp_expire_timer(&proxies[ct]) | free(aarp_entry) | unlock(aarp_lock) // UNLOCK!! | | lock(aarp_lock) // LOCK!! | UAF aarp_entry !! ================================================================== BUG: KASAN: slab-use-after-free in aarp_proxy_probe_network+0x560/0x630 net/appletalk/aarp.c:493 Read of size 4 at addr ffff8880123aa360 by task repro/13278 CPU: 3 UID: 0 PID: 13278 Comm: repro Not tainted 6.15.2 #3 PREEMPT(full) Call Trace: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x116/0x1b0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:408 [inline] print_report+0xc1/0x630 mm/kasan/report.c:521 kasan_report+0xca/0x100 mm/kasan/report.c:634 aarp_proxy_probe_network+0x560/0x630 net/appletalk/aarp.c:493 atif_proxy_probe_device net/appletalk/ddp.c:332 [inline] atif_ioctl+0xb58/0x16c0 net/appletalk/ddp.c:857 atalk_ioctl+0x198/0x2f0 net/appletalk/ddp.c:1818 sock_do_ioctl+0xdc/0x260 net/socket.c:1190 sock_ioctl+0x239/0x6a0 net/socket.c:1311 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:906 [inline] __se_sys_ioctl fs/ioctl.c:892 [inline] __x64_sys_ioctl+0x194/0x200 fs/ioctl.c:892 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcb/0x250 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Allocated: aarp_alloc net/appletalk/aarp.c:382 [inline] aarp_proxy_probe_network+0xd8/0x630 net/appletalk/aarp.c:468 atif_proxy_probe_device net/appletalk/ddp.c:332 [inline] atif_ioctl+0xb58/0x16c0 net/appletalk/ddp.c:857 atalk_ioctl+0x198/0x2f0 net/appletalk/ddp.c:1818 Freed: kfree+0x148/0x4d0 mm/slub.c:4841 __aarp_expire net/appletalk/aarp.c:90 [inline] __aarp_expire_timer net/appletalk/aarp.c:261 [inline] aarp_expire_timeout+0x480/0x6e0 net/appletalk/aarp.c:317 The buggy address belongs to the object at ffff8880123aa300 which belongs to the cache kmalloc-192 of size 192 The buggy address is located 96 bytes inside of freed 192-byte region [ffff8880123aa300, ffff8880123aa3c0) Memory state around the buggy address: ffff8880123aa200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff8880123aa280: 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc fc >ffff8880123aa300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff8880123aa380: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff8880123aa400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ================================================================== Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Kito Xu (veritas501) Link: https://patch.msgid.link/20250717012843.880423-1-hxzene@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/appletalk/aarp.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index be18af481d7d..17d9cb380e7b 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -35,6 +35,7 @@ #include #include #include +#include int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME; int sysctl_aarp_tick_time = AARP_TICK_TIME; @@ -44,6 +45,7 @@ int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; /* Lists of aarp entries */ /** * struct aarp_entry - AARP entry + * @refcnt: Reference count * @last_sent: Last time we xmitted the aarp request * @packet_queue: Queue of frames wait for resolution * @status: Used for proxy AARP @@ -55,6 +57,7 @@ int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; * @next: Next entry in chain */ struct aarp_entry { + refcount_t refcnt; /* These first two are only used for unresolved entries */ unsigned long last_sent; struct sk_buff_head packet_queue; @@ -79,6 +82,17 @@ static DEFINE_RWLOCK(aarp_lock); /* Used to walk the list and purge/kick entries. */ static struct timer_list aarp_timer; +static inline void aarp_entry_get(struct aarp_entry *a) +{ + refcount_inc(&a->refcnt); +} + +static inline void aarp_entry_put(struct aarp_entry *a) +{ + if (refcount_dec_and_test(&a->refcnt)) + kfree(a); +} + /* * Delete an aarp queue * @@ -87,7 +101,7 @@ static struct timer_list aarp_timer; static void __aarp_expire(struct aarp_entry *a) { skb_queue_purge(&a->packet_queue); - kfree(a); + aarp_entry_put(a); } /* @@ -380,9 +394,11 @@ static void aarp_purge(void) static struct aarp_entry *aarp_alloc(void) { struct aarp_entry *a = kmalloc(sizeof(*a), GFP_ATOMIC); + if (!a) + return NULL; - if (a) - skb_queue_head_init(&a->packet_queue); + refcount_set(&a->refcnt, 1); + skb_queue_head_init(&a->packet_queue); return a; } @@ -508,6 +524,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa) entry->dev = atif->dev; write_lock_bh(&aarp_lock); + aarp_entry_get(entry); hash = sa->s_node % (AARP_HASH_SIZE - 1); entry->next = proxies[hash]; @@ -533,6 +550,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa) retval = 1; } + aarp_entry_put(entry); write_unlock_bh(&aarp_lock); out: return retval; From 23cc07ce97f9d7b230e84f12bfe6427172538d97 Mon Sep 17 00:00:00 2001 From: Xiang Mei Date: Thu, 17 Jul 2025 16:01:28 -0700 Subject: [PATCH 060/404] net/sched: sch_qfq: Avoid triggering might_sleep in atomic context in qfq_delete_class [ Upstream commit cf074eca0065bc5142e6004ae236bb35a2687fdf ] might_sleep could be trigger in the atomic context in qfq_delete_class. qfq_destroy_class was moved into atomic context locked by sch_tree_lock to avoid a race condition bug on qfq_aggregate. However, might_sleep could be triggered by qfq_destroy_class, which introduced sleeping in atomic context (path: qfq_destroy_class->qdisc_put->__qdisc_destroy->lockdep_unregister_key ->might_sleep). Considering the race is on the qfq_aggregate objects, keeping qfq_rm_from_agg in the lock but moving the left part out can solve this issue. Fixes: 5e28d5a3f774 ("net/sched: sch_qfq: Fix race condition on qfq_aggregate") Reported-by: Dan Carpenter Signed-off-by: Xiang Mei Link: https://patch.msgid.link/4a04e0cc-a64b-44e7-9213-2880ed641d77@sabinyo.mountain Reviewed-by: Cong Wang Reviewed-by: Dan Carpenter Link: https://patch.msgid.link/20250717230128.159766-1-xmei5@asu.edu Signed-off-by: Paolo Abeni Signed-off-by: Sasha Levin --- net/sched/sch_qfq.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index 2a4331a08494..be04fcfcc585 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -534,9 +534,6 @@ destroy_class: static void qfq_destroy_class(struct Qdisc *sch, struct qfq_class *cl) { - struct qfq_sched *q = qdisc_priv(sch); - - qfq_rm_from_agg(q, cl); gen_kill_estimator(&cl->rate_est); qdisc_put(cl->qdisc); kfree(cl); @@ -554,10 +551,11 @@ static int qfq_delete_class(struct Qdisc *sch, unsigned long arg) qdisc_purge_queue(cl->qdisc); qdisc_class_hash_remove(&q->clhash, &cl->common); - qfq_destroy_class(sch, cl); + qfq_rm_from_agg(q, cl); sch_tree_unlock(sch); + qfq_destroy_class(sch, cl); return 0; } @@ -1507,6 +1505,7 @@ static void qfq_destroy_qdisc(struct Qdisc *sch) for (i = 0; i < q->clhash.hashsize; i++) { hlist_for_each_entry_safe(cl, next, &q->clhash.hash[i], common.hnode) { + qfq_rm_from_agg(q, cl); qfq_destroy_class(sch, cl); } } From cbec4406998185e0311ae97dfacc649f9cd79b0b Mon Sep 17 00:00:00 2001 From: Yang Xiwen Date: Mon, 16 Jun 2025 00:01:10 +0800 Subject: [PATCH 061/404] i2c: qup: jump out of the loop in case of timeout commit a7982a14b3012527a9583d12525cd0dc9f8d8934 upstream. Original logic only sets the return value but doesn't jump out of the loop if the bus is kept active by a client. This is not expected. A malicious or buggy i2c client can hang the kernel in this case and should be avoided. This is observed during a long time test with a PCA953x GPIO extender. Fix it by changing the logic to not only sets the return value, but also jumps out of the loop and return to the caller with -ETIMEDOUT. Fixes: fbfab1ab0658 ("i2c: qup: reorganization of driver code to remove polling for qup v1") Signed-off-by: Yang Xiwen Cc: # v4.17+ Signed-off-by: Andi Shyti Link: https://lore.kernel.org/r/20250616-qca-i2c-v1-1-2a8d37ee0a30@outlook.com Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-qup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index 3417f7dffa94..7bab436bd8f8 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c @@ -449,8 +449,10 @@ static int qup_i2c_bus_active(struct qup_i2c_dev *qup, int len) if (!(status & I2C_STATUS_BUS_ACTIVE)) break; - if (time_after(jiffies, timeout)) + if (time_after(jiffies, timeout)) { ret = -ETIMEDOUT; + break; + } usleep_range(len, len * 2); } From dd298c0b889acd3ecaf48b6e840c9ab91882e342 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Thu, 10 Jul 2025 22:49:08 +0900 Subject: [PATCH 062/404] nilfs2: reject invalid file types when reading inodes commit 4aead50caf67e01020c8be1945c3201e8a972a27 upstream. To prevent inodes with invalid file types from tripping through the vfs and causing malfunctions or assertion failures, add a missing sanity check when reading an inode from a block device. If the file type is not valid, treat it as a filesystem error. Link: https://lkml.kernel.org/r/20250710134952.29862-1-konishi.ryusuke@gmail.com Fixes: 05fe58fdc10d ("nilfs2: inode operations") Signed-off-by: Ryusuke Konishi Reported-by: syzbot+895c23f6917da440ed0d@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=895c23f6917da440ed0d Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/nilfs2/inode.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 7e4edc588d62..fa050a01577d 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -525,11 +525,18 @@ static int __nilfs_read_inode(struct super_block *sb, inode->i_op = &nilfs_symlink_inode_operations; inode_nohighmem(inode); inode->i_mapping->a_ops = &nilfs_aops; - } else { + } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || + S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { inode->i_op = &nilfs_special_inode_operations; init_special_inode( inode, inode->i_mode, huge_decode_dev(le64_to_cpu(raw_inode->i_device_code))); + } else { + nilfs_error(sb, + "invalid file type bits in mode 0%o for inode %lu", + inode->i_mode, ino); + err = -EIO; + goto failed_unmap; } nilfs_ifile_unmap_inode(root->ifile, ino, bh); brelse(bh); From 451c43bb4c762ba5d54fb13747e7c0a1b77a8da7 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 8 Jul 2025 14:06:27 +0100 Subject: [PATCH 063/404] comedi: comedi_test: Fix possible deletion of uninitialized timers commit 1b98304c09a0192598d0767f1eb8c83d7e793091 upstream. In `waveform_common_attach()`, the two timers `&devpriv->ai_timer` and `&devpriv->ao_timer` are initialized after the allocation of the device private data by `comedi_alloc_devpriv()` and the subdevices by `comedi_alloc_subdevices()`. The function may return with an error between those function calls. In that case, `waveform_detach()` will be called by the Comedi core to clean up. The check that `waveform_detach()` uses to decide whether to delete the timers is incorrect. It only checks that the device private data was allocated, but that does not guarantee that the timers were initialized. It also needs to check that the subdevices were allocated. Fix it. Fixes: 73e0e4dfed4c ("staging: comedi: comedi_test: fix timer lock-up") Cc: stable@vger.kernel.org # 6.15+ Signed-off-by: Ian Abbott Link: https://lore.kernel.org/r/20250708130627.21743-1-abbotti@mev.co.uk [ file location from drivers/comedi to drivers/staging/comedi and timer_delete_sync() to del_timer_sync(). ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 9e60d2a0edc1..7397495de4d6 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -790,7 +790,7 @@ static void waveform_detach(struct comedi_device *dev) { struct waveform_private *devpriv = dev->private; - if (devpriv) { + if (devpriv && dev->n_subdevices) { del_timer_sync(&devpriv->ai_timer); del_timer_sync(&devpriv->ao_timer); } From 6c77bc70f389e7c450250f7b581264fa935fb8df Mon Sep 17 00:00:00 2001 From: Daniel Dadap Date: Thu, 26 Jun 2025 16:16:30 -0500 Subject: [PATCH 064/404] ALSA: hda: Add missing NVIDIA HDA codec IDs commit e0a911ac86857a73182edde9e50d9b4b949b7f01 upstream. Add codec IDs for several NVIDIA products with HDA controllers to the snd_hda_id_hdmi[] patch table. Signed-off-by: Daniel Dadap Cc: Link: https://patch.msgid.link/aF24rqwMKFWoHu12@ddadap-lakeline.nvidia.com Signed-off-by: Takashi Iwai [ change patch_tegra234_hdmi function calls to patch_tegra_hdmi ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_hdmi.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 31ba21b80504..6bc441fa6abe 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -4161,6 +4161,8 @@ HDA_CODEC_ENTRY(0x10de002d, "Tegra186 HDMI/DP0", patch_tegra_hdmi), HDA_CODEC_ENTRY(0x10de002e, "Tegra186 HDMI/DP1", patch_tegra_hdmi), HDA_CODEC_ENTRY(0x10de002f, "Tegra194 HDMI/DP2", patch_tegra_hdmi), HDA_CODEC_ENTRY(0x10de0030, "Tegra194 HDMI/DP3", patch_tegra_hdmi), +HDA_CODEC_ENTRY(0x10de0033, "SoC 33 HDMI/DP", patch_tegra_hdmi), +HDA_CODEC_ENTRY(0x10de0035, "SoC 35 HDMI/DP", patch_tegra_hdmi), HDA_CODEC_ENTRY(0x10de0040, "GPU 40 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0041, "GPU 41 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0042, "GPU 42 HDMI/DP", patch_nvhdmi), @@ -4199,15 +4201,32 @@ HDA_CODEC_ENTRY(0x10de0097, "GPU 97 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0098, "GPU 98 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0099, "GPU 99 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de009a, "GPU 9a HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de009b, "GPU 9b HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de009c, "GPU 9c HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de009d, "GPU 9d HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de009e, "GPU 9e HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de009f, "GPU 9f HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de00a0, "GPU a0 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00a1, "GPU a1 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de00a3, "GPU a3 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de00a4, "GPU a4 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de00a5, "GPU a5 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de00a6, "GPU a6 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de00a7, "GPU a7 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00a8, "GPU a8 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00a9, "GPU a9 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00aa, "GPU aa HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00ab, "GPU ab HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00ad, "GPU ad HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00ae, "GPU ae HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00af, "GPU af HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00b0, "GPU b0 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00b1, "GPU b1 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00c0, "GPU c0 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00c1, "GPU c1 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00c3, "GPU c3 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00c4, "GPU c4 HDMI/DP", patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de00c5, "GPU c5 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch), HDA_CODEC_ENTRY(0x10de8067, "MCP67/68 HDMI", patch_nvhdmi_2ch), HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi), From 4fbf6bb0f97c66d9085352d85bea6adafb202abd Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 10 Sep 2019 10:54:52 +0800 Subject: [PATCH 065/404] usb: chipidea: udc: add new API ci_hdrc_gadget_connect [ Upstream commit d16ab536aad208421c5ed32cdcb01b5ab6aa1f19 ] This API is used enable device function, it is called at below situations: - VBUS is connected during boots up - Hot plug occurs during runtime Signed-off-by: Peter Chen Signed-off-by: Jun Li Stable-dep-of: b7a62611fab7 ("usb: chipidea: add USB PHY event") Signed-off-by: Sasha Levin --- drivers/usb/chipidea/udc.c | 63 +++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index a6ce6b89b271..e9ef6271e20d 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1533,6 +1533,33 @@ static const struct usb_ep_ops usb_ep_ops = { /****************************************************************************** * GADGET block *****************************************************************************/ +/** + * ci_hdrc_gadget_connect: caller makes sure gadget driver is binded + */ +static void ci_hdrc_gadget_connect(struct usb_gadget *_gadget, int is_active) +{ + struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); + + if (is_active) { + pm_runtime_get_sync(&_gadget->dev); + hw_device_reset(ci); + hw_device_state(ci, ci->ep0out->qh.dma); + usb_gadget_set_state(_gadget, USB_STATE_POWERED); + usb_udc_vbus_handler(_gadget, true); + } else { + usb_udc_vbus_handler(_gadget, false); + if (ci->driver) + ci->driver->disconnect(&ci->gadget); + hw_device_state(ci, 0); + if (ci->platdata->notify_event) + ci->platdata->notify_event(ci, + CI_HDRC_CONTROLLER_STOPPED_EVENT); + _gadget_stop_activity(&ci->gadget); + pm_runtime_put_sync(&_gadget->dev); + usb_gadget_set_state(_gadget, USB_STATE_NOTATTACHED); + } +} + static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) { struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); @@ -1549,26 +1576,8 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) usb_phy_set_charger_state(ci->usb_phy, is_active ? USB_CHARGER_PRESENT : USB_CHARGER_ABSENT); - if (gadget_ready) { - if (is_active) { - pm_runtime_get_sync(&_gadget->dev); - hw_device_reset(ci); - hw_device_state(ci, ci->ep0out->qh.dma); - usb_gadget_set_state(_gadget, USB_STATE_POWERED); - usb_udc_vbus_handler(_gadget, true); - } else { - usb_udc_vbus_handler(_gadget, false); - if (ci->driver) - ci->driver->disconnect(&ci->gadget); - hw_device_state(ci, 0); - if (ci->platdata->notify_event) - ci->platdata->notify_event(ci, - CI_HDRC_CONTROLLER_STOPPED_EVENT); - _gadget_stop_activity(&ci->gadget); - pm_runtime_put_sync(&_gadget->dev); - usb_gadget_set_state(_gadget, USB_STATE_NOTATTACHED); - } - } + if (gadget_ready) + ci_hdrc_gadget_connect(_gadget, is_active); return 0; } @@ -1794,18 +1803,10 @@ static int ci_udc_start(struct usb_gadget *gadget, return retval; } - pm_runtime_get_sync(&ci->gadget.dev); - if (ci->vbus_active) { - hw_device_reset(ci); - } else { + if (ci->vbus_active) + ci_hdrc_gadget_connect(gadget, 1); + else usb_udc_vbus_handler(&ci->gadget, false); - pm_runtime_put_sync(&ci->gadget.dev); - return retval; - } - - retval = hw_device_state(ci, ci->ep0out->qh.dma); - if (retval) - pm_runtime_put_sync(&ci->gadget.dev); return retval; } From 770809a95864ad8b79e02c7ea573f065e53ed96a Mon Sep 17 00:00:00 2001 From: Jun Li Date: Tue, 10 Sep 2019 14:54:57 +0800 Subject: [PATCH 066/404] usb: chipidea: udc: protect usb interrupt enable [ Upstream commit 72dc8df7920fc24eba0f586c56e900a1643ff2b3 ] We hit the problem with below sequence: - ci_udc_vbus_session() update vbus_active flag and ci->driver is valid, - before calling the ci_hdrc_gadget_connect(), usb_gadget_udc_stop() is called by application remove gadget driver, - ci_udc_vbus_session() will contine do ci_hdrc_gadget_connect() as gadget_ready is 1, so udc interrupt is enabled, but ci->driver is NULL. - USB connection irq generated but ci->driver is NULL. As udc irq only should be enabled when gadget driver is binded, so add spinlock to protect the usb irq enable for vbus session handling. Signed-off-by: Jun Li Signed-off-by: Peter Chen Stable-dep-of: b7a62611fab7 ("usb: chipidea: add USB PHY event") Signed-off-by: Sasha Levin --- drivers/usb/chipidea/udc.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index e9ef6271e20d..9212c3842a1b 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1539,13 +1539,18 @@ static const struct usb_ep_ops usb_ep_ops = { static void ci_hdrc_gadget_connect(struct usb_gadget *_gadget, int is_active) { struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); + unsigned long flags; if (is_active) { pm_runtime_get_sync(&_gadget->dev); hw_device_reset(ci); - hw_device_state(ci, ci->ep0out->qh.dma); - usb_gadget_set_state(_gadget, USB_STATE_POWERED); - usb_udc_vbus_handler(_gadget, true); + spin_lock_irqsave(&ci->lock, flags); + if (ci->driver) { + hw_device_state(ci, ci->ep0out->qh.dma); + usb_gadget_set_state(_gadget, USB_STATE_POWERED); + usb_udc_vbus_handler(_gadget, true); + } + spin_unlock_irqrestore(&ci->lock, flags); } else { usb_udc_vbus_handler(_gadget, false); if (ci->driver) @@ -1564,19 +1569,16 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) { struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); unsigned long flags; - int gadget_ready = 0; spin_lock_irqsave(&ci->lock, flags); ci->vbus_active = is_active; - if (ci->driver) - gadget_ready = 1; spin_unlock_irqrestore(&ci->lock, flags); if (ci->usb_phy) usb_phy_set_charger_state(ci->usb_phy, is_active ? USB_CHARGER_PRESENT : USB_CHARGER_ABSENT); - if (gadget_ready) + if (ci->driver) ci_hdrc_gadget_connect(_gadget, is_active); return 0; @@ -1836,6 +1838,7 @@ static int ci_udc_stop(struct usb_gadget *gadget) unsigned long flags; spin_lock_irqsave(&ci->lock, flags); + ci->driver = NULL; if (ci->vbus_active) { hw_device_state(ci, 0); @@ -1848,7 +1851,6 @@ static int ci_udc_stop(struct usb_gadget *gadget) pm_runtime_put(&ci->gadget.dev); } - ci->driver = NULL; spin_unlock_irqrestore(&ci->lock, flags); ci_udc_stop_for_otg_fsm(ci); From f2b6a88c1cbd764d8507c4f1bfab586782c0be02 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 23 Jan 2020 14:00:26 +0800 Subject: [PATCH 067/404] usb: chipidea: introduce CI_HDRC_CONTROLLER_VBUS_EVENT glue layer use [ Upstream commit d755cdb1b9d7e1b645e176b97eb137194bbe8cf9 ] Some vendors glue layer need to handle some events for vbus, eg, some i.mx platforms (imx7d, imx8mm, imx8mn, etc) needs vbus event to handle charger detection, its charger detection is finished at glue layer code, but not at USB PHY driver. Signed-off-by: Peter Chen Stable-dep-of: b7a62611fab7 ("usb: chipidea: add USB PHY event") Signed-off-by: Sasha Levin --- drivers/usb/chipidea/udc.c | 7 ++++++- include/linux/usb/chipidea.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 9212c3842a1b..dfae454ca9ba 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1569,6 +1569,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) { struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); unsigned long flags; + int ret = 0; spin_lock_irqsave(&ci->lock, flags); ci->vbus_active = is_active; @@ -1578,10 +1579,14 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) usb_phy_set_charger_state(ci->usb_phy, is_active ? USB_CHARGER_PRESENT : USB_CHARGER_ABSENT); + if (ci->platdata->notify_event) + ret = ci->platdata->notify_event(ci, + CI_HDRC_CONTROLLER_VBUS_EVENT); + if (ci->driver) ci_hdrc_gadget_connect(_gadget, is_active); - return 0; + return ret; } static int ci_udc_wakeup(struct usb_gadget *_gadget) diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index edd89b7c8f18..54167a2d28ea 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -67,6 +67,7 @@ struct ci_hdrc_platform_data { #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 #define CI_HDRC_IMX_HSIC_ACTIVE_EVENT 2 #define CI_HDRC_IMX_HSIC_SUSPEND_EVENT 3 +#define CI_HDRC_CONTROLLER_VBUS_EVENT 4 int (*notify_event) (struct ci_hdrc *ci, unsigned event); struct regulator *reg_vbus; struct usb_otg_caps ci_otg_caps; From 4eb4ad451e3ffb8abc33775a84baacf1a9a75d33 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Tue, 27 Jun 2023 19:03:51 +0800 Subject: [PATCH 068/404] usb: chipidea: add USB PHY event [ Upstream commit b7a62611fab72e585c729a7fcf666aa9c4144214 ] Add USB PHY event for below situation: - usb role changed - vbus connect - vbus disconnect - gadget driver is enumerated USB PHY driver can get the last event after above situation occurs and deal with different situations. Signed-off-by: Xu Yang Acked-by: Peter Chen Link: https://lore.kernel.org/r/20230627110353.1879477-1-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/chipidea/ci.h | 18 ++++++++++++++++-- drivers/usb/chipidea/udc.c | 10 ++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index ff61f88fc867..3a22bc727bb9 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -277,8 +277,19 @@ static inline int ci_role_start(struct ci_hdrc *ci, enum ci_role role) return -ENXIO; ret = ci->roles[role]->start(ci); - if (!ret) - ci->role = role; + if (ret) + return ret; + + ci->role = role; + + if (ci->usb_phy) { + if (role == CI_ROLE_HOST) + usb_phy_set_event(ci->usb_phy, USB_EVENT_ID); + else + /* in device mode but vbus is invalid*/ + usb_phy_set_event(ci->usb_phy, USB_EVENT_NONE); + } + return ret; } @@ -292,6 +303,9 @@ static inline void ci_role_stop(struct ci_hdrc *ci) ci->role = CI_ROLE_END; ci->roles[role]->stop(ci); + + if (ci->usb_phy) + usb_phy_set_event(ci->usb_phy, USB_EVENT_NONE); } static inline enum usb_role ci_role_to_usb_role(struct ci_hdrc *ci) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index dfae454ca9ba..19a9a4b83346 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1583,6 +1583,13 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) ret = ci->platdata->notify_event(ci, CI_HDRC_CONTROLLER_VBUS_EVENT); + if (ci->usb_phy) { + if (is_active) + usb_phy_set_event(ci->usb_phy, USB_EVENT_VBUS); + else + usb_phy_set_event(ci->usb_phy, USB_EVENT_NONE); + } + if (ci->driver) ci_hdrc_gadget_connect(_gadget, is_active); @@ -1898,6 +1905,9 @@ static irqreturn_t udc_irq(struct ci_hdrc *ci) if (USBi_PCI & intr) { ci->gadget.speed = hw_port_is_high_speed(ci) ? USB_SPEED_HIGH : USB_SPEED_FULL; + if (ci->usb_phy) + usb_phy_set_event(ci->usb_phy, + USB_EVENT_ENUMERATED); if (ci->suspended) { if (ci->driver->resume) { spin_unlock(&ci->lock); From e5d396f42d755d1be2c8b4ce83d2a07dc4469d01 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Tue, 27 Jun 2023 19:03:53 +0800 Subject: [PATCH 069/404] usb: phy: mxs: disconnect line when USB charger is attached [ Upstream commit 87ed257acb0934e08644568df6495988631afd4c ] For mxs PHY, if there is a vbus but the bus is not enumerated, we need to force the dp/dm as SE0 from the controller side. If not, there is possible USB wakeup due to unstable dp/dm, since there is possible no pull on dp/dm, such as there is a USB charger on the port. Signed-off-by: Xu Yang Acked-by: Peter Chen Link: https://lore.kernel.org/r/20230627110353.1879477-3-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/phy/phy-mxs-usb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index 6dfecbd47d7a..7c81ccaaf2e9 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -394,6 +394,7 @@ static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy) static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) { bool vbus_is_on = false; + enum usb_phy_events last_event = mxs_phy->phy.last_event; /* If the SoCs don't need to disconnect line without vbus, quit */ if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS)) @@ -405,7 +406,8 @@ static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) vbus_is_on = mxs_phy_get_vbus_status(mxs_phy); - if (on && !vbus_is_on && !mxs_phy_is_otg_host(mxs_phy)) + if (on && ((!vbus_is_on && !mxs_phy_is_otg_host(mxs_phy)) + || (last_event == USB_EVENT_VBUS))) __mxs_phy_disconnect_line(mxs_phy, true); else __mxs_phy_disconnect_line(mxs_phy, false); From 02bdbb8dc039d64b933756b735264140a06450e3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 20 Jun 2025 19:31:24 +0200 Subject: [PATCH 070/404] ethernet: intel: fix building with large NR_CPUS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 24171a5a4a952c26568ff0d2a0bc8c4708a95e1d ] With large values of CONFIG_NR_CPUS, three Intel ethernet drivers fail to compile like: In function ‘i40e_free_q_vector’, inlined from ‘i40e_vsi_alloc_q_vectors’ at drivers/net/ethernet/intel/i40e/i40e_main.c:12112:3: 571 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) include/linux/rcupdate.h:1084:17: note: in expansion of macro ‘BUILD_BUG_ON’ 1084 | BUILD_BUG_ON(offsetof(typeof(*(ptr)), rhf) >= 4096); \ drivers/net/ethernet/intel/i40e/i40e_main.c:5113:9: note: in expansion of macro ‘kfree_rcu’ 5113 | kfree_rcu(q_vector, rcu); | ^~~~~~~~~ The problem is that the 'rcu' member in 'q_vector' is too far from the start of the structure. Move this member before the CPU mask instead, in all three drivers. Signed-off-by: Arnd Bergmann Acked-by: David S. Miller Reviewed-by: Aleksandr Loktionov Reviewed-by: Alexander Lobakin Tested-by: Sunitha Mekala (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/fm10k/fm10k.h | 3 ++- drivers/net/ethernet/intel/i40e/i40e.h | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/fm10k/fm10k.h b/drivers/net/ethernet/intel/fm10k/fm10k.h index b14441944b4b..db72e5e4acd3 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k.h +++ b/drivers/net/ethernet/intel/fm10k/fm10k.h @@ -189,13 +189,14 @@ struct fm10k_q_vector { struct fm10k_ring_container rx, tx; struct napi_struct napi; + struct rcu_head rcu; /* to avoid race with update stats on free */ + cpumask_t affinity_mask; char name[IFNAMSIZ + 9]; #ifdef CONFIG_DEBUG_FS struct dentry *dbg_q_vector; #endif /* CONFIG_DEBUG_FS */ - struct rcu_head rcu; /* to avoid race with update stats on free */ /* for dynamic allocation of rings associated with this q_vector */ struct fm10k_ring ring[0] ____cacheline_internodealigned_in_smp; diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 4c8c31692e9e..edb5e408c980 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -864,6 +864,7 @@ struct i40e_q_vector { u16 reg_idx; /* register index of the interrupt */ struct napi_struct napi; + struct rcu_head rcu; /* to avoid race with update stats on free */ struct i40e_ring_container rx; struct i40e_ring_container tx; @@ -874,7 +875,6 @@ struct i40e_q_vector { cpumask_t affinity_mask; struct irq_affinity_notify affinity_notify; - struct rcu_head rcu; /* to avoid race with update stats on free */ char name[I40E_INT_NAME_STR_LEN]; bool arm_wb_state; } ____cacheline_internodealigned_in_smp; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 0142ca226bf5..0f9a1fce0dee 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -458,9 +458,10 @@ struct ixgbe_q_vector { struct ixgbe_ring_container rx, tx; struct napi_struct napi; + struct rcu_head rcu; /* to avoid race with update stats on free */ + cpumask_t affinity_mask; int numa_node; - struct rcu_head rcu; /* to avoid race with update stats on free */ char name[IFNAMSIZ + 9]; /* for dynamic allocation of rings associated with this q_vector */ From eac07e80d810efe5d589bc29787ab2eb07cbf5c0 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 9 Jul 2025 16:56:07 +0200 Subject: [PATCH 071/404] ASoC: Intel: fix SND_SOC_SOF dependencies [ Upstream commit e837b59f8b411b5baf5e3de7a5aea10b1c545a63 ] It is currently possible to configure a kernel with all Intel SoC configs as loadable modules, but the board config as built-in. This causes a link failure in the reference to the snd_soc_sof.ko module: x86_64-linux-ld: sound/soc/intel/boards/sof_rt5682.o: in function `sof_rt5682_hw_params': sof_rt5682.c:(.text+0x1f9): undefined reference to `sof_dai_get_mclk' x86_64-linux-ld: sof_rt5682.c:(.text+0x234): undefined reference to `sof_dai_get_bclk' x86_64-linux-ld: sound/soc/intel/boards/sof_rt5682.o: in function `sof_rt5682_codec_init': sof_rt5682.c:(.text+0x3e0): undefined reference to `sof_dai_get_mclk' x86_64-linux-ld: sound/soc/intel/boards/sof_cs42l42.o: in function `sof_cs42l42_hw_params': sof_cs42l42.c:(.text+0x2a): undefined reference to `sof_dai_get_bclk' x86_64-linux-ld: sound/soc/intel/boards/sof_nau8825.o: in function `sof_nau8825_hw_params': sof_nau8825.c:(.text+0x7f): undefined reference to `sof_dai_get_bclk' x86_64-linux-ld: sound/soc/intel/boards/sof_da7219.o: in function `da7219_codec_init': sof_da7219.c:(.text+0xbf): undefined reference to `sof_dai_get_mclk' x86_64-linux-ld: sound/soc/intel/boards/sof_maxim_common.o: in function `max_98373_hw_params': sof_maxim_common.c:(.text+0x6f9): undefined reference to `sof_dai_get_tdm_slots' x86_64-linux-ld: sound/soc/intel/boards/sof_realtek_common.o: in function `rt1015_hw_params': sof_realtek_common.c:(.text+0x54c): undefined reference to `sof_dai_get_bclk' x86_64-linux-ld: sound/soc/intel/boards/sof_realtek_common.o: in function `rt1308_hw_params': sof_realtek_common.c:(.text+0x702): undefined reference to `sof_dai_get_mclk' x86_64-linux-ld: sound/soc/intel/boards/sof_cirrus_common.o: in function `cs35l41_hw_params': sof_cirrus_common.c:(.text+0x2f): undefined reference to `sof_dai_get_bclk' Add an optional dependency on SND_SOC_SOF_INTEL_COMMON, to ensure that whenever the SOF support is in a loadable module, none of the board code can be built-in. This may be be a little heavy-handed, but I also don't see a reason why one would want the boards to be built-in but not the SoC, so it shouldn't actually cause any usability problems. Signed-off-by: Arnd Bergmann Link: https://patch.msgid.link/20250709145626.64125-1-arnd@kernel.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/boards/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 5c27f7ab4a5f..78a75c29ed88 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -11,7 +11,7 @@ menuconfig SND_SOC_INTEL_MACH kernel: saying N will just cause the configurator to skip all the questions about Intel ASoC machine drivers. -if SND_SOC_INTEL_MACH +if SND_SOC_INTEL_MACH && (SND_SOC_SOF_INTEL_COMMON || !SND_SOC_SOF_INTEL_COMMON) if SND_SOC_INTEL_HASWELL From 0807e4ac59a546f2346961c5e26a98901594b205 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Thu, 29 May 2025 00:18:06 -0600 Subject: [PATCH 072/404] hfsplus: remove mutex_lock check in hfsplus_free_extents [ Upstream commit fcb96956c921f1aae7e7b477f2435c56f77a31b4 ] Syzbot reported an issue in hfsplus filesystem: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 4400 at fs/hfsplus/extents.c:346 hfsplus_free_extents+0x700/0xad0 Call Trace: hfsplus_file_truncate+0x768/0xbb0 fs/hfsplus/extents.c:606 hfsplus_write_begin+0xc2/0xd0 fs/hfsplus/inode.c:56 cont_expand_zero fs/buffer.c:2383 [inline] cont_write_begin+0x2cf/0x860 fs/buffer.c:2446 hfsplus_write_begin+0x86/0xd0 fs/hfsplus/inode.c:52 generic_cont_expand_simple+0x151/0x250 fs/buffer.c:2347 hfsplus_setattr+0x168/0x280 fs/hfsplus/inode.c:263 notify_change+0xe38/0x10f0 fs/attr.c:420 do_truncate+0x1fb/0x2e0 fs/open.c:65 do_sys_ftruncate+0x2eb/0x380 fs/open.c:193 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd To avoid deadlock, Commit 31651c607151 ("hfsplus: avoid deadlock on file truncation") unlock extree before hfsplus_free_extents(), and add check wheather extree is locked in hfsplus_free_extents(). However, when operations such as hfsplus_file_release, hfsplus_setattr, hfsplus_unlink, and hfsplus_get_block are executed concurrently in different files, it is very likely to trigger the WARN_ON, which will lead syzbot and xfstest to consider it as an abnormality. The comment above this warning also describes one of the easy triggering situations, which can easily trigger and cause xfstest&syzbot to report errors. [task A] [task B] ->hfsplus_file_release ->hfsplus_file_truncate ->hfs_find_init ->mutex_lock ->mutex_unlock ->hfsplus_write_begin ->hfsplus_get_block ->hfsplus_file_extend ->hfsplus_ext_read_extent ->hfs_find_init ->mutex_lock ->hfsplus_free_extents WARN_ON(mutex_is_locked) !!! Several threads could try to lock the shared extents tree. And warning can be triggered in one thread when another thread has locked the tree. This is the wrong behavior of the code and we need to remove the warning. Fixes: 31651c607151f ("hfsplus: avoid deadlock on file truncation") Reported-by: syzbot+8c0bc9f818702ff75b76@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/00000000000057fa4605ef101c4c@google.com/ Signed-off-by: Yangtao Li Reviewed-by: Viacheslav Dubeyko Signed-off-by: Viacheslav Dubeyko Link: https://lore.kernel.org/r/20250529061807.2213498-1-frank.li@vivo.com Signed-off-by: Viacheslav Dubeyko Signed-off-by: Sasha Levin --- fs/hfsplus/extents.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index c95a2f0ed4a7..fad1c250f150 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c @@ -342,9 +342,6 @@ static int hfsplus_free_extents(struct super_block *sb, int i; int err = 0; - /* Mapping the allocation file may lock the extent tree */ - WARN_ON(mutex_is_locked(&HFSPLUS_SB(sb)->ext_tree->tree_lock)); - hfsplus_dump_extent(extent); for (i = 0; i < 8; extent++, i++) { count = be32_to_cpu(extent->block_count); From a30ce41de47001600f8a6654155a858d5f675b7a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 10 Jun 2025 11:30:53 +0200 Subject: [PATCH 073/404] ASoC: ops: dynamically allocate struct snd_ctl_elem_value [ Upstream commit 7e10d7242ea8a5947878880b912ffa5806520705 ] This structure is really too larget to be allocated on the stack: sound/soc/soc-ops.c:435:5: error: stack frame size (1296) exceeds limit (1280) in 'snd_soc_limit_volume' [-Werror,-Wframe-larger-than] Change the function to dynamically allocate it instead. There is probably a better way to do it since only two integer fields inside of that structure are actually used, but this is the simplest rework for the moment. Fixes: 783db6851c18 ("ASoC: ops: Enforce platform maximum on initial value") Signed-off-by: Arnd Bergmann Link: https://patch.msgid.link/20250610093057.2643233-1-arnd@kernel.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/soc-ops.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index a3b1f1c064dd..02e4f336b524 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -638,28 +638,32 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); static int snd_soc_clip_to_platform_max(struct snd_kcontrol *kctl) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; - struct snd_ctl_elem_value uctl; + struct snd_ctl_elem_value *uctl; int ret; if (!mc->platform_max) return 0; - ret = kctl->get(kctl, &uctl); - if (ret < 0) - return ret; + uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); + if (!uctl) + return -ENOMEM; - if (uctl.value.integer.value[0] > mc->platform_max) - uctl.value.integer.value[0] = mc->platform_max; + ret = kctl->get(kctl, uctl); + if (ret < 0) + goto out; + + if (uctl->value.integer.value[0] > mc->platform_max) + uctl->value.integer.value[0] = mc->platform_max; if (snd_soc_volsw_is_stereo(mc) && - uctl.value.integer.value[1] > mc->platform_max) - uctl.value.integer.value[1] = mc->platform_max; + uctl->value.integer.value[1] > mc->platform_max) + uctl->value.integer.value[1] = mc->platform_max; - ret = kctl->put(kctl, &uctl); - if (ret < 0) - return ret; + ret = kctl->put(kctl, uctl); - return 0; +out: + kfree(uctl); + return ret; } /** From 6ea0251d067f463b6e2d9f284c7488477d118e3c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 23 May 2025 09:19:22 +0200 Subject: [PATCH 074/404] ARM: dts: vfxxx: Correctly use two tuples for timer address [ Upstream commit f3440dcf8b994197c968fbafe047ce27eed226e8 ] Address and size-cells are 1 and the ftm timer node takes two address spaces in "reg" property, so this should be in two <> tuples. Change has no functional impact, but original code is confusing/less readable. Fixes: 07513e1330a9 ("ARM: dts: vf610: Add Freescale FlexTimer Module timer node.") Signed-off-by: Krzysztof Kozlowski Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/vfxxx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi index fa248066d9d9..3679922bbabc 100644 --- a/arch/arm/boot/dts/vfxxx.dtsi +++ b/arch/arm/boot/dts/vfxxx.dtsi @@ -617,7 +617,7 @@ ftm: ftm@400b8000 { compatible = "fsl,ftm-timer"; - reg = <0x400b8000 0x1000 0x400b9000 0x1000>; + reg = <0x400b8000 0x1000>, <0x400b9000 0x1000>; interrupts = <44 IRQ_TYPE_LEVEL_HIGH>; clock-names = "ftm-evt", "ftm-src", "ftm-evt-counter-en", "ftm-src-counter-en"; From 83ea0c7b8d12c67f6c4703d6c458627a7fc45fc0 Mon Sep 17 00:00:00 2001 From: Abdun Nihaal Date: Thu, 26 Jun 2025 22:54:10 +0530 Subject: [PATCH 075/404] staging: fbtft: fix potential memory leak in fbtft_framebuffer_alloc() [ Upstream commit eb2cb7dab60f9be0b435ac4a674255429a36d72c ] In the error paths after fb_info structure is successfully allocated, the memory allocated in fb_deferred_io_init() for info->pagerefs is not freed. Fix that by adding the cleanup function on the error path. Fixes: c296d5f9957c ("staging: fbtft: core support") Signed-off-by: Abdun Nihaal Reviewed-by: Dan Carpenter Link: https://lore.kernel.org/r/20250626172412.18355-1-abdun.nihaal@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/staging/fbtft/fbtft-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index 771697508cec..a524cacd89cd 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -752,6 +752,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, return info; release_framebuf: + fb_deferred_io_cleanup(info); framebuffer_release(info); alloc_fail: From 2c86366ce37f398e20fa09e7e9dc8788fbf6cf0c Mon Sep 17 00:00:00 2001 From: Lizhi Xu Date: Fri, 27 Jun 2025 13:52:14 +0800 Subject: [PATCH 076/404] vmci: Prevent the dispatching of uninitialized payloads [ Upstream commit bfb4cf9fb97e4063f0aa62e9e398025fb6625031 ] The reproducer executes the host's unlocked_ioctl call in two different tasks. When init_context fails, the struct vmci_event_ctx is not fully initialized when executing vmci_datagram_dispatch() to send events to all vm contexts. This affects the datagram taken from the datagram queue of its context by another task, because the datagram payload is not initialized according to the size payload_size, which causes the kernel data to leak to the user space. Before dispatching the datagram, and before setting the payload content, explicitly set the payload content to 0 to avoid data leakage caused by incomplete payload initialization. Fixes: 28d6692cd8fb ("VMCI: context implementation.") Reported-by: syzbot+9b9124ae9b12d5af5d95@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=9b9124ae9b12d5af5d95 Tested-by: syzbot+9b9124ae9b12d5af5d95@syzkaller.appspotmail.com Signed-off-by: Lizhi Xu Link: https://lore.kernel.org/r/20250627055214.2967129-1-lizhi.xu@windriver.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/misc/vmw_vmci/vmci_context.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/misc/vmw_vmci/vmci_context.c b/drivers/misc/vmw_vmci/vmci_context.c index 26ff49fdf0f7..ccadbc0d8f7d 100644 --- a/drivers/misc/vmw_vmci/vmci_context.c +++ b/drivers/misc/vmw_vmci/vmci_context.c @@ -251,6 +251,8 @@ static int ctx_fire_notification(u32 context_id, u32 priv_flags) ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_CONTEXT_RESOURCE_ID); ev.msg.hdr.payload_size = sizeof(ev) - sizeof(ev.msg.hdr); + memset((char*)&ev.msg.hdr + sizeof(ev.msg.hdr), 0, + ev.msg.hdr.payload_size); ev.msg.event_data.event = VMCI_EVENT_CTX_REMOVED; ev.payload.context_id = context_id; From 7465f4f15fbbfa366f5c77613b93f95dfb787008 Mon Sep 17 00:00:00 2001 From: Denis OSTERLAND-HEIM Date: Wed, 28 May 2025 12:57:50 +0200 Subject: [PATCH 077/404] pps: fix poll support [ Upstream commit 12c409aa1ec2592280a2ddcc66ff8f3c7f7bb171 ] Because pps_cdev_poll() returns unconditionally EPOLLIN, a user space program that calls select/poll get always an immediate data ready-to-read response. As a result the intended use to wait until next data becomes ready does not work. User space snippet: struct pollfd pollfd = { .fd = open("/dev/pps0", O_RDONLY), .events = POLLIN|POLLERR, .revents = 0 }; while(1) { poll(&pollfd, 1, 2000/*ms*/); // returns immediate, but should wait if(revents & EPOLLIN) { // always true struct pps_fdata fdata; memset(&fdata, 0, sizeof(memdata)); ioctl(PPS_FETCH, &fdata); // currently fetches data at max speed } } Lets remember the last fetch event counter and compare this value in pps_cdev_poll() with most recent event counter and return 0 if they are equal. Signed-off-by: Denis OSTERLAND-HEIM Co-developed-by: Rodolfo Giometti Signed-off-by: Rodolfo Giometti Fixes: eae9d2ba0cfc ("LinuxPPS: core support") Link: https://lore.kernel.org/all/f6bed779-6d59-4f0f-8a59-b6312bd83b4e@enneenne.com/ Acked-by: Rodolfo Giometti Link: https://lore.kernel.org/r/c3c50ad1eb19ef553eca8a57c17f4c006413ab70.camel@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/pps/pps.c | 11 +++++++++-- include/linux/pps_kernel.h | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index 2d008e0d116a..ea966fc67d28 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c @@ -41,6 +41,9 @@ static __poll_t pps_cdev_poll(struct file *file, poll_table *wait) poll_wait(file, &pps->queue, wait); + if (pps->last_fetched_ev == pps->last_ev) + return 0; + return EPOLLIN | EPOLLRDNORM; } @@ -186,9 +189,11 @@ static long pps_cdev_ioctl(struct file *file, if (err) return err; - /* Return the fetched timestamp */ + /* Return the fetched timestamp and save last fetched event */ spin_lock_irq(&pps->lock); + pps->last_fetched_ev = pps->last_ev; + fdata.info.assert_sequence = pps->assert_sequence; fdata.info.clear_sequence = pps->clear_sequence; fdata.info.assert_tu = pps->assert_tu; @@ -272,9 +277,11 @@ static long pps_cdev_compat_ioctl(struct file *file, if (err) return err; - /* Return the fetched timestamp */ + /* Return the fetched timestamp and save last fetched event */ spin_lock_irq(&pps->lock); + pps->last_fetched_ev = pps->last_ev; + compat.info.assert_sequence = pps->assert_sequence; compat.info.clear_sequence = pps->clear_sequence; compat.info.current_mode = pps->current_mode; diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h index c7abce28ed29..aab0aebb529e 100644 --- a/include/linux/pps_kernel.h +++ b/include/linux/pps_kernel.h @@ -52,6 +52,7 @@ struct pps_device { int current_mode; /* PPS mode at event time */ unsigned int last_ev; /* last PPS event id */ + unsigned int last_fetched_ev; /* last fetched PPS event id */ wait_queue_head_t queue; /* PPS event queue */ unsigned int id; /* PPS source unique ID */ From c3bfaf9c8193d46193fdb2f3eaf602df33b56730 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 3 Jul 2025 10:30:09 +0200 Subject: [PATCH 078/404] Revert "vmci: Prevent the dispatching of uninitialized payloads" [ Upstream commit 8f5d9bed6122b8d96508436e5ad2498bb797eb6b ] This reverts commit bfb4cf9fb97e4063f0aa62e9e398025fb6625031. While the code "looks" correct, the compiler has no way to know that doing "fun" pointer math like this really isn't a write off the end of the structure as there is no hint anywhere that the structure has data at the end of it. This causes the following build warning: In function 'fortify_memset_chk', inlined from 'ctx_fire_notification.isra' at drivers/misc/vmw_vmci/vmci_context.c:254:3: include/linux/fortify-string.h:480:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Werror=attribute-warning] 480 | __write_overflow_field(p_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ So revert it for now and it can come back in the future in a "sane" way that either correctly makes the structure know that there is trailing data, OR just the payload structure is properly referenced and zeroed out. Fixes: bfb4cf9fb97e ("vmci: Prevent the dispatching of uninitialized payloads") Cc: Stephen Rothwell Cc: Lizhi Xu Link: https://lore.kernel.org/r/20250703171021.0aee1482@canb.auug.org.au Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/misc/vmw_vmci/vmci_context.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/misc/vmw_vmci/vmci_context.c b/drivers/misc/vmw_vmci/vmci_context.c index ccadbc0d8f7d..26ff49fdf0f7 100644 --- a/drivers/misc/vmw_vmci/vmci_context.c +++ b/drivers/misc/vmw_vmci/vmci_context.c @@ -251,8 +251,6 @@ static int ctx_fire_notification(u32 context_id, u32 priv_flags) ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_CONTEXT_RESOURCE_ID); ev.msg.hdr.payload_size = sizeof(ev) - sizeof(ev.msg.hdr); - memset((char*)&ev.msg.hdr + sizeof(ev.msg.hdr), 0, - ev.msg.hdr.payload_size); ev.msg.event_data.event = VMCI_EVENT_CTX_REMOVED; ev.payload.context_id = context_id; From d12d31cd5bdb09ba117380c62ebc2dc2b3ebac06 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Fri, 27 Jun 2025 14:47:47 -0700 Subject: [PATCH 079/404] usb: early: xhci-dbc: Fix early_ioremap leak [ Upstream commit 2b7eec2ec3015f52fc74cf45d0408925e984ecd1 ] Using the kernel param earlyprintk=xdbc,keep without proper hardware setup leads to this: [ ] xhci_dbc:early_xdbc_parse_parameter: dbgp_num: 0 ... [ ] xhci_dbc:early_xdbc_setup_hardware: failed to setup the connection to host ... [ ] calling kmemleak_late_init+0x0/0xa0 @ 1 [ ] kmemleak: Kernel memory leak detector initialized (mem pool available: 14919) [ ] kmemleak: Automatic memory scanning thread started [ ] initcall kmemleak_late_init+0x0/0xa0 returned 0 after 417 usecs [ ] calling check_early_ioremap_leak+0x0/0x70 @ 1 [ ] ------------[ cut here ]------------ [ ] Debug warning: early ioremap leak of 1 areas detected. please boot with early_ioremap_debug and report the dmesg. [ ] WARNING: CPU: 11 PID: 1 at mm/early_ioremap.c:90 check_early_ioremap_leak+0x4e/0x70 When early_xdbc_setup_hardware() fails, make sure to call early_iounmap() since xdbc_init() won't handle it. Signed-off-by: Lucas De Marchi Fixes: aeb9dd1de98c ("usb/early: Add driver for xhci debug capability") Link: https://lore.kernel.org/r/20250627-xdbc-v1-1-43cc8c317b1b@intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/early/xhci-dbc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/early/xhci-dbc.c b/drivers/usb/early/xhci-dbc.c index 5a462a1d1896..7673ded077a4 100644 --- a/drivers/usb/early/xhci-dbc.c +++ b/drivers/usb/early/xhci-dbc.c @@ -678,6 +678,10 @@ int __init early_xdbc_setup_hardware(void) xdbc.table_base = NULL; xdbc.out_buf = NULL; + + early_iounmap(xdbc.xhci_base, xdbc.xhci_length); + xdbc.xhci_base = NULL; + xdbc.xhci_length = 0; } return ret; From c1289b6fe3aeb40a48da4b1b6035263b2b73af06 Mon Sep 17 00:00:00 2001 From: Annette Kobou Date: Tue, 8 Jul 2025 14:24:41 +0200 Subject: [PATCH 080/404] ARM: dts: imx6ul-kontron-bl-common: Fix RTS polarity for RS485 interface [ Upstream commit 47ef5256124fb939d8157b13ca048c902435cf23 ] The polarity of the DE signal of the transceiver is active-high for sending. Therefore rs485-rts-active-low is wrong and needs to be removed to make RS485 transmissions work. Signed-off-by: Annette Kobou Signed-off-by: Frieder Schrempf Fixes: 1ea4b76cdfde ("ARM: dts: imx6ul-kontron-n6310: Add Kontron i.MX6UL N6310 SoM and boards") Signed-off-by: Shawn Guo Signed-off-by: Sasha Levin --- arch/arm/boot/dts/imx6ul-kontron-n6310-s.dts | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6310-s.dts b/arch/arm/boot/dts/imx6ul-kontron-n6310-s.dts index 4e99e6c79a68..9b347029c2f6 100644 --- a/arch/arm/boot/dts/imx6ul-kontron-n6310-s.dts +++ b/arch/arm/boot/dts/imx6ul-kontron-n6310-s.dts @@ -168,7 +168,6 @@ pinctrl-0 = <&pinctrl_uart2>; linux,rs485-enabled-at-boot-time; rs485-rx-during-tx; - rs485-rts-active-low; uart-has-rtscts; status = "okay"; }; From 6e6f190207083a72826023c5c45bcb9c35babfac Mon Sep 17 00:00:00 2001 From: Lifeng Zheng Date: Wed, 9 Jul 2025 18:41:43 +0800 Subject: [PATCH 081/404] cpufreq: Init policy->rwsem before it may be possibly used [ Upstream commit d1378d1d7edb3a4c4935a44fe834ae135be03564 ] In cpufreq_policy_put_kobj(), policy->rwsem is used. But in cpufreq_policy_alloc(), if freq_qos_add_notifier() returns an error, error path via err_kobj_remove or err_min_qos_notifier will be reached and cpufreq_policy_put_kobj() will be called before policy->rwsem is initialized. Thus, the calling of init_rwsem() should be moved to where before these two error paths can be reached. Fixes: 67d874c3b2c6 ("cpufreq: Register notifiers with the PM QoS framework") Signed-off-by: Lifeng Zheng Link: https://patch.msgid.link/20250709104145.2348017-3-zhenglifeng1@huawei.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/cpufreq/cpufreq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 2a2fea6743aa..00f12d23077c 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1220,6 +1220,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) goto err_free_real_cpus; } + init_rwsem(&policy->rwsem); + freq_constraints_init(&policy->constraints); policy->nb_min.notifier_call = cpufreq_notifier_min; @@ -1242,7 +1244,6 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) } INIT_LIST_HEAD(&policy->policy_list); - init_rwsem(&policy->rwsem); spin_lock_init(&policy->transition_lock); init_waitqueue_head(&policy->transition_wait); INIT_WORK(&policy->update, handle_update); From 3bbdc6686af9b1fcbec9bcd2b87cbce825cf9916 Mon Sep 17 00:00:00 2001 From: Brahmajit Das Date: Wed, 2 Jul 2025 19:29:55 +0530 Subject: [PATCH 082/404] samples: mei: Fix building on musl libc [ Upstream commit 239df3e4b4752524e7c0fb3417c218d8063654b4 ] The header bits/wordsize.h is glibc specific and on building on musl with allyesconfig results in samples/mei/mei-amt-version.c:77:10: fatal error: bits/wordsize.h: No such file or directory 77 | #include | ^~~~~~~~~~~~~~~~~ mei-amt-version.c build file without bits/wordsize.h on musl and glibc. However on musl we get the follwing error without sys/time.h samples/mei/mei-amt-version.c: In function 'mei_recv_msg': samples/mei/mei-amt-version.c:159:24: error: storage size of 'tv' isn't known 159 | struct timeval tv; | ^~ samples/mei/mei-amt-version.c:160:9: error: unknown type name 'fd_set' 160 | fd_set set; | ^~~~~~ samples/mei/mei-amt-version.c:168:9: error: implicit declaration of function 'FD_ZERO' [-Wimplicit-function-declaration] 168 | FD_ZERO(&set); | ^~~~~~~ samples/mei/mei-amt-version.c:169:9: error: implicit declaration of function 'FD_SET'; did you mean 'L_SET'? [-Wimplicit-function-declaration] 169 | FD_SET(me->fd, &set); | ^~~~~~ | L_SET samples/mei/mei-amt-version.c:170:14: error: implicit declaration of function 'select' [-Wimplicit-function-declaration] 170 | rc = select(me->fd + 1, &set, NULL, NULL, &tv); | ^~~~~~ samples/mei/mei-amt-version.c:171:23: error: implicit declaration of function 'FD_ISSET' [-Wimplicit-function-declaration] 171 | if (rc > 0 && FD_ISSET(me->fd, &set)) { | ^~~~~~~~ samples/mei/mei-amt-version.c:159:24: warning: unused variable 'tv' [-Wunused-variable] 159 | struct timeval tv; | ^~ Hence the the file has been included. Fixes: c52827cc4ddf ("staging/mei: add mei user space example") Signed-off-by: Brahmajit Das Link: https://lore.kernel.org/r/20250702135955.24955-1-listout@listout.xyz Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- samples/mei/mei-amt-version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/mei/mei-amt-version.c b/samples/mei/mei-amt-version.c index 32234481ad7d..9e8028e45e3b 100644 --- a/samples/mei/mei-amt-version.c +++ b/samples/mei/mei-amt-version.c @@ -69,11 +69,11 @@ #include #include #include +#include #include #include #include #include -#include #include /***************************************************************************** From 9ca96350d7aabeb4a9b498ddbe23f059fdf0311a Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Sat, 19 Jul 2025 01:07:42 -0700 Subject: [PATCH 083/404] staging: nvec: Fix incorrect null termination of battery manufacturer [ Upstream commit a8934352ba01081c51d2df428e9d540aae0e88b5 ] The battery manufacturer string was incorrectly null terminated using bat_model instead of bat_manu. This could result in an unintended write to the wrong field and potentially incorrect behavior. fixe the issue by correctly null terminating the bat_manu string. Fixes: 32890b983086 ("Staging: initial version of the nvec driver") Signed-off-by: Alok Tiwari Reviewed-by: Dan Carpenter Link: https://lore.kernel.org/r/20250719080755.3954373-1-alok.a.tiwari@oracle.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/staging/nvec/nvec_power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c index 0e861c4bfcbf..590b801c5992 100644 --- a/drivers/staging/nvec/nvec_power.c +++ b/drivers/staging/nvec/nvec_power.c @@ -194,7 +194,7 @@ static int nvec_power_bat_notifier(struct notifier_block *nb, break; case MANUFACTURER: memcpy(power->bat_manu, &res->plc, res->length - 2); - power->bat_model[res->length - 2] = '\0'; + power->bat_manu[res->length - 2] = '\0'; break; case MODEL: memcpy(power->bat_model, &res->plc, res->length - 2); From 6ba20ff3cdb96a908b9dc93cf247d0b087672e7c Mon Sep 17 00:00:00 2001 From: Jiayuan Chen Date: Mon, 9 Jun 2025 10:08:52 +0800 Subject: [PATCH 084/404] bpf, ktls: Fix data corruption when using bpf_msg_pop_data() in ktls [ Upstream commit 178f6a5c8cb3b6be1602de0964cd440243f493c9 ] When sending plaintext data, we initially calculated the corresponding ciphertext length. However, if we later reduced the plaintext data length via socket policy, we failed to recalculate the ciphertext length. This results in transmitting buffers containing uninitialized data during ciphertext transmission. This causes uninitialized bytes to be appended after a complete "Application Data" packet, leading to errors on the receiving end when parsing TLS record. Fixes: d3b18ad31f93 ("tls: add bpf support to sk_msg handling") Reported-by: Cong Wang Signed-off-by: Jiayuan Chen Signed-off-by: Daniel Borkmann Reviewed-by: John Fastabend Acked-by: Jakub Kicinski Link: https://lore.kernel.org/bpf/20250609020910.397930-2-jiayuan.chen@linux.dev Signed-off-by: Sasha Levin --- net/tls/tls_sw.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 432bce329392..8dabbbf52168 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -822,6 +822,19 @@ more_data: delta = msg->sg.size; psock->eval = sk_psock_msg_verdict(sk, psock, msg); delta -= msg->sg.size; + + if ((s32)delta > 0) { + /* It indicates that we executed bpf_msg_pop_data(), + * causing the plaintext data size to decrease. + * Therefore the encrypted data size also needs to + * correspondingly decrease. We only need to subtract + * delta to calculate the new ciphertext length since + * ktls does not support block encryption. + */ + struct sk_msg *enc = &ctx->open_rec->msg_encrypted; + + sk_msg_trim(sk, enc, enc->sg.size - delta); + } } if (msg->cork_bytes && msg->cork_bytes > msg->sg.size && !enospc && !full_record) { From 78561ada3f35c71946e99d9bc72561301ef2bf69 Mon Sep 17 00:00:00 2001 From: Yuan Chen Date: Fri, 20 Jun 2025 09:21:33 +0800 Subject: [PATCH 085/404] bpftool: Fix memory leak in dump_xx_nlmsg on realloc failure [ Upstream commit 99fe8af069a9fa5b09140518b1364e35713a642e ] In function dump_xx_nlmsg(), when realloc() fails to allocate memory, the original pointer to the buffer is overwritten with NULL. This causes a memory leak because the previously allocated buffer becomes unreachable without being freed. Fixes: 7900efc19214 ("tools/bpf: bpftool: improve output format for bpftool net") Signed-off-by: Yuan Chen Reviewed-by: Quentin Monnet Link: https://lore.kernel.org/r/20250620012133.14819-1-chenyuan_fl@163.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- tools/bpf/bpftool/net.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c index c6787a1daa48..c2953b2bf130 100644 --- a/tools/bpf/bpftool/net.c +++ b/tools/bpf/bpftool/net.c @@ -87,17 +87,18 @@ static int dump_link_nlmsg(void *cookie, void *msg, struct nlattr **tb) { struct bpf_netdev_t *netinfo = cookie; struct ifinfomsg *ifinfo = msg; + struct ip_devname_ifindex *tmp; if (netinfo->filter_idx > 0 && netinfo->filter_idx != ifinfo->ifi_index) return 0; if (netinfo->used_len == netinfo->array_len) { - netinfo->devices = realloc(netinfo->devices, - (netinfo->array_len + 16) * - sizeof(struct ip_devname_ifindex)); - if (!netinfo->devices) + tmp = realloc(netinfo->devices, + (netinfo->array_len + 16) * sizeof(struct ip_devname_ifindex)); + if (!tmp) return -ENOMEM; + netinfo->devices = tmp; netinfo->array_len += 16; } netinfo->devices[netinfo->used_len].ifindex = ifinfo->ifi_index; @@ -116,6 +117,7 @@ static int dump_class_qdisc_nlmsg(void *cookie, void *msg, struct nlattr **tb) { struct bpf_tcinfo_t *tcinfo = cookie; struct tcmsg *info = msg; + struct tc_kind_handle *tmp; if (tcinfo->is_qdisc) { /* skip clsact qdisc */ @@ -127,11 +129,12 @@ static int dump_class_qdisc_nlmsg(void *cookie, void *msg, struct nlattr **tb) } if (tcinfo->used_len == tcinfo->array_len) { - tcinfo->handle_array = realloc(tcinfo->handle_array, + tmp = realloc(tcinfo->handle_array, (tcinfo->array_len + 16) * sizeof(struct tc_kind_handle)); - if (!tcinfo->handle_array) + if (!tmp) return -ENOMEM; + tcinfo->handle_array = tmp; tcinfo->array_len += 16; } tcinfo->handle_array[tcinfo->used_len].handle = info->tcm_handle; From c3b69f0fdac986ebf0c525fce0404e5f8001ff9b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 20 Jun 2025 13:22:39 +0200 Subject: [PATCH 086/404] caif: reduce stack size, again [ Upstream commit b630c781bcf6ff87657146661816d0d30a902139 ] I tried to fix the stack usage in this function a couple of years ago, but there is still a problem with the latest gcc versions in some configurations: net/caif/cfctrl.c:553:1: error: the frame size of 1296 bytes is larger than 1280 bytes [-Werror=frame-larger-than=] Reduce this once again, with a separate cfctrl_link_setup() function that holds the bulk of all the local variables. It also turns out that the param[] array that takes up a large portion of the stack is write-only and can be left out here. Fixes: ce6289661b14 ("caif: reduce stack size with KASAN") Signed-off-by: Arnd Bergmann Link: https://patch.msgid.link/20250620112244.3425554-1-arnd@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/caif/cfctrl.c | 294 +++++++++++++++++++++++----------------------- 1 file changed, 144 insertions(+), 150 deletions(-) diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index d8cb4b2a076b..3eec293ab22f 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c @@ -351,17 +351,154 @@ int cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer) return found; } +static int cfctrl_link_setup(struct cfctrl *cfctrl, struct cfpkt *pkt, u8 cmdrsp) +{ + u8 len; + u8 linkid = 0; + enum cfctrl_srv serv; + enum cfctrl_srv servtype; + u8 endpoint; + u8 physlinkid; + u8 prio; + u8 tmp; + u8 *cp; + int i; + struct cfctrl_link_param linkparam; + struct cfctrl_request_info rsp, *req; + + memset(&linkparam, 0, sizeof(linkparam)); + + tmp = cfpkt_extr_head_u8(pkt); + + serv = tmp & CFCTRL_SRV_MASK; + linkparam.linktype = serv; + + servtype = tmp >> 4; + linkparam.chtype = servtype; + + tmp = cfpkt_extr_head_u8(pkt); + physlinkid = tmp & 0x07; + prio = tmp >> 3; + + linkparam.priority = prio; + linkparam.phyid = physlinkid; + endpoint = cfpkt_extr_head_u8(pkt); + linkparam.endpoint = endpoint & 0x03; + + switch (serv) { + case CFCTRL_SRV_VEI: + case CFCTRL_SRV_DBG: + if (CFCTRL_ERR_BIT & cmdrsp) + break; + /* Link ID */ + linkid = cfpkt_extr_head_u8(pkt); + break; + case CFCTRL_SRV_VIDEO: + tmp = cfpkt_extr_head_u8(pkt); + linkparam.u.video.connid = tmp; + if (CFCTRL_ERR_BIT & cmdrsp) + break; + /* Link ID */ + linkid = cfpkt_extr_head_u8(pkt); + break; + + case CFCTRL_SRV_DATAGRAM: + linkparam.u.datagram.connid = cfpkt_extr_head_u32(pkt); + if (CFCTRL_ERR_BIT & cmdrsp) + break; + /* Link ID */ + linkid = cfpkt_extr_head_u8(pkt); + break; + case CFCTRL_SRV_RFM: + /* Construct a frame, convert + * DatagramConnectionID + * to network format long and copy it out... + */ + linkparam.u.rfm.connid = cfpkt_extr_head_u32(pkt); + cp = (u8 *) linkparam.u.rfm.volume; + for (tmp = cfpkt_extr_head_u8(pkt); + cfpkt_more(pkt) && tmp != '\0'; + tmp = cfpkt_extr_head_u8(pkt)) + *cp++ = tmp; + *cp = '\0'; + + if (CFCTRL_ERR_BIT & cmdrsp) + break; + /* Link ID */ + linkid = cfpkt_extr_head_u8(pkt); + + break; + case CFCTRL_SRV_UTIL: + /* Construct a frame, convert + * DatagramConnectionID + * to network format long and copy it out... + */ + /* Fifosize KB */ + linkparam.u.utility.fifosize_kb = cfpkt_extr_head_u16(pkt); + /* Fifosize bufs */ + linkparam.u.utility.fifosize_bufs = cfpkt_extr_head_u16(pkt); + /* name */ + cp = (u8 *) linkparam.u.utility.name; + caif_assert(sizeof(linkparam.u.utility.name) + >= UTILITY_NAME_LENGTH); + for (i = 0; i < UTILITY_NAME_LENGTH && cfpkt_more(pkt); i++) { + tmp = cfpkt_extr_head_u8(pkt); + *cp++ = tmp; + } + /* Length */ + len = cfpkt_extr_head_u8(pkt); + linkparam.u.utility.paramlen = len; + /* Param Data */ + cp = linkparam.u.utility.params; + while (cfpkt_more(pkt) && len--) { + tmp = cfpkt_extr_head_u8(pkt); + *cp++ = tmp; + } + if (CFCTRL_ERR_BIT & cmdrsp) + break; + /* Link ID */ + linkid = cfpkt_extr_head_u8(pkt); + /* Length */ + len = cfpkt_extr_head_u8(pkt); + /* Param Data */ + cfpkt_extr_head(pkt, NULL, len); + break; + default: + pr_warn("Request setup, invalid type (%d)\n", serv); + return -1; + } + + rsp.cmd = CFCTRL_CMD_LINK_SETUP; + rsp.param = linkparam; + spin_lock_bh(&cfctrl->info_list_lock); + req = cfctrl_remove_req(cfctrl, &rsp); + + if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) || + cfpkt_erroneous(pkt)) { + pr_err("Invalid O/E bit or parse error " + "on CAIF control channel\n"); + cfctrl->res.reject_rsp(cfctrl->serv.layer.up, 0, + req ? req->client_layer : NULL); + } else { + cfctrl->res.linksetup_rsp(cfctrl->serv.layer.up, linkid, + serv, physlinkid, + req ? req->client_layer : NULL); + } + + kfree(req); + + spin_unlock_bh(&cfctrl->info_list_lock); + + return 0; +} + static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) { u8 cmdrsp; u8 cmd; - int ret = -1; - u8 len; - u8 param[255]; + int ret = 0; u8 linkid = 0; struct cfctrl *cfctrl = container_obj(layer); - struct cfctrl_request_info rsp, *req; - cmdrsp = cfpkt_extr_head_u8(pkt); cmd = cmdrsp & CFCTRL_CMD_MASK; @@ -374,150 +511,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) switch (cmd) { case CFCTRL_CMD_LINK_SETUP: - { - enum cfctrl_srv serv; - enum cfctrl_srv servtype; - u8 endpoint; - u8 physlinkid; - u8 prio; - u8 tmp; - u8 *cp; - int i; - struct cfctrl_link_param linkparam; - memset(&linkparam, 0, sizeof(linkparam)); - - tmp = cfpkt_extr_head_u8(pkt); - - serv = tmp & CFCTRL_SRV_MASK; - linkparam.linktype = serv; - - servtype = tmp >> 4; - linkparam.chtype = servtype; - - tmp = cfpkt_extr_head_u8(pkt); - physlinkid = tmp & 0x07; - prio = tmp >> 3; - - linkparam.priority = prio; - linkparam.phyid = physlinkid; - endpoint = cfpkt_extr_head_u8(pkt); - linkparam.endpoint = endpoint & 0x03; - - switch (serv) { - case CFCTRL_SRV_VEI: - case CFCTRL_SRV_DBG: - if (CFCTRL_ERR_BIT & cmdrsp) - break; - /* Link ID */ - linkid = cfpkt_extr_head_u8(pkt); - break; - case CFCTRL_SRV_VIDEO: - tmp = cfpkt_extr_head_u8(pkt); - linkparam.u.video.connid = tmp; - if (CFCTRL_ERR_BIT & cmdrsp) - break; - /* Link ID */ - linkid = cfpkt_extr_head_u8(pkt); - break; - - case CFCTRL_SRV_DATAGRAM: - linkparam.u.datagram.connid = - cfpkt_extr_head_u32(pkt); - if (CFCTRL_ERR_BIT & cmdrsp) - break; - /* Link ID */ - linkid = cfpkt_extr_head_u8(pkt); - break; - case CFCTRL_SRV_RFM: - /* Construct a frame, convert - * DatagramConnectionID - * to network format long and copy it out... - */ - linkparam.u.rfm.connid = - cfpkt_extr_head_u32(pkt); - cp = (u8 *) linkparam.u.rfm.volume; - for (tmp = cfpkt_extr_head_u8(pkt); - cfpkt_more(pkt) && tmp != '\0'; - tmp = cfpkt_extr_head_u8(pkt)) - *cp++ = tmp; - *cp = '\0'; - - if (CFCTRL_ERR_BIT & cmdrsp) - break; - /* Link ID */ - linkid = cfpkt_extr_head_u8(pkt); - - break; - case CFCTRL_SRV_UTIL: - /* Construct a frame, convert - * DatagramConnectionID - * to network format long and copy it out... - */ - /* Fifosize KB */ - linkparam.u.utility.fifosize_kb = - cfpkt_extr_head_u16(pkt); - /* Fifosize bufs */ - linkparam.u.utility.fifosize_bufs = - cfpkt_extr_head_u16(pkt); - /* name */ - cp = (u8 *) linkparam.u.utility.name; - caif_assert(sizeof(linkparam.u.utility.name) - >= UTILITY_NAME_LENGTH); - for (i = 0; - i < UTILITY_NAME_LENGTH - && cfpkt_more(pkt); i++) { - tmp = cfpkt_extr_head_u8(pkt); - *cp++ = tmp; - } - /* Length */ - len = cfpkt_extr_head_u8(pkt); - linkparam.u.utility.paramlen = len; - /* Param Data */ - cp = linkparam.u.utility.params; - while (cfpkt_more(pkt) && len--) { - tmp = cfpkt_extr_head_u8(pkt); - *cp++ = tmp; - } - if (CFCTRL_ERR_BIT & cmdrsp) - break; - /* Link ID */ - linkid = cfpkt_extr_head_u8(pkt); - /* Length */ - len = cfpkt_extr_head_u8(pkt); - /* Param Data */ - cfpkt_extr_head(pkt, ¶m, len); - break; - default: - pr_warn("Request setup, invalid type (%d)\n", - serv); - goto error; - } - - rsp.cmd = cmd; - rsp.param = linkparam; - spin_lock_bh(&cfctrl->info_list_lock); - req = cfctrl_remove_req(cfctrl, &rsp); - - if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) || - cfpkt_erroneous(pkt)) { - pr_err("Invalid O/E bit or parse error " - "on CAIF control channel\n"); - cfctrl->res.reject_rsp(cfctrl->serv.layer.up, - 0, - req ? req->client_layer - : NULL); - } else { - cfctrl->res.linksetup_rsp(cfctrl->serv. - layer.up, linkid, - serv, physlinkid, - req ? req-> - client_layer : NULL); - } - - kfree(req); - - spin_unlock_bh(&cfctrl->info_list_lock); - } + ret = cfctrl_link_setup(cfctrl, pkt, cmdrsp); break; case CFCTRL_CMD_LINK_DESTROY: linkid = cfpkt_extr_head_u8(pkt); @@ -544,9 +538,9 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) break; default: pr_err("Unrecognized Control Frame\n"); + ret = -1; goto error; } - ret = 0; error: cfpkt_destroy(pkt); return ret; From e64732ebff9e24258e7326f07adbe2f2b990daf8 Mon Sep 17 00:00:00 2001 From: Daniil Dulov Date: Tue, 17 Jun 2025 16:56:34 +0300 Subject: [PATCH 087/404] wifi: rtl818x: Kill URBs before clearing tx status queue [ Upstream commit 16d8fd74dbfca0ea58645cd2fca13be10cae3cdd ] In rtl8187_stop() move the call of usb_kill_anchored_urbs() before clearing b_tx_status.queue. This change prevents callbacks from using already freed skb due to anchor was not killed before freeing such skb. BUG: kernel NULL pointer dereference, address: 0000000000000080 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 7 UID: 0 PID: 0 Comm: swapper/7 Not tainted 6.15.0 #8 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015 RIP: 0010:ieee80211_tx_status_irqsafe+0x21/0xc0 [mac80211] Call Trace: rtl8187_tx_cb+0x116/0x150 [rtl8187] __usb_hcd_giveback_urb+0x9d/0x120 usb_giveback_urb_bh+0xbb/0x140 process_one_work+0x19b/0x3c0 bh_worker+0x1a7/0x210 tasklet_action+0x10/0x30 handle_softirqs+0xf0/0x340 __irq_exit_rcu+0xcd/0xf0 common_interrupt+0x85/0xa0 Tested on RTL8187BvE device. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: c1db52b9d27e ("rtl8187: Use usb anchor facilities to manage urbs") Signed-off-by: Daniil Dulov Reviewed-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250617135634.21760-1-d.dulov@aladdin.ru Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c index eb68b2d3caa1..c9df185dc3f4 100644 --- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c @@ -1041,10 +1041,11 @@ static void rtl8187_stop(struct ieee80211_hw *dev) rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); + usb_kill_anchored_urbs(&priv->anchored); + while ((skb = skb_dequeue(&priv->b_tx_status.queue))) dev_kfree_skb_any(skb); - usb_kill_anchored_urbs(&priv->anchored); mutex_unlock(&priv->conf_mutex); if (!priv->is_rtl8187b) From ee8cff4694d6803f59ccc78f9b6083b381dafbd6 Mon Sep 17 00:00:00 2001 From: Xiu Jianfeng Date: Wed, 9 Nov 2022 11:52:13 +0800 Subject: [PATCH 088/404] wifi: iwlwifi: Fix memory leak in iwl_mvm_init() [ Upstream commit ed2e916c890944633d6826dce267579334f63ea5 ] When iwl_opmode_register() fails, it does not unregster rate control, which will cause a memory leak issue, this patch fixes it. Fixes: 9f66a397c877 ("iwlwifi: mvm: rs: add ops for the new rate scaling in the FW") Signed-off-by: Xiu Jianfeng Link: https://patch.msgid.link/20221109035213.570-1-xiujianfeng@huawei.com Signed-off-by: Miri Korenblit Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 18c5975d7c03..70ba91d2bedf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -123,8 +123,10 @@ static int __init iwl_mvm_init(void) } ret = iwl_opmode_register("iwlmvm", &iwl_mvm_ops); - if (ret) + if (ret) { pr_err("Unable to register MVM op_mode: %d\n", ret); + iwl_mvm_rate_control_unregister(); + } return ret; } From c80832d445653baba5ac80cd2c2637c437ac881b Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Tue, 10 Jan 2023 09:48:48 +0800 Subject: [PATCH 089/404] iwlwifi: Add missing check for alloc_ordered_workqueue [ Upstream commit 90a0d9f339960448a3acc1437a46730f975efd6a ] Add check for the return value of alloc_ordered_workqueue since it may return NULL pointer. Fixes: b481de9ca074 ("[IWLWIFI]: add iwlwifi wireless drivers") Signed-off-by: Jiasheng Jiang Link: https://patch.msgid.link/20230110014848.28226-1-jiasheng@iscas.ac.cn Signed-off-by: Miri Korenblit Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index 4f2789bb3b5b..9ca704a2c679 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -1055,9 +1055,11 @@ static void iwl_bg_restart(struct work_struct *data) * *****************************************************************************/ -static void iwl_setup_deferred_work(struct iwl_priv *priv) +static int iwl_setup_deferred_work(struct iwl_priv *priv) { priv->workqueue = alloc_ordered_workqueue(DRV_NAME, 0); + if (!priv->workqueue) + return -ENOMEM; INIT_WORK(&priv->restart, iwl_bg_restart); INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); @@ -1074,6 +1076,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) timer_setup(&priv->statistics_periodic, iwl_bg_statistics_periodic, 0); timer_setup(&priv->ucode_trace, iwl_bg_ucode_trace, 0); + + return 0; } void iwl_cancel_deferred_work(struct iwl_priv *priv) @@ -1469,7 +1473,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, /******************** * 6. Setup services ********************/ - iwl_setup_deferred_work(priv); + if (iwl_setup_deferred_work(priv)) + goto out_uninit_drv; + iwl_setup_rx_handlers(priv); iwl_power_initialize(priv); @@ -1507,6 +1513,7 @@ out_destroy_workqueue: iwl_cancel_deferred_work(priv); destroy_workqueue(priv->workqueue); priv->workqueue = NULL; +out_uninit_drv: iwl_uninit_drv(priv); out_free_eeprom_blob: kfree(priv->eeprom_blob); From 2cbd59d0a6090fbef529e9435fcf1aebd40fff8e Mon Sep 17 00:00:00 2001 From: "xin.guo" Date: Thu, 26 Jun 2025 12:34:19 +0000 Subject: [PATCH 090/404] tcp: fix tcp_ofo_queue() to avoid including too much DUP SACK range [ Upstream commit a041f70e573e185d5d5fdbba53f0db2fbe7257ad ] If the new coming segment covers more than one skbs in the ofo queue, and which seq is equal to rcv_nxt, then the sequence range that is duplicated will be sent as DUP SACK, the detail as below, in step6, the {501,2001} range is clearly including too much DUP SACK range, in violation of RFC 2883 rules. 1. client > server: Flags [.], seq 501:1001, ack 1325288529, win 20000, length 500 2. server > client: Flags [.], ack 1, [nop,nop,sack 1 {501:1001}], length 0 3. client > server: Flags [.], seq 1501:2001, ack 1325288529, win 20000, length 500 4. server > client: Flags [.], ack 1, [nop,nop,sack 2 {1501:2001} {501:1001}], length 0 5. client > server: Flags [.], seq 1:2001, ack 1325288529, win 20000, length 2000 6. server > client: Flags [.], ack 2001, [nop,nop,sack 1 {501:2001}], length 0 After this fix, the final ACK is as below: 6. server > client: Flags [.], ack 2001, options [nop,nop,sack 1 {501:1001}], length 0 [edumazet] added a new packetdrill test in the following patch. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: xin.guo Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20250626123420.1933835-2-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ipv4/tcp_input.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 6b3bb8a59035..9d65e684e626 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4588,8 +4588,9 @@ static void tcp_ofo_queue(struct sock *sk) if (before(TCP_SKB_CB(skb)->seq, dsack_high)) { __u32 dsack = dsack_high; + if (before(TCP_SKB_CB(skb)->end_seq, dsack_high)) - dsack_high = TCP_SKB_CB(skb)->end_seq; + dsack = TCP_SKB_CB(skb)->end_seq; tcp_dsack_extend(sk, TCP_SKB_CB(skb)->seq, dsack); } p = rb_next(p); From aec49221d08c52b60dda9c54eea3698dcb0b4a19 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Tue, 1 Apr 2025 11:26:44 +1100 Subject: [PATCH 091/404] m68k: Don't unregister boot console needlessly [ Upstream commit 83f672a7f69ec38b1bbb27221e342937f68c11c7 ] When MACH_IS_MVME147, the boot console calls mvme147_scc_write() to generate console output. That will continue to work even after debug_cons_nputs() becomes unavailable so there's no need to unregister the boot console. Take the opportunity to remove a repeated MACH_IS_* test. Use the actual .write method (instead of a wrapper) and test that pointer instead. This means adding an unused parameter to debug_cons_nputs() for consistency with the struct console API. early_printk.c is only built when CONFIG_EARLY_PRINTK=y. As of late, head.S is only built when CONFIG_MMU_MOTOROLA=y. So let the former symbol depend on the latter, to obviate some ifdef conditionals. Cc: Daniel Palmer Fixes: 077b33b9e283 ("m68k: mvme147: Reinstate early console") Signed-off-by: Finn Thain Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/d1d4328e5aa9a87bd8352529ce62b767731c0530.1743467205.git.fthain@linux-m68k.org Signed-off-by: Geert Uytterhoeven Signed-off-by: Sasha Levin --- arch/m68k/Kconfig.debug | 2 +- arch/m68k/kernel/early_printk.c | 42 +++++++++++---------------------- arch/m68k/kernel/head.S | 8 +++---- 3 files changed, 19 insertions(+), 33 deletions(-) diff --git a/arch/m68k/Kconfig.debug b/arch/m68k/Kconfig.debug index f43643111eaf..f9fa89ba259d 100644 --- a/arch/m68k/Kconfig.debug +++ b/arch/m68k/Kconfig.debug @@ -10,7 +10,7 @@ config BOOTPARAM_STRING config EARLY_PRINTK bool "Early printk" - depends on !(SUN3 || M68000 || COLDFIRE) + depends on MMU_MOTOROLA help Write kernel log output directly to a serial port. Where implemented, output goes to the framebuffer as well. diff --git a/arch/m68k/kernel/early_printk.c b/arch/m68k/kernel/early_printk.c index f11ef9f1f56f..521cbb8a150c 100644 --- a/arch/m68k/kernel/early_printk.c +++ b/arch/m68k/kernel/early_printk.c @@ -16,25 +16,10 @@ #include "../mvme147/mvme147.h" #include "../mvme16x/mvme16x.h" -asmlinkage void __init debug_cons_nputs(const char *s, unsigned n); - -static void __ref debug_cons_write(struct console *c, - const char *s, unsigned n) -{ -#if !(defined(CONFIG_SUN3) || defined(CONFIG_M68000) || \ - defined(CONFIG_COLDFIRE)) - if (MACH_IS_MVME147) - mvme147_scc_write(c, s, n); - else if (MACH_IS_MVME16x) - mvme16x_cons_write(c, s, n); - else - debug_cons_nputs(s, n); -#endif -} +asmlinkage void __init debug_cons_nputs(struct console *c, const char *s, unsigned int n); static struct console early_console_instance = { .name = "debug", - .write = debug_cons_write, .flags = CON_PRINTBUFFER | CON_BOOT, .index = -1 }; @@ -44,6 +29,12 @@ static int __init setup_early_printk(char *buf) if (early_console || buf) return 0; + if (MACH_IS_MVME147) + early_console_instance.write = mvme147_scc_write; + else if (MACH_IS_MVME16x) + early_console_instance.write = mvme16x_cons_write; + else + early_console_instance.write = debug_cons_nputs; early_console = &early_console_instance; register_console(early_console); @@ -51,20 +42,15 @@ static int __init setup_early_printk(char *buf) } early_param("earlyprintk", setup_early_printk); -/* - * debug_cons_nputs() defined in arch/m68k/kernel/head.S cannot be called - * after init sections are discarded (for platforms that use it). - */ -#if !(defined(CONFIG_SUN3) || defined(CONFIG_M68000) || \ - defined(CONFIG_COLDFIRE)) - static int __init unregister_early_console(void) { - if (!early_console || MACH_IS_MVME16x) - return 0; + /* + * debug_cons_nputs() defined in arch/m68k/kernel/head.S cannot be + * called after init sections are discarded (for platforms that use it). + */ + if (early_console && early_console->write == debug_cons_nputs) + return unregister_console(early_console); - return unregister_console(early_console); + return 0; } late_initcall(unregister_early_console); - -#endif diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index a54788458ca3..692cdcfb3520 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -3242,8 +3242,8 @@ func_return putn * turns around and calls the internal routines. This routine * is used by the boot console. * - * The calling parameters are: - * void debug_cons_nputs(const char *str, unsigned length) + * The function signature is - + * void debug_cons_nputs(struct console *c, const char *s, unsigned int n) * * This routine does NOT understand variable arguments only * simple strings! @@ -3252,8 +3252,8 @@ ENTRY(debug_cons_nputs) moveml %d0/%d1/%a0,%sp@- movew %sr,%sp@- ori #0x0700,%sr - movel %sp@(18),%a0 /* fetch parameter */ - movel %sp@(22),%d1 /* fetch parameter */ + movel %sp@(22),%a0 /* char *s */ + movel %sp@(26),%d1 /* unsigned int n */ jra 2f 1: #ifdef CONSOLE_DEBUG From 25e053cb809c5d0696b1e027d713d4f69639081a Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Mon, 30 Jun 2025 23:26:17 +0300 Subject: [PATCH 092/404] drm/amd/pm/powerplay/hwmgr/smu_helper: fix order of mask and value [ Upstream commit a54e4639c4ef37a0241bac7d2a77f2e6ffb57099 ] There is a small typo in phm_wait_on_indirect_register(). Swap mask and value arguments provided to phm_wait_on_register() so that they satisfy the function signature and actual usage scheme. Found by Linux Verification Center (linuxtesting.org) with Svace static analysis tool. In practice this doesn't fix any issues because the only place this function is used uses the same value for the value and mask. Fixes: 3bace3591493 ("drm/amd/powerplay: add hardware manager sub-component") Signed-off-by: Fedor Pchelkin Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c index d09690fca452..8a1ad9305a21 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c @@ -148,7 +148,7 @@ int phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr, } cgs_write_register(hwmgr->device, indirect_port, index); - return phm_wait_on_register(hwmgr, indirect_port + 1, mask, value); + return phm_wait_on_register(hwmgr, indirect_port + 1, value, mask); } int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr, From 3584fa93d1099090e6f58e1348e27d4d8537bf48 Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Tue, 24 Jun 2025 14:12:15 +0300 Subject: [PATCH 093/404] netfilter: nf_tables: adjust lockdep assertions handling [ Upstream commit 8df1b40de76979bb8e975201d07b71103d5de820 ] It's needed to check the return value of lockdep_commit_lock_is_held(), otherwise there's no point in this assertion as it doesn't print any debug information on itself. Found by Linux Verification Center (linuxtesting.org) with Svace static analysis tool. Fixes: b04df3da1b5c ("netfilter: nf_tables: do not defer rule destruction via call_rcu") Reported-by: Alexey Khoroshilov Signed-off-by: Fedor Pchelkin Acked-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nf_tables_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 9e20fb759cb8..54c43f1cceac 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -2823,7 +2823,7 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx, static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule) { - lockdep_commit_lock_is_held(ctx->net); + WARN_ON_ONCE(!lockdep_commit_lock_is_held(ctx->net)); nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_RELEASE); nf_tables_rule_destroy(ctx, rule); @@ -4173,7 +4173,7 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, struct nft_set_binding *binding, enum nft_trans_phase phase) { - lockdep_commit_lock_is_held(ctx->net); + WARN_ON_ONCE(!lockdep_commit_lock_is_held(ctx->net)); switch (phase) { case NFT_TRANS_PREPARE_ERROR: From 39dd4db60acba07f3553fa8f0f930e452551088a Mon Sep 17 00:00:00 2001 From: Johan Korsnes Date: Sun, 23 Mar 2025 20:11:16 +0100 Subject: [PATCH 094/404] arch: powerpc: defconfig: Drop obsolete CONFIG_NET_CLS_TCINDEX [ Upstream commit 75cd37c5f28b85979fd5a65174013010f6b78f27 ] This option was removed from the Kconfig in commit 8c710f75256b ("net/sched: Retire tcindex classifier") but it was not removed from the defconfigs. Fixes: 8c710f75256b ("net/sched: Retire tcindex classifier") Signed-off-by: Johan Korsnes Reviewed-by: Christophe Leroy Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20250323191116.113482-1-johan.korsnes@gmail.com Signed-off-by: Sasha Levin --- arch/powerpc/configs/ppc6xx_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index b75b62b094b5..319fe81a4a39 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -274,7 +274,6 @@ CONFIG_NET_SCH_DSMARK=m CONFIG_NET_SCH_NETEM=m CONFIG_NET_SCH_INGRESS=m CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_TCINDEX=m CONFIG_NET_CLS_ROUTE4=m CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m From ad340a4b4adb855b18b3666f26ad65c8968e2deb Mon Sep 17 00:00:00 2001 From: William Liu Date: Tue, 8 Jul 2025 16:43:26 +0000 Subject: [PATCH 095/404] net/sched: Restrict conditions for adding duplicating netems to qdisc tree [ Upstream commit ec8e0e3d7adef940cdf9475e2352c0680189d14e ] netem_enqueue's duplication prevention logic breaks when a netem resides in a qdisc tree with other netems - this can lead to a soft lockup and OOM loop in netem_dequeue, as seen in [1]. Ensure that a duplicating netem cannot exist in a tree with other netems. Previous approaches suggested in discussions in chronological order: 1) Track duplication status or ttl in the sk_buff struct. Considered too specific a use case to extend such a struct, though this would be a resilient fix and address other previous and potential future DOS bugs like the one described in loopy fun [2]. 2) Restrict netem_enqueue recursion depth like in act_mirred with a per cpu variable. However, netem_dequeue can call enqueue on its child, and the depth restriction could be bypassed if the child is a netem. 3) Use the same approach as in 2, but add metadata in netem_skb_cb to handle the netem_dequeue case and track a packet's involvement in duplication. This is an overly complex approach, and Jamal notes that the skb cb can be overwritten to circumvent this safeguard. 4) Prevent the addition of a netem to a qdisc tree if its ancestral path contains a netem. However, filters and actions can cause a packet to change paths when re-enqueued to the root from netem duplication, leading us to the current solution: prevent a duplicating netem from inhabiting the same tree as other netems. [1] https://lore.kernel.org/netdev/8DuRWwfqjoRDLDmBMlIfbrsZg9Gx50DHJc1ilxsEBNe2D6NMoigR_eIRIG0LOjMc3r10nUUZtArXx4oZBIdUfZQrwjcQhdinnMis_0G7VEk=@willsroot.io/ [2] https://lwn.net/Articles/719297/ Fixes: 0afb51e72855 ("[PKT_SCHED]: netem: reinsert for duplication") Reported-by: William Liu Reported-by: Savino Dicanosa Signed-off-by: William Liu Signed-off-by: Savino Dicanosa Acked-by: Jamal Hadi Salim Link: https://patch.msgid.link/20250708164141.875402-1-will@willsroot.io Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_netem.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 27bd18c74e85..cdf2df194d24 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -962,6 +962,41 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla, return 0; } +static const struct Qdisc_class_ops netem_class_ops; + +static int check_netem_in_tree(struct Qdisc *sch, bool duplicates, + struct netlink_ext_ack *extack) +{ + struct Qdisc *root, *q; + unsigned int i; + + root = qdisc_root_sleeping(sch); + + if (sch != root && root->ops->cl_ops == &netem_class_ops) { + if (duplicates || + ((struct netem_sched_data *)qdisc_priv(root))->duplicate) + goto err; + } + + if (!qdisc_dev(root)) + return 0; + + hash_for_each(qdisc_dev(root)->qdisc_hash, i, q, hash) { + if (sch != q && q->ops->cl_ops == &netem_class_ops) { + if (duplicates || + ((struct netem_sched_data *)qdisc_priv(q))->duplicate) + goto err; + } + } + + return 0; + +err: + NL_SET_ERR_MSG(extack, + "netem: cannot mix duplicating netems with other netems in tree"); + return -EINVAL; +} + /* Parse netlink message to set options */ static int netem_change(struct Qdisc *sch, struct nlattr *opt, struct netlink_ext_ack *extack) @@ -1023,6 +1058,11 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt, q->gap = qopt->gap; q->counter = 0; q->loss = qopt->loss; + + ret = check_netem_in_tree(sch, qopt->duplicate, extack); + if (ret) + goto unlock; + q->duplicate = qopt->duplicate; /* for compatibility with earlier versions. From 5111d4d2863f4bea8bc21b8f6cb510c4428a51ce Mon Sep 17 00:00:00 2001 From: Martin Kaistra Date: Wed, 9 Jul 2025 14:15:22 +0200 Subject: [PATCH 096/404] wifi: rtl8xxxu: Fix RX skb size for aggregation disabled [ Upstream commit d76a1abcf57734d2bcd4a7ec051617edd4513d7f ] Commit 1e5b3b3fe9e0 ("rtl8xxxu: Adjust RX skb size to include space for phystats") increased the skb size when aggregation is enabled but decreased it for the aggregation disabled case. As a result, if a frame near the maximum size is received, rtl8xxxu_rx_complete() is called with status -EOVERFLOW and then the driver starts to malfunction and no further communication is possible. Restore the skb size in the aggregation disabled case. Fixes: 1e5b3b3fe9e0 ("rtl8xxxu: Adjust RX skb size to include space for phystats") Signed-off-by: Martin Kaistra Reviewed-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250709121522.1992366-1-martin.kaistra@linutronix.de Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 5611f00ef0bd..81d1c544313f 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -5387,7 +5387,7 @@ static int rtl8xxxu_submit_rx_urb(struct rtl8xxxu_priv *priv, skb_size = fops->rx_agg_buf_size; skb_size += (rx_desc_sz + sizeof(struct rtl8723au_phy_stats)); } else { - skb_size = IEEE80211_MAX_FRAME_LEN; + skb_size = IEEE80211_MAX_FRAME_LEN + rx_desc_sz; } skb = __netdev_alloc_skb(NULL, skb_size, GFP_KERNEL); From 92c6f0d47693c7605a236d00e897abb71b45fff4 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Wed, 9 Jul 2025 13:13:34 +0200 Subject: [PATCH 097/404] mwl8k: Add missing check after DMA map [ Upstream commit 50459501b9a212dbe7a673727589ee105a8a9954 ] The DMA map functions can fail and should be tested for errors. If the mapping fails, unmap and return an error. Fixes: 788838ebe8a4 ("mwl8k: use pci_unmap_addr{,set}() to keep track of unmap addresses on rx") Signed-off-by: Thomas Fourier Link: https://patch.msgid.link/20250709111339.25360-2-fourier.thomas@gmail.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- drivers/net/wireless/marvell/mwl8k.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/marvell/mwl8k.c b/drivers/net/wireless/marvell/mwl8k.c index abd5c8670bc4..a0c15af1b167 100644 --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c @@ -1220,6 +1220,10 @@ static int rxq_refill(struct ieee80211_hw *hw, int index, int limit) addr = pci_map_single(priv->pdev, skb->data, MWL8K_RX_MAXSZ, DMA_FROM_DEVICE); + if (dma_mapping_error(&priv->pdev->dev, addr)) { + kfree_skb(skb); + break; + } rxq->rxd_count++; rx = rxq->tail++; From ed0b809ff9a5684b70c804c9e1e9af5ccbec9a43 Mon Sep 17 00:00:00 2001 From: Remi Pommarel Date: Thu, 17 Jul 2025 17:45:29 +0200 Subject: [PATCH 098/404] Reapply "wifi: mac80211: Update skb's control block key in ieee80211_tx_dequeue()" [ Upstream commit 754fe848b3b297fc85ec24cd959bad22b6df8cb8 ] This reverts commit 0937cb5f345c ("Revert "wifi: mac80211: Update skb's control block key in ieee80211_tx_dequeue()""). This commit broke TX with 802.11 encapsulation HW offloading, now that this is fixed, reapply it. Fixes: bb42f2d13ffc ("mac80211: Move reorder-sensitive TX handlers to after TXQ dequeue") Signed-off-by: Remi Pommarel Link: https://patch.msgid.link/66b8fc39fb0194fa06c9ca7eeb6ffe0118dcb3ec.1752765971.git.repk@triplefau.lt Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- net/mac80211/tx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 461cff7b94ad..f8d72f3e4def 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3661,6 +3661,7 @@ begin: * The key can be removed while the packet was queued, so need to call * this here to get the current key. */ + info->control.hw_key = NULL; r = ieee80211_tx_h_select_key(&tx); if (r != TX_CONTINUE) { ieee80211_free_txskb(&local->hw, skb); From 37272a327bd99bd33d50d892acb97b678b3df1cf Mon Sep 17 00:00:00 2001 From: Gokul Sivakumar Date: Thu, 26 Jun 2025 10:37:02 +0530 Subject: [PATCH 099/404] wifi: brcmfmac: fix P2P discovery failure in P2P peer due to missing P2P IE [ Upstream commit 579bf8037b70b644a674c126a32bbb2212cf5c21 ] After commit bd99a3013bdc ("brcmfmac: move configuration of probe request IEs"), the probe request MGMT IE addition operation brcmf_vif_set_mgmt_ie() got moved from the brcmf_p2p_scan_prep() to the brcmf_cfg80211_scan(). Because of this, as part of the scan request handler for the P2P Discovery, vif struct used for adding the Probe Request P2P IE in firmware got changed from the P2PAPI_BSSCFG_DEVICE vif to P2PAPI_BSSCFG_PRIMARY vif incorrectly. So the firmware stopped adding P2P IE to the outgoing P2P Discovery probe requests frames and the other P2P peers were unable to discover this device causing a regression on the P2P feature. To fix this, while setting the P2P IE in firmware, properly use the vif of the P2P discovery wdev on which the driver received the P2P scan request. This is done by not changing the vif pointer, until brcmf_vif_set_mgmt_ie() is completed. Fixes: bd99a3013bdc ("brcmfmac: move configuration of probe request IEs") Signed-off-by: Gokul Sivakumar Acked-by: Arend van Spriel Link: https://patch.msgid.link/20250626050706.7271-1-gokulkumar.sivakumar@infineon.com Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 668c8897c109..f9508d71fc6c 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -1118,10 +1118,6 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) return -EAGAIN; } - /* If scan req comes for p2p0, send it over primary I/F */ - if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) - vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; - brcmf_dbg(SCAN, "START ESCAN\n"); cfg->scan_request = request; @@ -1137,6 +1133,10 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) if (err) goto scan_out; + /* If scan req comes for p2p0, send it over primary I/F */ + if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) + vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; + err = brcmf_do_escan(vif->ifp, request); if (err) goto scan_out; From 0fa86e3c919ed55c3a8fa2ccb4cebac188a5da7f Mon Sep 17 00:00:00 2001 From: Jimmy Assarsson Date: Fri, 25 Jul 2025 14:32:25 +0200 Subject: [PATCH 100/404] can: kvaser_pciefd: Store device channel index [ Upstream commit d54b16b40ddadb7d0a77fff48af7b319a0cd6aae ] Store device channel index in netdev.dev_port. Fixes: 26ad340e582d ("can: kvaser_pciefd: Add driver for Kvaser PCIEcan devices") Reviewed-by: Vincent Mailhol Signed-off-by: Jimmy Assarsson Link: https://patch.msgid.link/20250725123230.8-6-extja@kvaser.com Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin --- drivers/net/can/kvaser_pciefd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c index 560a0a5ba6f3..f269b5faa03a 100644 --- a/drivers/net/can/kvaser_pciefd.c +++ b/drivers/net/can/kvaser_pciefd.c @@ -953,6 +953,7 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie) can->err_rep_cnt = 0; can->bec.txerr = 0; can->bec.rxerr = 0; + can->can.dev->dev_port = i; init_completion(&can->start_comp); init_completion(&can->flush_comp); From caf0f743dd64d5ca1a213f31f7766d32b5f23f2e Mon Sep 17 00:00:00 2001 From: Jimmy Assarsson Date: Fri, 25 Jul 2025 14:34:44 +0200 Subject: [PATCH 101/404] can: kvaser_usb: Assign netdev.dev_port based on device channel index [ Upstream commit c151b06a087a61c7a1790b75ee2f1d6edb6a8a45 ] Assign netdev.dev_port based on the device channel index, to indicate the port number of the network device. While this driver already uses netdev.dev_id for that purpose, dev_port is more appropriate. However, retain dev_id to avoid potential regressions. Fixes: 3e66d0138c05 ("can: populate netdev::dev_id for udev discrimination") Reviewed-by: Vincent Mailhol Signed-off-by: Jimmy Assarsson Link: https://patch.msgid.link/20250725123452.41-4-extja@kvaser.com Signed-off-by: Marc Kleine-Budde Signed-off-by: Sasha Levin --- drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index a96b22398407..602f0b3bbcdf 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -813,6 +813,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) SET_NETDEV_DEV(netdev, &dev->intf->dev); netdev->dev_id = channel; + netdev->dev_port = channel; dev->nets[channel] = priv; From 66d41268ede1e1b6e71ba28be923397ff0b2b9c3 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 18 Jul 2025 13:27:13 +0200 Subject: [PATCH 102/404] netfilter: xt_nfacct: don't assume acct name is null-terminated [ Upstream commit bf58e667af7d96c8eb9411f926a0a0955f41ce21 ] BUG: KASAN: slab-out-of-bounds in .. lib/vsprintf.c:721 Read of size 1 at addr ffff88801eac95c8 by task syz-executor183/5851 [..] string+0x231/0x2b0 lib/vsprintf.c:721 vsnprintf+0x739/0xf00 lib/vsprintf.c:2874 [..] nfacct_mt_checkentry+0xd2/0xe0 net/netfilter/xt_nfacct.c:41 xt_check_match+0x3d1/0xab0 net/netfilter/x_tables.c:523 nfnl_acct_find_get() handles non-null input, but the error printk relied on its presence. Reported-by: syzbot+4ff165b9251e4d295690@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=4ff165b9251e4d295690 Tested-by: syzbot+4ff165b9251e4d295690@syzkaller.appspotmail.com Fixes: ceb98d03eac5 ("netfilter: xtables: add nfacct match to support extended accounting") Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/xt_nfacct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/xt_nfacct.c b/net/netfilter/xt_nfacct.c index 5aab6df74e0f..68b07476f754 100644 --- a/net/netfilter/xt_nfacct.c +++ b/net/netfilter/xt_nfacct.c @@ -38,8 +38,8 @@ nfacct_mt_checkentry(const struct xt_mtchk_param *par) nfacct = nfnl_acct_find_get(par->net, info->name); if (nfacct == NULL) { - pr_info_ratelimited("accounting object `%s' does not exists\n", - info->name); + pr_info_ratelimited("accounting object `%.*s' does not exist\n", + NFACCT_NAME_MAX, info->name); return -ENOENT; } info->nfacct = nfacct; From 0577db57455b67198d584f97b5d764a4b764435c Mon Sep 17 00:00:00 2001 From: Xiumei Mu Date: Fri, 25 Jul 2025 11:50:28 +0800 Subject: [PATCH 103/404] selftests: rtnetlink.sh: remove esp4_offload after test [ Upstream commit 5b32321fdaf3fd1a92ec726af18765e225b0ee2b ] The esp4_offload module, loaded during IPsec offload tests, should be reset to its default settings after testing. Otherwise, leaving it enabled could unintentionally affect subsequence test cases by keeping offload active. Without this fix: $ lsmod | grep offload; ./rtnetlink.sh -t kci_test_ipsec_offload ; lsmod | grep offload; PASS: ipsec_offload esp4_offload 12288 0 esp4 32768 1 esp4_offload With this fix: $ lsmod | grep offload; ./rtnetlink.sh -t kci_test_ipsec_offload ; lsmod | grep offload; PASS: ipsec_offload Fixes: 2766a11161cc ("selftests: rtnetlink: add ipsec offload API test") Signed-off-by: Xiumei Mu Reviewed-by: Shannon Nelson Reviewed-by: Hangbin Liu Link: https://patch.msgid.link/6d3a1d777c4de4eb0ca94ced9e77be8d48c5b12f.1753415428.git.xmu@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- tools/testing/selftests/net/rtnetlink.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh index 3b929e031f59..0c343954a17b 100755 --- a/tools/testing/selftests/net/rtnetlink.sh +++ b/tools/testing/selftests/net/rtnetlink.sh @@ -744,6 +744,11 @@ kci_test_ipsec_offload() sysfsf=$sysfsd/ipsec sysfsnet=/sys/bus/netdevsim/devices/netdevsim0/net/ probed=false + esp4_offload_probed_default=false + + if lsmod | grep -q esp4_offload; then + esp4_offload_probed_default=true + fi # setup netdevsim since dummydev doesn't have offload support if [ ! -w /sys/bus/netdevsim/new_device ] ; then @@ -833,6 +838,7 @@ EOF fi # clean up any leftovers + ! "$esp4_offload_probed_default" && lsmod | grep -q esp4_offload && rmmod esp4_offload echo 0 > /sys/bus/netdevsim/del_device $probed && rmmod netdevsim From 423778c85b89db43cbdb318912731aac626a241c Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Fri, 25 Jul 2025 09:00:43 -0700 Subject: [PATCH 104/404] vrf: Drop existing dst reference in vrf_ip6_input_dst [ Upstream commit f388f807eca1de9e6e70f9ffb1a573c3811c4215 ] Commit ff3fbcdd4724 ("selftests: tc: Add generic erspan_opts matching support for tc-flower") started triggering the following kmemleak warning: unreferenced object 0xffff888015fb0e00 (size 512): comm "softirq", pid 0, jiffies 4294679065 hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 40 d2 85 9e ff ff ff ff ........@....... 41 69 59 9d ff ff ff ff 00 00 00 00 00 00 00 00 AiY............. backtrace (crc 30b71e8b): __kmalloc_noprof+0x359/0x460 metadata_dst_alloc+0x28/0x490 erspan_rcv+0x4f1/0x1160 [ip_gre] gre_rcv+0x217/0x240 [ip_gre] gre_rcv+0x1b8/0x400 [gre] ip_protocol_deliver_rcu+0x31d/0x3a0 ip_local_deliver_finish+0x37d/0x620 ip_local_deliver+0x174/0x460 ip_rcv+0x52b/0x6b0 __netif_receive_skb_one_core+0x149/0x1a0 process_backlog+0x3c8/0x1390 __napi_poll.constprop.0+0xa1/0x390 net_rx_action+0x59b/0xe00 handle_softirqs+0x22b/0x630 do_softirq+0xb1/0xf0 __local_bh_enable_ip+0x115/0x150 vrf_ip6_input_dst unconditionally sets skb dst entry, add a call to skb_dst_drop to drop any existing entry. Cc: David Ahern Reviewed-by: Ido Schimmel Fixes: 9ff74384600a ("net: vrf: Handle ipv6 multicast and link-local addresses") Signed-off-by: Stanislav Fomichev Link: https://patch.msgid.link/20250725160043.350725-1-sdf@fomichev.me Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/vrf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index b51a2367dbaa..8a320300a617 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -1040,6 +1040,8 @@ static void vrf_ip6_input_dst(struct sk_buff *skb, struct net_device *vrf_dev, struct net *net = dev_net(vrf_dev); struct rt6_info *rt6; + skb_dst_drop(skb); + rt6 = vrf_ip6_route_lookup(net, vrf_dev, &fl6, ifindex, skb, RT6_LOOKUP_F_HAS_SADDR | RT6_LOOKUP_F_IFACE); if (unlikely(!rt6)) From 816a2c1977af3a336c906eab8a7a5a0ab492e701 Mon Sep 17 00:00:00 2001 From: Hans Zhang <18255117159@163.com> Date: Sun, 8 Jun 2025 00:01:59 +0800 Subject: [PATCH 105/404] PCI: rockchip-host: Fix "Unexpected Completion" log message [ Upstream commit fcc5f586c4edbcc10de23fb9b8c0972a84e945cd ] Fix the debug message for the PCIE_CORE_INT_UCR interrupt to clearly indicate "Unexpected Completion" instead of a duplicate "malformed TLP" message. Fixes: e77f847df54c ("PCI: rockchip: Add Rockchip PCIe controller support") Signed-off-by: Hans Zhang <18255117159@163.com> [mani: added fixes tag] Signed-off-by: Manivannan Sadhasivam Reviewed-by: Manivannan Sadhasivam Acked-by: Shawn Lin Link: https://patch.msgid.link/20250607160201.807043-2-18255117159@163.com Signed-off-by: Sasha Levin --- drivers/pci/controller/pcie-rockchip-host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c index ef8e677ce9d1..281ddde9d8cc 100644 --- a/drivers/pci/controller/pcie-rockchip-host.c +++ b/drivers/pci/controller/pcie-rockchip-host.c @@ -445,7 +445,7 @@ static irqreturn_t rockchip_pcie_subsys_irq_handler(int irq, void *arg) dev_dbg(dev, "malformed TLP received from the link\n"); if (sub_reg & PCIE_CORE_INT_UCR) - dev_dbg(dev, "malformed TLP received from the link\n"); + dev_dbg(dev, "Unexpected Completion received from the link\n"); if (sub_reg & PCIE_CORE_INT_FCE) dev_dbg(dev, "an error was observed in the flow control advertisements from the other side\n"); From b890f3d8d1759d94d78ce352ebc585927a9328c3 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 22 May 2025 20:41:28 +0800 Subject: [PATCH 106/404] crypto: marvell/cesa - Fix engine load inaccuracy [ Upstream commit 442134ab30e75b7229c4bfc1ac5641d245cffe27 ] If an error occurs during queueing the engine load will never be decremented. Fix this by moving the engine load adjustment into the cleanup function. Fixes: bf8f91e71192 ("crypto: marvell - Add load balancing between engines") Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/marvell/cipher.c | 4 +++- drivers/crypto/marvell/hash.c | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/marvell/cipher.c b/drivers/crypto/marvell/cipher.c index f92f86c94bff..d48034a9e0da 100644 --- a/drivers/crypto/marvell/cipher.c +++ b/drivers/crypto/marvell/cipher.c @@ -73,9 +73,12 @@ mv_cesa_skcipher_dma_cleanup(struct skcipher_request *req) static inline void mv_cesa_skcipher_cleanup(struct skcipher_request *req) { struct mv_cesa_skcipher_req *creq = skcipher_request_ctx(req); + struct mv_cesa_engine *engine = creq->base.engine; if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ) mv_cesa_skcipher_dma_cleanup(req); + + atomic_sub(req->cryptlen, &engine->load); } static void mv_cesa_skcipher_std_step(struct skcipher_request *req) @@ -202,7 +205,6 @@ mv_cesa_skcipher_complete(struct crypto_async_request *req) struct mv_cesa_engine *engine = creq->base.engine; unsigned int ivsize; - atomic_sub(skreq->cryptlen, &engine->load); ivsize = crypto_skcipher_ivsize(crypto_skcipher_reqtfm(skreq)); if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ) { diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c index de1599bca3b7..01dd597b6a2a 100644 --- a/drivers/crypto/marvell/hash.c +++ b/drivers/crypto/marvell/hash.c @@ -107,9 +107,12 @@ static inline void mv_cesa_ahash_dma_cleanup(struct ahash_request *req) static inline void mv_cesa_ahash_cleanup(struct ahash_request *req) { struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); + struct mv_cesa_engine *engine = creq->base.engine; if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ) mv_cesa_ahash_dma_cleanup(req); + + atomic_sub(req->nbytes, &engine->load); } static void mv_cesa_ahash_last_cleanup(struct ahash_request *req) @@ -363,8 +366,6 @@ static void mv_cesa_ahash_complete(struct crypto_async_request *req) } } } - - atomic_sub(ahashreq->nbytes, &engine->load); } static void mv_cesa_ahash_prepare(struct crypto_async_request *req, From a0d2de5561f48ee5d714a46e1c2a8c6a13926c0a Mon Sep 17 00:00:00 2001 From: Ivan Stepchenko Date: Thu, 19 Jun 2025 17:53:13 +0300 Subject: [PATCH 107/404] mtd: fix possible integer overflow in erase_xfer() [ Upstream commit 9358bdb9f9f54d94ceafc650deffefd737d19fdd ] The expression '1 << EraseUnitSize' is evaluated in int, which causes a negative result when shifting by 31 - the upper bound of the valid range [10, 31], enforced by scan_header(). This leads to incorrect extension when storing the result in 'erase->len' (uint64_t), producing a large unexpected value. Found by Linux Verification Center (linuxtesting.org) with Svace. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Ivan Stepchenko Signed-off-by: Miquel Raynal Signed-off-by: Sasha Levin --- drivers/mtd/ftl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index 2578f27914ef..ffe89209cf4b 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -344,7 +344,7 @@ static int erase_xfer(partition_t *part, return -ENOMEM; erase->addr = xfer->Offset; - erase->len = 1 << part->header.EraseUnitSize; + erase->len = 1ULL << part->header.EraseUnitSize; ret = mtd_erase(part->mbd.mtd, erase); if (!ret) { From 77e9ad7a2d0e2a771c9e0be04b9d1639413b5f13 Mon Sep 17 00:00:00 2001 From: Henry Martin Date: Tue, 1 Apr 2025 21:13:41 +0800 Subject: [PATCH 108/404] clk: davinci: Add NULL check in davinci_lpsc_clk_register() [ Upstream commit 13de464f445d42738fe18c9a28bab056ba3a290a ] devm_kasprintf() returns NULL when memory allocation fails. Currently, davinci_lpsc_clk_register() does not check for this case, which results in a NULL pointer dereference. Add NULL check after devm_kasprintf() to prevent this issue and ensuring no resources are left allocated. Fixes: c6ed4d734bc7 ("clk: davinci: New driver for davinci PSC clocks") Signed-off-by: Henry Martin Link: https://lore.kernel.org/r/20250401131341.26800-1-bsdhenrymartin@gmail.com Reviewed-by: David Lechner Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/davinci/psc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c index 5b69e24a224f..2e153320fc53 100644 --- a/drivers/clk/davinci/psc.c +++ b/drivers/clk/davinci/psc.c @@ -278,6 +278,11 @@ davinci_lpsc_clk_register(struct device *dev, const char *name, lpsc->pm_domain.name = devm_kasprintf(dev, GFP_KERNEL, "%s: %s", best_dev_name(dev), name); + if (!lpsc->pm_domain.name) { + clk_hw_unregister(&lpsc->hw); + kfree(lpsc); + return ERR_PTR(-ENOMEM); + } lpsc->pm_domain.attach_dev = davinci_psc_genpd_attach_dev; lpsc->pm_domain.detach_dev = davinci_psc_genpd_detach_dev; lpsc->pm_domain.flags = GENPD_FLAG_PM_CLK; From 05b5621bec74c99a02dad70ffb89106858f386ea Mon Sep 17 00:00:00 2001 From: Charles Han Date: Mon, 19 May 2025 14:16:01 +0800 Subject: [PATCH 109/404] power: supply: max14577: Handle NULL pdata when CONFIG_OF is not set [ Upstream commit 2937f5d2e24eefef8cb126244caec7fe3307f724 ] When the kernel is not configured CONFIG_OF, the max14577_charger_dt_init function returns NULL. Fix the max14577_charger_probe functionby returning -ENODATA instead of potentially passing a NULL pointer to PTR_ERR. This fixes the below smatch warning: max14577_charger_probe() warn: passing zero to 'PTR_ERR' Fixes: e30110e9c96f ("charger: max14577: Configure battery-dependent settings from DTS and sysfs") Signed-off-by: Charles Han Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250519061601.8755-1-hanchunchao@inspur.com Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/supply/max14577_charger.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/power/supply/max14577_charger.c b/drivers/power/supply/max14577_charger.c index 8a59feac6468..90b97736ac2a 100644 --- a/drivers/power/supply/max14577_charger.c +++ b/drivers/power/supply/max14577_charger.c @@ -501,7 +501,7 @@ static struct max14577_charger_platform_data *max14577_charger_dt_init( static struct max14577_charger_platform_data *max14577_charger_dt_init( struct platform_device *pdev) { - return NULL; + return ERR_PTR(-ENODATA); } #endif /* CONFIG_OF */ @@ -572,7 +572,7 @@ static int max14577_charger_probe(struct platform_device *pdev) chg->max14577 = max14577; chg->pdata = max14577_charger_dt_init(pdev); - if (IS_ERR_OR_NULL(chg->pdata)) + if (IS_ERR(chg->pdata)) return PTR_ERR(chg->pdata); ret = max14577_charger_reg_init(chg); From abe9813d60e12b79a3ef20b14dd1f95bce6b9241 Mon Sep 17 00:00:00 2001 From: Yuan Chen Date: Fri, 20 Jun 2025 09:27:08 +0800 Subject: [PATCH 110/404] pinctrl: sunxi: Fix memory leak on krealloc failure [ Upstream commit e3507c56cbb208d4f160942748c527ef6a528ba1 ] In sunxi_pctrl_dt_node_to_map(), when krealloc() fails to resize the pinctrl_map array, the function returns -ENOMEM directly without freeing the previously allocated *map buffer. This results in a memory leak of the original kmalloc_array allocation. Fixes: e11dee2e98f8 ("pinctrl: sunxi: Deal with configless pins") Signed-off-by: Yuan Chen Link: https://lore.kernel.org/20250620012708.16709-1-chenyuan_fl@163.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 8c41f8b818b2..83775dd12cfa 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -327,6 +327,7 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, const char *function, *pin_prop; const char *group; int ret, npins, nmaps, configlen = 0, i = 0; + struct pinctrl_map *new_map; *map = NULL; *num_maps = 0; @@ -401,9 +402,13 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, * We know have the number of maps we need, we can resize our * map array */ - *map = krealloc(*map, i * sizeof(struct pinctrl_map), GFP_KERNEL); - if (!*map) - return -ENOMEM; + new_map = krealloc(*map, i * sizeof(struct pinctrl_map), GFP_KERNEL); + if (!new_map) { + ret = -ENOMEM; + goto err_free_map; + } + + *map = new_map; return 0; From a25ab6dfa0ce323ec308966988be6b675eb9d3e5 Mon Sep 17 00:00:00 2001 From: Mengbiao Xiong Date: Tue, 24 Jun 2025 14:54:18 +0800 Subject: [PATCH 111/404] crypto: ccp - Fix crash when rebind ccp device for ccp.ko [ Upstream commit 181698af38d3f93381229ad89c09b5bd0496661a ] When CONFIG_CRYPTO_DEV_CCP_DEBUGFS is enabled, rebinding the ccp device causes the following crash: $ echo '0000:0a:00.2' > /sys/bus/pci/drivers/ccp/unbind $ echo '0000:0a:00.2' > /sys/bus/pci/drivers/ccp/bind [ 204.976930] BUG: kernel NULL pointer dereference, address: 0000000000000098 [ 204.978026] #PF: supervisor write access in kernel mode [ 204.979126] #PF: error_code(0x0002) - not-present page [ 204.980226] PGD 0 P4D 0 [ 204.981317] Oops: Oops: 0002 [#1] SMP NOPTI ... [ 204.997852] Call Trace: [ 204.999074] [ 205.000297] start_creating+0x9f/0x1c0 [ 205.001533] debugfs_create_dir+0x1f/0x170 [ 205.002769] ? srso_return_thunk+0x5/0x5f [ 205.004000] ccp5_debugfs_setup+0x87/0x170 [ccp] [ 205.005241] ccp5_init+0x8b2/0x960 [ccp] [ 205.006469] ccp_dev_init+0xd4/0x150 [ccp] [ 205.007709] sp_init+0x5f/0x80 [ccp] [ 205.008942] sp_pci_probe+0x283/0x2e0 [ccp] [ 205.010165] ? srso_return_thunk+0x5/0x5f [ 205.011376] local_pci_probe+0x4f/0xb0 [ 205.012584] pci_device_probe+0xdb/0x230 [ 205.013810] really_probe+0xed/0x380 [ 205.015024] __driver_probe_device+0x7e/0x160 [ 205.016240] device_driver_attach+0x2f/0x60 [ 205.017457] bind_store+0x7c/0xb0 [ 205.018663] drv_attr_store+0x28/0x40 [ 205.019868] sysfs_kf_write+0x5f/0x70 [ 205.021065] kernfs_fop_write_iter+0x145/0x1d0 [ 205.022267] vfs_write+0x308/0x440 [ 205.023453] ksys_write+0x6d/0xe0 [ 205.024616] __x64_sys_write+0x1e/0x30 [ 205.025778] x64_sys_call+0x16ba/0x2150 [ 205.026942] do_syscall_64+0x56/0x1e0 [ 205.028108] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 205.029276] RIP: 0033:0x7fbc36f10104 [ 205.030420] Code: 89 02 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 8d 05 e1 08 2e 00 8b 00 85 c0 75 13 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 f3 c3 66 90 41 54 55 49 89 d4 53 48 89 f5 This patch sets ccp_debugfs_dir to NULL after destroying it in ccp5_debugfs_destroy, allowing the directory dentry to be recreated when rebinding the ccp device. Tested on AMD Ryzen 7 1700X. Fixes: 3cdbe346ed3f ("crypto: ccp - Add debugfs entries for CCP information") Signed-off-by: Mengbiao Xiong Reviewed-by: Tom Lendacky Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/ccp/ccp-debugfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/crypto/ccp/ccp-debugfs.c b/drivers/crypto/ccp/ccp-debugfs.c index a1055554b47a..dc26bc22c91d 100644 --- a/drivers/crypto/ccp/ccp-debugfs.c +++ b/drivers/crypto/ccp/ccp-debugfs.c @@ -319,5 +319,8 @@ void ccp5_debugfs_setup(struct ccp_device *ccp) void ccp5_debugfs_destroy(void) { + mutex_lock(&ccp_debugfs_lock); debugfs_remove_recursive(ccp_debugfs_dir); + ccp_debugfs_dir = NULL; + mutex_unlock(&ccp_debugfs_lock); } From e6841818e2761fc4af41dc0aff8da2ee0e58b181 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Fri, 11 Jul 2025 12:10:15 +0100 Subject: [PATCH 112/404] perf tests bp_account: Fix leaked file descriptor [ Upstream commit 4a6cdecaa1497f1fbbd1d5307a225b6ca5a62a90 ] Since the commit e9846f5ead26 ("perf test: In forked mode add check that fds aren't leaked"), the test "Breakpoint accounting" reports the error: # perf test -vvv "Breakpoint accounting" 20: Breakpoint accounting: --- start --- test child forked, pid 373 failed opening event 0 failed opening event 0 watchpoints count 4, breakpoints count 6, has_ioctl 1, share 0 wp 0 created wp 1 created wp 2 created wp 3 created wp 0 modified to bp wp max created ---- end(0) ---- Leak of file descriptor 7 that opened: 'anon_inode:[perf_event]' A watchpoint's file descriptor was not properly released. This patch fixes the leak. Fixes: 032db28e5fa3 ("perf tests: Add breakpoint accounting/modify test") Reported-by: Aishwarya TCV Signed-off-by: Leo Yan Reviewed-by: Ian Rogers Link: https://lore.kernel.org/r/20250711-perf_fix_breakpoint_accounting-v1-1-b314393023f9@arm.com Signed-off-by: Namhyung Kim Signed-off-by: Sasha Levin --- tools/perf/tests/bp_account.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/tests/bp_account.c b/tools/perf/tests/bp_account.c index 55a9de311d7b..e1ff0faa0149 100644 --- a/tools/perf/tests/bp_account.c +++ b/tools/perf/tests/bp_account.c @@ -93,6 +93,7 @@ static int bp_accounting(int wp_cnt, int share) fd_wp = wp_event((void *)&the_var, &attr_new); TEST_ASSERT_VAL("failed to create max wp\n", fd_wp != -1); pr_debug("wp max created\n"); + close(fd_wp); } for (i = 0; i < wp_cnt; i++) From 15700b2380f3a703cf78282a5107d6bb7ea5e396 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Fri, 4 Jul 2025 17:40:07 +0200 Subject: [PATCH 113/404] clk: sunxi-ng: v3s: Fix de clock definition [ Upstream commit e8ab346f9907a1a3aa2f0e5decf849925c06ae2e ] The de clock is marked with CLK_SET_RATE_PARENT, which is really not necessary (as confirmed from experimentation) and significantly restricts flexibility for other clocks using the same parent. In addition the source selection (parent) field is marked as using 2 bits, when it the documentation reports that it uses 3. Fix both issues in the de clock definition. Fixes: d0f11d14b0bc ("clk: sunxi-ng: add support for V3s CCU") Signed-off-by: Paul Kocialkowski Link: https://patch.msgid.link/20250704154008.3463257-1-paulk@sys-base.io Signed-off-by: Chen-Yu Tsai Signed-off-by: Sasha Levin --- drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c index 0e36ca3bf3d5..4fddb489cdce 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c @@ -334,8 +334,7 @@ static SUNXI_CCU_GATE(dram_ohci_clk, "dram-ohci", "dram", static const char * const de_parents[] = { "pll-video", "pll-periph0" }; static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, - 0x104, 0, 4, 24, 2, BIT(31), - CLK_SET_RATE_PARENT); + 0x104, 0, 4, 24, 3, BIT(31), 0); static const char * const tcon_parents[] = { "pll-video" }; static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents, From 0d72595728e77d25aa3ad75df50c39517815cc17 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Mon, 30 Jun 2025 13:18:02 +0200 Subject: [PATCH 114/404] scsi: ibmvscsi_tgt: Fix dma_unmap_sg() nents value [ Upstream commit 023a293b9cd0bb86a9b50cd7688a3d9d266826db ] The dma_unmap_sg() functions should be called with the same nents as the dma_map_sg(), not the value the map function returned. Fixes: 88a678bbc34c ("ibmvscsis: Initial commit of IBM VSCSI Tgt Driver") Signed-off-by: Thomas Fourier Link: https://lore.kernel.org/r/20250630111803.94389-2-fourier.thomas@gmail.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/ibmvscsi_tgt/libsrp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ibmvscsi_tgt/libsrp.c b/drivers/scsi/ibmvscsi_tgt/libsrp.c index 8a0e28aec928..0ecad398ed3d 100644 --- a/drivers/scsi/ibmvscsi_tgt/libsrp.c +++ b/drivers/scsi/ibmvscsi_tgt/libsrp.c @@ -184,7 +184,8 @@ static int srp_direct_data(struct ibmvscsis_cmd *cmd, struct srp_direct_buf *md, err = rdma_io(cmd, sg, nsg, md, 1, dir, len); if (dma_map) - dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL); + dma_unmap_sg(iue->target->dev, sg, cmd->se_cmd.t_data_nents, + DMA_BIDIRECTIONAL); return err; } @@ -256,7 +257,8 @@ rdma: err = rdma_io(cmd, sg, nsg, md, nmd, dir, len); if (dma_map) - dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL); + dma_unmap_sg(iue->target->dev, sg, cmd->se_cmd.t_data_nents, + DMA_BIDIRECTIONAL); free_mem: if (token && dma_map) { From 8d795569b711e718435cb31dc06980da5495b5af Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Fri, 27 Jun 2025 15:48:18 +0200 Subject: [PATCH 115/404] scsi: mvsas: Fix dma_unmap_sg() nents value [ Upstream commit 0141618727bc929fe868153d21797f10ce5bef3f ] The dma_unmap_sg() functions should be called with the same nents as the dma_map_sg(), not the value the map function returned. Fixes: b5762948263d ("[SCSI] mvsas: Add Marvell 6440 SAS/SATA driver") Signed-off-by: Thomas Fourier Link: https://lore.kernel.org/r/20250627134822.234813-2-fourier.thomas@gmail.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/mvsas/mv_sas.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index 3e0b8ebe257f..68caeaf9e636 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -831,7 +831,7 @@ err_out: dev_printk(KERN_ERR, mvi->dev, "mvsas prep failed[%d]!\n", rc); if (!sas_protocol_ata(task->task_proto)) if (n_elem) - dma_unmap_sg(mvi->dev, task->scatter, n_elem, + dma_unmap_sg(mvi->dev, task->scatter, task->num_scatter, task->data_dir); prep_out: return rc; @@ -882,7 +882,7 @@ static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task, if (!sas_protocol_ata(task->task_proto)) if (slot->n_elem) dma_unmap_sg(mvi->dev, task->scatter, - slot->n_elem, task->data_dir); + task->num_scatter, task->data_dir); switch (task->task_proto) { case SAS_PROTOCOL_SMP: From fc293c4a23ff2fa36ea32f740aee91b0a22ccd2e Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Fri, 27 Jun 2025 16:24:47 +0200 Subject: [PATCH 116/404] scsi: isci: Fix dma_unmap_sg() nents value [ Upstream commit 063bec4444d54e5f35d11949c5c90eaa1ff84c11 ] The dma_unmap_sg() functions should be called with the same nents as the dma_map_sg(), not the value the map function returned. Fixes: ddcc7e347a89 ("isci: fix dma_unmap_sg usage") Signed-off-by: Thomas Fourier Link: https://lore.kernel.org/r/20250627142451.241713-2-fourier.thomas@gmail.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/isci/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 591aebb40a0f..2deeddad10e1 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -2914,7 +2914,7 @@ static void isci_request_io_request_complete(struct isci_host *ihost, task->total_xfer_len, task->data_dir); else /* unmap the sgl dma addresses */ dma_unmap_sg(&ihost->pdev->dev, task->scatter, - request->num_sg_entries, task->data_dir); + task->num_scatter, task->data_dir); break; case SAS_PROTOCOL_SMP: { struct scatterlist *sg = &task->smp_task.smp_req; From 61f9762e852f2b8857d2e71716842afc843dba2e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 28 May 2025 23:22:19 +0300 Subject: [PATCH 117/404] watchdog: ziirave_wdt: check record length in ziirave_firm_verify() [ Upstream commit 8b61d8ca751bc15875b50e0ff6ac3ba0cf95a529 ] The "rec->len" value comes from the firmware. We generally do trust firmware, but it's always better to double check. If the length value is too large it would lead to memory corruption when we set "data[i] = ret;" Fixes: 217209db0204 ("watchdog: ziirave_wdt: Add support to upload the firmware.") Signed-off-by: Dan Carpenter Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/3b58b453f0faa8b968c90523f52c11908b56c346.1748463049.git.dan.carpenter@linaro.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Sasha Levin --- drivers/watchdog/ziirave_wdt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/watchdog/ziirave_wdt.c b/drivers/watchdog/ziirave_wdt.c index 4a363a8b2d20..84c98c4c510c 100644 --- a/drivers/watchdog/ziirave_wdt.c +++ b/drivers/watchdog/ziirave_wdt.c @@ -306,6 +306,9 @@ static int ziirave_firm_verify(struct watchdog_device *wdd, const u16 len = be16_to_cpu(rec->len); const u32 addr = be32_to_cpu(rec->addr); + if (len > sizeof(data)) + return -EINVAL; + if (ziirave_firm_addr_readonly(addr)) continue; From 9a7c00f39b0244548c7c14572568485d094059a6 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Sun, 29 Jun 2025 20:31:41 +0300 Subject: [PATCH 118/404] hwrng: mtk - handle devm_pm_runtime_enable errors [ Upstream commit 522a242a18adc5c63a24836715dbeec4dc3faee1 ] Although unlikely, devm_pm_runtime_enable() call might fail, so handle the return value. Fixes: 78cb66caa6ab ("hwrng: mtk - Use devm_pm_runtime_enable") Signed-off-by: Ovidiu Panait Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/char/hw_random/mtk-rng.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/char/hw_random/mtk-rng.c b/drivers/char/hw_random/mtk-rng.c index 6c21eb749b51..f5325fe4f1de 100644 --- a/drivers/char/hw_random/mtk-rng.c +++ b/drivers/char/hw_random/mtk-rng.c @@ -149,7 +149,9 @@ static int mtk_rng_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, priv); pm_runtime_set_autosuspend_delay(&pdev->dev, RNG_AUTOSUSPEND_TIMEOUT); pm_runtime_use_autosuspend(&pdev->dev); - devm_pm_runtime_enable(&pdev->dev); + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; dev_info(&pdev->dev, "registered RNG driver\n"); From 84e68a8baa3172ca65282e455a4dc63ee1110203 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Mon, 30 Jun 2025 11:16:22 +0200 Subject: [PATCH 119/404] crypto: img-hash - Fix dma_unmap_sg() nents value [ Upstream commit 34b283636181ce02c52633551f594fec9876bec7 ] The dma_unmap_sg() functions should be called with the same nents as the dma_map_sg(), not the value the map function returned. Fixes: d358f1abbf71 ("crypto: img-hash - Add Imagination Technologies hw hash accelerator") Signed-off-by: Thomas Fourier Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/img-hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/img-hash.c b/drivers/crypto/img-hash.c index 17cc44f14e5c..b5fd15e0c050 100644 --- a/drivers/crypto/img-hash.c +++ b/drivers/crypto/img-hash.c @@ -434,7 +434,7 @@ static int img_hash_write_via_dma_stop(struct img_hash_dev *hdev) struct img_hash_request_ctx *ctx = ahash_request_ctx(hdev->req); if (ctx->flags & DRIVER_FLAGS_SG) - dma_unmap_sg(hdev->dev, ctx->sg, ctx->dma_ct, DMA_TO_DEVICE); + dma_unmap_sg(hdev->dev, ctx->sg, 1, DMA_TO_DEVICE); return 0; } From 397098da12c2e27cc6ca188b9bf858b80d8665a2 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 26 Jun 2025 14:09:52 +0800 Subject: [PATCH 120/404] soundwire: stream: restore params when prepare ports fail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit dba7d9dbfdc4389361ff3a910e767d3cfca22587 ] The bus->params should be restored if the stream is failed to prepare. The issue exists since beginning. The Fixes tag just indicates the first commit that the commit can be applied to. Fixes: 17ed5bef49f4 ("soundwire: add missing newlines in dynamic debug logs") Signed-off-by: Bard Liao Reviewed-by: Péter Ujfalusi Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20250626060952.405996-1-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/soundwire/stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index 3b3f909407c3..6e4c7bf9eb0d 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -1532,7 +1532,7 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream) if (ret < 0) { dev_err(bus->dev, "Prepare port(s) failed ret = %d\n", ret); - return ret; + goto restore_params; } } From 80d0535fdcd38d791b64a36deb90a9af289b88fc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 19 Jul 2025 09:19:10 -0500 Subject: [PATCH 121/404] fs/orangefs: Allow 2 more characters in do_c_string() [ Upstream commit 2138e89cb066b40386b1d9ddd61253347d356474 ] The do_k_string() and do_c_string() functions do essentially the same thing which is they add a string and a comma onto the end of an existing string. At the end, the caller will overwrite the last comma with a newline. Later, in orangefs_kernel_debug_init(), we add a newline to the string. The change to do_k_string() is just cosmetic. I moved the "- 1" to the other side of the comparison and made it "+ 1". This has no effect on runtime, I just wanted the functions to match each other and the rest of the file. However in do_c_string(), I removed the "- 2" which allows us to print two extra characters. I noticed this issue while reviewing the code and I doubt affects anything in real life. My guess is that this was double counting the comma and the newline. The "+ 1" accounts for the newline, and the caller will delete the final comma which ensures there is enough space for the newline. Removing the "- 2" lets us print 2 more characters, but mainly it makes the code more consistent and understandable for reviewers. Fixes: 44f4641073f1 ("orangefs: clean up debugfs globals") Signed-off-by: Dan Carpenter Signed-off-by: Mike Marshall Signed-off-by: Sasha Levin --- fs/orangefs/orangefs-debugfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c index fa41db088488..b57140ebfad0 100644 --- a/fs/orangefs/orangefs-debugfs.c +++ b/fs/orangefs/orangefs-debugfs.c @@ -728,8 +728,8 @@ static void do_k_string(void *k_mask, int index) if (*mask & s_kmod_keyword_mask_map[index].mask_val) { if ((strlen(kernel_debug_string) + - strlen(s_kmod_keyword_mask_map[index].keyword)) - < ORANGEFS_MAX_DEBUG_STRING_LEN - 1) { + strlen(s_kmod_keyword_mask_map[index].keyword) + 1) + < ORANGEFS_MAX_DEBUG_STRING_LEN) { strcat(kernel_debug_string, s_kmod_keyword_mask_map[index].keyword); strcat(kernel_debug_string, ","); @@ -756,7 +756,7 @@ static void do_c_string(void *c_mask, int index) (mask->mask2 & cdm_array[index].mask2)) { if ((strlen(client_debug_string) + strlen(cdm_array[index].keyword) + 1) - < ORANGEFS_MAX_DEBUG_STRING_LEN - 2) { + < ORANGEFS_MAX_DEBUG_STRING_LEN) { strcat(client_debug_string, cdm_array[index].keyword); strcat(client_debug_string, ","); From 5733fa2693e4073e45da4a5d1f3e2a91deed73a2 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Tue, 1 Jul 2025 14:37:52 +0200 Subject: [PATCH 122/404] dmaengine: mv_xor: Fix missing check after DMA map and missing unmap [ Upstream commit 60095aca6b471b7b7a79c80b7395f7e4e414b479 ] The DMA map functions can fail and should be tested for errors. In case of error, unmap the already mapped regions. Fixes: 22843545b200 ("dma: mv_xor: Add support for DMA_INTERRUPT") Signed-off-by: Thomas Fourier Link: https://lore.kernel.org/r/20250701123753.46935-2-fourier.thomas@gmail.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/mv_xor.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index e96032096042..827a1a9907b6 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1061,8 +1061,16 @@ mv_xor_channel_add(struct mv_xor_device *xordev, */ mv_chan->dummy_src_addr = dma_map_single(dma_dev->dev, mv_chan->dummy_src, MV_XOR_MIN_BYTE_COUNT, DMA_FROM_DEVICE); + if (dma_mapping_error(dma_dev->dev, mv_chan->dummy_src_addr)) + return ERR_PTR(-ENOMEM); + mv_chan->dummy_dst_addr = dma_map_single(dma_dev->dev, mv_chan->dummy_dst, MV_XOR_MIN_BYTE_COUNT, DMA_TO_DEVICE); + if (dma_mapping_error(dma_dev->dev, mv_chan->dummy_dst_addr)) { + ret = -ENOMEM; + goto err_unmap_src; + } + /* allocate coherent memory for hardware descriptors * note: writecombine gives slightly better performance, but @@ -1071,8 +1079,10 @@ mv_xor_channel_add(struct mv_xor_device *xordev, mv_chan->dma_desc_pool_virt = dma_alloc_wc(&pdev->dev, MV_XOR_POOL_SIZE, &mv_chan->dma_desc_pool, GFP_KERNEL); - if (!mv_chan->dma_desc_pool_virt) - return ERR_PTR(-ENOMEM); + if (!mv_chan->dma_desc_pool_virt) { + ret = -ENOMEM; + goto err_unmap_dst; + } /* discover transaction capabilites from the platform data */ dma_dev->cap_mask = cap_mask; @@ -1156,6 +1166,13 @@ err_free_irq: err_free_dma: dma_free_coherent(&pdev->dev, MV_XOR_POOL_SIZE, mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool); +err_unmap_dst: + dma_unmap_single(dma_dev->dev, mv_chan->dummy_dst_addr, + MV_XOR_MIN_BYTE_COUNT, DMA_TO_DEVICE); +err_unmap_src: + dma_unmap_single(dma_dev->dev, mv_chan->dummy_src_addr, + MV_XOR_MIN_BYTE_COUNT, DMA_FROM_DEVICE); + return ERR_PTR(ret); } From 91eea098ab87ab6a35fd82b1fe54dad590a1044a Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Mon, 7 Jul 2025 09:57:16 +0200 Subject: [PATCH 123/404] dmaengine: nbpfaxi: Add missing check after DMA map [ Upstream commit c6ee78fc8f3e653bec427cfd06fec7877ee782bd ] The DMA map functions can fail and should be tested for errors. If the mapping fails, unmap and return an error. Fixes: b45b262cefd5 ("dmaengine: add a driver for AMBA AXI NBPF DMAC IP cores") Signed-off-by: Thomas Fourier Link: https://lore.kernel.org/r/20250707075752.28674-2-fourier.thomas@gmail.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/nbpfaxi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c index b9a36a6a3852..0a8b04798b98 100644 --- a/drivers/dma/nbpfaxi.c +++ b/drivers/dma/nbpfaxi.c @@ -705,6 +705,9 @@ static int nbpf_desc_page_alloc(struct nbpf_channel *chan) list_add_tail(&ldesc->node, &lhead); ldesc->hwdesc_dma_addr = dma_map_single(dchan->device->dev, hwdesc, sizeof(*hwdesc), DMA_TO_DEVICE); + if (dma_mapping_error(dchan->device->dev, + ldesc->hwdesc_dma_addr)) + goto unmap_error; dev_dbg(dev, "%s(): mapped 0x%p to %pad\n", __func__, hwdesc, &ldesc->hwdesc_dma_addr); @@ -731,6 +734,16 @@ static int nbpf_desc_page_alloc(struct nbpf_channel *chan) spin_unlock_irq(&chan->lock); return ARRAY_SIZE(dpage->desc); + +unmap_error: + while (i--) { + ldesc--; hwdesc--; + + dma_unmap_single(dchan->device->dev, ldesc->hwdesc_dma_addr, + sizeof(hwdesc), DMA_TO_DEVICE); + } + + return -ENOMEM; } static void nbpf_desc_put(struct nbpf_desc *desc) From e4c864a14a63f85909e695678d0e4491d9dc11de Mon Sep 17 00:00:00 2001 From: Giovanni Cabiddu Date: Mon, 14 Jul 2025 08:10:29 +0100 Subject: [PATCH 124/404] crypto: qat - fix seq_file position update in adf_ring_next() [ Upstream commit 6908c5f4f066a0412c3d9a6f543a09fa7d87824b ] The `adf_ring_next()` function in the QAT debug transport interface fails to correctly update the position index when reaching the end of the ring elements. This triggers the following kernel warning when reading ring files, such as /sys/kernel/debug/qat_c6xx_/transport/bank_00/ring_00: [27725.022965] seq_file: buggy .next function adf_ring_next [intel_qat] did not update position index Ensure that the `*pos` index is incremented before returning NULL when after the last element in the ring is found, satisfying the seq_file API requirements and preventing the warning. Fixes: a672a9dc872e ("crypto: qat - Intel(R) QAT transport code") Signed-off-by: Giovanni Cabiddu Reviewed-by: Ahsan Atta Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- drivers/crypto/qat/qat_common/adf_transport_debug.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/qat/qat_common/adf_transport_debug.c b/drivers/crypto/qat/qat_common/adf_transport_debug.c index e794e9d97b2c..9303d6318207 100644 --- a/drivers/crypto/qat/qat_common/adf_transport_debug.c +++ b/drivers/crypto/qat/qat_common/adf_transport_debug.c @@ -75,8 +75,10 @@ static void *adf_ring_next(struct seq_file *sfile, void *v, loff_t *pos) struct adf_etr_ring_data *ring = sfile->private; if (*pos >= (ADF_SIZE_TO_RING_SIZE_IN_BYTES(ring->ring_size) / - ADF_MSG_SIZE_TO_BYTES(ring->msg_size))) + ADF_MSG_SIZE_TO_BYTES(ring->msg_size))) { + (*pos)++; return NULL; + } return ring->base_addr + (ADF_MSG_SIZE_TO_BYTES(ring->msg_size) * (*pos)++); From 69373502c2b5d364842c702c941d1171e4f35a7c Mon Sep 17 00:00:00 2001 From: Chenyuan Yang Date: Wed, 23 Jul 2025 22:25:34 -0500 Subject: [PATCH 125/404] fbdev: imxfb: Check fb_add_videomode to prevent null-ptr-deref [ Upstream commit da11e6a30e0bb8e911288bdc443b3dc8f6a7cac7 ] fb_add_videomode() can fail with -ENOMEM when its internal kmalloc() cannot allocate a struct fb_modelist. If that happens, the modelist stays empty but the driver continues to register. Add a check for its return value to prevent poteintial null-ptr-deref, which is similar to the commit 17186f1f90d3 ("fbdev: Fix do_register_framebuffer to prevent null-ptr-deref in fb_videomode_to_var"). Fixes: 1b6c79361ba5 ("video: imxfb: Add DT support") Signed-off-by: Chenyuan Yang Signed-off-by: Helge Deller Signed-off-by: Sasha Levin --- drivers/video/fbdev/imxfb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c index dbc8808b093a..8dac15bf2b0c 100644 --- a/drivers/video/fbdev/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -992,8 +992,13 @@ static int imxfb_probe(struct platform_device *pdev) INIT_LIST_HEAD(&info->modelist); - for (i = 0; i < fbi->num_modes; i++) - fb_add_videomode(&fbi->mode[i].mode, &info->modelist); + for (i = 0; i < fbi->num_modes; i++) { + ret = fb_add_videomode(&fbi->mode[i].mode, &info->modelist); + if (ret) { + dev_err(&pdev->dev, "Failed to add videomode\n"); + goto failed_cmap; + } + } /* * This makes sure that our colour bitfield From 9b38fb31c27149cde2d6ec1315d49a29c2e3f2cd Mon Sep 17 00:00:00 2001 From: Zheng Yu Date: Tue, 29 Jul 2025 01:22:14 +0000 Subject: [PATCH 126/404] jfs: fix metapage reference count leak in dbAllocCtl [ Upstream commit 856db37592021e9155384094e331e2d4589f28b1 ] In dbAllocCtl(), read_metapage() increases the reference count of the metapage. However, when dp->tree.budmin < 0, the function returns -EIO without calling release_metapage() to decrease the reference count, leading to a memory leak. Add release_metapage(mp) before the error return to properly manage the metapage reference count and prevent the leak. Fixes: a5f5e4698f8abbb25fe4959814093fb5bfa1aa9d ("jfs: fix shift-out-of-bounds in dbSplit") Signed-off-by: Zheng Yu Signed-off-by: Dave Kleikamp Signed-off-by: Sasha Levin --- fs/jfs/jfs_dmap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 8cffb5dd98cf..15f885d2fa3d 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -1875,8 +1875,10 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results) return -EIO; dp = (struct dmap *) mp->data; - if (dp->tree.budmin < 0) + if (dp->tree.budmin < 0) { + release_metapage(mp); return -EIO; + } /* try to allocate the blocks. */ From 2e1fcf6ee01373b9adae0540b276f278fc26b90d Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Wed, 2 Jul 2025 08:45:11 +0200 Subject: [PATCH 127/404] mtd: rawnand: atmel: Fix dma_mapping_error() address [ Upstream commit e1e6b933c56b1e9fda93caa0b8bae39f3f421e5c ] It seems like what was intended is to test if the dma_map of the previous line failed but the wrong dma address was passed. Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver") Signed-off-by: Thomas Fourier Rule: add Link: https://lore.kernel.org/stable/20250702064515.18145-2-fourier.thomas%40gmail.com Signed-off-by: Miquel Raynal Signed-off-by: Sasha Levin --- drivers/mtd/nand/raw/atmel/nand-controller.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index 997910bec727..a54ad340f1e2 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -370,7 +370,7 @@ static int atmel_nand_dma_transfer(struct atmel_nand_controller *nc, dma_cookie_t cookie; buf_dma = dma_map_single(nc->dev, buf, len, dir); - if (dma_mapping_error(nc->dev, dev_dma)) { + if (dma_mapping_error(nc->dev, buf_dma)) { dev_err(nc->dev, "Failed to prepare a buffer for DMA access\n"); goto err; From 89f46981ef483f3b292e282f93740e5e0a30fdde Mon Sep 17 00:00:00 2001 From: Balamanikandan Gunasundar Date: Mon, 21 Jul 2025 16:13:40 +0530 Subject: [PATCH 128/404] mtd: rawnand: atmel: set pmecc data setup time [ Upstream commit f552a7c7e0a14215cb8a6fd89e60fa3932a74786 ] Setup the pmecc data setup time as 3 clock cycles for 133MHz as recommended by the datasheet. Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver") Reported-by: Zixun LI Closes: https://lore.kernel.org/all/c015bb20-6a57-4f63-8102-34b3d83e0f5b@microchip.com Suggested-by: Ada Couprie Diaz Signed-off-by: Balamanikandan Gunasundar Signed-off-by: Miquel Raynal Signed-off-by: Sasha Levin --- drivers/mtd/nand/raw/atmel/pmecc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c index d1ed5878b3b1..28ed65dd3d43 100644 --- a/drivers/mtd/nand/raw/atmel/pmecc.c +++ b/drivers/mtd/nand/raw/atmel/pmecc.c @@ -143,6 +143,7 @@ struct atmel_pmecc_caps { int nstrengths; int el_offset; bool correct_erased_chunks; + bool clk_ctrl; }; struct atmel_pmecc { @@ -846,6 +847,10 @@ static struct atmel_pmecc *atmel_pmecc_create(struct platform_device *pdev, if (IS_ERR(pmecc->regs.errloc)) return ERR_CAST(pmecc->regs.errloc); + /* pmecc data setup time */ + if (caps->clk_ctrl) + writel(PMECC_CLK_133MHZ, pmecc->regs.base + ATMEL_PMECC_CLK); + /* Disable all interrupts before registering the PMECC handler. */ writel(0xffffffff, pmecc->regs.base + ATMEL_PMECC_IDR); atmel_pmecc_reset(pmecc); @@ -899,6 +904,7 @@ static struct atmel_pmecc_caps at91sam9g45_caps = { .strengths = atmel_pmecc_strengths, .nstrengths = 5, .el_offset = 0x8c, + .clk_ctrl = true, }; static struct atmel_pmecc_caps sama5d4_caps = { From ebd1205fc058d26a2601a017c87d001009ed6acb Mon Sep 17 00:00:00 2001 From: Paul Chaignon Date: Fri, 1 Aug 2025 11:47:23 +0200 Subject: [PATCH 129/404] bpf: Check flow_dissector ctx accesses are aligned [ Upstream commit ead3d7b2b6afa5ee7958620c4329982a7d9c2b78 ] flow_dissector_is_valid_access doesn't check that the context access is aligned. As a consequence, an unaligned access within one of the exposed field is considered valid and later rejected by flow_dissector_convert_ctx_access when we try to convert it. The later rejection is problematic because it's reported as a verifier bug with a kernel warning and doesn't point to the right instruction in verifier logs. Fixes: d58e468b1112 ("flow_dissector: implements flow dissector BPF hook") Reported-by: syzbot+ccac90e482b2a81d74aa@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=ccac90e482b2a81d74aa Signed-off-by: Paul Chaignon Acked-by: Yonghong Song Acked-by: Eduard Zingerman Link: https://lore.kernel.org/r/cc1b036be484c99be45eddf48bd78cc6f72839b1.1754039605.git.paul.chaignon@gmail.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- net/core/filter.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/core/filter.c b/net/core/filter.c index e6ec6f013ec0..fd18497977bd 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -7282,6 +7282,9 @@ static bool flow_dissector_is_valid_access(int off, int size, if (off < 0 || off >= sizeof(struct __sk_buff)) return false; + if (off % size != 0) + return false; + if (type == BPF_WRITE) return false; From a784d5b38765ebea404a7120d676a6be4bbd5864 Mon Sep 17 00:00:00 2001 From: Petr Pavlu Date: Mon, 30 Jun 2025 16:32:34 +0200 Subject: [PATCH 130/404] module: Restore the moduleparam prefix length check [ Upstream commit bdc877ba6b7ff1b6d2ebeff11e63da4a50a54854 ] The moduleparam code allows modules to provide their own definition of MODULE_PARAM_PREFIX, instead of using the default KBUILD_MODNAME ".". Commit 730b69d22525 ("module: check kernel param length at compile time, not runtime") added a check to ensure the prefix doesn't exceed MODULE_NAME_LEN, as this is what param_sysfs_builtin() expects. Later, commit 58f86cc89c33 ("VERIFY_OCTAL_PERMISSIONS: stricter checking for sysfs perms.") removed this check, but there is no indication this was intentional. Since the check is still useful for param_sysfs_builtin() to function properly, reintroduce it in __module_param_call(), but in a modernized form using static_assert(). While here, clean up the __module_param_call() comments. In particular, remove the comment "Default value instead of permissions?", which comes from commit 9774a1f54f17 ("[PATCH] Compile-time check re world-writeable module params"). This comment was related to the test variable __param_perm_check_##name, which was removed in the previously mentioned commit 58f86cc89c33. Fixes: 58f86cc89c33 ("VERIFY_OCTAL_PERMISSIONS: stricter checking for sysfs perms.") Signed-off-by: Petr Pavlu Reviewed-by: Daniel Gomez Link: https://lore.kernel.org/r/20250630143535.267745-4-petr.pavlu@suse.com Signed-off-by: Daniel Gomez Signed-off-by: Sasha Levin --- include/linux/moduleparam.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 4d5a851cafe8..6e9062caa7df 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -214,10 +214,9 @@ struct kparam_array #define __moduleparam_const const #endif -/* This is the fundamental function for registering boot/module - parameters. */ +/* This is the fundamental function for registering boot/module parameters. */ #define __module_param_call(prefix, name, ops, arg, perm, level, flags) \ - /* Default value instead of permissions? */ \ + static_assert(sizeof(""prefix) - 1 <= MAX_PARAM_PREFIX_LEN); \ static const char __param_str_##name[] = prefix #name; \ static struct kernel_param __moduleparam_const __param_##name \ __used \ From 0a9ac7f4244d3b51a234a567fd9c0256630ce047 Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 10 Jul 2025 11:20:21 -0400 Subject: [PATCH 131/404] rtc: ds1307: fix incorrect maximum clock rate handling [ Upstream commit cf6eb547a24af7ad7bbd2abe9c5327f956bbeae8 ] When ds3231_clk_sqw_round_rate() is called with a requested rate higher than the highest supported rate, it currently returns 0, which disables the clock. According to the clk API, round_rate() should instead return the highest supported rate. Update the function to return the maximum supported rate in this case. Fixes: 6c6ff145b3346 ("rtc: ds1307: add clock provider support for DS3231") Signed-off-by: Brian Masney Link: https://lore.kernel.org/r/20250710-rtc-clk-round-rate-v1-1-33140bb2278e@redhat.com Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin --- drivers/rtc/rtc-ds1307.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 40532a36ae67..b371d1e48942 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1381,7 +1381,7 @@ static long ds3231_clk_sqw_round_rate(struct clk_hw *hw, unsigned long rate, return ds3231_clk_sqw_rates[i]; } - return 0; + return ds3231_clk_sqw_rates[ARRAY_SIZE(ds3231_clk_sqw_rates) - 1]; } static int ds3231_clk_sqw_set_rate(struct clk_hw *hw, unsigned long rate, From 53ac364d1e334224f24a09fa58a875e23a5a658d Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 10 Jul 2025 11:20:22 -0400 Subject: [PATCH 132/404] rtc: hym8563: fix incorrect maximum clock rate handling [ Upstream commit d0a518eb0a692a2ab8357e844970660c5ea37720 ] When hym8563_clkout_round_rate() is called with a requested rate higher than the highest supported rate, it currently returns 0, which disables the clock. According to the clk API, round_rate() should instead return the highest supported rate. Update the function to return the maximum supported rate in this case. Fixes: dcaf038493525 ("rtc: add hym8563 rtc-driver") Signed-off-by: Brian Masney Link: https://lore.kernel.org/r/20250710-rtc-clk-round-rate-v1-2-33140bb2278e@redhat.com Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin --- drivers/rtc/rtc-hym8563.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index fb6d7967ec00..bd625ab70617 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -316,7 +316,7 @@ static long hym8563_clkout_round_rate(struct clk_hw *hw, unsigned long rate, if (clkout_rates[i] <= rate) return clkout_rates[i]; - return 0; + return clkout_rates[0]; } static int hym8563_clkout_set_rate(struct clk_hw *hw, unsigned long rate, From 75024aae0ee5b8f90798352aef022e11e939512a Mon Sep 17 00:00:00 2001 From: Brian Masney Date: Thu, 10 Jul 2025 11:20:25 -0400 Subject: [PATCH 133/404] rtc: pcf8563: fix incorrect maximum clock rate handling [ Upstream commit 906726a5efeefe0ef0103ccff5312a09080c04ae ] When pcf8563_clkout_round_rate() is called with a requested rate higher than the highest supported rate, it currently returns 0, which disables the clock. According to the clk API, round_rate() should instead return the highest supported rate. Update the function to return the maximum supported rate in this case. Fixes: a39a6405d5f94 ("rtc: pcf8563: add CLKOUT to common clock framework") Signed-off-by: Brian Masney Link: https://lore.kernel.org/r/20250710-rtc-clk-round-rate-v1-5-33140bb2278e@redhat.com Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin --- drivers/rtc/rtc-pcf8563.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 24baa4767b11..9e4fdfe9d86a 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -421,7 +421,7 @@ static long pcf8563_clkout_round_rate(struct clk_hw *hw, unsigned long rate, if (clkout_rates[i] <= rate) return clkout_rates[i]; - return 0; + return clkout_rates[0]; } static int pcf8563_clkout_set_rate(struct clk_hw *hw, unsigned long rate, From 37e78cad7e9e025e63bb35bc200f44637b009bb1 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 8 Jul 2025 17:53:39 +0800 Subject: [PATCH 134/404] f2fs: fix to avoid UAF in f2fs_sync_inode_meta() [ Upstream commit 7c30d79930132466f5be7d0b57add14d1a016bda ] syzbot reported an UAF issue as below: [1] [2] [1] https://syzkaller.appspot.com/text?tag=CrashReport&x=16594c60580000 ================================================================== BUG: KASAN: use-after-free in __list_del_entry_valid+0xa6/0x130 lib/list_debug.c:62 Read of size 8 at addr ffff888100567dc8 by task kworker/u4:0/8 CPU: 1 PID: 8 Comm: kworker/u4:0 Tainted: G W 6.1.129-syzkaller-00017-g642656a36791 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025 Workqueue: writeback wb_workfn (flush-7:0) Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x151/0x1b7 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:316 [inline] print_report+0x158/0x4e0 mm/kasan/report.c:427 kasan_report+0x13c/0x170 mm/kasan/report.c:531 __asan_report_load8_noabort+0x14/0x20 mm/kasan/report_generic.c:351 __list_del_entry_valid+0xa6/0x130 lib/list_debug.c:62 __list_del_entry include/linux/list.h:134 [inline] list_del_init include/linux/list.h:206 [inline] f2fs_inode_synced+0x100/0x2e0 fs/f2fs/super.c:1553 f2fs_update_inode+0x72/0x1c40 fs/f2fs/inode.c:588 f2fs_update_inode_page+0x135/0x170 fs/f2fs/inode.c:706 f2fs_write_inode+0x416/0x790 fs/f2fs/inode.c:734 write_inode fs/fs-writeback.c:1460 [inline] __writeback_single_inode+0x4cf/0xb80 fs/fs-writeback.c:1677 writeback_sb_inodes+0xb32/0x1910 fs/fs-writeback.c:1903 __writeback_inodes_wb+0x118/0x3f0 fs/fs-writeback.c:1974 wb_writeback+0x3da/0xa00 fs/fs-writeback.c:2081 wb_check_background_flush fs/fs-writeback.c:2151 [inline] wb_do_writeback fs/fs-writeback.c:2239 [inline] wb_workfn+0xbba/0x1030 fs/fs-writeback.c:2266 process_one_work+0x73d/0xcb0 kernel/workqueue.c:2299 worker_thread+0xa60/0x1260 kernel/workqueue.c:2446 kthread+0x26d/0x300 kernel/kthread.c:386 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295 Allocated by task 298: kasan_save_stack mm/kasan/common.c:45 [inline] kasan_set_track+0x4b/0x70 mm/kasan/common.c:52 kasan_save_alloc_info+0x1f/0x30 mm/kasan/generic.c:505 __kasan_slab_alloc+0x6c/0x80 mm/kasan/common.c:333 kasan_slab_alloc include/linux/kasan.h:202 [inline] slab_post_alloc_hook+0x53/0x2c0 mm/slab.h:768 slab_alloc_node mm/slub.c:3421 [inline] slab_alloc mm/slub.c:3431 [inline] __kmem_cache_alloc_lru mm/slub.c:3438 [inline] kmem_cache_alloc_lru+0x102/0x270 mm/slub.c:3454 alloc_inode_sb include/linux/fs.h:3255 [inline] f2fs_alloc_inode+0x2d/0x350 fs/f2fs/super.c:1437 alloc_inode fs/inode.c:261 [inline] iget_locked+0x18c/0x7e0 fs/inode.c:1373 f2fs_iget+0x55/0x4ca0 fs/f2fs/inode.c:486 f2fs_lookup+0x3c1/0xb50 fs/f2fs/namei.c:484 __lookup_slow+0x2b9/0x3e0 fs/namei.c:1689 lookup_slow+0x5a/0x80 fs/namei.c:1706 walk_component+0x2e7/0x410 fs/namei.c:1997 lookup_last fs/namei.c:2454 [inline] path_lookupat+0x16d/0x450 fs/namei.c:2478 filename_lookup+0x251/0x600 fs/namei.c:2507 vfs_statx+0x107/0x4b0 fs/stat.c:229 vfs_fstatat fs/stat.c:267 [inline] vfs_lstat include/linux/fs.h:3434 [inline] __do_sys_newlstat fs/stat.c:423 [inline] __se_sys_newlstat+0xda/0x7c0 fs/stat.c:417 __x64_sys_newlstat+0x5b/0x70 fs/stat.c:417 x64_sys_call+0x52/0x9a0 arch/x86/include/generated/asm/syscalls_64.h:7 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x3b/0x80 arch/x86/entry/common.c:81 entry_SYSCALL_64_after_hwframe+0x68/0xd2 Freed by task 0: kasan_save_stack mm/kasan/common.c:45 [inline] kasan_set_track+0x4b/0x70 mm/kasan/common.c:52 kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:516 ____kasan_slab_free+0x131/0x180 mm/kasan/common.c:241 __kasan_slab_free+0x11/0x20 mm/kasan/common.c:249 kasan_slab_free include/linux/kasan.h:178 [inline] slab_free_hook mm/slub.c:1745 [inline] slab_free_freelist_hook mm/slub.c:1771 [inline] slab_free mm/slub.c:3686 [inline] kmem_cache_free+0x291/0x560 mm/slub.c:3711 f2fs_free_inode+0x24/0x30 fs/f2fs/super.c:1584 i_callback+0x4b/0x70 fs/inode.c:250 rcu_do_batch+0x552/0xbe0 kernel/rcu/tree.c:2297 rcu_core+0x502/0xf40 kernel/rcu/tree.c:2557 rcu_core_si+0x9/0x10 kernel/rcu/tree.c:2574 handle_softirqs+0x1db/0x650 kernel/softirq.c:624 __do_softirq kernel/softirq.c:662 [inline] invoke_softirq kernel/softirq.c:479 [inline] __irq_exit_rcu+0x52/0xf0 kernel/softirq.c:711 irq_exit_rcu+0x9/0x10 kernel/softirq.c:723 instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1118 [inline] sysvec_apic_timer_interrupt+0xa9/0xc0 arch/x86/kernel/apic/apic.c:1118 asm_sysvec_apic_timer_interrupt+0x1b/0x20 arch/x86/include/asm/idtentry.h:691 Last potentially related work creation: kasan_save_stack+0x3b/0x60 mm/kasan/common.c:45 __kasan_record_aux_stack+0xb4/0xc0 mm/kasan/generic.c:486 kasan_record_aux_stack_noalloc+0xb/0x10 mm/kasan/generic.c:496 __call_rcu_common kernel/rcu/tree.c:2807 [inline] call_rcu+0xdc/0x10f0 kernel/rcu/tree.c:2926 destroy_inode fs/inode.c:316 [inline] evict+0x87d/0x930 fs/inode.c:720 iput_final fs/inode.c:1834 [inline] iput+0x616/0x690 fs/inode.c:1860 do_unlinkat+0x4e1/0x920 fs/namei.c:4396 __do_sys_unlink fs/namei.c:4437 [inline] __se_sys_unlink fs/namei.c:4435 [inline] __x64_sys_unlink+0x49/0x50 fs/namei.c:4435 x64_sys_call+0x289/0x9a0 arch/x86/include/generated/asm/syscalls_64.h:88 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x3b/0x80 arch/x86/entry/common.c:81 entry_SYSCALL_64_after_hwframe+0x68/0xd2 The buggy address belongs to the object at ffff888100567a10 which belongs to the cache f2fs_inode_cache of size 1360 The buggy address is located 952 bytes inside of 1360-byte region [ffff888100567a10, ffff888100567f60) The buggy address belongs to the physical page: page:ffffea0004015800 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x100560 head:ffffea0004015800 order:3 compound_mapcount:0 compound_pincount:0 flags: 0x4000000000010200(slab|head|zone=1) raw: 4000000000010200 0000000000000000 dead000000000122 ffff8881002c4d80 raw: 0000000000000000 0000000080160016 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected page_owner tracks the page as allocated page last allocated via order 3, migratetype Reclaimable, gfp_mask 0xd2050(__GFP_IO|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC|__GFP_RECLAIMABLE), pid 298, tgid 298 (syz-executor330), ts 26489303743, free_ts 0 set_page_owner include/linux/page_owner.h:33 [inline] post_alloc_hook+0x213/0x220 mm/page_alloc.c:2637 prep_new_page+0x1b/0x110 mm/page_alloc.c:2644 get_page_from_freelist+0x3a98/0x3b10 mm/page_alloc.c:4539 __alloc_pages+0x234/0x610 mm/page_alloc.c:5837 alloc_slab_page+0x6c/0xf0 include/linux/gfp.h:-1 allocate_slab mm/slub.c:1962 [inline] new_slab+0x90/0x3e0 mm/slub.c:2015 ___slab_alloc+0x6f9/0xb80 mm/slub.c:3203 __slab_alloc+0x5d/0xa0 mm/slub.c:3302 slab_alloc_node mm/slub.c:3387 [inline] slab_alloc mm/slub.c:3431 [inline] __kmem_cache_alloc_lru mm/slub.c:3438 [inline] kmem_cache_alloc_lru+0x149/0x270 mm/slub.c:3454 alloc_inode_sb include/linux/fs.h:3255 [inline] f2fs_alloc_inode+0x2d/0x350 fs/f2fs/super.c:1437 alloc_inode fs/inode.c:261 [inline] iget_locked+0x18c/0x7e0 fs/inode.c:1373 f2fs_iget+0x55/0x4ca0 fs/f2fs/inode.c:486 f2fs_fill_super+0x5360/0x6dc0 fs/f2fs/super.c:4488 mount_bdev+0x282/0x3b0 fs/super.c:1445 f2fs_mount+0x34/0x40 fs/f2fs/super.c:4743 legacy_get_tree+0xf1/0x190 fs/fs_context.c:632 page_owner free stack trace missing Memory state around the buggy address: ffff888100567c80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888100567d00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >ffff888100567d80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff888100567e00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888100567e80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== [2] https://syzkaller.appspot.com/text?tag=CrashLog&x=13654c60580000 [ 24.675720][ T28] audit: type=1400 audit(1745327318.732:72): avc: denied { write } for pid=298 comm="syz-executor399" name="/" dev="loop0" ino=3 scontext=root:sysadm_r:sysadm_t tcontext=system_u:object_r:unlabeled_t tclass=dir permissive=1 [ 24.705426][ T296] ------------[ cut here ]------------ [ 24.706608][ T28] audit: type=1400 audit(1745327318.732:73): avc: denied { remove_name } for pid=298 comm="syz-executor399" name="file0" dev="loop0" ino=4 scontext=root:sysadm_r:sysadm_t tcontext=system_u:object_r:unlabeled_t tclass=dir permissive=1 [ 24.711550][ T296] WARNING: CPU: 0 PID: 296 at fs/f2fs/inode.c:847 f2fs_evict_inode+0x1262/0x1540 [ 24.734141][ T28] audit: type=1400 audit(1745327318.732:74): avc: denied { rename } for pid=298 comm="syz-executor399" name="file0" dev="loop0" ino=4 scontext=root:sysadm_r:sysadm_t tcontext=system_u:object_r:unlabeled_t tclass=dir permissive=1 [ 24.742969][ T296] Modules linked in: [ 24.765201][ T28] audit: type=1400 audit(1745327318.732:75): avc: denied { add_name } for pid=298 comm="syz-executor399" name="bus" scontext=root:sysadm_r:sysadm_t tcontext=system_u:object_r:unlabeled_t tclass=dir permissive=1 [ 24.768847][ T296] CPU: 0 PID: 296 Comm: syz-executor399 Not tainted 6.1.129-syzkaller-00017-g642656a36791 #0 [ 24.799506][ T296] Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025 [ 24.809401][ T296] RIP: 0010:f2fs_evict_inode+0x1262/0x1540 [ 24.815018][ T296] Code: 34 70 4a ff eb 0d e8 2d 70 4a ff 4d 89 e5 4c 8b 64 24 18 48 8b 5c 24 28 4c 89 e7 e8 78 38 03 00 e9 84 fc ff ff e8 0e 70 4a ff <0f> 0b 4c 89 f7 be 08 00 00 00 e8 7f 21 92 ff f0 41 80 0e 04 e9 61 [ 24.834584][ T296] RSP: 0018:ffffc90000db7a40 EFLAGS: 00010293 [ 24.840465][ T296] RAX: ffffffff822aca42 RBX: 0000000000000002 RCX: ffff888110948000 [ 24.848291][ T296] RDX: 0000000000000000 RSI: 0000000000000002 RDI: 0000000000000000 [ 24.856064][ T296] RBP: ffffc90000db7bb0 R08: ffffffff822ac6a8 R09: ffffed10200b005d [ 24.864073][ T296] R10: 0000000000000000 R11: dffffc0000000001 R12: ffff888100580000 [ 24.871812][ T296] R13: dffffc0000000000 R14: ffff88810fef4078 R15: 1ffff920001b6f5c The root cause is w/ a fuzzed image, f2fs may missed to clear FI_DIRTY_INODE flag for target inode, after f2fs_evict_inode(), the inode is still linked in sbi->inode_list[DIRTY_META] global list, once it triggers checkpoint, f2fs_sync_inode_meta() may access the released inode. In f2fs_evict_inode(), let's always call f2fs_inode_synced() to clear FI_DIRTY_INODE flag and drop inode from global dirty list to avoid this UAF issue. Fixes: 0f18b462b2e5 ("f2fs: flush inode metadata when checkpoint is doing") Closes: https://syzkaller.appspot.com/bug?extid=849174b2efaf0d8be6ba Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/inode.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index b0cbb01df8cb..859ff287467e 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -740,8 +740,12 @@ no_delete: if (likely(!f2fs_cp_error(sbi) && !is_sbi_flag_set(sbi, SBI_CP_DISABLED))) f2fs_bug_on(sbi, is_inode_flag_set(inode, FI_DIRTY_INODE)); - else - f2fs_inode_synced(inode); + + /* + * anyway, it needs to remove the inode from sbi->inode_list[DIRTY_META] + * list to avoid UAF in f2fs_sync_inode_meta() during checkpoint. + */ + f2fs_inode_synced(inode); /* ino == 0, if f2fs_new_inode() was failed t*/ if (inode->i_ino) From 15df59809c54fbd687cdf27efbd2103a937459be Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 8 Jul 2025 17:56:57 +0800 Subject: [PATCH 135/404] f2fs: fix to avoid panic in f2fs_evict_inode [ Upstream commit a509a55f8eecc8970b3980c6f06886bbff0e2f68 ] As syzbot [1] reported as below: R10: 0000000000000100 R11: 0000000000000206 R12: 00007ffe17473450 R13: 00007f28b1c10854 R14: 000000000000dae5 R15: 00007ffe17474520 ---[ end trace 0000000000000000 ]--- ================================================================== BUG: KASAN: use-after-free in __list_del_entry_valid+0xa6/0x130 lib/list_debug.c:62 Read of size 8 at addr ffff88812d962278 by task syz-executor/564 CPU: 1 PID: 564 Comm: syz-executor Tainted: G W 6.1.129-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025 Call Trace: __dump_stack+0x21/0x24 lib/dump_stack.c:88 dump_stack_lvl+0xee/0x158 lib/dump_stack.c:106 print_address_description+0x71/0x210 mm/kasan/report.c:316 print_report+0x4a/0x60 mm/kasan/report.c:427 kasan_report+0x122/0x150 mm/kasan/report.c:531 __asan_report_load8_noabort+0x14/0x20 mm/kasan/report_generic.c:351 __list_del_entry_valid+0xa6/0x130 lib/list_debug.c:62 __list_del_entry include/linux/list.h:134 [inline] list_del_init include/linux/list.h:206 [inline] f2fs_inode_synced+0xf7/0x2e0 fs/f2fs/super.c:1531 f2fs_update_inode+0x74/0x1c40 fs/f2fs/inode.c:585 f2fs_update_inode_page+0x137/0x170 fs/f2fs/inode.c:703 f2fs_write_inode+0x4ec/0x770 fs/f2fs/inode.c:731 write_inode fs/fs-writeback.c:1460 [inline] __writeback_single_inode+0x4a0/0xab0 fs/fs-writeback.c:1677 writeback_single_inode+0x221/0x8b0 fs/fs-writeback.c:1733 sync_inode_metadata+0xb6/0x110 fs/fs-writeback.c:2789 f2fs_sync_inode_meta+0x16d/0x2a0 fs/f2fs/checkpoint.c:1159 block_operations fs/f2fs/checkpoint.c:1269 [inline] f2fs_write_checkpoint+0xca3/0x2100 fs/f2fs/checkpoint.c:1658 kill_f2fs_super+0x231/0x390 fs/f2fs/super.c:4668 deactivate_locked_super+0x98/0x100 fs/super.c:332 deactivate_super+0xaf/0xe0 fs/super.c:363 cleanup_mnt+0x45f/0x4e0 fs/namespace.c:1186 __cleanup_mnt+0x19/0x20 fs/namespace.c:1193 task_work_run+0x1c6/0x230 kernel/task_work.c:203 exit_task_work include/linux/task_work.h:39 [inline] do_exit+0x9fb/0x2410 kernel/exit.c:871 do_group_exit+0x210/0x2d0 kernel/exit.c:1021 __do_sys_exit_group kernel/exit.c:1032 [inline] __se_sys_exit_group kernel/exit.c:1030 [inline] __x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1030 x64_sys_call+0x7b4/0x9a0 arch/x86/include/generated/asm/syscalls_64.h:232 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x4c/0xa0 arch/x86/entry/common.c:81 entry_SYSCALL_64_after_hwframe+0x68/0xd2 RIP: 0033:0x7f28b1b8e169 Code: Unable to access opcode bytes at 0x7f28b1b8e13f. RSP: 002b:00007ffe174710a8 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7 RAX: ffffffffffffffda RBX: 00007f28b1c10879 RCX: 00007f28b1b8e169 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000001 RBP: 0000000000000002 R08: 00007ffe1746ee47 R09: 00007ffe17472360 R10: 0000000000000009 R11: 0000000000000246 R12: 00007ffe17472360 R13: 00007f28b1c10854 R14: 000000000000dae5 R15: 00007ffe17474520 Allocated by task 569: kasan_save_stack mm/kasan/common.c:45 [inline] kasan_set_track+0x4b/0x70 mm/kasan/common.c:52 kasan_save_alloc_info+0x25/0x30 mm/kasan/generic.c:505 __kasan_slab_alloc+0x72/0x80 mm/kasan/common.c:328 kasan_slab_alloc include/linux/kasan.h:201 [inline] slab_post_alloc_hook+0x4f/0x2c0 mm/slab.h:737 slab_alloc_node mm/slub.c:3398 [inline] slab_alloc mm/slub.c:3406 [inline] __kmem_cache_alloc_lru mm/slub.c:3413 [inline] kmem_cache_alloc_lru+0x104/0x220 mm/slub.c:3429 alloc_inode_sb include/linux/fs.h:3245 [inline] f2fs_alloc_inode+0x2d/0x340 fs/f2fs/super.c:1419 alloc_inode fs/inode.c:261 [inline] iget_locked+0x186/0x880 fs/inode.c:1373 f2fs_iget+0x55/0x4c60 fs/f2fs/inode.c:483 f2fs_lookup+0x366/0xab0 fs/f2fs/namei.c:487 __lookup_slow+0x2a3/0x3d0 fs/namei.c:1690 lookup_slow+0x57/0x70 fs/namei.c:1707 walk_component+0x2e6/0x410 fs/namei.c:1998 lookup_last fs/namei.c:2455 [inline] path_lookupat+0x180/0x490 fs/namei.c:2479 filename_lookup+0x1f0/0x500 fs/namei.c:2508 vfs_statx+0x10b/0x660 fs/stat.c:229 vfs_fstatat fs/stat.c:267 [inline] vfs_lstat include/linux/fs.h:3424 [inline] __do_sys_newlstat fs/stat.c:423 [inline] __se_sys_newlstat+0xd5/0x350 fs/stat.c:417 __x64_sys_newlstat+0x5b/0x70 fs/stat.c:417 x64_sys_call+0x393/0x9a0 arch/x86/include/generated/asm/syscalls_64.h:7 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x4c/0xa0 arch/x86/entry/common.c:81 entry_SYSCALL_64_after_hwframe+0x68/0xd2 Freed by task 13: kasan_save_stack mm/kasan/common.c:45 [inline] kasan_set_track+0x4b/0x70 mm/kasan/common.c:52 kasan_save_free_info+0x31/0x50 mm/kasan/generic.c:516 ____kasan_slab_free+0x132/0x180 mm/kasan/common.c:236 __kasan_slab_free+0x11/0x20 mm/kasan/common.c:244 kasan_slab_free include/linux/kasan.h:177 [inline] slab_free_hook mm/slub.c:1724 [inline] slab_free_freelist_hook+0xc2/0x190 mm/slub.c:1750 slab_free mm/slub.c:3661 [inline] kmem_cache_free+0x12d/0x2a0 mm/slub.c:3683 f2fs_free_inode+0x24/0x30 fs/f2fs/super.c:1562 i_callback+0x4c/0x70 fs/inode.c:250 rcu_do_batch+0x503/0xb80 kernel/rcu/tree.c:2297 rcu_core+0x5a2/0xe70 kernel/rcu/tree.c:2557 rcu_core_si+0x9/0x10 kernel/rcu/tree.c:2574 handle_softirqs+0x178/0x500 kernel/softirq.c:578 run_ksoftirqd+0x28/0x30 kernel/softirq.c:945 smpboot_thread_fn+0x45a/0x8c0 kernel/smpboot.c:164 kthread+0x270/0x310 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295 Last potentially related work creation: kasan_save_stack+0x3a/0x60 mm/kasan/common.c:45 __kasan_record_aux_stack+0xb6/0xc0 mm/kasan/generic.c:486 kasan_record_aux_stack_noalloc+0xb/0x10 mm/kasan/generic.c:496 call_rcu+0xd4/0xf70 kernel/rcu/tree.c:2845 destroy_inode fs/inode.c:316 [inline] evict+0x7da/0x870 fs/inode.c:720 iput_final fs/inode.c:1834 [inline] iput+0x62b/0x830 fs/inode.c:1860 do_unlinkat+0x356/0x540 fs/namei.c:4397 __do_sys_unlink fs/namei.c:4438 [inline] __se_sys_unlink fs/namei.c:4436 [inline] __x64_sys_unlink+0x49/0x50 fs/namei.c:4436 x64_sys_call+0x958/0x9a0 arch/x86/include/generated/asm/syscalls_64.h:88 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x4c/0xa0 arch/x86/entry/common.c:81 entry_SYSCALL_64_after_hwframe+0x68/0xd2 The buggy address belongs to the object at ffff88812d961f20 which belongs to the cache f2fs_inode_cache of size 1200 The buggy address is located 856 bytes inside of 1200-byte region [ffff88812d961f20, ffff88812d9623d0) The buggy address belongs to the physical page: page:ffffea0004b65800 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x12d960 head:ffffea0004b65800 order:2 compound_mapcount:0 compound_pincount:0 flags: 0x4000000000010200(slab|head|zone=1) raw: 4000000000010200 0000000000000000 dead000000000122 ffff88810a94c500 raw: 0000000000000000 00000000800c000c 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected page_owner tracks the page as allocated page last allocated via order 2, migratetype Reclaimable, gfp_mask 0x1d2050(__GFP_IO|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC|__GFP_HARDWALL|__GFP_RECLAIMABLE), pid 569, tgid 568 (syz.2.16), ts 55943246141, free_ts 0 set_page_owner include/linux/page_owner.h:31 [inline] post_alloc_hook+0x1d0/0x1f0 mm/page_alloc.c:2532 prep_new_page mm/page_alloc.c:2539 [inline] get_page_from_freelist+0x2e63/0x2ef0 mm/page_alloc.c:4328 __alloc_pages+0x235/0x4b0 mm/page_alloc.c:5605 alloc_slab_page include/linux/gfp.h:-1 [inline] allocate_slab mm/slub.c:1939 [inline] new_slab+0xec/0x4b0 mm/slub.c:1992 ___slab_alloc+0x6f6/0xb50 mm/slub.c:3180 __slab_alloc+0x5e/0xa0 mm/slub.c:3279 slab_alloc_node mm/slub.c:3364 [inline] slab_alloc mm/slub.c:3406 [inline] __kmem_cache_alloc_lru mm/slub.c:3413 [inline] kmem_cache_alloc_lru+0x13f/0x220 mm/slub.c:3429 alloc_inode_sb include/linux/fs.h:3245 [inline] f2fs_alloc_inode+0x2d/0x340 fs/f2fs/super.c:1419 alloc_inode fs/inode.c:261 [inline] iget_locked+0x186/0x880 fs/inode.c:1373 f2fs_iget+0x55/0x4c60 fs/f2fs/inode.c:483 f2fs_fill_super+0x3ad7/0x6bb0 fs/f2fs/super.c:4293 mount_bdev+0x2ae/0x3e0 fs/super.c:1443 f2fs_mount+0x34/0x40 fs/f2fs/super.c:4642 legacy_get_tree+0xea/0x190 fs/fs_context.c:632 vfs_get_tree+0x89/0x260 fs/super.c:1573 do_new_mount+0x25a/0xa20 fs/namespace.c:3056 page_owner free stack trace missing Memory state around the buggy address: ffff88812d962100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88812d962180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >ffff88812d962200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff88812d962280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88812d962300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== [1] https://syzkaller.appspot.com/x/report.txt?x=13448368580000 This bug can be reproduced w/ the reproducer [2], once we enable CONFIG_F2FS_CHECK_FS config, the reproducer will trigger panic as below, so the direct reason of this bug is the same as the one below patch [3] fixed. kernel BUG at fs/f2fs/inode.c:857! RIP: 0010:f2fs_evict_inode+0x1204/0x1a20 Call Trace: evict+0x32a/0x7a0 do_unlinkat+0x37b/0x5b0 __x64_sys_unlink+0xad/0x100 do_syscall_64+0x5a/0xb0 entry_SYSCALL_64_after_hwframe+0x6e/0xd8 RIP: 0010:f2fs_evict_inode+0x1204/0x1a20 [2] https://syzkaller.appspot.com/x/repro.c?x=17495ccc580000 [3] https://lore.kernel.org/linux-f2fs-devel/20250702120321.1080759-1-chao@kernel.org Tracepoints before panic: f2fs_unlink_enter: dev = (7,0), dir ino = 3, i_size = 4096, i_blocks = 8, name = file1 f2fs_unlink_exit: dev = (7,0), ino = 7, ret = 0 f2fs_evict_inode: dev = (7,0), ino = 7, pino = 3, i_mode = 0x81ed, i_size = 10, i_nlink = 0, i_blocks = 0, i_advise = 0x0 f2fs_truncate_node: dev = (7,0), ino = 7, nid = 8, block_address = 0x3c05 f2fs_unlink_enter: dev = (7,0), dir ino = 3, i_size = 4096, i_blocks = 8, name = file3 f2fs_unlink_exit: dev = (7,0), ino = 8, ret = 0 f2fs_evict_inode: dev = (7,0), ino = 8, pino = 3, i_mode = 0x81ed, i_size = 9000, i_nlink = 0, i_blocks = 24, i_advise = 0x4 f2fs_truncate: dev = (7,0), ino = 8, pino = 3, i_mode = 0x81ed, i_size = 0, i_nlink = 0, i_blocks = 24, i_advise = 0x4 f2fs_truncate_blocks_enter: dev = (7,0), ino = 8, i_size = 0, i_blocks = 24, start file offset = 0 f2fs_truncate_blocks_exit: dev = (7,0), ino = 8, ret = -2 The root cause is: in the fuzzed image, dnode #8 belongs to inode #7, after inode #7 eviction, dnode #8 was dropped. However there is dirent that has ino #8, so, once we unlink file3, in f2fs_evict_inode(), both f2fs_truncate() and f2fs_update_inode_page() will fail due to we can not load node #8, result in we missed to call f2fs_inode_synced() to clear inode dirty status. Let's fix this by calling f2fs_inode_synced() in error path of f2fs_evict_inode(). PS: As I verified, the reproducer [2] can trigger this bug in v6.1.129, but it failed in v6.16-rc4, this is because the testcase will stop due to other corruption has been detected by f2fs: F2FS-fs (loop0): inconsistent node block, node_type:2, nid:8, node_footer[nid:8,ino:8,ofs:0,cpver:5013063228981249506,blkaddr:15366] F2FS-fs (loop0): f2fs_lookup: inode (ino=9) has zero i_nlink Fixes: 0f18b462b2e5 ("f2fs: flush inode metadata when checkpoint is doing") Closes: https://syzkaller.appspot.com/x/report.txt?x=13448368580000 Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/inode.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 859ff287467e..03444ebc741b 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -728,6 +728,19 @@ retry: f2fs_update_inode_page(inode); if (dquot_initialize_needed(inode)) set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); + + /* + * If both f2fs_truncate() and f2fs_update_inode_page() failed + * due to fuzzed corrupted inode, call f2fs_inode_synced() to + * avoid triggering later f2fs_bug_on(). + */ + if (is_inode_flag_set(inode, FI_DIRTY_INODE)) { + f2fs_warn(sbi, + "f2fs_evict_inode: inode is dirty, ino:%lu", + inode->i_ino); + f2fs_inode_synced(inode); + set_sbi_flag(sbi, SBI_NEED_FSCK); + } } sb_end_intwrite(inode->i_sb); no_delete: From dc0172c74bd9edaee7bea2ebb35f3dbd37a8ae80 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Fri, 11 Jul 2025 15:14:50 +0800 Subject: [PATCH 136/404] f2fs: fix to avoid out-of-boundary access in devs.path [ Upstream commit 5661998536af52848cc4d52a377e90368196edea ] - touch /mnt/f2fs/012345678901234567890123456789012345678901234567890123 - truncate -s $((1024*1024*1024)) \ /mnt/f2fs/012345678901234567890123456789012345678901234567890123 - touch /mnt/f2fs/file - truncate -s $((1024*1024*1024)) /mnt/f2fs/file - mkfs.f2fs /mnt/f2fs/012345678901234567890123456789012345678901234567890123 \ -c /mnt/f2fs/file - mount /mnt/f2fs/012345678901234567890123456789012345678901234567890123 \ /mnt/f2fs/loop [16937.192225] F2FS-fs (loop0): Mount Device [ 0]: /mnt/f2fs/012345678901234567890123456789012345678901234567890123\xff\x01, 511, 0 - 3ffff [16937.192268] F2FS-fs (loop0): Failed to find devices If device path length equals to MAX_PATH_LEN, sbi->devs.path[] may not end up w/ null character due to path array is fully filled, So accidently, fields locate after path[] may be treated as part of device path, result in parsing wrong device path. struct f2fs_dev_info { ... char path[MAX_PATH_LEN]; ... }; Let's add one byte space for sbi->devs.path[] to store null character of device path string. Fixes: 3c62be17d4f5 ("f2fs: support multiple devices") Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- fs/f2fs/f2fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 1b8f41daddba..e17b19bb4148 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1098,7 +1098,7 @@ struct f2fs_bio_info { #define RDEV(i) (raw_super->devs[i]) struct f2fs_dev_info { struct block_device *bdev; - char path[MAX_PATH_LEN]; + char path[MAX_PATH_LEN + 1]; unsigned int total_segments; block_t start_blk; block_t end_blk; From 651a71f931f8c6f30bc675f9723dab2c79ec1ede Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 16 Mar 2020 11:10:34 +0800 Subject: [PATCH 137/404] usb: chipidea: udc: fix sleeping function called from invalid context [ Upstream commit 7368760d1bcdabf515c41a502568b489de3da683 ] The code calls pm_runtime_get_sync with irq disabled, it causes below warning: BUG: sleeping function called from invalid context at wer/runtime.c:1075 in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: er/u8:1 CPU: 1 PID: 37 Comm: kworker/u8:1 Not tainted 20200304-00181-gbebfd2a5be98 #1588 Hardware name: NVIDIA Tegra SoC (Flattened Device Tree) Workqueue: ci_otg ci_otg_work [] (unwind_backtrace) from [] 1/0x14) [] (show_stack) from [] 5/0x94) [] (dump_stack) from [] +0xeb/0x118) [] (___might_sleep) from [] esume+0x75/0x78) [] (__pm_runtime_resume) from [] 0x23/0x74) [] (ci_udc_pullup) from [] nect+0x2b/0xcc) [] (usb_gadget_connect) from [] _connect+0x59/0x104) [] (ci_hdrc_gadget_connect) from [] ssion+0x43/0x48) [] (ci_udc_vbus_session) from [] s_connect+0x17/0x9c) [] (usb_gadget_vbus_connect) from [] bd/0x128) [] (ci_otg_work) from [] rk+0x149/0x404) [] (process_one_work) from [] 0xf7/0x3bc) [] (worker_thread) from [] x118) [] (kthread) from [] (ret_from_fork+0x11/0x34) Tested-by: Dmitry Osipenko Cc: #v5.5 Fixes: 72dc8df7920f ("usb: chipidea: udc: protect usb interrupt enable") Reported-by: Dmitry Osipenko Signed-off-by: Peter Chen Link: https://lore.kernel.org/r/20200316031034.17847-2-peter.chen@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/chipidea/udc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 19a9a4b83346..d483a957804b 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1539,18 +1539,19 @@ static const struct usb_ep_ops usb_ep_ops = { static void ci_hdrc_gadget_connect(struct usb_gadget *_gadget, int is_active) { struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); - unsigned long flags; if (is_active) { pm_runtime_get_sync(&_gadget->dev); hw_device_reset(ci); - spin_lock_irqsave(&ci->lock, flags); + spin_lock_irq(&ci->lock); if (ci->driver) { hw_device_state(ci, ci->ep0out->qh.dma); usb_gadget_set_state(_gadget, USB_STATE_POWERED); + spin_unlock_irq(&ci->lock); usb_udc_vbus_handler(_gadget, true); + } else { + spin_unlock_irq(&ci->lock); } - spin_unlock_irqrestore(&ci->lock, flags); } else { usb_udc_vbus_handler(_gadget, false); if (ci->driver) From 0f28008b27d37e0e583a983f63f49d8124f526c9 Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Thu, 21 Nov 2019 14:49:14 +0100 Subject: [PATCH 138/404] pci/hotplug/pnv-php: Improve error msg on power state change failure [ Upstream commit 323c2a26ff43500a96799250330fab68903d776f ] When changing the slot state, if opal hits an error and tells as such in the asynchronous reply, the warning "Wrong msg" is logged, which is rather confusing. Instead we can reuse the better message which is already used when we couldn't submit the asynchronous opal request initially. Reviewed-by: Alastair D'Silva Reviewed-by: Andrew Donnellan Signed-off-by: Frederic Barrat Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191121134918.7155-8-fbarrat@linux.ibm.com Stable-dep-of: 466861909255 ("PCI: pnv_php: Clean up allocated IRQs on unplug") Signed-off-by: Sasha Levin --- drivers/pci/hotplug/pnv_php.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c index 382494261830..8223fe0b751f 100644 --- a/drivers/pci/hotplug/pnv_php.c +++ b/drivers/pci/hotplug/pnv_php.c @@ -341,18 +341,19 @@ int pnv_php_set_slot_power_state(struct hotplug_slot *slot, ret = pnv_pci_set_power_state(php_slot->id, state, &msg); if (ret > 0) { if (be64_to_cpu(msg.params[1]) != php_slot->dn->phandle || - be64_to_cpu(msg.params[2]) != state || - be64_to_cpu(msg.params[3]) != OPAL_SUCCESS) { + be64_to_cpu(msg.params[2]) != state) { pci_warn(php_slot->pdev, "Wrong msg (%lld, %lld, %lld)\n", be64_to_cpu(msg.params[1]), be64_to_cpu(msg.params[2]), be64_to_cpu(msg.params[3])); return -ENOMSG; } + if (be64_to_cpu(msg.params[3]) != OPAL_SUCCESS) { + ret = -ENODEV; + goto error; + } } else if (ret < 0) { - pci_warn(php_slot->pdev, "Error %d powering %s\n", - ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off"); - return ret; + goto error; } if (state == OPAL_PCI_SLOT_POWER_OFF || state == OPAL_PCI_SLOT_OFFLINE) @@ -361,6 +362,11 @@ int pnv_php_set_slot_power_state(struct hotplug_slot *slot, ret = pnv_php_add_devtree(php_slot); return ret; + +error: + pci_warn(php_slot->pdev, "Error %d powering %s\n", + ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off"); + return ret; } EXPORT_SYMBOL_GPL(pnv_php_set_slot_power_state); From 18834f5ee75ecf562ca9e478bc31d3f9dddc4d26 Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Thu, 21 Nov 2019 14:49:17 +0100 Subject: [PATCH 139/404] pci/hotplug/pnv-php: Wrap warnings in macro [ Upstream commit 748ac391ab9acd8d7f3c93cbf3e63c773c0b2638 ] An opencapi slot doesn't have an associated bridge device. It's not needed for operation, but any warning is displayed through pci_warn() which uses the pci_dev struct of the assocated bridge device. So wrap those warning so that a different trace mechanism can be used if it's an opencapi slot. Reviewed-by: Alastair D'Silva Reviewed-by: Andrew Donnellan Signed-off-by: Frederic Barrat Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191121134918.7155-11-fbarrat@linux.ibm.com Stable-dep-of: 466861909255 ("PCI: pnv_php: Clean up allocated IRQs on unplug") Signed-off-by: Sasha Levin --- drivers/pci/hotplug/pnv_php.c | 51 +++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c index 8223fe0b751f..3687a99383c1 100644 --- a/drivers/pci/hotplug/pnv_php.c +++ b/drivers/pci/hotplug/pnv_php.c @@ -18,6 +18,9 @@ #define DRIVER_AUTHOR "Gavin Shan, IBM Corporation" #define DRIVER_DESC "PowerPC PowerNV PCI Hotplug Driver" +#define SLOT_WARN(sl, x...) \ + ((sl)->pdev ? pci_warn((sl)->pdev, x) : dev_warn(&(sl)->bus->dev, x)) + struct pnv_php_event { bool added; struct pnv_php_slot *php_slot; @@ -270,7 +273,7 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot) ret = pnv_pci_get_device_tree(php_slot->dn->phandle, fdt1, 0x10000); if (ret) { - pci_warn(php_slot->pdev, "Error %d getting FDT blob\n", ret); + SLOT_WARN(php_slot, "Error %d getting FDT blob\n", ret); goto free_fdt1; } @@ -284,7 +287,7 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot) dt = of_fdt_unflatten_tree(fdt, php_slot->dn, NULL); if (!dt) { ret = -EINVAL; - pci_warn(php_slot->pdev, "Cannot unflatten FDT\n"); + SLOT_WARN(php_slot, "Cannot unflatten FDT\n"); goto free_fdt; } @@ -294,15 +297,15 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot) ret = pnv_php_populate_changeset(&php_slot->ocs, php_slot->dn); if (ret) { pnv_php_reverse_nodes(php_slot->dn); - pci_warn(php_slot->pdev, "Error %d populating changeset\n", - ret); + SLOT_WARN(php_slot, "Error %d populating changeset\n", + ret); goto free_dt; } php_slot->dn->child = NULL; ret = of_changeset_apply(&php_slot->ocs); if (ret) { - pci_warn(php_slot->pdev, "Error %d applying changeset\n", ret); + SLOT_WARN(php_slot, "Error %d applying changeset\n", ret); goto destroy_changeset; } @@ -342,10 +345,10 @@ int pnv_php_set_slot_power_state(struct hotplug_slot *slot, if (ret > 0) { if (be64_to_cpu(msg.params[1]) != php_slot->dn->phandle || be64_to_cpu(msg.params[2]) != state) { - pci_warn(php_slot->pdev, "Wrong msg (%lld, %lld, %lld)\n", - be64_to_cpu(msg.params[1]), - be64_to_cpu(msg.params[2]), - be64_to_cpu(msg.params[3])); + SLOT_WARN(php_slot, "Wrong msg (%lld, %lld, %lld)\n", + be64_to_cpu(msg.params[1]), + be64_to_cpu(msg.params[2]), + be64_to_cpu(msg.params[3])); return -ENOMSG; } if (be64_to_cpu(msg.params[3]) != OPAL_SUCCESS) { @@ -364,8 +367,8 @@ int pnv_php_set_slot_power_state(struct hotplug_slot *slot, return ret; error: - pci_warn(php_slot->pdev, "Error %d powering %s\n", - ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off"); + SLOT_WARN(php_slot, "Error %d powering %s\n", + ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off"); return ret; } EXPORT_SYMBOL_GPL(pnv_php_set_slot_power_state); @@ -383,8 +386,8 @@ static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state) */ ret = pnv_pci_get_power_state(php_slot->id, &power_state); if (ret) { - pci_warn(php_slot->pdev, "Error %d getting power status\n", - ret); + SLOT_WARN(php_slot, "Error %d getting power status\n", + ret); } else { *state = power_state; } @@ -407,7 +410,7 @@ static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state) *state = presence; ret = 0; } else { - pci_warn(php_slot->pdev, "Error %d getting presence\n", ret); + SLOT_WARN(php_slot, "Error %d getting presence\n", ret); } return ret; @@ -680,7 +683,7 @@ static int pnv_php_register_slot(struct pnv_php_slot *php_slot) ret = pci_hp_register(&php_slot->slot, php_slot->bus, php_slot->slot_no, php_slot->name); if (ret) { - pci_warn(php_slot->pdev, "Error %d registering slot\n", ret); + SLOT_WARN(php_slot, "Error %d registering slot\n", ret); return ret; } @@ -733,7 +736,7 @@ static int pnv_php_enable_msix(struct pnv_php_slot *php_slot) /* Enable MSIx */ ret = pci_enable_msix_exact(pdev, &entry, 1); if (ret) { - pci_warn(pdev, "Error %d enabling MSIx\n", ret); + SLOT_WARN(php_slot, "Error %d enabling MSIx\n", ret); return ret; } @@ -783,8 +786,9 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data) (sts & PCI_EXP_SLTSTA_PDC)) { ret = pnv_pci_get_presence_state(php_slot->id, &presence); if (ret) { - pci_warn(pdev, "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n", - php_slot->name, ret, sts); + SLOT_WARN(php_slot, + "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n", + php_slot->name, ret, sts); return IRQ_HANDLED; } @@ -814,8 +818,9 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data) */ event = kzalloc(sizeof(*event), GFP_ATOMIC); if (!event) { - pci_warn(pdev, "PCI slot [%s] missed hotplug event 0x%04x\n", - php_slot->name, sts); + SLOT_WARN(php_slot, + "PCI slot [%s] missed hotplug event 0x%04x\n", + php_slot->name, sts); return IRQ_HANDLED; } @@ -839,7 +844,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq) /* Allocate workqueue */ php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name); if (!php_slot->wq) { - pci_warn(pdev, "Cannot alloc workqueue\n"); + SLOT_WARN(php_slot, "Cannot alloc workqueue\n"); pnv_php_disable_irq(php_slot, true); return; } @@ -863,7 +868,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq) php_slot->name, php_slot); if (ret) { pnv_php_disable_irq(php_slot, true); - pci_warn(pdev, "Error %d enabling IRQ %d\n", ret, irq); + SLOT_WARN(php_slot, "Error %d enabling IRQ %d\n", ret, irq); return; } @@ -899,7 +904,7 @@ static void pnv_php_enable_irq(struct pnv_php_slot *php_slot) ret = pci_enable_device(pdev); if (ret) { - pci_warn(pdev, "Error %d enabling device\n", ret); + SLOT_WARN(php_slot, "Error %d enabling device\n", ret); return; } From 7f8eca87fef7519e9c41f3258f25ebc2752247ee Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 22 Jul 2025 09:24:58 -0400 Subject: [PATCH 140/404] NFS: Fix filehandle bounds checking in nfs_fh_to_dentry() [ Upstream commit ef93a685e01a281b5e2a25ce4e3428cf9371a205 ] The function needs to check the minimal filehandle length before it can access the embedded filehandle. Reported-by: zhangjian Fixes: 20fa19027286 ("nfs: add export operations") Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin --- fs/nfs/export.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/nfs/export.c b/fs/nfs/export.c index deecb67638aa..97b6fa0adb57 100644 --- a/fs/nfs/export.c +++ b/fs/nfs/export.c @@ -67,14 +67,21 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid, struct nfs4_label *label = NULL; struct nfs_fattr *fattr = NULL; struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw); - size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size; + size_t fh_size = offsetof(struct nfs_fh, data); const struct nfs_rpc_ops *rpc_ops; struct dentry *dentry; struct inode *inode; - int len = EMBED_FH_OFF + XDR_QUADLEN(fh_size); + int len = EMBED_FH_OFF; u32 *p = fid->raw; int ret; + /* Initial check of bounds */ + if (fh_len < len + XDR_QUADLEN(fh_size) || + fh_len > XDR_QUADLEN(NFS_MAXFHSIZE)) + return NULL; + /* Calculate embedded filehandle size */ + fh_size += server_fh->size; + len += XDR_QUADLEN(fh_size); /* NULL translates to ESTALE */ if (fh_len < len || fh_type != len) return NULL; From 7bf4c6e5a856fb4b3906482a51d0acd238dcd305 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 25 Jul 2025 18:08:46 -0700 Subject: [PATCH 141/404] netpoll: prevent hanging NAPI when netcons gets enabled [ Upstream commit 2da4def0f487f24bbb0cece3bb2bcdcb918a0b72 ] Paolo spotted hangs in NIPA running driver tests against virtio. The tests hang in virtnet_close() -> virtnet_napi_tx_disable(). The problem is only reproducible if running multiple of our tests in sequence (I used TEST_PROGS="xdp.py ping.py netcons_basic.sh \ netpoll_basic.py stats.py"). Initial suspicion was that this is a simple case of double-disable of NAPI, but instrumenting the code reveals: Deadlocked on NAPI ffff888007cd82c0 (virtnet_poll_tx): state: 0x37, disabled: false, owner: 0, listed: false, weight: 64 The NAPI was not in fact disabled, owner is 0 (rather than -1), so the NAPI "thinks" it's scheduled for CPU 0 but it's not listed (!list_empty(&n->poll_list) => false). It seems odd that normal NAPI processing would wedge itself like this. Better suspicion is that netpoll gets enabled while NAPI is polling, and also grabs the NAPI instance. This confuses napi_complete_done(): [netpoll] [normal NAPI] napi_poll() have = netpoll_poll_lock() rcu_access_pointer(dev->npinfo) return NULL # no netpoll __napi_poll() ->poll(->weight) poll_napi() cmpxchg(->poll_owner, -1, cpu) poll_one_napi() set_bit(NAPI_STATE_NPSVC, ->state) napi_complete_done() if (NAPIF_STATE_NPSVC) return false # exit without clearing SCHED This feels very unlikely, but perhaps virtio has some interactions with the hypervisor in the NAPI ->poll that makes the race window larger? Best I could to to prove the theory was to add and trigger this warning in napi_poll (just before netpoll_poll_unlock()): WARN_ONCE(!have && rcu_access_pointer(n->dev->npinfo) && napi_is_scheduled(n) && list_empty(&n->poll_list), "NAPI race with netpoll %px", n); If this warning hits the next virtio_close() will hang. This patch survived 30 test iterations without a hang (without it the longest clean run was around 10). Credit for triggering this goes to Breno's recent netconsole tests. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: Paolo Abeni Link: https://lore.kernel.org/c5a93ed1-9abe-4880-a3bb-8d1678018b1d@redhat.com Acked-by: Jason Wang Reviewed-by: Xuan Zhuo Link: https://patch.msgid.link/20250726010846.1105875-1-kuba@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/core/netpoll.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 940d371f5f3b..09ae2fc41fa9 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -807,6 +807,13 @@ put_noaddr: goto put; rtnl_unlock(); + + /* Make sure all NAPI polls which started before dev->npinfo + * was visible have exited before we start calling NAPI poll. + * NAPI skips locking if dev->npinfo is NULL. + */ + synchronize_rcu(); + return 0; put: From 97b8c5d322c5c0038cac4bc56fdbe237d0be426f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 29 Jul 2025 08:02:07 +0000 Subject: [PATCH 142/404] pptp: ensure minimal skb length in pptp_xmit() [ Upstream commit de9c4861fb42f0cd72da844c3c34f692d5895b7b ] Commit aabc6596ffb3 ("net: ppp: Add bound checking for skb data on ppp_sync_txmung") fixed ppp_sync_txmunge() We need a similar fix in pptp_xmit(), otherwise we might read uninit data as reported by syzbot. BUG: KMSAN: uninit-value in pptp_xmit+0xc34/0x2720 drivers/net/ppp/pptp.c:193 pptp_xmit+0xc34/0x2720 drivers/net/ppp/pptp.c:193 ppp_channel_bridge_input drivers/net/ppp/ppp_generic.c:2290 [inline] ppp_input+0x1d6/0xe60 drivers/net/ppp/ppp_generic.c:2314 pppoe_rcv_core+0x1e8/0x760 drivers/net/ppp/pppoe.c:379 sk_backlog_rcv+0x142/0x420 include/net/sock.h:1148 __release_sock+0x1d3/0x330 net/core/sock.c:3213 release_sock+0x6b/0x270 net/core/sock.c:3767 pppoe_sendmsg+0x15d/0xcb0 drivers/net/ppp/pppoe.c:904 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg+0x330/0x3d0 net/socket.c:727 ____sys_sendmsg+0x893/0xd80 net/socket.c:2566 ___sys_sendmsg+0x271/0x3b0 net/socket.c:2620 __sys_sendmmsg+0x2d9/0x7c0 net/socket.c:2709 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: syzbot+afad90ffc8645324afe5@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/68887d86.a00a0220.b12ec.00cd.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Reviewed-by: Dawid Osuchowski Link: https://patch.msgid.link/20250729080207.1863408-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ppp/pptp.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index e1fabb3e3246..5e2f4702aa2b 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c @@ -141,9 +141,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) int len; unsigned char *data; __u32 seq_recv; - - - struct rtable *rt; + struct rtable *rt = NULL; struct net_device *tdev; struct iphdr *iph; int max_headroom; @@ -165,16 +163,20 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); - if (!new_skb) { - ip_rt_put(rt); + + if (!new_skb) goto tx_error; - } + if (skb->sk) skb_set_owner_w(new_skb, skb->sk); consume_skb(skb); skb = new_skb; } + /* Ensure we can safely access protocol field and LCP code */ + if (!pskb_may_pull(skb, 3)) + goto tx_error; + data = skb->data; islcp = ((data[0] << 8) + data[1]) == PPP_LCP && 1 <= data[2] && data[2] <= 7; @@ -248,6 +250,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) return 1; tx_error: + ip_rt_put(rt); kfree_skb(skb); return 1; } From 5dc60b2a00ed7629214ac0c48e43f40af2078703 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 30 Jul 2025 13:17:38 +0000 Subject: [PATCH 143/404] ipv6: reject malicious packets in ipv6_gso_segment() [ Upstream commit d45cf1e7d7180256e17c9ce88e32e8061a7887fe ] syzbot was able to craft a packet with very long IPv6 extension headers leading to an overflow of skb->transport_header. This 16bit field has a limited range. Add skb_reset_transport_header_careful() helper and use it from ipv6_gso_segment() WARNING: CPU: 0 PID: 5871 at ./include/linux/skbuff.h:3032 skb_reset_transport_header include/linux/skbuff.h:3032 [inline] WARNING: CPU: 0 PID: 5871 at ./include/linux/skbuff.h:3032 ipv6_gso_segment+0x15e2/0x21e0 net/ipv6/ip6_offload.c:151 Modules linked in: CPU: 0 UID: 0 PID: 5871 Comm: syz-executor211 Not tainted 6.16.0-rc6-syzkaller-g7abc678e3084 #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025 RIP: 0010:skb_reset_transport_header include/linux/skbuff.h:3032 [inline] RIP: 0010:ipv6_gso_segment+0x15e2/0x21e0 net/ipv6/ip6_offload.c:151 Call Trace: skb_mac_gso_segment+0x31c/0x640 net/core/gso.c:53 nsh_gso_segment+0x54a/0xe10 net/nsh/nsh.c:110 skb_mac_gso_segment+0x31c/0x640 net/core/gso.c:53 __skb_gso_segment+0x342/0x510 net/core/gso.c:124 skb_gso_segment include/net/gso.h:83 [inline] validate_xmit_skb+0x857/0x11b0 net/core/dev.c:3950 validate_xmit_skb_list+0x84/0x120 net/core/dev.c:4000 sch_direct_xmit+0xd3/0x4b0 net/sched/sch_generic.c:329 __dev_xmit_skb net/core/dev.c:4102 [inline] __dev_queue_xmit+0x17b6/0x3a70 net/core/dev.c:4679 Fixes: d1da932ed4ec ("ipv6: Separate ipv6 offload support") Reported-by: syzbot+af43e647fd835acc02df@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/688a1a05.050a0220.5d226.0008.GAE@google.com/T/#u Signed-off-by: Eric Dumazet Reviewed-by: Dawid Osuchowski Reviewed-by: Willem de Bruijn Link: https://patch.msgid.link/20250730131738.3385939-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- include/linux/skbuff.h | 23 +++++++++++++++++++++++ net/ipv6/ip6_offload.c | 4 +++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 4edce28fb454..d9abd9e6833e 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2493,6 +2493,29 @@ static inline void skb_reset_transport_header(struct sk_buff *skb) skb->transport_header = skb->data - skb->head; } +/** + * skb_reset_transport_header_careful - conditionally reset transport header + * @skb: buffer to alter + * + * Hardened version of skb_reset_transport_header(). + * + * Returns: true if the operation was a success. + */ +static inline bool __must_check +skb_reset_transport_header_careful(struct sk_buff *skb) +{ + long offset = skb->data - skb->head; + + if (unlikely(offset != (typeof(skb->transport_header))offset)) + return false; + + if (unlikely(offset == (typeof(skb->transport_header))~0U)) + return false; + + skb->transport_header = offset; + return true; +} + static inline void skb_set_transport_header(struct sk_buff *skb, const int offset) { diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index b7b4ba68f3a2..0d9d11902b1b 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c @@ -109,7 +109,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, ops = rcu_dereference(inet6_offloads[proto]); if (likely(ops && ops->callbacks.gso_segment)) { - skb_reset_transport_header(skb); + if (!skb_reset_transport_header_careful(skb)) + goto out; + segs = ops->callbacks.gso_segment(skb, features); if (!segs) skb->network_header = skb_mac_header(skb) + nhoff - skb->head; From 72f97d3cb791e26492236b2be7fd70d2c6222555 Mon Sep 17 00:00:00 2001 From: Wang Liang Date: Wed, 30 Jul 2025 18:14:58 +0800 Subject: [PATCH 144/404] net: drop UFO packets in udp_rcv_segment() [ Upstream commit d46e51f1c78b9ab9323610feb14238d06d46d519 ] When sending a packet with virtio_net_hdr to tun device, if the gso_type in virtio_net_hdr is SKB_GSO_UDP and the gso_size is less than udphdr size, below crash may happen. ------------[ cut here ]------------ kernel BUG at net/core/skbuff.c:4572! Oops: invalid opcode: 0000 [#1] SMP NOPTI CPU: 0 UID: 0 PID: 62 Comm: mytest Not tainted 6.16.0-rc7 #203 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 RIP: 0010:skb_pull_rcsum+0x8e/0xa0 Code: 00 00 5b c3 cc cc cc cc 8b 93 88 00 00 00 f7 da e8 37 44 38 00 f7 d8 89 83 88 00 00 00 48 8b 83 c8 00 00 00 5b c3 cc cc cc cc <0f> 0b 0f 0b 66 66 2e 0f 1f 84 00 000 RSP: 0018:ffffc900001fba38 EFLAGS: 00000297 RAX: 0000000000000004 RBX: ffff8880040c1000 RCX: ffffc900001fb948 RDX: ffff888003e6d700 RSI: 0000000000000008 RDI: ffff88800411a062 RBP: ffff8880040c1000 R08: 0000000000000000 R09: 0000000000000001 R10: ffff888003606c00 R11: 0000000000000001 R12: 0000000000000000 R13: ffff888004060900 R14: ffff888004050000 R15: ffff888004060900 FS: 000000002406d3c0(0000) GS:ffff888084a19000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020000040 CR3: 0000000004007000 CR4: 00000000000006f0 Call Trace: udp_queue_rcv_one_skb+0x176/0x4b0 net/ipv4/udp.c:2445 udp_queue_rcv_skb+0x155/0x1f0 net/ipv4/udp.c:2475 udp_unicast_rcv_skb+0x71/0x90 net/ipv4/udp.c:2626 __udp4_lib_rcv+0x433/0xb00 net/ipv4/udp.c:2690 ip_protocol_deliver_rcu+0xa6/0x160 net/ipv4/ip_input.c:205 ip_local_deliver_finish+0x72/0x90 net/ipv4/ip_input.c:233 ip_sublist_rcv_finish+0x5f/0x70 net/ipv4/ip_input.c:579 ip_sublist_rcv+0x122/0x1b0 net/ipv4/ip_input.c:636 ip_list_rcv+0xf7/0x130 net/ipv4/ip_input.c:670 __netif_receive_skb_list_core+0x21d/0x240 net/core/dev.c:6067 netif_receive_skb_list_internal+0x186/0x2b0 net/core/dev.c:6210 napi_complete_done+0x78/0x180 net/core/dev.c:6580 tun_get_user+0xa63/0x1120 drivers/net/tun.c:1909 tun_chr_write_iter+0x65/0xb0 drivers/net/tun.c:1984 vfs_write+0x300/0x420 fs/read_write.c:593 ksys_write+0x60/0xd0 fs/read_write.c:686 do_syscall_64+0x50/0x1c0 arch/x86/entry/syscall_64.c:63 To trigger gso segment in udp_queue_rcv_skb(), we should also set option UDP_ENCAP_ESPINUDP to enable udp_sk(sk)->encap_rcv. When the encap_rcv hook return 1 in udp_queue_rcv_one_skb(), udp_csum_pull_header() will try to pull udphdr, but the skb size has been segmented to gso size, which leads to this crash. Previous commit cf329aa42b66 ("udp: cope with UDP GRO packet misdirection") introduces segmentation in UDP receive path only for GRO, which was never intended to be used for UFO, so drop UFO packets in udp_rcv_segment(). Link: https://lore.kernel.org/netdev/20250724083005.3918375-1-wangliang74@huawei.com/ Link: https://lore.kernel.org/netdev/20250729123907.3318425-1-wangliang74@huawei.com/ Fixes: cf329aa42b66 ("udp: cope with UDP GRO packet misdirection") Suggested-by: Willem de Bruijn Signed-off-by: Wang Liang Reviewed-by: Willem de Bruijn Link: https://patch.msgid.link/20250730101458.3470788-1-wangliang74@huawei.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- include/net/udp.h | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/include/net/udp.h b/include/net/udp.h index 7323f72fed70..bab7b68c5f6d 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -471,6 +471,16 @@ static inline struct sk_buff *udp_rcv_segment(struct sock *sk, { netdev_features_t features = NETIF_F_SG; struct sk_buff *segs; + int drop_count; + + /* + * Segmentation in UDP receive path is only for UDP GRO, drop udp + * fragmentation offload (UFO) packets. + */ + if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP) { + drop_count = 1; + goto drop; + } /* Avoid csum recalculation by skb_segment unless userspace explicitly * asks for the final checksum values @@ -494,16 +504,18 @@ static inline struct sk_buff *udp_rcv_segment(struct sock *sk, */ segs = __skb_gso_segment(skb, features, false); if (IS_ERR_OR_NULL(segs)) { - int segs_nr = skb_shinfo(skb)->gso_segs; - - atomic_add(segs_nr, &sk->sk_drops); - SNMP_ADD_STATS(__UDPX_MIB(sk, ipv4), UDP_MIB_INERRORS, segs_nr); - kfree_skb(skb); - return NULL; + drop_count = skb_shinfo(skb)->gso_segs; + goto drop; } consume_skb(skb); return segs; + +drop: + atomic_add(drop_count, &sk->sk_drops); + SNMP_ADD_STATS(__UDPX_MIB(sk, ipv4), UDP_MIB_INERRORS, drop_count); + kfree_skb(skb); + return NULL; } #endif /* _UDP_H */ From 3697e37e012bbd2bb5a5b467689811ba097b2eff Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Fri, 1 Aug 2025 12:13:37 +0200 Subject: [PATCH 145/404] benet: fix BUG when creating VFs [ Upstream commit 5a40f8af2ba1b9bdf46e2db10e8c9710538fbc63 ] benet crashes as soon as SRIOV VFs are created: kernel BUG at mm/vmalloc.c:3457! Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI CPU: 4 UID: 0 PID: 7408 Comm: test.sh Kdump: loaded Not tainted 6.16.0+ #1 PREEMPT(voluntary) [...] RIP: 0010:vunmap+0x5f/0x70 [...] Call Trace: __iommu_dma_free+0xe8/0x1c0 be_cmd_set_mac_list+0x3fe/0x640 [be2net] be_cmd_set_mac+0xaf/0x110 [be2net] be_vf_eth_addr_config+0x19f/0x330 [be2net] be_vf_setup+0x4f7/0x990 [be2net] be_pci_sriov_configure+0x3a1/0x470 [be2net] sriov_numvfs_store+0x20b/0x380 kernfs_fop_write_iter+0x354/0x530 vfs_write+0x9b9/0xf60 ksys_write+0xf3/0x1d0 do_syscall_64+0x8c/0x3d0 be_cmd_set_mac_list() calls dma_free_coherent() under a spin_lock_bh. Fix it by freeing only after the lock has been released. Fixes: 1a82d19ca2d6 ("be2net: fix sleeping while atomic bugs in be_ndo_bridge_getlink") Signed-off-by: Michal Schmidt Reviewed-by: Nikolay Aleksandrov Link: https://patch.msgid.link/20250801101338.72502-1-mschmidt@redhat.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/emulex/benet/be_cmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index d9bceb26f4e5..d6984c179bae 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -3851,8 +3851,8 @@ int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, status = be_mcc_notify_wait(adapter); err: - dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); spin_unlock_bh(&adapter->mcc_lock); + dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); return status; } From 0fbf5e367d7684fd5138cb3099cc7f7c8d16f93b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 4 Aug 2025 14:10:15 +0200 Subject: [PATCH 146/404] smb: client: let recv_done() cleanup before notifying the callers. [ Upstream commit bdd7afc6dca5e0ebbb75583484aa6ea9e03fbb13 ] We should call put_receive_buffer() before waking up the callers. For the internal error case of response->type being unexpected, we now also call smbd_disconnect_rdma_connection() instead of not waking up the callers at all. Note that the SMBD_TRANSFER_DATA case still has problems, which will be addressed in the next commit in order to make it easier to review this one. Cc: Steve French Cc: Tom Talpey Cc: Long Li Cc: linux-cifs@vger.kernel.org Cc: samba-technical@lists.samba.org Fixes: f198186aa9bb ("CIFS: SMBD: Establish SMB Direct connection") Signed-off-by: Stefan Metzmacher Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/smbdirect.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index 0842a1af0b98..72df002e8ae3 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c @@ -495,7 +495,6 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) { log_rdma_recv(INFO, "wc->status=%d opcode=%d\n", wc->status, wc->opcode); - smbd_disconnect_rdma_connection(info); goto error; } @@ -512,8 +511,9 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) info->full_packet_received = true; info->negotiate_done = process_negotiation_response(response, wc->byte_len); + put_receive_buffer(info, response); complete(&info->negotiate_completion); - break; + return; /* SMBD data transfer packet */ case SMBD_TRANSFER_DATA: @@ -565,14 +565,16 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) queue_work(info->workqueue, &info->recv_done_work); return; - - default: - log_rdma_recv(ERR, - "unexpected response type=%d\n", response->type); } + /* + * This is an internal error! + */ + log_rdma_recv(ERR, "unexpected response type=%d\n", response->type); + WARN_ON_ONCE(response->type != SMBD_TRANSFER_DATA); error: put_receive_buffer(info, response); + smbd_disconnect_rdma_connection(info); } static struct rdma_cm_id *smbd_create_id( From 8ff1aa99d2ad81dccefb87c6e83b62557454e52f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 7 Aug 2025 14:21:46 +0000 Subject: [PATCH 147/404] pptp: fix pptp_xmit() error path [ Upstream commit ae633388cae349886f1a3cfb27aa092854b24c1b ] I accidentally added a bug in pptp_xmit() that syzbot caught for us. Only call ip_rt_put() if a route has been allocated. BUG: unable to handle page fault for address: ffffffffffffffdb PGD df3b067 P4D df3b067 PUD df3d067 PMD 0 Oops: Oops: 0002 [#1] SMP KASAN PTI CPU: 1 UID: 0 PID: 6346 Comm: syz.0.336 Not tainted 6.16.0-next-20250804-syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025 RIP: 0010:arch_atomic_add_return arch/x86/include/asm/atomic.h:85 [inline] RIP: 0010:raw_atomic_sub_return_release include/linux/atomic/atomic-arch-fallback.h:846 [inline] RIP: 0010:atomic_sub_return_release include/linux/atomic/atomic-instrumented.h:327 [inline] RIP: 0010:__rcuref_put include/linux/rcuref.h:109 [inline] RIP: 0010:rcuref_put+0x172/0x210 include/linux/rcuref.h:173 Call Trace: dst_release+0x24/0x1b0 net/core/dst.c:167 ip_rt_put include/net/route.h:285 [inline] pptp_xmit+0x14b/0x1a90 drivers/net/ppp/pptp.c:267 __ppp_channel_push+0xf2/0x1c0 drivers/net/ppp/ppp_generic.c:2166 ppp_channel_push+0x123/0x660 drivers/net/ppp/ppp_generic.c:2198 ppp_write+0x2b0/0x400 drivers/net/ppp/ppp_generic.c:544 vfs_write+0x27b/0xb30 fs/read_write.c:684 ksys_write+0x145/0x250 fs/read_write.c:738 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f Fixes: de9c4861fb42 ("pptp: ensure minimal skb length in pptp_xmit()") Reported-by: syzbot+27d7cfbc93457e472e00@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/689095a5.050a0220.1fc43d.0009.GAE@google.com/ Signed-off-by: Eric Dumazet Link: https://patch.msgid.link/20250807142146.2877060-1-edumazet@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ppp/pptp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index 5e2f4702aa2b..83541444bc8c 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c @@ -141,13 +141,13 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) int len; unsigned char *data; __u32 seq_recv; - struct rtable *rt = NULL; + struct rtable *rt; struct net_device *tdev; struct iphdr *iph; int max_headroom; if (sk_pppox(po)->sk_state & PPPOX_DEAD) - goto tx_error; + goto tx_drop; rt = ip_route_output_ports(net, &fl4, NULL, opt->dst_addr.sin_addr.s_addr, @@ -155,7 +155,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) 0, 0, IPPROTO_GRE, RT_TOS(0), 0); if (IS_ERR(rt)) - goto tx_error; + goto tx_drop; tdev = rt->dst.dev; @@ -251,6 +251,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) tx_error: ip_rt_put(rt); +tx_drop: kfree_skb(skb); return 1; } From db3984ebe1da447b76f01c3277f2091918df3436 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 2 Aug 2025 12:39:39 +0200 Subject: [PATCH 148/404] perf/core: Don't leak AUX buffer refcount on allocation failure commit 5468c0fbccbb9d156522c50832244a8b722374fb upstream. Failure of the AUX buffer allocation leaks the reference count. Set the reference count to 1 only when the allocation succeeds. Fixes: 45bfb2e50471 ("perf/core: Add AUX area to ring buffer for raw data streams") Signed-off-by: Thomas Gleixner Reviewed-by: Lorenzo Stoakes Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- kernel/events/core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index ecae7c7f895b..0d5b343dad83 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5877,9 +5877,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) goto unlock; } - atomic_set(&rb->aux_mmap_count, 1); user_extra = nr_pages; - goto accounting; } @@ -5986,8 +5984,10 @@ accounting: } else { ret = rb_alloc_aux(rb, event, vma->vm_pgoff, nr_pages, event->attr.aux_watermark, flags); - if (!ret) + if (!ret) { + atomic_set(&rb->aux_mmap_count, 1); rb->aux_mmap_locked = extra; + } } unlock: @@ -5997,6 +5997,7 @@ unlock: atomic_inc(&event->mmap_count); } else if (rb) { + /* AUX allocation failed */ atomic_dec(&rb->mmap_count); } aux_unlock: From 5ffda7f3ed76ec8defc19d985e33b3b82ba07839 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 2 Aug 2025 12:49:48 +0200 Subject: [PATCH 149/404] perf/core: Exit early on perf_mmap() fail commit 07091aade394f690e7b655578140ef84d0e8d7b0 upstream. When perf_mmap() fails to allocate a buffer, it still invokes the event_mapped() callback of the related event. On X86 this might increase the perf_rdpmc_allowed reference counter. But nothing undoes this as perf_mmap_close() is never called in this case, which causes another reference count leak. Return early on failure to prevent that. Fixes: 1e0fb9ec679c ("perf/core: Add pmu callbacks to track event mapping and unmapping") Signed-off-by: Thomas Gleixner Reviewed-by: Lorenzo Stoakes Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- kernel/events/core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/events/core.c b/kernel/events/core.c index 0d5b343dad83..ee902a68c4ce 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6003,6 +6003,9 @@ unlock: aux_unlock: mutex_unlock(&event->mmap_mutex); + if (ret) + return ret; + /* * Since pinned accounting is per vm we cannot allow fork() to copy our * vma. From e4346ffec2c44d6b0be834d59b20632b5bb5729e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jul 2025 23:01:21 +0200 Subject: [PATCH 150/404] perf/core: Prevent VMA split of buffer mappings commit b024d7b56c77191cde544f838debb7f8451cd0d6 upstream. The perf mmap code is careful about mmap()'ing the user page with the ringbuffer and additionally the auxiliary buffer, when the event supports it. Once the first mapping is established, subsequent mapping have to use the same offset and the same size in both cases. The reference counting for the ringbuffer and the auxiliary buffer depends on this being correct. Though perf does not prevent that a related mapping is split via mmap(2), munmap(2) or mremap(2). A split of a VMA results in perf_mmap_open() calls, which take reference counts, but then the subsequent perf_mmap_close() calls are not longer fulfilling the offset and size checks. This leads to reference count leaks. As perf already has the requirement for subsequent mappings to match the initial mapping, the obvious consequence is that VMA splits, caused by resizing of a mapping or partial unmapping, have to be prevented. Implement the vm_operations_struct::may_split() callback and return unconditionally -EINVAL. That ensures that the mapping offsets and sizes cannot be changed after the fact. Remapping to a different fixed address with the same size is still possible as it takes the references for the new mapping and drops those of the old mapping. Fixes: 45bfb2e50471 ("perf/core: Add AUX area to ring buffer for raw data streams") Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-27504 Signed-off-by: Thomas Gleixner Reviewed-by: Lorenzo Stoakes Acked-by: Arnaldo Carvalho de Melo Acked-by: Vlastimil Babka Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- kernel/events/core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/kernel/events/core.c b/kernel/events/core.c index ee902a68c4ce..6816507803fc 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5789,11 +5789,21 @@ out_put: ring_buffer_put(rb); /* could be last */ } +static int perf_mmap_may_split(struct vm_area_struct *vma, unsigned long addr) +{ + /* + * Forbid splitting perf mappings to prevent refcount leaks due to + * the resulting non-matching offsets and sizes. See open()/close(). + */ + return -EINVAL; +} + static const struct vm_operations_struct perf_mmap_vmops = { .open = perf_mmap_open, .close = perf_mmap_close, /* non mergeable */ .fault = perf_mmap_fault, .page_mkwrite = perf_mmap_fault, + .split = perf_mmap_may_split, }; static int perf_mmap(struct file *file, struct vm_area_struct *vma) From 18f13f2a83eb81be349a9757ba2141ff1da9ad73 Mon Sep 17 00:00:00 2001 From: Quang Le Date: Fri, 1 Aug 2025 13:54:16 -0400 Subject: [PATCH 151/404] net/packet: fix a race in packet_set_ring() and packet_notifier() commit 01d3c8417b9c1b884a8a981a3b886da556512f36 upstream. When packet_set_ring() releases po->bind_lock, another thread can run packet_notifier() and process an NETDEV_UP event. This race and the fix are both similar to that of commit 15fe076edea7 ("net/packet: fix a race in packet_bind() and packet_notifier()"). There too the packet_notifier NETDEV_UP event managed to run while a po->bind_lock critical section had to be temporarily released. And the fix was similarly to temporarily set po->num to zero to keep the socket unhooked until the lock is retaken. The po->bind_lock in packet_set_ring and packet_notifier precede the introduction of git history. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Quang Le Signed-off-by: Willem de Bruijn Link: https://patch.msgid.link/20250801175423.2970334-1-willemdebruijn.kernel@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/packet/af_packet.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index d9799310ef0d..c6a301516bb0 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -4504,10 +4504,10 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, spin_lock(&po->bind_lock); was_running = po->running; num = po->num; - if (was_running) { - WRITE_ONCE(po->num, 0); + WRITE_ONCE(po->num, 0); + if (was_running) __unregister_prot_hook(sk, false); - } + spin_unlock(&po->bind_lock); synchronize_net(); @@ -4539,10 +4539,10 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, mutex_unlock(&po->pg_vec_lock); spin_lock(&po->bind_lock); - if (was_running) { - WRITE_ONCE(po->num, num); + WRITE_ONCE(po->num, num); + if (was_running) register_prot_hook(sk); - } + spin_unlock(&po->bind_lock); if (pg_vec && (po->tp_version > TPACKET_V2)) { /* Because we don't support block-based V3 on tx-ring */ From c04a2c1ca25b9b23104124d3b2d349d934e302de Mon Sep 17 00:00:00 2001 From: Budimir Markovic Date: Thu, 7 Aug 2025 04:18:11 +0000 Subject: [PATCH 152/404] vsock: Do not allow binding to VMADDR_PORT_ANY commit aba0c94f61ec05315fa7815d21aefa4c87f6a9f4 upstream. It is possible for a vsock to autobind to VMADDR_PORT_ANY. This can cause a use-after-free when a connection is made to the bound socket. The socket returned by accept() also has port VMADDR_PORT_ANY but is not on the list of unbound sockets. Binding it will result in an extra refcount decrement similar to the one fixed in fcdd2242c023 (vsock: Keep the binding until socket destruction). Modify the check in __vsock_bind_connectible() to also prevent binding to VMADDR_PORT_ANY. Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") Reported-by: Budimir Markovic Signed-off-by: Budimir Markovic Reviewed-by: Stefano Garzarella Link: https://patch.msgid.link/20250807041811.678-1-markovicbudimir@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/vmw_vsock/af_vsock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 7877515a6962..831ca8da8481 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -487,7 +487,8 @@ static int __vsock_bind_stream(struct vsock_sock *vsk, unsigned int i; for (i = 0; i < MAX_PORT_RETRIES; i++) { - if (port <= LAST_RESERVED_PORT) + if (port == VMADDR_PORT_ANY || + port <= LAST_RESERVED_PORT) port = LAST_RESERVED_PORT + 1; new_addr.svm_port = port++; From 1db292bca68eb52b38673db3eb4edca2a5f34251 Mon Sep 17 00:00:00 2001 From: Slark Xiao Date: Mon, 21 Jul 2025 19:39:19 +0800 Subject: [PATCH 153/404] USB: serial: option: add Foxconn T99W709 commit ad1244e1ce18f8c1a5ebad8074bfcf10eacb0311 upstream. T99W709 is designed based on MTK T300(5G redcap) chip. There are 7 serial ports to be enumerated: AP_LOG, GNSS, AP_META, AT, MD_META, NPT, DBG. RSVD(5) for ADB port. test evidence as below: T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 7 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e15f Rev=00.01 S: Manufacturer=MediaTek Inc. S: Product=USB DATA CARD S: SerialNumber=355511220000399 C: #Ifs=10 Cfg#= 1 Atr=a0 MxPwr=500mA I: If#=0x0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim I: If#=0x1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I: If#=0x2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs I: If#=0x6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x7 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x8 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option I: If#=0x9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option Signed-off-by: Slark Xiao Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 70c70461655a..233be8250b61 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -2346,6 +2346,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = RSVD(3) }, { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe145, 0xff), /* Foxconn T99W651 RNDIS */ .driver_info = RSVD(5) | RSVD(6) }, + { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe15f, 0xff), /* Foxconn T99W709 */ + .driver_info = RSVD(5) }, { USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe167, 0xff), /* Foxconn T99W640 MBIM */ .driver_info = RSVD(3) }, { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */ From 020f105387c4095e8d9f335ed37980564127b497 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Sat, 7 Jun 2025 13:43:56 +0100 Subject: [PATCH 154/404] MIPS: mm: tlb-r4k: Uniquify TLB entries on init commit 35ad7e181541aa5757f9f316768d3e64403ec843 upstream. Hardware or bootloader will initialize TLB entries to any value, which may collide with kernel's UNIQUE_ENTRYHI value. On MIPS microAptiv/M5150 family of cores this will trigger machine check exception and cause boot failure. On M5150 simulation this could happen 7 times out of 1000 boots. Replace local_flush_tlb_all() with r4k_tlb_uniquify() which probes each TLB ENTRIHI unique value for collisions before it's written, and in case of collision try a different ASID. Cc: stable@kernel.org Signed-off-by: Jiaxun Yang Signed-off-by: Thomas Bogendoerfer Signed-off-by: Greg Kroah-Hartman --- arch/mips/mm/tlb-r4k.c | 56 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index b6104d9413e0..5f63235e110e 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -497,6 +497,60 @@ static int __init set_ntlb(char *str) __setup("ntlb=", set_ntlb); +/* Initialise all TLB entries with unique values */ +static void r4k_tlb_uniquify(void) +{ + int entry = num_wired_entries(); + + htw_stop(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + + while (entry < current_cpu_data.tlbsize) { + unsigned long asid_mask = cpu_asid_mask(¤t_cpu_data); + unsigned long asid = 0; + int idx; + + /* Skip wired MMID to make ginvt_mmid work */ + if (cpu_has_mmid) + asid = MMID_KERNEL_WIRED + 1; + + /* Check for match before using UNIQUE_ENTRYHI */ + do { + if (cpu_has_mmid) { + write_c0_memorymapid(asid); + write_c0_entryhi(UNIQUE_ENTRYHI(entry)); + } else { + write_c0_entryhi(UNIQUE_ENTRYHI(entry) | asid); + } + mtc0_tlbw_hazard(); + tlb_probe(); + tlb_probe_hazard(); + idx = read_c0_index(); + /* No match or match is on current entry */ + if (idx < 0 || idx == entry) + break; + /* + * If we hit a match, we need to try again with + * a different ASID. + */ + asid++; + } while (asid < asid_mask); + + if (idx >= 0 && idx != entry) + panic("Unable to uniquify TLB entry %d", idx); + + write_c0_index(entry); + mtc0_tlbw_hazard(); + tlb_write_indexed(); + entry++; + } + + tlbw_use_hazard(); + htw_start(); + flush_micro_tlb(); +} + /* * Configure TLB (for init or after a CPU has been powered off). */ @@ -536,7 +590,7 @@ static void r4k_tlb_configure(void) temp_tlb_entry = current_cpu_data.tlbsize - 1; /* From this point on the ARC firmware is dead. */ - local_flush_tlb_all(); + r4k_tlb_uniquify(); /* Did I tell you that ARC SUCKS? */ } From dba96dfa5a0f685b959dd28a52ac8dab0b805204 Mon Sep 17 00:00:00 2001 From: Tao Xue Date: Mon, 21 Jul 2025 17:39:08 +0800 Subject: [PATCH 155/404] usb: gadget : fix use-after-free in composite_dev_cleanup() commit 151c0aa896c47a4459e07fee7d4843f44c1bb18e upstream. 1. In func configfs_composite_bind() -> composite_os_desc_req_prepare(): if kmalloc fails, the pointer cdev->os_desc_req will be freed but not set to NULL. Then it will return a failure to the upper-level function. 2. in func configfs_composite_bind() -> composite_dev_cleanup(): it will checks whether cdev->os_desc_req is NULL. If it is not NULL, it will attempt to use it.This will lead to a use-after-free issue. BUG: KASAN: use-after-free in composite_dev_cleanup+0xf4/0x2c0 Read of size 8 at addr 0000004827837a00 by task init/1 CPU: 10 PID: 1 Comm: init Tainted: G O 5.10.97-oh #1 kasan_report+0x188/0x1cc __asan_load8+0xb4/0xbc composite_dev_cleanup+0xf4/0x2c0 configfs_composite_bind+0x210/0x7ac udc_bind_to_driver+0xb4/0x1ec usb_gadget_probe_driver+0xec/0x21c gadget_dev_desc_UDC_store+0x264/0x27c Fixes: 37a3a533429e ("usb: gadget: OS Feature Descriptors support") Cc: stable Signed-off-by: Tao Xue Link: https://lore.kernel.org/r/20250721093908.14967-1-xuetao09@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/composite.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 4b2e9df97b11..55597a898f40 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2241,6 +2241,11 @@ int composite_os_desc_req_prepare(struct usb_composite_dev *cdev, if (!cdev->os_desc_req->buf) { ret = -ENOMEM; usb_ep_free_request(ep0, cdev->os_desc_req); + /* + * Set os_desc_req to NULL so that composite_dev_cleanup() + * will not try to free it again. + */ + cdev->os_desc_req = NULL; goto end; } cdev->os_desc_req->context = cdev; From 6d96e0c7cf283af8811283ee4aca82f7bafbff7c Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Wed, 2 Jul 2025 21:31:54 +0100 Subject: [PATCH 156/404] io_uring: don't use int for ABI commit cf73d9970ea4f8cace5d8f02d2565a2723003112 upstream. __kernel_rwf_t is defined as int, the actual size of which is implementation defined. It won't go well if some compiler / archs ever defines it as i64, so replace it with __u32, hoping that there is no one using i16 for it. Cc: stable@vger.kernel.org Fixes: 2b188cc1bb857 ("Add io_uring IO interface") Signed-off-by: Pavel Begunkov Link: https://lore.kernel.org/r/47c666c4ee1df2018863af3a2028af18feef11ed.1751412511.git.asml.silence@gmail.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/io_uring.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index ea57526a5b89..1bad6701f2b2 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -23,7 +23,7 @@ struct io_uring_sqe { __u64 addr; /* pointer to buffer or iovecs */ __u32 len; /* buffer size or number of iovecs */ union { - __kernel_rwf_t rw_flags; + __u32 rw_flags; __u32 fsync_flags; __u16 poll_events; __u32 sync_range_flags; From 1666207ba0a5973735ef010812536adde6174e81 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 14 Aug 2025 10:12:42 +0200 Subject: [PATCH 157/404] ALSA: usb-audio: Validate UAC3 power domain descriptors, too commit d832ccbc301fbd9e5a1d691bdcf461cdb514595f upstream. UAC3 power domain descriptors need to be verified with its variable bLength for avoiding the unexpected OOB accesses by malicious firmware, too. Fixes: 9a2fe9b801f5 ("ALSA: usb: initial USB Audio Device Class 3.0 support") Reported-and-tested-by: Youngjun Lee Cc: Link: https://patch.msgid.link/20250814081245.8902-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/validate.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/usb/validate.c b/sound/usb/validate.c index 89a48d731719..4ee2a328cb5b 100644 --- a/sound/usb/validate.c +++ b/sound/usb/validate.c @@ -221,6 +221,17 @@ static bool validate_uac3_feature_unit(const void *p, return d->bLength >= sizeof(*d) + 4 + 2; } +static bool validate_uac3_power_domain_unit(const void *p, + const struct usb_desc_validator *v) +{ + const struct uac3_power_domain_descriptor *d = p; + + if (d->bLength < sizeof(*d)) + return false; + /* baEntities[] + wPDomainDescrStr */ + return d->bLength >= sizeof(*d) + d->bNrEntities + 2; +} + static bool validate_midi_out_jack(const void *p, const struct usb_desc_validator *v) { @@ -285,6 +296,7 @@ static const struct usb_desc_validator audio_validators[] = { struct uac3_clock_multiplier_descriptor), /* UAC_VERSION_3, UAC3_SAMPLE_RATE_CONVERTER: not implemented yet */ /* UAC_VERSION_3, UAC3_CONNECTORS: not implemented yet */ + FUNC(UAC_VERSION_3, UAC3_POWER_DOMAIN, validate_uac3_power_domain_unit), { } /* terminator */ }; From 799c06ad4c9c790c265e8b6b94947213f1fb389c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 14 Aug 2025 10:12:43 +0200 Subject: [PATCH 158/404] ALSA: usb-audio: Validate UAC3 cluster segment descriptors commit ecfd41166b72b67d3bdeb88d224ff445f6163869 upstream. UAC3 class segment descriptors need to be verified whether their sizes match with the declared lengths and whether they fit with the allocated buffer sizes, too. Otherwise malicious firmware may lead to the unexpected OOB accesses. Fixes: 11785ef53228 ("ALSA: usb-audio: Initial Power Domain support") Reported-and-tested-by: Youngjun Lee Cc: Link: https://patch.msgid.link/20250814081245.8902-2-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/stream.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/sound/usb/stream.c b/sound/usb/stream.c index d698b609fe52..47cfaf29fdd7 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -342,20 +342,28 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor len = le16_to_cpu(cluster->wLength); c = 0; - p += sizeof(struct uac3_cluster_header_descriptor); + p += sizeof(*cluster); + len -= sizeof(*cluster); - while (((p - (void *)cluster) < len) && (c < channels)) { + while (len > 0 && (c < channels)) { struct uac3_cluster_segment_descriptor *cs_desc = p; u16 cs_len; u8 cs_type; + if (len < sizeof(*p)) + break; cs_len = le16_to_cpu(cs_desc->wLength); + if (len < cs_len) + break; cs_type = cs_desc->bSegmentType; if (cs_type == UAC3_CHANNEL_INFORMATION) { struct uac3_cluster_information_segment_descriptor *is = p; unsigned char map; + if (cs_len < sizeof(*is)) + break; + /* * TODO: this conversion is not complete, update it * after adding UAC3 values to asound.h @@ -457,6 +465,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor chmap->map[c++] = map; } p += cs_len; + len -= cs_len; } if (channels < c) @@ -873,7 +882,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip, u64 badd_formats = 0; unsigned int num_channels; struct audioformat *fp; - u16 cluster_id, wLength; + u16 cluster_id, wLength, cluster_wLength; int clock = 0; int err; @@ -1002,6 +1011,16 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip, return ERR_PTR(-EIO); } + cluster_wLength = le16_to_cpu(cluster->wLength); + if (cluster_wLength < sizeof(*cluster) || + cluster_wLength > wLength) { + dev_err(&dev->dev, + "%u:%d : invalid Cluster Descriptor size\n", + iface_no, altno); + kfree(cluster); + return ERR_PTR(-EIO); + } + num_channels = cluster->bNrChannels; chmap = convert_chmap_v3(cluster); kfree(cluster); From 47d49fd07f86d1f55ea1083287303d237e9e0922 Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Mon, 28 Jul 2025 11:06:47 +0300 Subject: [PATCH 159/404] netlink: avoid infinite retry looping in netlink_unicast() commit 759dfc7d04bab1b0b86113f1164dc1fec192b859 upstream. netlink_attachskb() checks for the socket's read memory allocation constraints. Firstly, it has: rmem < READ_ONCE(sk->sk_rcvbuf) to check if the just increased rmem value fits into the socket's receive buffer. If not, it proceeds and tries to wait for the memory under: rmem + skb->truesize > READ_ONCE(sk->sk_rcvbuf) The checks don't cover the case when skb->truesize + sk->sk_rmem_alloc is equal to sk->sk_rcvbuf. Thus the function neither successfully accepts these conditions, nor manages to reschedule the task - and is called in retry loop for indefinite time which is caught as: rcu: INFO: rcu_sched self-detected stall on CPU rcu: 0-....: (25999 ticks this GP) idle=ef2/1/0x4000000000000000 softirq=262269/262269 fqs=6212 (t=26000 jiffies g=230833 q=259957) NMI backtrace for cpu 0 CPU: 0 PID: 22 Comm: kauditd Not tainted 5.10.240 #68 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-4.fc42 04/01/2014 Call Trace: dump_stack lib/dump_stack.c:120 nmi_cpu_backtrace.cold lib/nmi_backtrace.c:105 nmi_trigger_cpumask_backtrace lib/nmi_backtrace.c:62 rcu_dump_cpu_stacks kernel/rcu/tree_stall.h:335 rcu_sched_clock_irq.cold kernel/rcu/tree.c:2590 update_process_times kernel/time/timer.c:1953 tick_sched_handle kernel/time/tick-sched.c:227 tick_sched_timer kernel/time/tick-sched.c:1399 __hrtimer_run_queues kernel/time/hrtimer.c:1652 hrtimer_interrupt kernel/time/hrtimer.c:1717 __sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1113 asm_call_irq_on_stack arch/x86/entry/entry_64.S:808 netlink_attachskb net/netlink/af_netlink.c:1234 netlink_unicast net/netlink/af_netlink.c:1349 kauditd_send_queue kernel/audit.c:776 kauditd_thread kernel/audit.c:897 kthread kernel/kthread.c:328 ret_from_fork arch/x86/entry/entry_64.S:304 Restore the original behavior of the check which commit in Fixes accidentally missed when restructuring the code. Found by Linux Verification Center (linuxtesting.org). Fixes: ae8f160e7eb2 ("netlink: Fix wraparounds of sk->sk_rmem_alloc.") Cc: stable@vger.kernel.org Signed-off-by: Fedor Pchelkin Reviewed-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20250728080727.255138-1-pchelkin@ispras.ru Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/netlink/af_netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 808ca542bfba..3259fb5b58dd 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1212,7 +1212,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, nlk = nlk_sk(sk); rmem = atomic_add_return(skb->truesize, &sk->sk_rmem_alloc); - if ((rmem == skb->truesize || rmem < READ_ONCE(sk->sk_rcvbuf)) && + if ((rmem == skb->truesize || rmem <= READ_ONCE(sk->sk_rcvbuf)) && !test_bit(NETLINK_S_CONGESTED, &nlk->state)) { netlink_skb_set_owner_r(skb, sk); return 0; From aecfeb82ddcc1786d69975ff758069aa176ec2ec Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 25 Jul 2025 19:12:11 +0200 Subject: [PATCH 160/404] net: gianfar: fix device leak when querying time stamp info commit da717540acd34e5056e3fa35791d50f6b3303f55 upstream. Make sure to drop the reference to the ptp device taken by of_find_device_by_node() when querying the time stamping capabilities. Note that holding a reference to the ptp device does not prevent its driver data from going away. Fixes: 7349a74ea75c ("net: ethernet: gianfar_ethtool: get phc index through drvdata") Cc: stable@vger.kernel.org # 4.18 Cc: Yangbo Lu Signed-off-by: Johan Hovold Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250725171213.880-4-johan@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/freescale/gianfar_ethtool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 01a7255e86c9..e5cd8fe4bd0f 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c @@ -1490,8 +1490,10 @@ static int gfar_get_ts_info(struct net_device *dev, if (ptp_node) { ptp_dev = of_find_device_by_node(ptp_node); of_node_put(ptp_node); - if (ptp_dev) + if (ptp_dev) { ptp = platform_get_drvdata(ptp_dev); + put_device(&ptp_dev->dev); + } } if (ptp) From 736881a2a0976da492d37f1a8a2f0fd091e99aa3 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 25 Jul 2025 19:12:09 +0200 Subject: [PATCH 161/404] net: dpaa: fix device leak when querying time stamp info commit 3fa840230f534385b34a4f39c8dd313fbe723f05 upstream. Make sure to drop the reference to the ptp device taken by of_find_device_by_node() when querying the time stamping capabilities. Note that holding a reference to the ptp device does not prevent its driver data from going away. Fixes: 17ae0b0ee9db ("dpaa_eth: add the get_ts_info interface for ethtool") Cc: stable@vger.kernel.org # 4.19 Cc: Yangbo Lu Signed-off-by: Johan Hovold Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250725171213.880-2-johan@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c index 0a186d16e73f..3e44e60f15ff 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c @@ -516,8 +516,10 @@ static int dpaa_get_ts_info(struct net_device *net_dev, of_node_put(ptp_node); } - if (ptp_dev) + if (ptp_dev) { ptp = platform_get_drvdata(ptp_dev); + put_device(&ptp_dev->dev); + } if (ptp) info->phc_index = ptp->phc_index; From 6797a995937c4b0545447cc77733394fb286d19f Mon Sep 17 00:00:00 2001 From: Dai Ngo Date: Tue, 10 Jun 2025 08:35:28 -0700 Subject: [PATCH 162/404] NFSD: detect mismatch of file handle and delegation stateid in OPEN op commit 9c65001c57164033ad08b654c8b5ae35512ddf4a upstream. When the client sends an OPEN with claim type CLAIM_DELEG_CUR_FH or CLAIM_DELEGATION_CUR, the delegation stateid and the file handle must belong to the same file, otherwise return NFS4ERR_INVAL. Note that RFC8881, section 8.2.4, mandates the server to return NFS4ERR_BAD_STATEID if the selected table entry does not match the current filehandle. However returning NFS4ERR_BAD_STATEID in the OPEN causes the client to retry the operation and therefor get the client into a loop. To avoid this situation we return NFS4ERR_INVAL instead. Reported-by: Petro Pavlov Fixes: c44c5eeb2c02 ("[PATCH] nfsd4: add open state code for CLAIM_DELEGATE_CUR") Cc: stable@vger.kernel.org Signed-off-by: Dai Ngo Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever Signed-off-by: Greg Kroah-Hartman --- fs/nfsd/nfs4state.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index a3f8660803c7..1fd81ccf0c71 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5081,6 +5081,20 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf status = nfs4_check_deleg(cl, open, &dp); if (status) goto out; + if (dp && nfsd4_is_deleg_cur(open) && + (dp->dl_stid.sc_file != fp)) { + /* + * RFC8881 section 8.2.4 mandates the server to return + * NFS4ERR_BAD_STATEID if the selected table entry does + * not match the current filehandle. However returning + * NFS4ERR_BAD_STATEID in the OPEN can cause the client + * to repeatedly retry the operation with the same + * stateid, since the stateid itself is valid. To avoid + * this situation NFSD returns NFS4ERR_INVAL instead. + */ + status = nfserr_inval; + goto out; + } stp = nfsd4_find_and_lock_existing_open(fp, open); } else { open->op_file = NULL; From 944474274e9082aabc597f1b6bb6822f46188c41 Mon Sep 17 00:00:00 2001 From: Ma Ke Date: Sat, 19 Jul 2025 15:58:56 +0800 Subject: [PATCH 163/404] sunvdc: Balance device refcount in vdc_port_mpgroup_check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 63ce53724637e2e7ba51fe3a4f78351715049905 upstream. Using device_find_child() to locate a probed virtual-device-port node causes a device refcount imbalance, as device_find_child() internally calls get_device() to increment the device’s reference count before returning its pointer. vdc_port_mpgroup_check() directly returns true upon finding a matching device without releasing the reference via put_device(). We should call put_device() to decrement refcount. As comment of device_find_child() says, 'NOTE: you will need to drop the reference with put_device() after use'. Found by code review. Cc: stable@vger.kernel.org Fixes: 3ee70591d6c4 ("sunvdc: prevent sunvdc panic when mpgroup disk added to guest domain") Signed-off-by: Ma Ke Link: https://lore.kernel.org/r/20250719075856.3447953-1-make24@iscas.ac.cn Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/block/sunvdc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 6622dd1aa07b..59d73c3147b6 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -967,8 +967,10 @@ static bool vdc_port_mpgroup_check(struct vio_dev *vdev) dev = device_find_child(vdev->dev.parent, &port_data, vdc_device_probed); - if (dev) + if (dev) { + put_device(dev); return true; + } return false; } From b4159c5a90c03f8acd3de345a7f5fc63b0909818 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 29 Jun 2025 03:40:21 -0400 Subject: [PATCH 164/404] fs: Prevent file descriptor table allocations exceeding INT_MAX commit 04a2c4b4511d186b0fce685da21085a5d4acd370 upstream. When sysctl_nr_open is set to a very high value (for example, 1073741816 as set by systemd), processes attempting to use file descriptors near the limit can trigger massive memory allocation attempts that exceed INT_MAX, resulting in a WARNING in mm/slub.c: WARNING: CPU: 0 PID: 44 at mm/slub.c:5027 __kvmalloc_node_noprof+0x21a/0x288 This happens because kvmalloc_array() and kvmalloc() check if the requested size exceeds INT_MAX and emit a warning when the allocation is not flagged with __GFP_NOWARN. Specifically, when nr_open is set to 1073741816 (0x3ffffff8) and a process calls dup2(oldfd, 1073741880), the kernel attempts to allocate: - File descriptor array: 1073741880 * 8 bytes = 8,589,935,040 bytes - Multiple bitmaps: ~400MB - Total allocation size: > 8GB (exceeding INT_MAX = 2,147,483,647) Reproducer: 1. Set /proc/sys/fs/nr_open to 1073741816: # echo 1073741816 > /proc/sys/fs/nr_open 2. Run a program that uses a high file descriptor: #include #include int main() { struct rlimit rlim = {1073741824, 1073741824}; setrlimit(RLIMIT_NOFILE, &rlim); dup2(2, 1073741880); // Triggers the warning return 0; } 3. Observe WARNING in dmesg at mm/slub.c:5027 systemd commit a8b627a introduced automatic bumping of fs.nr_open to the maximum possible value. The rationale was that systems with memory control groups (memcg) no longer need separate file descriptor limits since memory is properly accounted. However, this change overlooked that: 1. The kernel's allocation functions still enforce INT_MAX as a maximum size regardless of memcg accounting 2. Programs and tests that legitimately test file descriptor limits can inadvertently trigger massive allocations 3. The resulting allocations (>8GB) are impractical and will always fail systemd's algorithm starts with INT_MAX and keeps halving the value until the kernel accepts it. On most systems, this results in nr_open being set to 1073741816 (0x3ffffff8), which is just under 1GB of file descriptors. While processes rarely use file descriptors near this limit in normal operation, certain selftests (like tools/testing/selftests/core/unshare_test.c) and programs that test file descriptor limits can trigger this issue. Fix this by adding a check in alloc_fdtable() to ensure the requested allocation size does not exceed INT_MAX. This causes the operation to fail with -EMFILE instead of triggering a kernel warning and avoids the impractical >8GB memory allocation request. Fixes: 9cfe015aa424 ("get rid of NR_OPEN and introduce a sysctl_nr_open") Cc: stable@vger.kernel.org Signed-off-by: Sasha Levin Link: https://lore.kernel.org/20250629074021.1038845-1-sashal@kernel.org Signed-off-by: Christian Brauner Signed-off-by: Greg Kroah-Hartman --- fs/file.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fs/file.c b/fs/file.c index cf7c04f35564..9574a9116468 100644 --- a/fs/file.c +++ b/fs/file.c @@ -104,6 +104,21 @@ static struct fdtable * alloc_fdtable(unsigned int nr) if (unlikely(nr > sysctl_nr_open)) nr = ((sysctl_nr_open - 1) | (BITS_PER_LONG - 1)) + 1; + /* + * Check if the allocation size would exceed INT_MAX. kvmalloc_array() + * and kvmalloc() will warn if the allocation size is greater than + * INT_MAX, as filp_cachep objects are not __GFP_NOWARN. + * + * This can happen when sysctl_nr_open is set to a very high value and + * a process tries to use a file descriptor near that limit. For example, + * if sysctl_nr_open is set to 1073741816 (0x3ffffff8) - which is what + * systemd typically sets it to - then trying to use a file descriptor + * close to that value will require allocating a file descriptor table + * that exceeds 8GB in size. + */ + if (unlikely(nr > INT_MAX / sizeof(struct file *))) + return ERR_PTR(-EMFILE); + fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL_ACCOUNT); if (!fdt) goto out; From b8cb1b57a5edcdac9f93cbbd53e7a30932bacab0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 10 Jul 2025 20:00:23 +0300 Subject: [PATCH 165/404] Documentation: ACPI: Fix parent device references commit e65cb011349e653ded541dddd6469c2ca813edcf upstream. The _CRS resources in many cases want to have ResourceSource field to be a type of ACPI String. This means that to compile properly we need to enclosure the name path into double quotes. This will in practice defer the interpretation to a run-time stage, However, this may be interpreted differently on different OSes and ACPI interpreter implementations. In particular ACPICA might not correctly recognize the leading '^' (caret) character and will not resolve the relative name path properly. On top of that, this piece may be used in SSDTs which are loaded after the DSDT and on itself may also not resolve relative name paths outside of their own scopes. With this all said, fix documentation to use fully-qualified name paths always to avoid any misinterpretations, which is proven to work. Fixes: 8eb5c87a92c0 ("i2c: add ACPI support for I2C mux ports") Reported-by: Yevhen Kondrashyn Cc: All applicable Signed-off-by: Andy Shevchenko Link: https://patch.msgid.link/20250710170225.961303-1-andriy.shevchenko@linux.intel.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- Documentation/firmware-guide/acpi/i2c-muxes.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/firmware-guide/acpi/i2c-muxes.rst b/Documentation/firmware-guide/acpi/i2c-muxes.rst index 3a8997ccd7c4..f366539acd79 100644 --- a/Documentation/firmware-guide/acpi/i2c-muxes.rst +++ b/Documentation/firmware-guide/acpi/i2c-muxes.rst @@ -14,7 +14,7 @@ Consider this topology:: | | | 0x70 |--CH01--> i2c client B (0x50) +------+ +------+ -which corresponds to the following ASL:: +which corresponds to the following ASL (in the scope of \_SB):: Device (SMB1) { @@ -24,7 +24,7 @@ which corresponds to the following ASL:: Name (_HID, ...) Name (_CRS, ResourceTemplate () { I2cSerialBus (0x70, ControllerInitiated, I2C_SPEED, - AddressingMode7Bit, "^SMB1", 0x00, + AddressingMode7Bit, "\\_SB.SMB1", 0x00, ResourceConsumer,,) } @@ -37,7 +37,7 @@ which corresponds to the following ASL:: Name (_HID, ...) Name (_CRS, ResourceTemplate () { I2cSerialBus (0x50, ControllerInitiated, I2C_SPEED, - AddressingMode7Bit, "^CH00", 0x00, + AddressingMode7Bit, "\\_SB.SMB1.CH00", 0x00, ResourceConsumer,,) } } @@ -52,7 +52,7 @@ which corresponds to the following ASL:: Name (_HID, ...) Name (_CRS, ResourceTemplate () { I2cSerialBus (0x50, ControllerInitiated, I2C_SPEED, - AddressingMode7Bit, "^CH01", 0x00, + AddressingMode7Bit, "\\_SB.SMB1.CH01", 0x00, ResourceConsumer,,) } } From bd844a24e56c1869adbf94ab4e30e655323495c7 Mon Sep 17 00:00:00 2001 From: Jiayi Li Date: Mon, 21 Jul 2025 11:26:06 +0800 Subject: [PATCH 166/404] ACPI: processor: perflib: Fix initial _PPC limit application commit d33bd88ac0ebb49e7f7c8f29a8c7ee9eae85d765 upstream. If the BIOS sets a _PPC frequency limit upfront, it will fail to take effect due to a call ordering issue. Namely, freq_qos_update_request() is called before freq_qos_add_request() for the given request causing the constraint update to be ignored. The call sequence in question is as follows: cpufreq_policy_online() acpi_cpufreq_cpu_init() acpi_processor_register_performance() acpi_processor_get_performance_info() acpi_processor_get_platform_limit() freq_qos_update_request(&perflib_req) <- inactive QoS request blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_CREATE_POLICY) acpi_processor_notifier() acpi_processor_ppc_init() freq_qos_add_request(&perflib_req) <- QoS request activation Address this by adding an acpi_processor_get_platform_limit() call to acpi_processor_ppc_init(), after the perflib_req activation via freq_qos_add_request(), which causes the initial _PPC limit to be picked up as appropriate. However, also ensure that the _PPC limit will not be picked up in the cases when the cpufreq driver does not call acpi_processor_register_performance() by adding a pr->performance check to the related_cpus loop in acpi_processor_ppc_init(). Fixes: d15ce412737a ("ACPI: cpufreq: Switch to QoS requests instead of cpufreq notifier") Signed-off-by: Jiayi Li Link: https://patch.msgid.link/20250721032606.3459369-1-lijiayi@kylinos.cn [ rjw: Consolidate pr-related checks in acpi_processor_ppc_init() ] [ rjw: Subject and changelog adjustments ] Cc: 5.4+ # 5.4+: 2d8b39a62a5d ACPI: processor: Avoid NULL pointer dereferences at init time Cc: 5.4+ # 5.4+: 3000ce3c52f8 cpufreq: Use per-policy frequency QoS Cc: 5.4+ # 5.4+: a1bb46c36ce3 ACPI: processor: Add QoS requests for all CPUs Cc: 5.4+ # 5.4+ Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/processor_perflib.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 6937aedc0a03..f1ba57bdbdbe 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -176,11 +176,14 @@ void acpi_processor_ppc_init(struct cpufreq_policy *policy) { unsigned int cpu; + if (ignore_ppc == 1) + return; + for_each_cpu(cpu, policy->related_cpus) { struct acpi_processor *pr = per_cpu(processors, cpu); int ret; - if (!pr) + if (!pr || !pr->performance) continue; /* @@ -196,6 +199,11 @@ void acpi_processor_ppc_init(struct cpufreq_policy *policy) if (ret < 0) pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, ret); + + ret = acpi_processor_get_platform_limit(pr); + if (ret) + pr_err("Failed to update freq constraint for CPU%d (%d)\n", + cpu, ret); } } From cb4b5f4a1e778f6a20d06d4eda6842714a817618 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 12 Aug 2025 14:57:06 +0200 Subject: [PATCH 167/404] ACPI: processor: perflib: Move problematic pr->performance check commit d405ec23df13e6df599f5bd965a55d13420366b8 upstream. Commit d33bd88ac0eb ("ACPI: processor: perflib: Fix initial _PPC limit application") added a pr->performance check that prevents the frequency QoS request from being added when the given processor has no performance object. Unfortunately, this causes a WARN() in freq_qos_remove_request() to trigger on an attempt to take the given CPU offline later because the frequency QoS object has not been added for it due to the missing performance object. Address this by moving the pr->performance check before calling acpi_processor_get_platform_limit() so it only prevents a limit from being set for the CPU if the performance object is not present. This way, the frequency QoS request is added as it was before the above commit and it is present all the time along with the CPU's cpufreq policy regardless of whether or not the CPU is online. Fixes: d33bd88ac0eb ("ACPI: processor: perflib: Fix initial _PPC limit application") Tested-by: Rafael J. Wysocki Cc: 5.4+ # 5.4+ Signed-off-by: Rafael J. Wysocki Link: https://patch.msgid.link/2801421.mvXUDI8C0e@rafael.j.wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/processor_perflib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index f1ba57bdbdbe..4db106e5ce1a 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -183,7 +183,7 @@ void acpi_processor_ppc_init(struct cpufreq_policy *policy) struct acpi_processor *pr = per_cpu(processors, cpu); int ret; - if (!pr || !pr->performance) + if (!pr) continue; /* @@ -200,6 +200,9 @@ void acpi_processor_ppc_init(struct cpufreq_policy *policy) pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, ret); + if (!pr->performance) + continue; + ret = acpi_processor_get_platform_limit(pr); if (ret) pr_err("Failed to update freq constraint for CPU%d (%d)\n", From 7ac418e59623ddca0cad210c8efb44c8746b5168 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Mon, 4 Aug 2025 11:26:27 +0200 Subject: [PATCH 168/404] udp: also consider secpath when evaluating ipsec use for checksumming [ Upstream commit 1118aaa3b35157777890fffab91d8c1da841b20b ] Commit b40c5f4fde22 ("udp: disable inner UDP checksum offloads in IPsec case") tried to fix checksumming in UFO when the packets are going through IPsec, so that we can't rely on offloads because the UDP header and payload will be encrypted. But when doing a TCP test over VXLAN going through IPsec transport mode with GSO enabled (esp4_offload module loaded), I'm seeing broken UDP checksums on the encap after successful decryption. The skbs get to udp4_ufo_fragment/__skb_udp_tunnel_segment via __dev_queue_xmit -> validate_xmit_skb -> skb_gso_segment and at this point we've already dropped the dst (unless the device sets IFF_XMIT_DST_RELEASE, which is not common), so need_ipsec is false and we proceed with checksum offload. Make need_ipsec also check the secpath, which is not dropped on this callpath. Fixes: b40c5f4fde22 ("udp: disable inner UDP checksum offloads in IPsec case") Signed-off-by: Sabrina Dubroca Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin --- net/ipv4/udp_offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 6505a6fd245a..7e025f3517b8 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -58,7 +58,7 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb, remcsum = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TUNNEL_REMCSUM); skb->remcsum_offload = remcsum; - need_ipsec = skb_dst(skb) && dst_xfrm(skb_dst(skb)); + need_ipsec = (skb_dst(skb) && dst_xfrm(skb_dst(skb))) || skb_sec_path(skb); /* Try to offload checksum if possible */ offload_csum = !!(need_csum && !need_ipsec && From 586892e341fbf698e7cbaca293e1353957db725a Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 1 Aug 2025 17:25:08 +0200 Subject: [PATCH 169/404] netfilter: ctnetlink: fix refcount leak on table dump [ Upstream commit de788b2e6227462b6dcd0e07474e72c089008f74 ] There is a reference count leak in ctnetlink_dump_table(): if (res < 0) { nf_conntrack_get(&ct->ct_general); // HERE cb->args[1] = (unsigned long)ct; ... While its very unlikely, its possible that ct == last. If this happens, then the refcount of ct was already incremented. This 2nd increment is never undone. This prevents the conntrack object from being released, which in turn keeps prevents cnet->count from dropping back to 0. This will then block the netns dismantle (or conntrack rmmod) as nf_conntrack_cleanup_net_list() will wait forever. This can be reproduced by running conntrack_resize.sh selftest in a loop. It takes ~20 minutes for me on a preemptible kernel on average before I see a runaway kworker spinning in nf_conntrack_cleanup_net_list. One fix would to change this to: if (res < 0) { if (ct != last) nf_conntrack_get(&ct->ct_general); But this reference counting isn't needed in the first place. We can just store a cookie value instead. A followup patch will do the same for ctnetlink_exp_dump_table, it looks to me as if this has the same problem and like ctnetlink_dump_table, we only need a 'skip hint', not the actual object so we can apply the same cookie strategy there as well. Fixes: d205dc40798d ("[NETFILTER]: ctnetlink: fix deadlock in table dumping") Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- net/netfilter/nf_conntrack_netlink.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index eeb000e41ad7..5d6f9b375c0f 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -808,8 +808,6 @@ errout: static int ctnetlink_done(struct netlink_callback *cb) { - if (cb->args[1]) - nf_ct_put((struct nf_conn *)cb->args[1]); kfree(cb->data); return 0; } @@ -890,18 +888,25 @@ ignore_entry: return 0; } +static unsigned long ctnetlink_get_id(const struct nf_conn *ct) +{ + unsigned long id = nf_ct_get_id(ct); + + return id ? id : 1; +} + static int ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) { struct net *net = sock_net(skb->sk); - struct nf_conn *ct, *last; + unsigned long last_id = cb->args[1]; struct nf_conntrack_tuple_hash *h; struct hlist_nulls_node *n; struct nf_conn *nf_ct_evict[8]; + struct nf_conn *ct; int res, i; spinlock_t *lockp; - last = (struct nf_conn *)cb->args[1]; i = 0; local_bh_disable(); @@ -936,7 +941,7 @@ restart: continue; if (cb->args[1]) { - if (ct != last) + if (ctnetlink_get_id(ct) != last_id) continue; cb->args[1] = 0; } @@ -951,8 +956,7 @@ restart: ct); rcu_read_unlock(); if (res < 0) { - nf_conntrack_get(&ct->ct_general); - cb->args[1] = (unsigned long)ct; + cb->args[1] = ctnetlink_get_id(ct); spin_unlock(lockp); goto out; } @@ -965,12 +969,10 @@ restart: } out: local_bh_enable(); - if (last) { + if (last_id) { /* nf ct hash resize happened, now clear the leftover. */ - if ((struct nf_conn *)cb->args[1] == last) + if (cb->args[1] == last_id) cb->args[1] = 0; - - nf_ct_put(last); } while (i) { From d0194e391bb493aa6cec56d177b14df6b29188d5 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Thu, 7 Aug 2025 15:40:11 -0400 Subject: [PATCH 170/404] sctp: linearize cloned gso packets in sctp_rcv [ Upstream commit fd60d8a086191fe33c2d719732d2482052fa6805 ] A cloned head skb still shares these frag skbs in fraglist with the original head skb. It's not safe to access these frag skbs. syzbot reported two use-of-uninitialized-memory bugs caused by this: BUG: KMSAN: uninit-value in sctp_inq_pop+0x15b7/0x1920 net/sctp/inqueue.c:211 sctp_inq_pop+0x15b7/0x1920 net/sctp/inqueue.c:211 sctp_assoc_bh_rcv+0x1a7/0xc50 net/sctp/associola.c:998 sctp_inq_push+0x2ef/0x380 net/sctp/inqueue.c:88 sctp_backlog_rcv+0x397/0xdb0 net/sctp/input.c:331 sk_backlog_rcv+0x13b/0x420 include/net/sock.h:1122 __release_sock+0x1da/0x330 net/core/sock.c:3106 release_sock+0x6b/0x250 net/core/sock.c:3660 sctp_wait_for_connect+0x487/0x820 net/sctp/socket.c:9360 sctp_sendmsg_to_asoc+0x1ec1/0x1f00 net/sctp/socket.c:1885 sctp_sendmsg+0x32b9/0x4a80 net/sctp/socket.c:2031 inet_sendmsg+0x25a/0x280 net/ipv4/af_inet.c:851 sock_sendmsg_nosec net/socket.c:718 [inline] and BUG: KMSAN: uninit-value in sctp_assoc_bh_rcv+0x34e/0xbc0 net/sctp/associola.c:987 sctp_assoc_bh_rcv+0x34e/0xbc0 net/sctp/associola.c:987 sctp_inq_push+0x2a3/0x350 net/sctp/inqueue.c:88 sctp_backlog_rcv+0x3c7/0xda0 net/sctp/input.c:331 sk_backlog_rcv+0x142/0x420 include/net/sock.h:1148 __release_sock+0x1d3/0x330 net/core/sock.c:3213 release_sock+0x6b/0x270 net/core/sock.c:3767 sctp_wait_for_connect+0x458/0x820 net/sctp/socket.c:9367 sctp_sendmsg_to_asoc+0x223a/0x2260 net/sctp/socket.c:1886 sctp_sendmsg+0x3910/0x49f0 net/sctp/socket.c:2032 inet_sendmsg+0x269/0x2a0 net/ipv4/af_inet.c:851 sock_sendmsg_nosec net/socket.c:712 [inline] This patch fixes it by linearizing cloned gso packets in sctp_rcv(). Fixes: 90017accff61 ("sctp: Add GSO support") Reported-by: syzbot+773e51afe420baaf0e2b@syzkaller.appspotmail.com Reported-by: syzbot+70a42f45e76bede082be@syzkaller.appspotmail.com Signed-off-by: Xin Long Reviewed-by: Marcelo Ricardo Leitner Link: https://patch.msgid.link/dd7dc337b99876d4132d0961f776913719f7d225.1754595611.git.lucien.xin@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sctp/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sctp/input.c b/net/sctp/input.c index b1d3e342ac83..9013257cf3df 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -114,7 +114,7 @@ int sctp_rcv(struct sk_buff *skb) * it's better to just linearize it otherwise crc computing * takes longer. */ - if ((!is_gso && skb_linearize(skb)) || + if (((!is_gso || skb_cloned(skb)) && skb_linearize(skb)) || !pskb_may_pull(skb, sizeof(struct sctphdr))) goto discard_it; From e7d2dc2421e821e4045775e6dc226378328de6f6 Mon Sep 17 00:00:00 2001 From: Viacheslav Dubeyko Date: Thu, 3 Jul 2025 14:49:12 -0700 Subject: [PATCH 171/404] hfs: fix slab-out-of-bounds in hfs_bnode_read() [ Upstream commit a431930c9bac518bf99d6b1da526a7f37ddee8d8 ] This patch introduces is_bnode_offset_valid() method that checks the requested offset value. Also, it introduces check_and_correct_requested_length() method that checks and correct the requested length (if it is necessary). These methods are used in hfs_bnode_read(), hfs_bnode_write(), hfs_bnode_clear(), hfs_bnode_copy(), and hfs_bnode_move() with the goal to prevent the access out of allocated memory and triggering the crash. Signed-off-by: Viacheslav Dubeyko Link: https://lore.kernel.org/r/20250703214912.244138-1-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko Signed-off-by: Sasha Levin --- fs/hfs/bnode.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index 2251286cd83f..2039cb6d5f66 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c @@ -15,6 +15,48 @@ #include "btree.h" +static inline +bool is_bnode_offset_valid(struct hfs_bnode *node, int off) +{ + bool is_valid = off < node->tree->node_size; + + if (!is_valid) { + pr_err("requested invalid offset: " + "NODE: id %u, type %#x, height %u, " + "node_size %u, offset %d\n", + node->this, node->type, node->height, + node->tree->node_size, off); + } + + return is_valid; +} + +static inline +int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len) +{ + unsigned int node_size; + + if (!is_bnode_offset_valid(node, off)) + return 0; + + node_size = node->tree->node_size; + + if ((off + len) > node_size) { + int new_len = (int)node_size - off; + + pr_err("requested length has been corrected: " + "NODE: id %u, type %#x, height %u, " + "node_size %u, offset %d, " + "requested_len %d, corrected_len %d\n", + node->this, node->type, node->height, + node->tree->node_size, off, len, new_len); + + return new_len; + } + + return len; +} + void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len) { struct page *page; @@ -23,6 +65,20 @@ void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len) int bytes_to_read; void *vaddr; + if (!is_bnode_offset_valid(node, off)) + return; + + if (len == 0) { + pr_err("requested zero length: " + "NODE: id %u, type %#x, height %u, " + "node_size %u, offset %d, len %d\n", + node->this, node->type, node->height, + node->tree->node_size, off, len); + return; + } + + len = check_and_correct_requested_length(node, off, len); + off += node->page_offset; pagenum = off >> PAGE_SHIFT; off &= ~PAGE_MASK; /* compute page offset for the first page */ @@ -83,6 +139,20 @@ void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len) { struct page *page; + if (!is_bnode_offset_valid(node, off)) + return; + + if (len == 0) { + pr_err("requested zero length: " + "NODE: id %u, type %#x, height %u, " + "node_size %u, offset %d, len %d\n", + node->this, node->type, node->height, + node->tree->node_size, off, len); + return; + } + + len = check_and_correct_requested_length(node, off, len); + off += node->page_offset; page = node->page[0]; @@ -108,6 +178,20 @@ void hfs_bnode_clear(struct hfs_bnode *node, int off, int len) { struct page *page; + if (!is_bnode_offset_valid(node, off)) + return; + + if (len == 0) { + pr_err("requested zero length: " + "NODE: id %u, type %#x, height %u, " + "node_size %u, offset %d, len %d\n", + node->this, node->type, node->height, + node->tree->node_size, off, len); + return; + } + + len = check_and_correct_requested_length(node, off, len); + off += node->page_offset; page = node->page[0]; @@ -124,6 +208,10 @@ void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len); if (!len) return; + + len = check_and_correct_requested_length(src_node, src, len); + len = check_and_correct_requested_length(dst_node, dst, len); + src += src_node->page_offset; dst += dst_node->page_offset; src_page = src_node->page[0]; @@ -143,6 +231,10 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) hfs_dbg(BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len); if (!len) return; + + len = check_and_correct_requested_length(node, src, len); + len = check_and_correct_requested_length(node, dst, len); + src += node->page_offset; dst += node->page_offset; page = node->page[0]; From 032f7ed6717a4cd3714f9801be39fdfc7f1c7644 Mon Sep 17 00:00:00 2001 From: Viacheslav Dubeyko Date: Thu, 3 Jul 2025 14:48:04 -0700 Subject: [PATCH 172/404] hfsplus: fix slab-out-of-bounds in hfsplus_bnode_read() [ Upstream commit c80aa2aaaa5e69d5219c6af8ef7e754114bd08d2 ] The hfsplus_bnode_read() method can trigger the issue: [ 174.852007][ T9784] ================================================================== [ 174.852709][ T9784] BUG: KASAN: slab-out-of-bounds in hfsplus_bnode_read+0x2f4/0x360 [ 174.853412][ T9784] Read of size 8 at addr ffff88810b5fc6c0 by task repro/9784 [ 174.854059][ T9784] [ 174.854272][ T9784] CPU: 1 UID: 0 PID: 9784 Comm: repro Not tainted 6.16.0-rc3 #7 PREEMPT(full) [ 174.854281][ T9784] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 174.854286][ T9784] Call Trace: [ 174.854289][ T9784] [ 174.854292][ T9784] dump_stack_lvl+0x10e/0x1f0 [ 174.854305][ T9784] print_report+0xd0/0x660 [ 174.854315][ T9784] ? __virt_addr_valid+0x81/0x610 [ 174.854323][ T9784] ? __phys_addr+0xe8/0x180 [ 174.854330][ T9784] ? hfsplus_bnode_read+0x2f4/0x360 [ 174.854337][ T9784] kasan_report+0xc6/0x100 [ 174.854346][ T9784] ? hfsplus_bnode_read+0x2f4/0x360 [ 174.854354][ T9784] hfsplus_bnode_read+0x2f4/0x360 [ 174.854362][ T9784] hfsplus_bnode_dump+0x2ec/0x380 [ 174.854370][ T9784] ? __pfx_hfsplus_bnode_dump+0x10/0x10 [ 174.854377][ T9784] ? hfsplus_bnode_write_u16+0x83/0xb0 [ 174.854385][ T9784] ? srcu_gp_start+0xd0/0x310 [ 174.854393][ T9784] ? __mark_inode_dirty+0x29e/0xe40 [ 174.854402][ T9784] hfsplus_brec_remove+0x3d2/0x4e0 [ 174.854411][ T9784] __hfsplus_delete_attr+0x290/0x3a0 [ 174.854419][ T9784] ? __pfx_hfs_find_1st_rec_by_cnid+0x10/0x10 [ 174.854427][ T9784] ? __pfx___hfsplus_delete_attr+0x10/0x10 [ 174.854436][ T9784] ? __asan_memset+0x23/0x50 [ 174.854450][ T9784] hfsplus_delete_all_attrs+0x262/0x320 [ 174.854459][ T9784] ? __pfx_hfsplus_delete_all_attrs+0x10/0x10 [ 174.854469][ T9784] ? rcu_is_watching+0x12/0xc0 [ 174.854476][ T9784] ? __mark_inode_dirty+0x29e/0xe40 [ 174.854483][ T9784] hfsplus_delete_cat+0x845/0xde0 [ 174.854493][ T9784] ? __pfx_hfsplus_delete_cat+0x10/0x10 [ 174.854507][ T9784] hfsplus_unlink+0x1ca/0x7c0 [ 174.854516][ T9784] ? __pfx_hfsplus_unlink+0x10/0x10 [ 174.854525][ T9784] ? down_write+0x148/0x200 [ 174.854532][ T9784] ? __pfx_down_write+0x10/0x10 [ 174.854540][ T9784] vfs_unlink+0x2fe/0x9b0 [ 174.854549][ T9784] do_unlinkat+0x490/0x670 [ 174.854557][ T9784] ? __pfx_do_unlinkat+0x10/0x10 [ 174.854565][ T9784] ? __might_fault+0xbc/0x130 [ 174.854576][ T9784] ? getname_flags.part.0+0x1c5/0x550 [ 174.854584][ T9784] __x64_sys_unlink+0xc5/0x110 [ 174.854592][ T9784] do_syscall_64+0xc9/0x480 [ 174.854600][ T9784] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 174.854608][ T9784] RIP: 0033:0x7f6fdf4c3167 [ 174.854614][ T9784] Code: f0 ff ff 73 01 c3 48 8b 0d 26 0d 0e 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 08 [ 174.854622][ T9784] RSP: 002b:00007ffcb948bca8 EFLAGS: 00000206 ORIG_RAX: 0000000000000057 [ 174.854630][ T9784] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f6fdf4c3167 [ 174.854636][ T9784] RDX: 00007ffcb948bcc0 RSI: 00007ffcb948bcc0 RDI: 00007ffcb948bd50 [ 174.854641][ T9784] RBP: 00007ffcb948cd90 R08: 0000000000000001 R09: 00007ffcb948bb40 [ 174.854645][ T9784] R10: 00007f6fdf564fc0 R11: 0000000000000206 R12: 0000561e1bc9c2d0 [ 174.854650][ T9784] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [ 174.854658][ T9784] [ 174.854661][ T9784] [ 174.879281][ T9784] Allocated by task 9784: [ 174.879664][ T9784] kasan_save_stack+0x20/0x40 [ 174.880082][ T9784] kasan_save_track+0x14/0x30 [ 174.880500][ T9784] __kasan_kmalloc+0xaa/0xb0 [ 174.880908][ T9784] __kmalloc_noprof+0x205/0x550 [ 174.881337][ T9784] __hfs_bnode_create+0x107/0x890 [ 174.881779][ T9784] hfsplus_bnode_find+0x2d0/0xd10 [ 174.882222][ T9784] hfsplus_brec_find+0x2b0/0x520 [ 174.882659][ T9784] hfsplus_delete_all_attrs+0x23b/0x320 [ 174.883144][ T9784] hfsplus_delete_cat+0x845/0xde0 [ 174.883595][ T9784] hfsplus_rmdir+0x106/0x1b0 [ 174.884004][ T9784] vfs_rmdir+0x206/0x690 [ 174.884379][ T9784] do_rmdir+0x2b7/0x390 [ 174.884751][ T9784] __x64_sys_rmdir+0xc5/0x110 [ 174.885167][ T9784] do_syscall_64+0xc9/0x480 [ 174.885568][ T9784] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 174.886083][ T9784] [ 174.886293][ T9784] The buggy address belongs to the object at ffff88810b5fc600 [ 174.886293][ T9784] which belongs to the cache kmalloc-192 of size 192 [ 174.887507][ T9784] The buggy address is located 40 bytes to the right of [ 174.887507][ T9784] allocated 152-byte region [ffff88810b5fc600, ffff88810b5fc698) [ 174.888766][ T9784] [ 174.888976][ T9784] The buggy address belongs to the physical page: [ 174.889533][ T9784] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10b5fc [ 174.890295][ T9784] flags: 0x57ff00000000000(node=1|zone=2|lastcpupid=0x7ff) [ 174.890927][ T9784] page_type: f5(slab) [ 174.891284][ T9784] raw: 057ff00000000000 ffff88801b4423c0 ffffea000426dc80 dead000000000002 [ 174.892032][ T9784] raw: 0000000000000000 0000000080100010 00000000f5000000 0000000000000000 [ 174.892774][ T9784] page dumped because: kasan: bad access detected [ 174.893327][ T9784] page_owner tracks the page as allocated [ 174.893825][ T9784] page last allocated via order 0, migratetype Unmovable, gfp_mask 0x52c00(GFP_NOIO|__GFP_NOWARN|__GFP_NO1 [ 174.895373][ T9784] post_alloc_hook+0x1c0/0x230 [ 174.895801][ T9784] get_page_from_freelist+0xdeb/0x3b30 [ 174.896284][ T9784] __alloc_frozen_pages_noprof+0x25c/0x2460 [ 174.896810][ T9784] alloc_pages_mpol+0x1fb/0x550 [ 174.897242][ T9784] new_slab+0x23b/0x340 [ 174.897614][ T9784] ___slab_alloc+0xd81/0x1960 [ 174.898028][ T9784] __slab_alloc.isra.0+0x56/0xb0 [ 174.898468][ T9784] __kmalloc_noprof+0x2b0/0x550 [ 174.898896][ T9784] usb_alloc_urb+0x73/0xa0 [ 174.899289][ T9784] usb_control_msg+0x1cb/0x4a0 [ 174.899718][ T9784] usb_get_string+0xab/0x1a0 [ 174.900133][ T9784] usb_string_sub+0x107/0x3c0 [ 174.900549][ T9784] usb_string+0x307/0x670 [ 174.900933][ T9784] usb_cache_string+0x80/0x150 [ 174.901355][ T9784] usb_new_device+0x1d0/0x19d0 [ 174.901786][ T9784] register_root_hub+0x299/0x730 [ 174.902231][ T9784] page last free pid 10 tgid 10 stack trace: [ 174.902757][ T9784] __free_frozen_pages+0x80c/0x1250 [ 174.903217][ T9784] vfree.part.0+0x12b/0xab0 [ 174.903645][ T9784] delayed_vfree_work+0x93/0xd0 [ 174.904073][ T9784] process_one_work+0x9b5/0x1b80 [ 174.904519][ T9784] worker_thread+0x630/0xe60 [ 174.904927][ T9784] kthread+0x3a8/0x770 [ 174.905291][ T9784] ret_from_fork+0x517/0x6e0 [ 174.905709][ T9784] ret_from_fork_asm+0x1a/0x30 [ 174.906128][ T9784] [ 174.906338][ T9784] Memory state around the buggy address: [ 174.906828][ T9784] ffff88810b5fc580: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc [ 174.907528][ T9784] ffff88810b5fc600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 174.908222][ T9784] >ffff88810b5fc680: 00 00 00 fc fc fc fc fc fc fc fc fc fc fc fc fc [ 174.908917][ T9784] ^ [ 174.909481][ T9784] ffff88810b5fc700: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 174.910432][ T9784] ffff88810b5fc780: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc [ 174.911401][ T9784] ================================================================== The reason of the issue that code doesn't check the correctness of the requested offset and length. As a result, incorrect value of offset or/and length could result in access out of allocated memory. This patch introduces is_bnode_offset_valid() method that checks the requested offset value. Also, it introduces check_and_correct_requested_length() method that checks and correct the requested length (if it is necessary). These methods are used in hfsplus_bnode_read(), hfsplus_bnode_write(), hfsplus_bnode_clear(), hfsplus_bnode_copy(), and hfsplus_bnode_move() with the goal to prevent the access out of allocated memory and triggering the crash. Reported-by: Kun Hu Reported-by: Jiaji Qin Reported-by: Shuoran Bai Signed-off-by: Viacheslav Dubeyko Link: https://lore.kernel.org/r/20250703214804.244077-1-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko Signed-off-by: Sasha Levin --- fs/hfsplus/bnode.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index cf6e5de7b9da..c9c38fddf505 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -18,12 +18,68 @@ #include "hfsplus_fs.h" #include "hfsplus_raw.h" +static inline +bool is_bnode_offset_valid(struct hfs_bnode *node, int off) +{ + bool is_valid = off < node->tree->node_size; + + if (!is_valid) { + pr_err("requested invalid offset: " + "NODE: id %u, type %#x, height %u, " + "node_size %u, offset %d\n", + node->this, node->type, node->height, + node->tree->node_size, off); + } + + return is_valid; +} + +static inline +int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len) +{ + unsigned int node_size; + + if (!is_bnode_offset_valid(node, off)) + return 0; + + node_size = node->tree->node_size; + + if ((off + len) > node_size) { + int new_len = (int)node_size - off; + + pr_err("requested length has been corrected: " + "NODE: id %u, type %#x, height %u, " + "node_size %u, offset %d, " + "requested_len %d, corrected_len %d\n", + node->this, node->type, node->height, + node->tree->node_size, off, len, new_len); + + return new_len; + } + + return len; +} + /* Copy a specified range of bytes from the raw data of a node */ void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len) { struct page **pagep; int l; + if (!is_bnode_offset_valid(node, off)) + return; + + if (len == 0) { + pr_err("requested zero length: " + "NODE: id %u, type %#x, height %u, " + "node_size %u, offset %d, len %d\n", + node->this, node->type, node->height, + node->tree->node_size, off, len); + return; + } + + len = check_and_correct_requested_length(node, off, len); + off += node->page_offset; pagep = node->page + (off >> PAGE_SHIFT); off &= ~PAGE_MASK; @@ -83,6 +139,20 @@ void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len) struct page **pagep; int l; + if (!is_bnode_offset_valid(node, off)) + return; + + if (len == 0) { + pr_err("requested zero length: " + "NODE: id %u, type %#x, height %u, " + "node_size %u, offset %d, len %d\n", + node->this, node->type, node->height, + node->tree->node_size, off, len); + return; + } + + len = check_and_correct_requested_length(node, off, len); + off += node->page_offset; pagep = node->page + (off >> PAGE_SHIFT); off &= ~PAGE_MASK; @@ -113,6 +183,20 @@ void hfs_bnode_clear(struct hfs_bnode *node, int off, int len) struct page **pagep; int l; + if (!is_bnode_offset_valid(node, off)) + return; + + if (len == 0) { + pr_err("requested zero length: " + "NODE: id %u, type %#x, height %u, " + "node_size %u, offset %d, len %d\n", + node->this, node->type, node->height, + node->tree->node_size, off, len); + return; + } + + len = check_and_correct_requested_length(node, off, len); + off += node->page_offset; pagep = node->page + (off >> PAGE_SHIFT); off &= ~PAGE_MASK; @@ -139,6 +223,10 @@ void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, hfs_dbg(BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len); if (!len) return; + + len = check_and_correct_requested_length(src_node, src, len); + len = check_and_correct_requested_length(dst_node, dst, len); + src += src_node->page_offset; dst += dst_node->page_offset; src_page = src_node->page + (src >> PAGE_SHIFT); @@ -196,6 +284,10 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) hfs_dbg(BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len); if (!len) return; + + len = check_and_correct_requested_length(node, src, len); + len = check_and_correct_requested_length(node, dst, len); + src += node->page_offset; dst += node->page_offset; if (dst > src) { From 73f7da507d787b489761a0fa280716f84fa32b2f Mon Sep 17 00:00:00 2001 From: Viacheslav Dubeyko Date: Thu, 10 Jul 2025 16:08:30 -0700 Subject: [PATCH 173/404] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc() [ Upstream commit 94458781aee6045bd3d0ad4b80b02886b9e2219b ] The hfsplus_readdir() method is capable to crash by calling hfsplus_uni2asc(): [ 667.121659][ T9805] ================================================================== [ 667.122651][ T9805] BUG: KASAN: slab-out-of-bounds in hfsplus_uni2asc+0x902/0xa10 [ 667.123627][ T9805] Read of size 2 at addr ffff88802592f40c by task repro/9805 [ 667.124578][ T9805] [ 667.124876][ T9805] CPU: 3 UID: 0 PID: 9805 Comm: repro Not tainted 6.16.0-rc3 #1 PREEMPT(full) [ 667.124886][ T9805] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 667.124890][ T9805] Call Trace: [ 667.124893][ T9805] [ 667.124896][ T9805] dump_stack_lvl+0x10e/0x1f0 [ 667.124911][ T9805] print_report+0xd0/0x660 [ 667.124920][ T9805] ? __virt_addr_valid+0x81/0x610 [ 667.124928][ T9805] ? __phys_addr+0xe8/0x180 [ 667.124934][ T9805] ? hfsplus_uni2asc+0x902/0xa10 [ 667.124942][ T9805] kasan_report+0xc6/0x100 [ 667.124950][ T9805] ? hfsplus_uni2asc+0x902/0xa10 [ 667.124959][ T9805] hfsplus_uni2asc+0x902/0xa10 [ 667.124966][ T9805] ? hfsplus_bnode_read+0x14b/0x360 [ 667.124974][ T9805] hfsplus_readdir+0x845/0xfc0 [ 667.124984][ T9805] ? __pfx_hfsplus_readdir+0x10/0x10 [ 667.124994][ T9805] ? stack_trace_save+0x8e/0xc0 [ 667.125008][ T9805] ? iterate_dir+0x18b/0xb20 [ 667.125015][ T9805] ? trace_lock_acquire+0x85/0xd0 [ 667.125022][ T9805] ? lock_acquire+0x30/0x80 [ 667.125029][ T9805] ? iterate_dir+0x18b/0xb20 [ 667.125037][ T9805] ? down_read_killable+0x1ed/0x4c0 [ 667.125044][ T9805] ? putname+0x154/0x1a0 [ 667.125051][ T9805] ? __pfx_down_read_killable+0x10/0x10 [ 667.125058][ T9805] ? apparmor_file_permission+0x239/0x3e0 [ 667.125069][ T9805] iterate_dir+0x296/0xb20 [ 667.125076][ T9805] __x64_sys_getdents64+0x13c/0x2c0 [ 667.125084][ T9805] ? __pfx___x64_sys_getdents64+0x10/0x10 [ 667.125091][ T9805] ? __x64_sys_openat+0x141/0x200 [ 667.125126][ T9805] ? __pfx_filldir64+0x10/0x10 [ 667.125134][ T9805] ? do_user_addr_fault+0x7fe/0x12f0 [ 667.125143][ T9805] do_syscall_64+0xc9/0x480 [ 667.125151][ T9805] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 667.125158][ T9805] RIP: 0033:0x7fa8753b2fc9 [ 667.125164][ T9805] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 48 [ 667.125172][ T9805] RSP: 002b:00007ffe96f8e0f8 EFLAGS: 00000217 ORIG_RAX: 00000000000000d9 [ 667.125181][ T9805] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fa8753b2fc9 [ 667.125185][ T9805] RDX: 0000000000000400 RSI: 00002000000063c0 RDI: 0000000000000004 [ 667.125190][ T9805] RBP: 00007ffe96f8e110 R08: 00007ffe96f8e110 R09: 00007ffe96f8e110 [ 667.125195][ T9805] R10: 0000000000000000 R11: 0000000000000217 R12: 0000556b1e3b4260 [ 667.125199][ T9805] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [ 667.125207][ T9805] [ 667.125210][ T9805] [ 667.145632][ T9805] Allocated by task 9805: [ 667.145991][ T9805] kasan_save_stack+0x20/0x40 [ 667.146352][ T9805] kasan_save_track+0x14/0x30 [ 667.146717][ T9805] __kasan_kmalloc+0xaa/0xb0 [ 667.147065][ T9805] __kmalloc_noprof+0x205/0x550 [ 667.147448][ T9805] hfsplus_find_init+0x95/0x1f0 [ 667.147813][ T9805] hfsplus_readdir+0x220/0xfc0 [ 667.148174][ T9805] iterate_dir+0x296/0xb20 [ 667.148549][ T9805] __x64_sys_getdents64+0x13c/0x2c0 [ 667.148937][ T9805] do_syscall_64+0xc9/0x480 [ 667.149291][ T9805] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 667.149809][ T9805] [ 667.150030][ T9805] The buggy address belongs to the object at ffff88802592f000 [ 667.150030][ T9805] which belongs to the cache kmalloc-2k of size 2048 [ 667.151282][ T9805] The buggy address is located 0 bytes to the right of [ 667.151282][ T9805] allocated 1036-byte region [ffff88802592f000, ffff88802592f40c) [ 667.152580][ T9805] [ 667.152798][ T9805] The buggy address belongs to the physical page: [ 667.153373][ T9805] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x25928 [ 667.154157][ T9805] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 [ 667.154916][ T9805] anon flags: 0xfff00000000040(head|node=0|zone=1|lastcpupid=0x7ff) [ 667.155631][ T9805] page_type: f5(slab) [ 667.155997][ T9805] raw: 00fff00000000040 ffff88801b442f00 0000000000000000 dead000000000001 [ 667.156770][ T9805] raw: 0000000000000000 0000000080080008 00000000f5000000 0000000000000000 [ 667.157536][ T9805] head: 00fff00000000040 ffff88801b442f00 0000000000000000 dead000000000001 [ 667.158317][ T9805] head: 0000000000000000 0000000080080008 00000000f5000000 0000000000000000 [ 667.159088][ T9805] head: 00fff00000000003 ffffea0000964a01 00000000ffffffff 00000000ffffffff [ 667.159865][ T9805] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008 [ 667.160643][ T9805] page dumped because: kasan: bad access detected [ 667.161216][ T9805] page_owner tracks the page as allocated [ 667.161732][ T9805] page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN9 [ 667.163566][ T9805] post_alloc_hook+0x1c0/0x230 [ 667.164003][ T9805] get_page_from_freelist+0xdeb/0x3b30 [ 667.164503][ T9805] __alloc_frozen_pages_noprof+0x25c/0x2460 [ 667.165040][ T9805] alloc_pages_mpol+0x1fb/0x550 [ 667.165489][ T9805] new_slab+0x23b/0x340 [ 667.165872][ T9805] ___slab_alloc+0xd81/0x1960 [ 667.166313][ T9805] __slab_alloc.isra.0+0x56/0xb0 [ 667.166767][ T9805] __kmalloc_cache_noprof+0x255/0x3e0 [ 667.167255][ T9805] psi_cgroup_alloc+0x52/0x2d0 [ 667.167693][ T9805] cgroup_mkdir+0x694/0x1210 [ 667.168118][ T9805] kernfs_iop_mkdir+0x111/0x190 [ 667.168568][ T9805] vfs_mkdir+0x59b/0x8d0 [ 667.168956][ T9805] do_mkdirat+0x2ed/0x3d0 [ 667.169353][ T9805] __x64_sys_mkdir+0xef/0x140 [ 667.169784][ T9805] do_syscall_64+0xc9/0x480 [ 667.170195][ T9805] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 667.170730][ T9805] page last free pid 1257 tgid 1257 stack trace: [ 667.171304][ T9805] __free_frozen_pages+0x80c/0x1250 [ 667.171770][ T9805] vfree.part.0+0x12b/0xab0 [ 667.172182][ T9805] delayed_vfree_work+0x93/0xd0 [ 667.172612][ T9805] process_one_work+0x9b5/0x1b80 [ 667.173067][ T9805] worker_thread+0x630/0xe60 [ 667.173486][ T9805] kthread+0x3a8/0x770 [ 667.173857][ T9805] ret_from_fork+0x517/0x6e0 [ 667.174278][ T9805] ret_from_fork_asm+0x1a/0x30 [ 667.174703][ T9805] [ 667.174917][ T9805] Memory state around the buggy address: [ 667.175411][ T9805] ffff88802592f300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 667.176114][ T9805] ffff88802592f380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 667.176830][ T9805] >ffff88802592f400: 00 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 667.177547][ T9805] ^ [ 667.177933][ T9805] ffff88802592f480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 667.178640][ T9805] ffff88802592f500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 667.179350][ T9805] ================================================================== The hfsplus_uni2asc() method operates by struct hfsplus_unistr: struct hfsplus_unistr { __be16 length; hfsplus_unichr unicode[HFSPLUS_MAX_STRLEN]; } __packed; where HFSPLUS_MAX_STRLEN is 255 bytes. The issue happens if length of the structure instance has value bigger than 255 (for example, 65283). In such case, pointer on unicode buffer is going beyond of the allocated memory. The patch fixes the issue by checking the length value of hfsplus_unistr instance and using 255 value in the case if length value is bigger than HFSPLUS_MAX_STRLEN. Potential reason of such situation could be a corruption of Catalog File b-tree's node. Reported-by: Wenzhi Wang Signed-off-by: Liu Shixin Signed-off-by: Viacheslav Dubeyko cc: John Paul Adrian Glaubitz cc: Yangtao Li cc: linux-fsdevel@vger.kernel.org Reviewed-by: Yangtao Li Link: https://lore.kernel.org/r/20250710230830.110500-1-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko Signed-off-by: Sasha Levin --- fs/hfsplus/unicode.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c index 73342c925a4b..36b6cf2a3abb 100644 --- a/fs/hfsplus/unicode.c +++ b/fs/hfsplus/unicode.c @@ -132,7 +132,14 @@ int hfsplus_uni2asc(struct super_block *sb, op = astr; ip = ustr->unicode; + ustrlen = be16_to_cpu(ustr->length); + if (ustrlen > HFSPLUS_MAX_STRLEN) { + ustrlen = HFSPLUS_MAX_STRLEN; + pr_err("invalid length %u has been corrected to %d\n", + be16_to_cpu(ustr->length), ustrlen); + } + len = *len_p; ce1 = NULL; compose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags); From bb0eea8e375677f586ad11c12e2525ed3fc698c2 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 15 Jul 2025 14:17:56 +0900 Subject: [PATCH 174/404] hfsplus: don't use BUG_ON() in hfsplus_create_attributes_file() [ Upstream commit c7c6363ca186747ebc2df10c8a1a51e66e0e32d9 ] When the volume header contains erroneous values that do not reflect the actual state of the filesystem, hfsplus_fill_super() assumes that the attributes file is not yet created, which later results in hitting BUG_ON() when hfsplus_create_attributes_file() is called. Replace this BUG_ON() with -EIO error with a message to suggest running fsck tool. Reported-by: syzbot Closes: https://syzkaller.appspot.com/bug?extid=1107451c16b9eb9d29e6 Signed-off-by: Tetsuo Handa Reviewed-by: Viacheslav Dubeyko Link: https://lore.kernel.org/r/7b587d24-c8a1-4413-9b9a-00a33fbd849f@I-love.SAKURA.ne.jp Signed-off-by: Viacheslav Dubeyko Signed-off-by: Sasha Levin --- fs/hfsplus/xattr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c index d91f76ef18d9..2438cd759620 100644 --- a/fs/hfsplus/xattr.c +++ b/fs/hfsplus/xattr.c @@ -172,7 +172,11 @@ check_attr_tree_state_again: return PTR_ERR(attr_file); } - BUG_ON(i_size_read(attr_file) != 0); + if (i_size_read(attr_file) != 0) { + err = -EIO; + pr_err("detected inconsistent attributes file, running fsck.hfsplus is recommended.\n"); + goto end_attr_file_creation; + } hip = HFSPLUS_I(attr_file); From 105036cae41c1bcac71c9b77ab16d6391d1e1a21 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 23 Jul 2025 22:50:25 -0700 Subject: [PATCH 175/404] arm64: Handle KCOV __init vs inline mismatches [ Upstream commit 65c430906efffee9bd7551d474f01a6b1197df90 ] GCC appears to have kind of fragile inlining heuristics, in the sense that it can change whether or not it inlines something based on optimizations. It looks like the kcov instrumentation being added (or in this case, removed) from a function changes the optimization results, and some functions marked "inline" are _not_ inlined. In that case, we end up with __init code calling a function not marked __init, and we get the build warnings I'm trying to eliminate in the coming patch that adds __no_sanitize_coverage to __init functions: WARNING: modpost: vmlinux: section mismatch in reference: acpi_get_enable_method+0x1c (section: .text.unlikely) -> acpi_psci_present (section: .init.text) This problem is somewhat fragile (though using either __always_inline or __init will deterministically solve it), but we've tripped over this before with GCC and the solution has usually been to just use __always_inline and move on. For arm64 this requires forcing one ACPI function to be inlined with __always_inline. Link: https://lore.kernel.org/r/20250724055029.3623499-1-kees@kernel.org Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- arch/arm64/include/asm/acpi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h index cbf97e648d19..d1ddf5575973 100644 --- a/arch/arm64/include/asm/acpi.h +++ b/arch/arm64/include/asm/acpi.h @@ -141,7 +141,7 @@ acpi_set_mailbox_entry(int cpu, struct acpi_madt_generic_interrupt *processor) {} #endif -static inline const char *acpi_get_enable_method(int cpu) +static __always_inline const char *acpi_get_enable_method(int cpu) { if (acpi_psci_present()) return "psci"; From a47a7ef1ac886f71464689b0b43399a7fa913c1e Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 11 Jul 2025 19:01:20 +0200 Subject: [PATCH 176/404] udf: Verify partition map count [ Upstream commit 1a11201668e8635602577dcf06f2e96c591d8819 ] Verify that number of partition maps isn't insanely high which can lead to large allocation in udf_sb_alloc_partition_maps(). All partition maps have to fit in the LVD which is in a single block. Reported-by: syzbot+478f2c1a6f0f447a46bb@syzkaller.appspotmail.com Signed-off-by: Jan Kara Signed-off-by: Sasha Levin --- fs/udf/super.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/udf/super.c b/fs/udf/super.c index 9f2de5e7c6e1..361bc8acfb0f 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1417,7 +1417,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, struct genericPartitionMap *gpm; uint16_t ident; struct buffer_head *bh; - unsigned int table_len; + unsigned int table_len, part_map_count; int ret; bh = udf_read_tagged(sb, block, block, &ident); @@ -1438,7 +1438,16 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, "logical volume"); if (ret) goto out_bh; - ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); + + part_map_count = le32_to_cpu(lvd->numPartitionMaps); + if (part_map_count > table_len / sizeof(struct genericPartitionMap1)) { + udf_err(sb, "error loading logical volume descriptor: " + "Too many partition maps (%u > %u)\n", part_map_count, + table_len / (unsigned)sizeof(struct genericPartitionMap1)); + ret = -EIO; + goto out_bh; + } + ret = udf_sb_alloc_partition_maps(sb, part_map_count); if (ret) goto out_bh; From 0336bfe9c237476bd7c45605a36ca79c2bca62e5 Mon Sep 17 00:00:00 2001 From: Sarah Newman Date: Fri, 27 Jun 2025 11:57:28 +0200 Subject: [PATCH 177/404] drbd: add missing kref_get in handle_write_conflicts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 00c9c9628b49e368d140cfa61d7df9b8922ec2a8 ] With `two-primaries` enabled, DRBD tries to detect "concurrent" writes and handle write conflicts, so that even if you write to the same sector simultaneously on both nodes, they end up with the identical data once the writes are completed. In handling "superseeded" writes, we forgot a kref_get, resulting in a premature drbd_destroy_device and use after free, and further to kernel crashes with symptoms. Relevance: No one should use DRBD as a random data generator, and apparently all users of "two-primaries" handle concurrent writes correctly on layer up. That is cluster file systems use some distributed lock manager, and live migration in virtualization environments stops writes on one node before starting writes on the other node. Which means that other than for "test cases", this code path is never taken in real life. FYI, in DRBD 9, things are handled differently nowadays. We still detect "write conflicts", but no longer try to be smart about them. We decided to disconnect hard instead: upper layers must not submit concurrent writes. If they do, that's their fault. Signed-off-by: Sarah Newman Signed-off-by: Lars Ellenberg Signed-off-by: Christoph Böhmwalder Link: https://lore.kernel.org/r/20250627095728.800688-1-christoph.boehmwalder@linbit.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- drivers/block/drbd/drbd_receiver.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index d94f41a0abbe..d75050b0d1b3 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -2531,7 +2531,11 @@ static int handle_write_conflicts(struct drbd_device *device, peer_req->w.cb = superseded ? e_send_superseded : e_send_retry_write; list_add_tail(&peer_req->w.list, &device->done_ee); - queue_work(connection->ack_sender, &peer_req->peer_device->send_acks_work); + /* put is in drbd_send_acks_wf() */ + kref_get(&device->kref); + if (!queue_work(connection->ack_sender, + &peer_req->peer_device->send_acks_work)) + kref_put(&device->kref, drbd_destroy_device); err = -ENOENT; goto out; From 1db925b747de23556f4f6c05cb3e1cea65f05909 Mon Sep 17 00:00:00 2001 From: Viacheslav Dubeyko Date: Tue, 29 Apr 2025 17:12:11 -0700 Subject: [PATCH 178/404] hfs: fix not erasing deleted b-tree node issue [ Upstream commit d3ed6d6981f4756f145766753c872482bc3b28d3 ] The generic/001 test of xfstests suite fails and corrupts the HFS volume: sudo ./check generic/001 FSTYP -- hfs PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.15.0-rc2+ #3 SMP PREEMPT_DYNAMIC Fri Apr 25 17:13:00 PDT 2> MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch generic/001 32s ... _check_generic_filesystem: filesystem on /dev/loop50 is inconsistent (see /home/slavad/XFSTESTS-2/xfstests-dev/results//generic/001.full for details) Ran: generic/001 Failures: generic/001 Failed 1 of 1 tests fsck.hfs -d -n ./test-image.bin ** ./test-image.bin (NO WRITE) Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. Executing fsck_hfs (version 540.1-Linux). ** Checking HFS volume. The volume name is untitled ** Checking extents overflow file. ** Checking catalog file. Unused node is not erased (node = 2) Unused node is not erased (node = 4) Unused node is not erased (node = 253) Unused node is not erased (node = 254) Unused node is not erased (node = 255) Unused node is not erased (node = 256) ** Checking catalog hierarchy. ** Checking volume bitmap. ** Checking volume information. Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0000 CBTStat = 0x0004 CatStat = 0x00000000 ** The volume untitled was found corrupt and needs to be repaired. volume type is HFS primary MDB is at block 2 0x02 alternate MDB is at block 20971518 0x13ffffe primary VHB is at block 0 0x00 alternate VHB is at block 0 0x00 sector size = 512 0x200 VolumeObject flags = 0x19 total sectors for volume = 20971520 0x1400000 total sectors for embedded volume = 0 0x00 This patch adds logic of clearing the deleted b-tree node. sudo ./check generic/001 FSTYP -- hfs PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.15.0-rc2+ #3 SMP PREEMPT_DYNAMIC Fri Apr 25 17:13:00 PDT 2025 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch generic/001 9s ... 32s Ran: generic/001 Passed all 1 tests fsck.hfs -d -n ./test-image.bin ** ./test-image.bin (NO WRITE) Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. Executing fsck_hfs (version 540.1-Linux). ** Checking HFS volume. The volume name is untitled ** Checking extents overflow file. ** Checking catalog file. ** Checking catalog hierarchy. ** Checking volume bitmap. ** Checking volume information. ** The volume untitled appears to be OK. Signed-off-by: Viacheslav Dubeyko Reviewed-by: Johannes Thumshirn Link: https://lore.kernel.org/r/20250430001211.1912533-1-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko Signed-off-by: Sasha Levin --- fs/hfs/bnode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index 2039cb6d5f66..219e3b8fd6a8 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c @@ -586,6 +586,7 @@ void hfs_bnode_put(struct hfs_bnode *node) if (test_bit(HFS_BNODE_DELETED, &node->flags)) { hfs_bnode_unhash(node); spin_unlock(&tree->hash_lock); + hfs_bnode_clear(node, 0, tree->node_size); hfs_bmap_free(node); hfs_bnode_free(node); return; From 41d4cb818a2a7189b6da96e34c601ba9a3615071 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 8 May 2025 23:38:01 -0400 Subject: [PATCH 179/404] securityfs: don't pin dentries twice, once is enough... [ Upstream commit 27cd1bf1240d482e4f02ca4f9812e748f3106e4f ] incidentally, securityfs_recursive_remove() is broken without that - it leaks dentries, since simple_recursive_removal() does not expect anything of that sort. It could be worked around by dput() in remove_one() callback, but it's easier to just drop that double-get stuff. Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- security/inode.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/security/inode.c b/security/inode.c index 6c326939750d..e6e07787eec9 100644 --- a/security/inode.c +++ b/security/inode.c @@ -159,7 +159,6 @@ static struct dentry *securityfs_create_dentry(const char *name, umode_t mode, inode->i_fop = fops; } d_instantiate(dentry, inode); - dget(dentry); inode_unlock(dir); return dentry; @@ -306,7 +305,6 @@ void securityfs_remove(struct dentry *dentry) simple_rmdir(dir, dentry); else simple_unlink(dir, dentry); - dput(dentry); } inode_unlock(dir); simple_release_fs(&mount, &mount_count); From c698f6d03d17aa11f5ca91e43a77036a41e68270 Mon Sep 17 00:00:00 2001 From: Su Hui Date: Fri, 25 Jul 2025 14:01:18 +0800 Subject: [PATCH 180/404] usb: xhci: print xhci->xhc_state when queue_command failed [ Upstream commit 7919407eca2ef562fa6c98c41cfdf6f6cdd69d92 ] When encounters some errors like these: xhci_hcd 0000:4a:00.2: xHCI dying or halted, can't queue_command xhci_hcd 0000:4a:00.2: FIXME: allocate a command ring segment usb usb5-port6: couldn't allocate usb_device It's hard to know whether xhc_state is dying or halted. So it's better to print xhc_state's value which can help locate the resaon of the bug. Signed-off-by: Su Hui Link: https://lore.kernel.org/r/20250725060117.1773770-1-suhui@nfschina.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/host/xhci-ring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 08b016864fc0..71b17a00d3ed 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -4076,7 +4076,8 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd, if ((xhci->xhc_state & XHCI_STATE_DYING) || (xhci->xhc_state & XHCI_STATE_HALTED)) { - xhci_dbg(xhci, "xHCI dying or halted, can't queue_command\n"); + xhci_dbg(xhci, "xHCI dying or halted, can't queue_command. state: 0x%x\n", + xhci->xhc_state); return -ESHUTDOWN; } From 86b225d594b507246ef952194a6daff58ae45a42 Mon Sep 17 00:00:00 2001 From: Cynthia Huang Date: Thu, 10 Jul 2025 18:36:30 +0800 Subject: [PATCH 181/404] selftests/futex: Define SYS_futex on 32-bit architectures with 64-bit time_t [ Upstream commit 04850819c65c8242072818655d4341e70ae998b5 ] The kernel does not provide sys_futex() on 32-bit architectures that do not support 32-bit time representations, such as riscv32. As a result, glibc cannot define SYS_futex, causing compilation failures in tests that rely on this syscall. Define SYS_futex as SYS_futex_time64 in such cases to ensure successful compilation and compatibility. Signed-off-by: Cynthia Huang Signed-off-by: Ben Zong-You Xie Signed-off-by: Thomas Gleixner Reviewed-by: Muhammad Usama Anjum Link: https://lore.kernel.org/all/20250710103630.3156130-1-ben717@andestech.com Signed-off-by: Sasha Levin --- tools/testing/selftests/futex/include/futextest.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/testing/selftests/futex/include/futextest.h b/tools/testing/selftests/futex/include/futextest.h index ddbcfc9b7bac..7a5fd1d5355e 100644 --- a/tools/testing/selftests/futex/include/futextest.h +++ b/tools/testing/selftests/futex/include/futextest.h @@ -47,6 +47,17 @@ typedef volatile u_int32_t futex_t; FUTEX_PRIVATE_FLAG) #endif +/* + * SYS_futex is expected from system C library, in glibc some 32-bit + * architectures (e.g. RV32) are using 64-bit time_t, therefore it doesn't have + * SYS_futex defined but just SYS_futex_time64. Define SYS_futex as + * SYS_futex_time64 in this situation to ensure the compilation and the + * compatibility. + */ +#if !defined(SYS_futex) && defined(SYS_futex_time64) +#define SYS_futex SYS_futex_time64 +#endif + /** * futex() - SYS_futex syscall wrapper * @uaddr: address of first futex From fcd65f3530125b3204891d5a2ecd7f21a0bdcff8 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 17 Jul 2025 10:31:06 +0300 Subject: [PATCH 182/404] usb: xhci: Avoid showing warnings for dying controller [ Upstream commit 65fc0fc137b5da3ee1f4ca4f61050fcb203d7582 ] When a USB4 dock is unplugged from a system it won't respond to ring events. The PCI core handles the surprise removal event and notifies all PCI drivers. The XHCI PCI driver sets a flag that the device is being removed, and when the device stops responding a flag is also added to indicate it's dying. When that flag is set don't bother to show warnings about a missing controller. Signed-off-by: Mario Limonciello Signed-off-by: Mathias Nyman Acked-by: Mathias Nyman Link: https://lore.kernel.org/r/20250717073107.488599-3-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/host/xhci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 3383d7f0c88f..dcda4d7c2b75 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -118,7 +118,8 @@ int xhci_halt(struct xhci_hcd *xhci) ret = xhci_handshake(&xhci->op_regs->status, STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); if (ret) { - xhci_warn(xhci, "Host halt failed, %d\n", ret); + if (!(xhci->xhc_state & XHCI_STATE_DYING)) + xhci_warn(xhci, "Host halt failed, %d\n", ret); return ret; } xhci->xhc_state |= XHCI_STATE_HALTED; @@ -175,7 +176,8 @@ int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us) state = readl(&xhci->op_regs->status); if (state == ~(u32)0) { - xhci_warn(xhci, "Host not accessible, reset failed.\n"); + if (!(xhci->xhc_state & XHCI_STATE_DYING)) + xhci_warn(xhci, "Host not accessible, reset failed.\n"); return -ENODEV; } From 0913e9234c0f119b04ba6a9423f0de2ed19d07fb Mon Sep 17 00:00:00 2001 From: Jay Chen Date: Thu, 17 Jul 2025 10:31:07 +0300 Subject: [PATCH 183/404] usb: xhci: Set avg_trb_len = 8 for EP0 during Address Device Command [ Upstream commit f72b9aa821a2bfe4b6dfec4be19f264d0673b008 ] There is a subtle contradiction between sections of the xHCI 1.2 spec regarding the initialization of Input Endpoint Context fields. Section 4.8.2 ("Endpoint Context Initialization") states that all fields should be initialized to 0. However, Section 6.2.3 ("Endpoint Context", p.453) specifies that the Average TRB Length (avg_trb_len) field shall be greater than 0, and explicitly notes (p.454): "Software shall set Average TRB Length to '8' for control endpoints." Strictly setting all fields to 0 during initialization conflicts with the specific recommendation for control endpoints. In practice, setting avg_trb_len = 0 is not meaningful for the hardware/firmware, as the value is used for bandwidth calculation. Motivation: Our company is developing a custom Virtual xHC hardware platform that strictly follows the xHCI spec and its recommendations. During validation, we observed that enumeration fails and a parameter error (TRB Completion Code = 5) is reported if avg_trb_len for EP0 is not set to 8 as recommended by Section 6.2.3. This demonstrates the importance of assigning a meaningful, non-zero value to avg_trb_len, even in virtualized or emulated environments. This patch explicitly sets avg_trb_len to 8 for EP0 in xhci_setup_addressable_virt_dev(), as recommended in Section 6.2.3, to prevent potential issues with xHCI host controllers that enforce the spec strictly. Link: https://bugzilla.kernel.org/show_bug.cgi?id=220033 Signed-off-by: Jay Chen Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20250717073107.488599-4-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/host/xhci-mem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 610190bf62da..6dddd5414fe9 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1214,6 +1214,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud ep0_ctx->deq = cpu_to_le64(dev->eps[0].ring->first_seg->dma | dev->eps[0].ring->cycle_state); + ep0_ctx->tx_info = cpu_to_le32(EP_AVG_TRB_LENGTH(8)); + trace_xhci_setup_addressable_virt_device(dev); /* Steps 7 and 8 were done in xhci_alloc_virt_device() */ From 608ab9ff21181f64f862f3a4e1a30e0bceaedd61 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 17 Jul 2025 10:31:05 +0300 Subject: [PATCH 184/404] usb: xhci: Avoid showing errors during surprise removal [ Upstream commit 4b9c60e440525b729ac5f071e00bcee12e0a7e84 ] When a USB4 dock is unplugged from a system it won't respond to ring events. The PCI core handles the surprise removal event and notifies all PCI drivers. The XHCI PCI driver sets a flag that the device is being removed as well. When that flag is set don't show messages in the cleanup path for marking the controller dead. Signed-off-by: Mario Limonciello Signed-off-by: Mathias Nyman Acked-by: Mathias Nyman Link: https://lore.kernel.org/r/20250717073107.488599-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/host/xhci-ring.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 71b17a00d3ed..47326fb8b1fc 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -973,12 +973,15 @@ static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci, */ void xhci_hc_died(struct xhci_hcd *xhci) { + bool notify; int i, j; if (xhci->xhc_state & XHCI_STATE_DYING) return; - xhci_err(xhci, "xHCI host controller not responding, assume dead\n"); + notify = !(xhci->xhc_state & XHCI_STATE_REMOVING); + if (notify) + xhci_err(xhci, "xHCI host controller not responding, assume dead\n"); xhci->xhc_state |= XHCI_STATE_DYING; xhci_cleanup_command_queue(xhci); @@ -992,7 +995,7 @@ void xhci_hc_died(struct xhci_hcd *xhci) } /* inform usb core hc died if PCI remove isn't already handling it */ - if (!(xhci->xhc_state & XHCI_STATE_REMOVING)) + if (notify) usb_hc_died(xhci_to_hcd(xhci)); } From a242ace7a510b49f3c425b8869d2f1afeb8826b1 Mon Sep 17 00:00:00 2001 From: Lifeng Zheng Date: Wed, 9 Jul 2025 18:41:45 +0800 Subject: [PATCH 185/404] cpufreq: Exit governor when failed to start old governor [ Upstream commit 0ae204405095abfbc2d694ee0fbb49bcbbe55c57 ] Detect the result of starting old governor in cpufreq_set_policy(). If it fails, exit the governor and clear policy->governor. Signed-off-by: Lifeng Zheng Link: https://patch.msgid.link/20250709104145.2348017-5-zhenglifeng1@huawei.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/cpufreq/cpufreq.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 00f12d23077c..0f8777343e21 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2483,10 +2483,12 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, pr_debug("starting governor %s failed\n", policy->governor->name); if (old_gov) { policy->governor = old_gov; - if (cpufreq_init_governor(policy)) + if (cpufreq_init_governor(policy)) { policy->governor = NULL; - else - cpufreq_start_governor(policy); + } else if (cpufreq_start_governor(policy)) { + cpufreq_exit_governor(policy); + policy->governor = NULL; + } } return ret; From 3c6bf7a324b8995b9c7d790c8d2abf0668f51551 Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Thu, 3 Jul 2025 17:04:53 +0300 Subject: [PATCH 186/404] ARM: rockchip: fix kernel hang during smp initialization [ Upstream commit 7cdb433bb44cdc87dc5260cdf15bf03cc1cd1814 ] In order to bring up secondary CPUs main CPU write trampoline code to SRAM. The trampoline code is written while secondary CPUs are powered on (at least that true for RK3188 CPU). Sometimes that leads to kernel hang. Probably because secondary CPU execute trampoline code while kernel doesn't expect. The patch moves SRAM initialization step to the point where all secondary CPUs are powered down. That fixes rarely hangs on RK3188: [ 0.091568] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000 [ 0.091996] rockchip_smp_prepare_cpus: ncores 4 Signed-off-by: Alexander Kochetkov Link: https://lore.kernel.org/r/20250703140453.1273027-1-al.kochet@gmail.com Signed-off-by: Heiko Stuebner Signed-off-by: Sasha Levin --- arch/arm/mach-rockchip/platsmp.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index 649e0a54784c..246a525d1d26 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -279,11 +279,6 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus) } if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) { - if (rockchip_smp_prepare_sram(node)) { - of_node_put(node); - return; - } - /* enable the SCU power domain */ pmu_set_power_domain(PMU_PWRDN_SCU, true); @@ -316,11 +311,19 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus) asm ("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr)); ncores = ((l2ctlr >> 24) & 0x3) + 1; } - of_node_put(node); /* Make sure that all cores except the first are really off */ for (i = 1; i < ncores; i++) pmu_set_power_domain(0 + i, false); + + if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) { + if (rockchip_smp_prepare_sram(node)) { + of_node_put(node); + return; + } + } + + of_node_put(node); } static void __init rk3036_smp_prepare_cpus(unsigned int max_cpus) From d8e03f70c1f9a24baff128f5dca4eec53647468a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 11 Jul 2025 02:26:39 +0000 Subject: [PATCH 187/404] ASoC: soc-dapm: set bias_level if snd_soc_dapm_set_bias_level() was successed [ Upstream commit f40ecc2743652c0b0f19935f81baf57c601eb7f0 ] ASoC has 2 functions to set bias level. (A) snd_soc_dapm_force_bias_level() (B) snd_soc_dapm_set_bias_level() snd_soc_dapm_force_bias_level() (A) will set dapm->bias_level (a) if successed. (A) int snd_soc_dapm_force_bias_level(...) { ... if (ret == 0) (a) dapm->bias_level = level; ... } snd_soc_dapm_set_bias_level() (B) is also a function that sets bias_level. It will call snd_soc_dapm_force_bias_level() (A) inside, but doesn't set dapm->bias_level by itself. One note is that (A) might not be called. (B) static int snd_soc_dapm_set_bias_level(...) { ... ret = snd_soc_card_set_bias_level(...); ... if (dapm != &card->dapm) (A) ret = snd_soc_dapm_force_bias_level(...); ... ret = snd_soc_card_set_bias_level_post(...); ... } dapm->bias_level will be set if (A) was called, but might not be set if (B) was called, even though it calles set_bias_level() function. We should set dapm->bias_level if we calls snd_soc_dapm_set_bias_level() (B), too. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87qzyn4g4h.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/soc-dapm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 9f764d92469e..6142ce468c3b 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -741,6 +741,10 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm, out: trace_snd_soc_bias_level_done(card, level); + /* success */ + if (ret == 0) + snd_soc_dapm_init_bias_level(dapm, level); + return ret; } From 4cfa95dc42e9a48a7d0d25d1c27fca248f13bf69 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 7 Jul 2025 09:50:15 +0200 Subject: [PATCH 188/404] gpio: tps65912: check the return value of regmap_update_bits() [ Upstream commit a0b2a6bbff8c26aafdecd320f38f52c341d5cafa ] regmap_update_bits() can fail, check its return value like we do elsewhere in the driver. Link: https://lore.kernel.org/r/20250707-gpiochip-set-rv-gpio-round4-v1-2-35668aaaf6d2@linaro.org Signed-off-by: Bartosz Golaszewski Signed-off-by: Sasha Levin --- drivers/gpio/gpio-tps65912.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-tps65912.c b/drivers/gpio/gpio-tps65912.c index 3ad68bd78282..736af805e54a 100644 --- a/drivers/gpio/gpio-tps65912.c +++ b/drivers/gpio/gpio-tps65912.c @@ -49,10 +49,13 @@ static int tps65912_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int value) { struct tps65912_gpio *gpio = gpiochip_get_data(gc); + int ret; /* Set the initial value */ - regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, - GPIO_SET_MASK, value ? GPIO_SET_MASK : 0); + ret = regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, + GPIO_SET_MASK, value ? GPIO_SET_MASK : 0); + if (ret) + return ret; return regmap_update_bits(gpio->tps->regmap, TPS65912_GPIO1 + offset, GPIO_CFG_MASK, GPIO_CFG_MASK); From b28c1a14accc79ead1e87bbdae53309da60be1e7 Mon Sep 17 00:00:00 2001 From: Aaron Kling Date: Thu, 22 May 2025 11:11:24 -0500 Subject: [PATCH 189/404] ARM: tegra: Use I/O memcpy to write to IRAM [ Upstream commit 398e67e0f5ae04b29bcc9cbf342e339fe9d3f6f1 ] Kasan crashes the kernel trying to check boundaries when using the normal memcpy. Signed-off-by: Aaron Kling Link: https://lore.kernel.org/r/20250522-mach-tegra-kasan-v1-1-419041b8addb@gmail.com Signed-off-by: Thierry Reding Signed-off-by: Sasha Levin --- arch/arm/mach-tegra/reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c index 76a65df42d10..dce0cb1fdd6f 100644 --- a/arch/arm/mach-tegra/reset.c +++ b/arch/arm/mach-tegra/reset.c @@ -63,7 +63,7 @@ static void __init tegra_cpu_reset_handler_enable(void) BUG_ON(is_enabled); BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE); - memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start, + memcpy_toio(iram_base, (void *)__tegra_cpu_reset_handler_start, tegra_cpu_reset_handler_size); err = call_firmware_op(set_cpu_boot_addr, 0, reset_address); From efea60c80d2324619bb752d1da2c4caa26eb8dc5 Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Thu, 3 Jul 2025 13:26:43 +0900 Subject: [PATCH 190/404] selftests: tracing: Use mutex_unlock for testing glob filter [ Upstream commit a089bb2822a49b0c5777a8936f82c1f8629231fb ] Since commit c5b6ababd21a ("locking/mutex: implement mutex_trylock_nested") makes mutex_trylock() as an inlined function if CONFIG_DEBUG_LOCK_ALLOC=y, we can not use mutex_trylock() for testing the glob filter of ftrace. Use mutex_unlock instead. Link: https://lore.kernel.org/r/175151680309.2149615.9795104805153538717.stgit@mhiramat.tok.corp.google.com Signed-off-by: Masami Hiramatsu (Google) Acked-by: Steven Rostedt (Google) Signed-off-by: Shuah Khan Signed-off-by: Sasha Levin --- .../testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc index f4e92afab14b..9a7b7c62cbd9 100644 --- a/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc +++ b/tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc @@ -33,7 +33,7 @@ ftrace_filter_check 'schedule*' '^schedule.*$' ftrace_filter_check '*pin*lock' '.*pin.*lock$' # filter by start*mid* -ftrace_filter_check 'mutex*try*' '^mutex.*try.*' +ftrace_filter_check 'mutex*unl*' '^mutex.*unl.*' # Advanced full-glob matching feature is recently supported. # Skip the tests if we are sure the kernel does not support it. From 2f6af29069e03262eb9bf10f65e56d9f6ff26dcc Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 27 Jun 2025 21:16:05 +0200 Subject: [PATCH 191/404] PM: runtime: Clear power.needs_force_resume in pm_runtime_reinit() [ Upstream commit 89d9cec3b1e9c49bae9375a2db6dc49bc7468af0 ] Clear power.needs_force_resume in pm_runtime_reinit() in case it has been set by pm_runtime_force_suspend() invoked from a driver remove callback. Suggested-by: Ulf Hansson Signed-off-by: Rafael J. Wysocki Reviewed-by: Ulf Hansson Link: https://patch.msgid.link/9495163.CDJkKcVGEf@rjwysocki.net Signed-off-by: Sasha Levin --- drivers/base/power/runtime.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 7fa231076ad5..7d362b38f2e8 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1698,6 +1698,11 @@ void pm_runtime_reinit(struct device *dev) pm_runtime_put(dev->parent); } } + /* + * Clear power.needs_force_resume in case it has been set by + * pm_runtime_force_suspend() invoked from a driver remove callback. + */ + dev->power.needs_force_resume = false; } /** From f948542e646d1cbe9b09baca3bacba1d04e4e7d1 Mon Sep 17 00:00:00 2001 From: Hsin-Te Yuan Date: Fri, 20 Jun 2025 10:41:43 +0000 Subject: [PATCH 192/404] thermal: sysfs: Return ENODATA instead of EAGAIN for reads [ Upstream commit 1a4aabc27e95674837f2e25f4ef340c0469e6203 ] According to POSIX spec, EAGAIN returned by read with O_NONBLOCK set means the read would block. Hence, the common implementation in nonblocking model will poll the file when the nonblocking read returns EAGAIN. However, when the target file is thermal zone, this mechanism will totally malfunction because thermal zone doesn't implement sysfs notification and thus the poll will never return. For example, the read in Golang implemnts such method and sometimes hangs at reading some thermal zones via sysfs. Change to return -ENODATA instead of -EAGAIN to userspace. Signed-off-by: Hsin-Te Yuan Link: https://patch.msgid.link/20250620-temp-v3-1-6becc6aeb66c@chromium.org Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/thermal/thermal_sysfs.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index 17b2361bc8f2..fc768b61f483 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -39,10 +39,13 @@ temp_show(struct device *dev, struct device_attribute *attr, char *buf) ret = thermal_zone_get_temp(tz, &temperature); - if (ret) - return ret; + if (!ret) + return sprintf(buf, "%d\n", temperature); - return sprintf(buf, "%d\n", temperature); + if (ret == -EAGAIN) + return -ENODATA; + + return ret; } static ssize_t From f829e4b3815a617c4f4f001653a11d220df49cd4 Mon Sep 17 00:00:00 2001 From: tuhaowen Date: Wed, 11 Jun 2025 11:23:45 +0800 Subject: [PATCH 193/404] PM: sleep: console: Fix the black screen issue [ Upstream commit 4266e8fa56d3d982bf451d382a410b9db432015c ] When the computer enters sleep status without a monitor connected, the system switches the console to the virtual terminal tty63(SUSPEND_CONSOLE). If a monitor is subsequently connected before waking up, the system skips the required VT restoration process during wake-up, leaving the console on tty63 instead of switching back to tty1. To fix this issue, a global flag vt_switch_done is introduced to record whether the system has successfully switched to the suspend console via vt_move_to_console() during suspend. If the switch was completed, vt_switch_done is set to 1. Later during resume, this flag is checked to ensure that the original console is restored properly by calling vt_move_to_console(orig_fgconsole, 0). This prevents scenarios where the resume logic skips console restoration due to incorrect detection of the console state, especially when a monitor is reconnected before waking up. Signed-off-by: tuhaowen Link: https://patch.msgid.link/20250611032345.29962-1-tuhaowen@uniontech.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- kernel/power/console.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/power/console.c b/kernel/power/console.c index fcdf0e14a47d..19c48aa5355d 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c @@ -16,6 +16,7 @@ #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) static int orig_fgconsole, orig_kmsg; +static bool vt_switch_done; static DEFINE_MUTEX(vt_switch_mutex); @@ -136,17 +137,21 @@ void pm_prepare_console(void) if (orig_fgconsole < 0) return; + vt_switch_done = true; + orig_kmsg = vt_kmsg_redirect(SUSPEND_CONSOLE); return; } void pm_restore_console(void) { - if (!pm_vt_switch()) + if (!pm_vt_switch() && !vt_switch_done) return; if (orig_fgconsole >= 0) { vt_move_to_console(orig_fgconsole, 0); vt_kmsg_redirect(orig_kmsg); } + + vt_switch_done = false; } From 6783224b9d2468efb456fcab9d69bbd6a4d76be0 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Thu, 3 Jul 2025 14:42:15 +0200 Subject: [PATCH 194/404] ACPI: processor: fix acpi_object initialization [ Upstream commit 13edf7539211d8f7d0068ce3ed143005f1da3547 ] Initialization of the local acpi_object in acpi_processor_get_info() only sets the first 4 bytes to zero and is thus incomplete. This is indicated by messages like: acpi ACPI0007:be: Invalid PBLK length [166288104] Fix this by initializing all 16 bytes of the processor member of that union. Signed-off-by: Sebastian Ott Link: https://patch.msgid.link/20250703124215.12522-1-sebott@redhat.com Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/acpi_processor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index c8338d627857..9cbf0593da05 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -228,7 +228,7 @@ static inline int acpi_processor_hotadd_init(struct acpi_processor *pr) static int acpi_processor_get_info(struct acpi_device *device) { - union acpi_object object = { 0 }; + union acpi_object object = { .processor = { 0 } }; struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; struct acpi_processor *pr = acpi_driver_data(device); int device_declaration = 0; From 36bfbdadd6707e60ee931f1d9463c847981f238b Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Wed, 2 Jul 2025 08:39:51 -0700 Subject: [PATCH 195/404] ACPI: APEI: GHES: add TAINT_MACHINE_CHECK on GHES panic path [ Upstream commit 4734c8b46b901cff2feda8b82abc710b65dc31c1 ] When a GHES (Generic Hardware Error Source) triggers a panic, add the TAINT_MACHINE_CHECK taint flag to the kernel. This explicitly marks the kernel as tainted due to a machine check event, improving diagnostics and post-mortem analysis. The taint is set with LOCKDEP_STILL_OK to indicate lockdep remains valid. At large scale deployment, this helps to quickly determine panics that are coming due to hardware failures. Signed-off-by: Breno Leitao Reviewed-by: Tony Luck Link: https://patch.msgid.link/20250702-add_tain-v1-1-9187b10914b9@debian.org Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/apei/ghes.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 50bed5a70812..d02d7cbab387 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -709,6 +709,8 @@ static void __ghes_panic(struct ghes *ghes, __ghes_print_estatus(KERN_EMERG, ghes->generic, estatus); + add_taint(TAINT_MACHINE_CHECK, LOCKDEP_STILL_OK); + ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx); if (!panic_timeout) From a35952fbe2da22bb5ab0009167f99b1751804b77 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 10 Jun 2025 13:16:23 +0200 Subject: [PATCH 196/404] mmc: rtsx_usb_sdmmc: Fix error-path in sd_set_power_mode() [ Upstream commit 47a255f7d2eabee06cfbf5b1c2379749442fd01d ] In the error path of sd_set_power_mode() we don't update host->power_mode, which could lead to an imbalance of the runtime PM usage count. Fix this by always updating host->power_mode. Reviewed-by: Avri Altman Signed-off-by: Ulf Hansson Acked-by: Ricky Wu Link: https://lore.kernel.org/r/20250610111633.504366-2-ulf.hansson@linaro.org Signed-off-by: Sasha Levin --- drivers/mmc/host/rtsx_usb_sdmmc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c index 3261560bede4..581bec5c4caf 100644 --- a/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c @@ -1038,9 +1038,7 @@ static int sd_set_power_mode(struct rtsx_usb_sdmmc *host, err = sd_power_on(host); } - if (!err) - host->power_mode = power_mode; - + host->power_mode = power_mode; return err; } From 1fca80060715378d72636fe5d831e05662b875fa Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 13 Jun 2025 17:41:04 +0100 Subject: [PATCH 197/404] ASoC: hdac_hdmi: Rate limit logging on connection and disconnection [ Upstream commit c4ca928a6db1593802cd945f075a7e21dd0430c1 ] We currently log parse failures for ELD data and some disconnection events as errors without rate limiting. These log messages can be triggered very frequently in some situations, especially ELD parsing when there is nothing connected to a HDMI port which will generate: hdmi-audio-codec hdmi-audio-codec.1.auto: HDMI: Unknown ELD version 0 While there's doubtless work that could be done on reducing the number of connection notification callbacks it's possible these may be legitimately generated by poor quality physical connections so let's use rate limiting to mitigate the log spam for the parse errors and lower the severity for disconnect logging to debug level. Signed-off-by: Mark Brown Link: https://patch.msgid.link/20250613-asoc-hdmi-eld-logging-v1-1-76d64154d969@kernel.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/hdac_hdmi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 78d5b4d31bb6..71d13b413418 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -1231,7 +1231,8 @@ static int hdac_hdmi_parse_eld(struct hdac_device *hdev, >> DRM_ELD_VER_SHIFT; if (ver != ELD_VER_CEA_861D && ver != ELD_VER_PARTIAL) { - dev_err(&hdev->dev, "HDMI: Unknown ELD version %d\n", ver); + dev_err_ratelimited(&hdev->dev, + "HDMI: Unknown ELD version %d\n", ver); return -EINVAL; } @@ -1239,7 +1240,8 @@ static int hdac_hdmi_parse_eld(struct hdac_device *hdev, DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT; if (mnl > ELD_MAX_MNL) { - dev_err(&hdev->dev, "HDMI: MNL Invalid %d\n", mnl); + dev_err_ratelimited(&hdev->dev, + "HDMI: MNL Invalid %d\n", mnl); return -EINVAL; } @@ -1293,8 +1295,8 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, if (!port->eld.monitor_present || !port->eld.eld_valid) { - dev_err(&hdev->dev, "%s: disconnect for pin:port %d:%d\n", - __func__, pin->nid, port->id); + dev_dbg(&hdev->dev, "%s: disconnect for pin:port %d:%d\n", + __func__, pin->nid, port->id); /* * PCMs are not registered during device probe, so don't From 98e92be291ca29b608cf4e7faa0cccbfd71a20f3 Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Sat, 21 Jun 2025 11:52:24 -0700 Subject: [PATCH 198/404] ALSA: intel8x0: Fix incorrect codec index usage in mixer for ICH4 [ Upstream commit 87aafc8580acf87fcaf1a7e30ed858d8c8d37d81 ] code mistakenly used a hardcoded index (codec[1]) instead of iterating, over the codec array using the loop variable i. Use codec[i] instead of codec[1] to match the loop iteration. Signed-off-by: Alok Tiwari Link: https://patch.msgid.link/20250621185233.4081094-1-alok.a.tiwari@oracle.com Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/intel8x0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 5150e8d38975..87a23a4660e8 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -2285,7 +2285,7 @@ static int snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, tmp |= chip->ac97_sdin[0] << ICH_DI1L_SHIFT; for (i = 1; i < 4; i++) { if (pcm->r[0].codec[i]) { - tmp |= chip->ac97_sdin[pcm->r[0].codec[1]->num] << ICH_DI2L_SHIFT; + tmp |= chip->ac97_sdin[pcm->r[0].codec[i]->num] << ICH_DI2L_SHIFT; break; } } From c41fef8b2dfe9db90421fbc2cde1edc8fff58a35 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 12 Jun 2025 14:20:25 +0200 Subject: [PATCH 199/404] usb: core: usb_submit_urb: downgrade type check [ Upstream commit 503bbde34cc3dd2acd231f277ba70c3f9ed22e59 ] Checking for the endpoint type is no reason for a WARN, as that can cause a reboot. A driver not checking the endpoint type must not cause a reboot, as there is just no point in this. We cannot prevent a device from doing something incorrect as a reaction to a transfer. Hence warning for a mere assumption being wrong is not sensible. Signed-off-by: Oliver Neukum Acked-by: Alan Stern Link: https://lore.kernel.org/r/20250612122149.2559724-1-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/core/urb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 850d0fffe1c6..e60f4ef06e3d 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -490,7 +490,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) /* Check that the pipe's type matches the endpoint's type */ if (usb_pipe_type_check(urb->dev, urb->pipe)) - dev_WARN(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n", + dev_warn_once(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n", usb_pipetype(urb->pipe), pipetypes[xfertype]); /* Check against a simple/standard policy */ From 1b5c6a600ff46296309892c7ec6030b2b768bd45 Mon Sep 17 00:00:00 2001 From: "Gautham R. Shenoy" Date: Thu, 12 Jun 2025 17:53:54 +0530 Subject: [PATCH 200/404] pm: cpupower: Fix the snapshot-order of tsc,mperf, clock in mperf_stop() [ Upstream commit cda7ac8ce7de84cf32a3871ba5f318aa3b79381e ] In the function mperf_start(), mperf_monitor snapshots the time, tsc and finally the aperf,mperf MSRs. However, this order of snapshotting in is reversed in mperf_stop(). As a result, the C0 residency (which is computed as delta_mperf * 100 / delta_tsc) is under-reported on CPUs that is 100% busy. Fix this by snapshotting time, tsc and then aperf,mperf in mperf_stop() in the same order as in mperf_start(). Link: https://lore.kernel.org/r/20250612122355.19629-2-gautham.shenoy@amd.com Signed-off-by: Gautham R. Shenoy Signed-off-by: Shuah Khan Signed-off-by: Sasha Levin --- tools/power/cpupower/utils/idle_monitor/mperf_monitor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c index 0e8c0b879d4b..09c606760464 100644 --- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c @@ -201,9 +201,9 @@ static int mperf_stop(void) int cpu; for (cpu = 0; cpu < cpu_count; cpu++) { - mperf_measure_stats(cpu); - mperf_get_tsc(&tsc_at_measure_end[cpu]); clock_gettime(CLOCK_REALTIME, &time_end[cpu]); + mperf_get_tsc(&tsc_at_measure_end[cpu]); + mperf_measure_stats(cpu); } return 0; From cfff555f6c101c7b5f1957d5139e096a0e18e567 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 29 May 2025 11:18:37 -0700 Subject: [PATCH 201/404] platform/x86: thinkpad_acpi: Handle KCOV __init vs inline mismatches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 6418a8504187dc7f5b6f9d0649c03e362cb0664b ] When KCOV is enabled all functions get instrumented, unless the __no_sanitize_coverage attribute is used. To prepare for __no_sanitize_coverage being applied to __init functions[1], we have to handle differences in how GCC's inline optimizations get resolved. For thinkpad_acpi routines, this means forcing two functions to be inline with __always_inline. Link: https://lore.kernel.org/lkml/20250523043935.2009972-11-kees@kernel.org/ [1] Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20250529181831.work.439-kees@kernel.org Signed-off-by: Ilpo Järvinen Signed-off-by: Sasha Levin --- drivers/platform/x86/thinkpad_acpi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 9eb74d9e1519..e480fff7142a 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -514,12 +514,12 @@ static unsigned long __init tpacpi_check_quirks( return 0; } -static inline bool __pure __init tpacpi_is_lenovo(void) +static __always_inline bool __pure __init tpacpi_is_lenovo(void) { return thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO; } -static inline bool __pure __init tpacpi_is_ibm(void) +static __always_inline bool __pure __init tpacpi_is_ibm(void) { return thinkpad_id.vendor == PCI_VENDOR_ID_IBM; } From 04fa6f5e94034654da3505d9e908dd9090f0e83c Mon Sep 17 00:00:00 2001 From: Lucy Thrun Date: Tue, 10 Jun 2025 19:50:12 +0200 Subject: [PATCH 202/404] ALSA: hda/ca0132: Fix buffer overflow in add_tuning_control [ Upstream commit a409c60111e6bb98fcabab2aeaa069daa9434ca0 ] The 'sprintf' call in 'add_tuning_control' may exceed the 44-byte buffer if either string argument is too long. This triggers a compiler warning. Replaced 'sprintf' with 'snprintf' to limit string lengths to prevent overflow. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202506100642.95jpuMY1-lkp@intel.com/ Signed-off-by: Lucy Thrun Link: https://patch.msgid.link/20250610175012.918-3-lucy.thrun@digital-rabbithole.de Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/pci/hda/patch_ca0132.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 40f50571ad63..dee38dd872b5 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -4014,7 +4014,7 @@ static int add_tuning_control(struct hda_codec *codec, } knew.private_value = HDA_COMPOSE_AMP_VAL(nid, 1, 0, type); - sprintf(namestr, "%s %s Volume", name, dirstr[dir]); + snprintf(namestr, sizeof(namestr), "%s %s Volume", name, dirstr[dir]); return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); } From a9310a0fa94f1e4e22b9ec2453d7e0d0e65558bc Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Mon, 26 May 2025 17:07:42 +0300 Subject: [PATCH 203/404] ALSA: usb-audio: Avoid precedence issues in mixer_quirks macros [ Upstream commit fd3ab72e42e9871a9902b945a2bf8bb87b49c718 ] Fix all macro related issues identified by checkpatch.pl: CHECK: Macro argument 'x' may be better as '(x)' to avoid precedence issues Signed-off-by: Cristian Ciocaltea Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250526-dualsense-alsa-jack-v1-3-1a821463b632@collabora.com Signed-off-by: Sasha Levin --- sound/usb/mixer_quirks.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index e752b6bb03ec..04267d4e3ecf 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -1990,15 +1990,15 @@ static int dell_dock_mixer_init(struct usb_mixer_interface *mixer) #define SND_RME_CLK_FREQMUL_SHIFT 18 #define SND_RME_CLK_FREQMUL_MASK 0x7 #define SND_RME_CLK_SYSTEM(x) \ - ((x >> SND_RME_CLK_SYSTEM_SHIFT) & SND_RME_CLK_SYSTEM_MASK) + (((x) >> SND_RME_CLK_SYSTEM_SHIFT) & SND_RME_CLK_SYSTEM_MASK) #define SND_RME_CLK_AES(x) \ - ((x >> SND_RME_CLK_AES_SHIFT) & SND_RME_CLK_AES_SPDIF_MASK) + (((x) >> SND_RME_CLK_AES_SHIFT) & SND_RME_CLK_AES_SPDIF_MASK) #define SND_RME_CLK_SPDIF(x) \ - ((x >> SND_RME_CLK_SPDIF_SHIFT) & SND_RME_CLK_AES_SPDIF_MASK) + (((x) >> SND_RME_CLK_SPDIF_SHIFT) & SND_RME_CLK_AES_SPDIF_MASK) #define SND_RME_CLK_SYNC(x) \ - ((x >> SND_RME_CLK_SYNC_SHIFT) & SND_RME_CLK_SYNC_MASK) + (((x) >> SND_RME_CLK_SYNC_SHIFT) & SND_RME_CLK_SYNC_MASK) #define SND_RME_CLK_FREQMUL(x) \ - ((x >> SND_RME_CLK_FREQMUL_SHIFT) & SND_RME_CLK_FREQMUL_MASK) + (((x) >> SND_RME_CLK_FREQMUL_SHIFT) & SND_RME_CLK_FREQMUL_MASK) #define SND_RME_CLK_AES_LOCK 0x1 #define SND_RME_CLK_AES_SYNC 0x4 #define SND_RME_CLK_SPDIF_LOCK 0x2 @@ -2007,9 +2007,9 @@ static int dell_dock_mixer_init(struct usb_mixer_interface *mixer) #define SND_RME_SPDIF_FORMAT_SHIFT 5 #define SND_RME_BINARY_MASK 0x1 #define SND_RME_SPDIF_IF(x) \ - ((x >> SND_RME_SPDIF_IF_SHIFT) & SND_RME_BINARY_MASK) + (((x) >> SND_RME_SPDIF_IF_SHIFT) & SND_RME_BINARY_MASK) #define SND_RME_SPDIF_FORMAT(x) \ - ((x >> SND_RME_SPDIF_FORMAT_SHIFT) & SND_RME_BINARY_MASK) + (((x) >> SND_RME_SPDIF_FORMAT_SHIFT) & SND_RME_BINARY_MASK) static const u32 snd_rme_rate_table[] = { 32000, 44100, 48000, 50000, From f1aa0fb41b27411d3e67c95a02dc6b4788c2957c Mon Sep 17 00:00:00 2001 From: Xinxin Wan Date: Fri, 30 May 2025 16:21:19 +0200 Subject: [PATCH 204/404] ASoC: codecs: rt5640: Retry DEVICE_ID verification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 19f971057b2d7b99c80530ec1052b45de236a8da ] To be more resilient to codec-detection failures when the hardware powers on slowly, add retry mechanism to the device verification check. Similar pattern is found throughout a number of Realtek codecs. Our tests show that 60ms delay is sufficient to address readiness issues on rt5640 chip. Reviewed-by: Amadeusz Sławiński Reviewed-by: Cezary Rojewski Signed-off-by: Xinxin Wan Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20250530142120.2944095-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/codecs/rt5640.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 3bc63fbcb188..e290a83c20af 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2810,6 +2810,11 @@ static int rt5640_i2c_probe(struct i2c_client *i2c, } regmap_read(rt5640->regmap, RT5640_VENDOR_ID2, &val); + if (val != RT5640_DEVICE_ID) { + usleep_range(60000, 100000); + regmap_read(rt5640->regmap, RT5640_VENDOR_ID2, &val); + } + if (val != RT5640_DEVICE_ID) { dev_err(&i2c->dev, "Device with ID register %#x is not rt5640/39\n", val); From 061d24625de3b84476687208e3bb217b31c6e54c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 18 Jul 2025 16:18:44 -0400 Subject: [PATCH 205/404] ktest.pl: Prevent recursion of default variable options [ Upstream commit 61f7e318e99d3b398670518dd3f4f8510d1800fc ] If a default variable contains itself, do not recurse on it. For example: ADD_CONFIG := ${CONFIG_DIR}/temp_config DEFAULTS ADD_CONFIG = ${CONFIG_DIR}/default_config ${ADD_CONFIG} The above works because the temp variable ADD_CONFIG (is a temp because it is created with ":=") is already defined, it will be substituted in the variable option. But if it gets commented out: # ADD_CONFIG := ${CONFIG_DIR}/temp_config DEFAULTS ADD_CONFIG = ${CONFIG_DIR}/default_config ${ADD_CONFIG} Then the above will go into a recursive loop where ${ADD_CONFIG} will get replaced with the current definition of ADD_CONFIG which contains the ${ADD_CONFIG} and that will also try to get converted. ktest.pl will error after 100 attempts of recursion and fail. When replacing a variable with the default variable, if the default variable contains itself, do not replace it. Cc: "John Warthog9 Hawley" Cc: Dhaval Giani Cc: Greg KH Link: https://lore.kernel.org/20250718202053.732189428@kernel.org Signed-off-by: Steven Rostedt Signed-off-by: Sasha Levin --- tools/testing/ktest/ktest.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 10b3c5b25b69..964a531e1a65 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -1280,7 +1280,10 @@ sub __eval_option { # If a variable contains itself, use the default var if (($var eq $name) && defined($opt{$var})) { $o = $opt{$var}; - $retval = "$retval$o"; + # Only append if the default doesn't contain itself + if ($o !~ m/\$\{$var\}/) { + $retval = "$retval$o"; + } } elsif (defined($opt{$o})) { $o = $opt{$o}; $retval = "$retval$o"; From 79d464eda49dbf57e15f90c6b78ab86acb9179a9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 18 Jul 2025 20:23:06 +0200 Subject: [PATCH 206/404] wifi: cfg80211: reject HTC bit for management frames [ Upstream commit be06a8c7313943109fa870715356503c4c709cbc ] Management frames sent by userspace should never have the order/HTC bit set, reject that. It could also cause some confusion with the length of the buffer and the header so the validation might end up wrong. Link: https://patch.msgid.link/20250718202307.97a0455f0f35.I1805355c7e331352df16611839bc8198c855a33f@changeid Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- net/wireless/mlme.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index f9462010575f..ea75459ac272 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -598,7 +598,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, mgmt = (const struct ieee80211_mgmt *)params->buf; - if (!ieee80211_is_mgmt(mgmt->frame_control)) + if (!ieee80211_is_mgmt(mgmt->frame_control) || + ieee80211_has_order(mgmt->frame_control)) return -EINVAL; stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; From 92d523fac8c93a74887d0a4d1f616c79ee18f8c7 Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Thu, 10 Jul 2025 09:42:29 +0200 Subject: [PATCH 207/404] s390/time: Use monotonic clock in get_cycles() [ Upstream commit 09e7e29d2b49ba84bcefb3dc1657726d2de5bb24 ] Otherwise the code might not work correctly when the clock is changed. Signed-off-by: Sven Schnelle Reviewed-by: Heiko Carstens Signed-off-by: Alexander Gordeev Signed-off-by: Sasha Levin --- arch/s390/include/asm/timex.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index 99a7e028232d..8ab537d0d6f8 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h @@ -172,13 +172,6 @@ static inline unsigned long long get_tod_clock_fast(void) return get_tod_clock(); #endif } - -static inline cycles_t get_cycles(void) -{ - return (cycles_t) get_tod_clock() >> 2; -} -#define get_cycles get_cycles - int get_phys_clock(unsigned long *clock); void init_cpu_timer(void); unsigned long long monotonic_clock(void); @@ -202,6 +195,12 @@ static inline unsigned long long get_tod_clock_monotonic(void) return tod; } +static inline cycles_t get_cycles(void) +{ + return (cycles_t)get_tod_clock_monotonic() >> 2; +} +#define get_cycles get_cycles + /** * tod_to_ns - convert a TOD format value to nanoseconds * @todval: to be converted TOD format value From 72dff0255e8ea60370fe04f9655fc0832c99473b Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Thu, 17 Jul 2025 12:35:47 -0700 Subject: [PATCH 208/404] be2net: Use correct byte order and format string for TCP seq and ack_seq [ Upstream commit 4701ee5044fb3992f1c910630a9673c2dc600ce5 ] The TCP header fields seq and ack_seq are 32-bit values in network byte order as (__be32). these fields were earlier printed using ntohs(), which converts only 16-bit values and produces incorrect results for 32-bit fields. This patch is changeing the conversion to ntohl(), ensuring correct interpretation of these sequence numbers. Notably, the format specifier is updated from %d to %u to reflect the unsigned nature of these fields. improves the accuracy of debug log messages for TCP sequence and acknowledgment numbers during TX timeouts. Signed-off-by: Alok Tiwari Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250717193552.3648791-1-alok.a.tiwari@oracle.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/emulex/benet/be_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 4b9380003c85..ce235def334f 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1467,10 +1467,10 @@ static void be_tx_timeout(struct net_device *netdev) ntohs(tcphdr->source)); dev_info(dev, "TCP dest port %d\n", ntohs(tcphdr->dest)); - dev_info(dev, "TCP sequence num %d\n", - ntohs(tcphdr->seq)); - dev_info(dev, "TCP ack_seq %d\n", - ntohs(tcphdr->ack_seq)); + dev_info(dev, "TCP sequence num %u\n", + ntohl(tcphdr->seq)); + dev_info(dev, "TCP ack_seq %u\n", + ntohl(tcphdr->ack_seq)); } else if (ip_hdr(skb)->protocol == IPPROTO_UDP) { udphdr = udp_hdr(skb); From 128ed836b7285ac98f5514d6e19f9645e20d30ab Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Wed, 16 Jul 2025 11:47:30 +0200 Subject: [PATCH 209/404] et131x: Add missing check after DMA map [ Upstream commit d61f6cb6f6ef3c70d2ccc0d9c85c508cb8017da9 ] The DMA map functions can fail and should be tested for errors. If the mapping fails, unmap and return an error. Signed-off-by: Thomas Fourier Acked-by: Mark Einon Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250716094733.28734-2-fourier.thomas@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/agere/et131x.c | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/net/ethernet/agere/et131x.c b/drivers/net/ethernet/agere/et131x.c index 174344c450af..f6232e8178b8 100644 --- a/drivers/net/ethernet/agere/et131x.c +++ b/drivers/net/ethernet/agere/et131x.c @@ -2464,6 +2464,10 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) skb->data, skb_headlen(skb), DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, + dma_addr)) + return -ENOMEM; + desc[frag].addr_lo = lower_32_bits(dma_addr); desc[frag].addr_hi = upper_32_bits(dma_addr); frag++; @@ -2473,6 +2477,10 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) skb->data, skb_headlen(skb) / 2, DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, + dma_addr)) + return -ENOMEM; + desc[frag].addr_lo = lower_32_bits(dma_addr); desc[frag].addr_hi = upper_32_bits(dma_addr); frag++; @@ -2483,6 +2491,10 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) skb_headlen(skb) / 2, skb_headlen(skb) / 2, DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, + dma_addr)) + goto unmap_first_out; + desc[frag].addr_lo = lower_32_bits(dma_addr); desc[frag].addr_hi = upper_32_bits(dma_addr); frag++; @@ -2494,6 +2506,9 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) 0, desc[frag].len_vlan, DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, dma_addr)) + goto unmap_out; + desc[frag].addr_lo = lower_32_bits(dma_addr); desc[frag].addr_hi = upper_32_bits(dma_addr); frag++; @@ -2583,6 +2598,27 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) &adapter->regs->global.watchdog_timer); } return 0; + +unmap_out: + // Unmap the body of the packet with map_page + while (--i) { + frag--; + dma_addr = desc[frag].addr_lo; + dma_addr |= (u64)desc[frag].addr_hi << 32; + dma_unmap_page(&adapter->pdev->dev, dma_addr, + desc[frag].len_vlan, DMA_TO_DEVICE); + } + +unmap_first_out: + // Unmap the header with map_single + while (frag--) { + dma_addr = desc[frag].addr_lo; + dma_addr |= (u64)desc[frag].addr_hi << 32; + dma_unmap_single(&adapter->pdev->dev, dma_addr, + desc[frag].len_vlan, DMA_TO_DEVICE); + } + + return -ENOMEM; } static int send_packet(struct sk_buff *skb, struct et131x_adapter *adapter) From 54e755bd476a8c8081f0bac6eaab4506574ef286 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Wed, 16 Jul 2025 11:57:25 +0200 Subject: [PATCH 210/404] net: ag71xx: Add missing check after DMA map [ Upstream commit 96a1e15e60216b52da0e6da5336b6d7f5b0188b0 ] The DMA map functions can fail and should be tested for errors. Signed-off-by: Thomas Fourier Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250716095733.37452-3-fourier.thomas@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/atheros/ag71xx.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c index 58a002dd758c..ba07817d0a22 100644 --- a/drivers/net/ethernet/atheros/ag71xx.c +++ b/drivers/net/ethernet/atheros/ag71xx.c @@ -1049,6 +1049,11 @@ static bool ag71xx_fill_rx_buf(struct ag71xx *ag, struct ag71xx_buf *buf, buf->rx.rx_buf = data; buf->rx.dma_addr = dma_map_single(&ag->pdev->dev, data, ag->rx_buf_size, DMA_FROM_DEVICE); + if (dma_mapping_error(&ag->pdev->dev, buf->rx.dma_addr)) { + skb_free_frag(data); + buf->rx.rx_buf = NULL; + return false; + } desc->data = (u32)buf->rx.dma_addr + offset; return true; } @@ -1343,6 +1348,10 @@ static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb, dma_addr = dma_map_single(&ag->pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(&ag->pdev->dev, dma_addr)) { + netif_dbg(ag, tx_err, ndev, "DMA mapping error\n"); + goto err_drop; + } i = ring->curr & ring_mask; desc = ag71xx_ring_desc(ring, i); From 74f58f382a7c8333f8d09701aefaa25913bdbe0e Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 24 Apr 2025 16:49:53 -0700 Subject: [PATCH 211/404] rcu: Protect ->defer_qs_iw_pending from data race [ Upstream commit 90c09d57caeca94e6f3f87c49e96a91edd40cbfd ] On kernels built with CONFIG_IRQ_WORK=y, when rcu_read_unlock() is invoked within an interrupts-disabled region of code [1], it will invoke rcu_read_unlock_special(), which uses an irq-work handler to force the system to notice when the RCU read-side critical section actually ends. That end won't happen until interrupts are enabled at the soonest. In some kernels, such as those booted with rcutree.use_softirq=y, the irq-work handler is used unconditionally. The per-CPU rcu_data structure's ->defer_qs_iw_pending field is updated by the irq-work handler and is both read and updated by rcu_read_unlock_special(). This resulted in the following KCSAN splat: ------------------------------------------------------------------------ BUG: KCSAN: data-race in rcu_preempt_deferred_qs_handler / rcu_read_unlock_special read to 0xffff96b95f42d8d8 of 1 bytes by task 90 on cpu 8: rcu_read_unlock_special+0x175/0x260 __rcu_read_unlock+0x92/0xa0 rt_spin_unlock+0x9b/0xc0 __local_bh_enable+0x10d/0x170 __local_bh_enable_ip+0xfb/0x150 rcu_do_batch+0x595/0xc40 rcu_cpu_kthread+0x4e9/0x830 smpboot_thread_fn+0x24d/0x3b0 kthread+0x3bd/0x410 ret_from_fork+0x35/0x40 ret_from_fork_asm+0x1a/0x30 write to 0xffff96b95f42d8d8 of 1 bytes by task 88 on cpu 8: rcu_preempt_deferred_qs_handler+0x1e/0x30 irq_work_single+0xaf/0x160 run_irq_workd+0x91/0xc0 smpboot_thread_fn+0x24d/0x3b0 kthread+0x3bd/0x410 ret_from_fork+0x35/0x40 ret_from_fork_asm+0x1a/0x30 no locks held by irq_work/8/88. irq event stamp: 200272 hardirqs last enabled at (200272): [] finish_task_switch+0x131/0x320 hardirqs last disabled at (200271): [] __schedule+0x129/0xd70 softirqs last enabled at (0): [] copy_process+0x4df/0x1cc0 softirqs last disabled at (0): [<0000000000000000>] 0x0 ------------------------------------------------------------------------ The problem is that irq-work handlers run with interrupts enabled, which means that rcu_preempt_deferred_qs_handler() could be interrupted, and that interrupt handler might contain an RCU read-side critical section, which might invoke rcu_read_unlock_special(). In the strict KCSAN mode of operation used by RCU, this constitutes a data race on the ->defer_qs_iw_pending field. This commit therefore disables interrupts across the portion of the rcu_preempt_deferred_qs_handler() that updates the ->defer_qs_iw_pending field. This suffices because this handler is not a fast path. Signed-off-by: Paul E. McKenney Reviewed-by: Frederic Weisbecker Signed-off-by: Neeraj Upadhyay (AMD) Signed-off-by: Sasha Levin --- kernel/rcu/tree_plugin.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h index 1d9f2831b54e..197fefa82d18 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h @@ -582,10 +582,13 @@ static void rcu_preempt_deferred_qs(struct task_struct *t) */ static void rcu_preempt_deferred_qs_handler(struct irq_work *iwp) { + unsigned long flags; struct rcu_data *rdp; rdp = container_of(iwp, struct rcu_data, defer_qs_iw); + local_irq_save(flags); rdp->defer_qs_iw_pending = false; + local_irq_restore(flags); } /* From 731bb6ba85faaa70f0916c9c693473db567fc3fd Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Wed, 9 Jul 2025 23:37:55 +0300 Subject: [PATCH 212/404] wifi: cfg80211: Fix interface type validation [ Upstream commit 14450be2332a49445106403492a367412b8c23f4 ] Fix a condition that verified valid values of interface types. Signed-off-by: Ilan Peer Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20250709233537.7ad199ca5939.I0ac1ff74798bf59a87a57f2e18f2153c308b119b@changeid Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- include/net/cfg80211.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 2dfa3331604e..3a550544dd9f 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -433,7 +433,7 @@ ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *sband, { int i; - if (WARN_ON(iftype >= NL80211_IFTYPE_MAX)) + if (WARN_ON(iftype >= NUM_NL80211_IFTYPES)) return NULL; if (iftype == NL80211_IFTYPE_AP_VLAN) From 83ea1eb275005aed2788a9df1ab9e6e0c2b10474 Mon Sep 17 00:00:00 2001 From: Oscar Maes Date: Thu, 10 Jul 2025 16:27:13 +0200 Subject: [PATCH 213/404] net: ipv4: fix incorrect MTU in broadcast routes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 9e30ecf23b1b8f091f7d08b27968dea83aae7908 ] Currently, __mkroute_output overrules the MTU value configured for broadcast routes. This buggy behaviour can be reproduced with: ip link set dev eth1 mtu 9000 ip route del broadcast 192.168.0.255 dev eth1 proto kernel scope link src 192.168.0.2 ip route add broadcast 192.168.0.255 dev eth1 proto kernel scope link src 192.168.0.2 mtu 1500 The maximum packet size should be 1500, but it is actually 8000: ping -b 192.168.0.255 -s 8000 Fix __mkroute_output to allow MTU values to be configured for for broadcast routes (to support a mixed-MTU local-area-network). Signed-off-by: Oscar Maes Link: https://patch.msgid.link/20250710142714.12986-1-oscmaes92@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ipv4/route.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d173234503f9..80612f73ff53 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2378,7 +2378,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res, do_cache = true; if (type == RTN_BROADCAST) { flags |= RTCF_BROADCAST | RTCF_LOCAL; - fi = NULL; } else if (type == RTN_MULTICAST) { flags |= RTCF_MULTICAST | RTCF_LOCAL; if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr, From 893caa1ec59a697673e3885d4b34e88bc5b7c2b7 Mon Sep 17 00:00:00 2001 From: Alok Tiwari Date: Fri, 11 Jul 2025 07:05:30 -0700 Subject: [PATCH 214/404] net: thunderx: Fix format-truncation warning in bgx_acpi_match_id() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 53d20606c40678d425cc03f0978c614dca51f25e ] The buffer bgx_sel used in snprintf() was too small to safely hold the formatted string "BGX%d" for all valid bgx_id values. This caused a -Wformat-truncation warning with `Werror` enabled during build. Increase the buffer size from 5 to 7 and use `sizeof(bgx_sel)` in snprintf() to ensure safety and suppress the warning. Build warning: CC drivers/net/ethernet/cavium/thunder/thunder_bgx.o drivers/net/ethernet/cavium/thunder/thunder_bgx.c: In function ‘bgx_acpi_match_id’: drivers/net/ethernet/cavium/thunder/thunder_bgx.c:1434:27: error: ‘%d’ directive output may be truncated writing between 1 and 3 bytes into a region of size 2 [-Werror=format-truncation=] snprintf(bgx_sel, 5, "BGX%d", bgx->bgx_id); ^~ drivers/net/ethernet/cavium/thunder/thunder_bgx.c:1434:23: note: directive argument in the range [0, 255] snprintf(bgx_sel, 5, "BGX%d", bgx->bgx_id); ^~~~~~~ drivers/net/ethernet/cavium/thunder/thunder_bgx.c:1434:2: note: ‘snprintf’ output between 5 and 7 bytes into a destination of size 5 snprintf(bgx_sel, 5, "BGX%d", bgx->bgx_id); compiler warning due to insufficient snprintf buffer size. Signed-off-by: Alok Tiwari Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250711140532.2463602-1-alok.a.tiwari@oracle.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c index a34c33e8a8ad..8854025610e6 100644 --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c @@ -1430,9 +1430,9 @@ static acpi_status bgx_acpi_match_id(acpi_handle handle, u32 lvl, { struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; struct bgx *bgx = context; - char bgx_sel[5]; + char bgx_sel[7]; - snprintf(bgx_sel, 5, "BGX%d", bgx->bgx_id); + snprintf(bgx_sel, sizeof(bgx_sel), "BGX%d", bgx->bgx_id); if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &string))) { pr_warn("Invalid link device\n"); return AE_OK; From aaa6dc2d0feb36b9076b3bc643b808604063af35 Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Wed, 9 Jul 2025 23:05:43 +0300 Subject: [PATCH 215/404] wifi: iwlwifi: mvm: fix scan request validation [ Upstream commit 7c2f3ec7707188d8d5269ae2dce97d7be3e9f261 ] The scan request validation function uses bitwise and instead of logical and. Fix it. Signed-off-by: Avraham Stern Reviewed-by: Ilan Peer Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20250709230308.3fbc1f27871b.I7a8ee91f463c1a2d9d8561c8232e196885d02c43@changeid Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 55292e9b15c1..b860aad4c155 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -874,7 +874,7 @@ static inline bool iwl_mvm_scan_fits(struct iwl_mvm *mvm, int n_ssids, int n_channels) { return ((n_ssids <= PROBE_OPTION_MAX) && - (n_channels <= mvm->fw->ucode_capa.n_scan_channels) & + (n_channels <= mvm->fw->ucode_capa.n_scan_channels) && (ies->common_ie_len + ies->len[NL80211_BAND_2GHZ] + ies->len[NL80211_BAND_5GHZ] <= From 0c02d35d6732c640bf286264b15fe91308e628be Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Thu, 3 Jul 2025 13:50:27 +0200 Subject: [PATCH 216/404] s390/stp: Remove udelay from stp_sync_clock() [ Upstream commit b367017cdac21781a74eff4e208d3d38e1f38d3f ] When an stp sync check is handled on a system with multiple cpus each cpu gets a machine check but only the first one actually handles the sync operation. All other CPUs spin waiting for the first one to finish with a short udelay(). But udelay can't be used here as the first CPU modifies tod_clock_base before performing the sync op. During this timeframe get_tod_clock_monotonic() might return a non-monotonic time. The time spent waiting should be very short and udelay is a busy loop anyways, therefore simply remove the udelay. Reviewed-by: Heiko Carstens Signed-off-by: Sven Schnelle Signed-off-by: Alexander Gordeev Signed-off-by: Sasha Levin --- arch/s390/kernel/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 11c32b228f51..0e1925104fcf 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -642,7 +642,7 @@ static int stp_sync_clock(void *data) atomic_dec(&sync->cpus); /* Wait for in_sync to be set. */ while (READ_ONCE(sync->in_sync) == 0) - __udelay(1); + ; } if (sync->in_sync != 1) /* Didn't work. Clear per-cpu in sync bit again. */ From dca836a04bc30b582973033781cb7b62defdd7c7 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Tue, 10 Jun 2025 16:29:11 +0200 Subject: [PATCH 217/404] (powerpc/512) Fix possible `dma_unmap_single()` on uninitialized pointer [ Upstream commit 760b9b4f6de9a33ca56a05f950cabe82138d25bd ] If the device configuration fails (if `dma_dev->device_config()`), `sg_dma_address(&sg)` is not initialized and the jump to `err_dma_prep` leads to calling `dma_unmap_single()` on `sg_dma_address(&sg)`. Signed-off-by: Thomas Fourier Reviewed-by: Christophe Leroy Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/20250610142918.169540-2-fourier.thomas@gmail.com Signed-off-by: Sasha Levin --- arch/powerpc/platforms/512x/mpc512x_lpbfifo.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c b/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c index 13631f35cd14..12fb94968f3c 100644 --- a/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c +++ b/arch/powerpc/platforms/512x/mpc512x_lpbfifo.c @@ -240,10 +240,8 @@ static int mpc512x_lpbfifo_kick(void) dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; /* Make DMA channel work with LPB FIFO data register */ - if (dma_dev->device_config(lpbfifo.chan, &dma_conf)) { - ret = -EINVAL; - goto err_dma_prep; - } + if (dma_dev->device_config(lpbfifo.chan, &dma_conf)) + return -EINVAL; sg_init_table(&sg, 1); From ecb68d57f35de0dc48eb6b8156affb9d73744e8c Mon Sep 17 00:00:00 2001 From: Jonas Rebmann Date: Thu, 26 Jun 2025 15:44:02 +0200 Subject: [PATCH 218/404] net: fec: allow disable coalescing [ Upstream commit b7ad21258f9e9a7f58b19595d5ceed2cde3bed68 ] In the current implementation, IP coalescing is always enabled and cannot be disabled. As setting maximum frames to 0 or 1, or setting delay to zero implies immediate delivery of single packets/IRQs, disable coalescing in hardware in these cases. This also guarantees that coalescing is never enabled with ICFT or ICTT set to zero, a configuration that could lead to unpredictable behaviour according to i.MX8MP reference manual. Signed-off-by: Jonas Rebmann Reviewed-by: Wei Fang Link: https://patch.msgid.link/20250626-fec_deactivate_coalescing-v2-1-0b217f2e80da@pengutronix.de Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/freescale/fec_main.c | 34 +++++++++++------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index fd7c504b44f2..f8a096633280 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -2590,27 +2590,25 @@ static int fec_enet_us_to_itr_clock(struct net_device *ndev, int us) static void fec_enet_itr_coal_set(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - int rx_itr, tx_itr; + u32 rx_itr = 0, tx_itr = 0; + int rx_ictt, tx_ictt; - /* Must be greater than zero to avoid unpredictable behavior */ - if (!fep->rx_time_itr || !fep->rx_pkts_itr || - !fep->tx_time_itr || !fep->tx_pkts_itr) - return; + rx_ictt = fec_enet_us_to_itr_clock(ndev, fep->rx_time_itr); + tx_ictt = fec_enet_us_to_itr_clock(ndev, fep->tx_time_itr); - /* Select enet system clock as Interrupt Coalescing - * timer Clock Source - */ - rx_itr = FEC_ITR_CLK_SEL; - tx_itr = FEC_ITR_CLK_SEL; + if (rx_ictt > 0 && fep->rx_pkts_itr > 1) { + /* Enable with enet system clock as Interrupt Coalescing timer Clock Source */ + rx_itr = FEC_ITR_EN | FEC_ITR_CLK_SEL; + rx_itr |= FEC_ITR_ICFT(fep->rx_pkts_itr); + rx_itr |= FEC_ITR_ICTT(rx_ictt); + } - /* set ICFT and ICTT */ - rx_itr |= FEC_ITR_ICFT(fep->rx_pkts_itr); - rx_itr |= FEC_ITR_ICTT(fec_enet_us_to_itr_clock(ndev, fep->rx_time_itr)); - tx_itr |= FEC_ITR_ICFT(fep->tx_pkts_itr); - tx_itr |= FEC_ITR_ICTT(fec_enet_us_to_itr_clock(ndev, fep->tx_time_itr)); - - rx_itr |= FEC_ITR_EN; - tx_itr |= FEC_ITR_EN; + if (tx_ictt > 0 && fep->tx_pkts_itr > 1) { + /* Enable with enet system clock as Interrupt Coalescing timer Clock Source */ + tx_itr = FEC_ITR_EN | FEC_ITR_CLK_SEL; + tx_itr |= FEC_ITR_ICFT(fep->tx_pkts_itr); + tx_itr |= FEC_ITR_ICTT(tx_ictt); + } writel(tx_itr, fep->hwp + FEC_TXIC0); writel(rx_itr, fep->hwp + FEC_RXIC0); From 137d67e903867062ee27877a8da8d0229ba9a363 Mon Sep 17 00:00:00 2001 From: Rand Deeb Date: Wed, 13 Mar 2024 13:17:55 +0300 Subject: [PATCH 219/404] wifi: iwlwifi: dvm: fix potential overflow in rs_fill_link_cmd() [ Upstream commit e3ad987e9dc7d1e12e3f2f1e623f0e174cd0ca78 ] The 'index' variable in the rs_fill_link_cmd() function can reach LINK_QUAL_MAX_RETRY_NUM during the execution of the inner loop. This variable is used as an index for the lq_cmd->rs_table array, which has a size of LINK_QUAL_MAX_RETRY_NUM, without proper validation. Modify the condition of the inner loop to ensure that the 'index' variable does not exceed LINK_QUAL_MAX_RETRY_NUM - 1, thereby preventing any potential overflow issues. Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Rand Deeb Link: https://patch.msgid.link/20240313101755.269209-1-rand.sec96@gmail.com Signed-off-by: Miri Korenblit Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/dvm/rs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c index e68a13c33c45..19defdb43126 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c @@ -2935,7 +2935,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, /* Repeat initial/next rate. * For legacy IWL_NUMBER_TRY == 1, this loop will not execute. * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */ - while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) { + while (repeat_rate > 0 && index < (LINK_QUAL_MAX_RETRY_NUM - 1)) { if (is_legacy(tbl_type.lq_type)) { if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) ant_toggle_cnt++; From ecd425c5091b018c2b5d786fb70123e2b0c6731f Mon Sep 17 00:00:00 2001 From: Pagadala Yesu Anjaneyulu Date: Wed, 11 Jun 2025 22:26:23 +0300 Subject: [PATCH 220/404] wifi: iwlwifi: fw: Fix possible memory leak in iwl_fw_dbg_collect [ Upstream commit cc8d9cbf269dab363c768bfa9312265bc807fca5 ] Ensure descriptor is freed on error to avoid memory leak. Signed-off-by: Pagadala Yesu Anjaneyulu Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20250611222325.8158d15ec866.Ifa3e422c302397111f20a16da7509e6574bc19e3@changeid Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 286b5ca3b167..14f96bd41377 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -2130,6 +2130,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt, struct iwl_fw_dump_desc *desc; unsigned int delay = 0; bool monitor_only = false; + int ret; if (trigger) { u16 occurrences = le16_to_cpu(trigger->occurrences) - 1; @@ -2160,7 +2161,11 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt, desc->trig_desc.type = cpu_to_le32(trig); memcpy(desc->trig_desc.data, str, len); - return iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay); + ret = iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay); + if (ret) + kfree(desc); + + return ret; } IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect); From 1764376ae0046ae37b3e18baef0def2d21209378 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Mon, 16 Jun 2025 12:56:30 +0200 Subject: [PATCH 221/404] wifi: rtlwifi: fix possible skb memory leak in `_rtl_pci_rx_interrupt()`. [ Upstream commit 44c0e191004f0e3aa1bdee3be248be14dbe5b020 ] The function `_rtl_pci_init_one_rxdesc()` can fail even when the new `skb` is passed because of a DMA mapping error. If it fails, the `skb` is not saved in the rx ringbuffer and thus lost. Compile tested only Signed-off-by: Thomas Fourier Acked-by: Ping-Ke Shih Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20250616105631.444309-4-fourier.thomas@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtlwifi/pci.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c index 9339c6d2b258..daf6d0eeb3e3 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.c +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -804,13 +804,19 @@ new_trx_end: skb = new_skb; no_new: if (rtlpriv->use_new_trx_flow) { - _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc, - rxring_idx, - rtlpci->rx_ring[rxring_idx].idx); + if (!_rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc, + rxring_idx, + rtlpci->rx_ring[rxring_idx].idx)) { + if (new_skb) + dev_kfree_skb_any(skb); + } } else { - _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc, - rxring_idx, - rtlpci->rx_ring[rxring_idx].idx); + if (!_rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc, + rxring_idx, + rtlpci->rx_ring[rxring_idx].idx)) { + if (new_skb) + dev_kfree_skb_any(skb); + } if (rtlpci->rx_ring[rxring_idx].idx == rtlpci->rxringcount - 1) rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, From 95e9175cd9dfe4c6526c4b5a3f06280350554452 Mon Sep 17 00:00:00 2001 From: Mina Almasry Date: Thu, 19 Jun 2025 17:52:38 +0000 Subject: [PATCH 222/404] netmem: fix skb_frag_address_safe with unreadable skbs [ Upstream commit 4672aec56d2e8edabcb74c3e2320301d106a377e ] skb_frag_address_safe() needs a check that the skb_frag_page exists check similar to skb_frag_address(). Cc: ap420073@gmail.com Signed-off-by: Mina Almasry Acked-by: Stanislav Fomichev Link: https://patch.msgid.link/20250619175239.3039329-1-almasrymina@google.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- include/linux/skbuff.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index d9abd9e6833e..101ac3d6581e 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -3073,7 +3073,13 @@ static inline void *skb_frag_address(const skb_frag_t *frag) */ static inline void *skb_frag_address_safe(const skb_frag_t *frag) { - void *ptr = page_address(skb_frag_page(frag)); + struct page *page = skb_frag_page(frag); + void *ptr; + + if (!page) + return NULL; + + ptr = page_address(page); if (unlikely(!ptr)) return NULL; From 1870f42bd95da79299e94a90c9c2421e5bbeea9e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sun, 25 May 2025 16:45:24 +0200 Subject: [PATCH 223/404] wifi: iwlegacy: Check rate_idx range after addition [ Upstream commit 0de19d5ae0b2c5b18b88c5c7f0442f707a207409 ] Limit rate_idx to IL_LAST_OFDM_RATE for 5GHz band for thinkable case the index is incorrect. Reported-by: Fedor Pchelkin Reported-by: Alexei Safin Signed-off-by: Stanislaw Gruszka Reviewed-by: Fedor Pchelkin Link: https://patch.msgid.link/20250525144524.GA172583@wp.pl Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlegacy/4965-mac.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c index 20c933602f0a..31f1c57450d4 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c @@ -1573,8 +1573,11 @@ il4965_tx_cmd_build_rate(struct il_priv *il, || rate_idx > RATE_COUNT_LEGACY) rate_idx = rate_lowest_index(&il->bands[info->band], sta); /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ - if (info->band == NL80211_BAND_5GHZ) + if (info->band == NL80211_BAND_5GHZ) { rate_idx += IL_FIRST_OFDM_RATE; + if (rate_idx > IL_LAST_OFDM_RATE) + rate_idx = IL_LAST_OFDM_RATE; + } /* Get PLCP rate for tx_cmd->rate_n_flags */ rate_plcp = il_rates[rate_idx].plcp; /* Zero out flags for this packet */ From 0648dbd794ce78e580222acafe77ed893cd29b0c Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Mon, 16 Jun 2025 16:26:25 +0300 Subject: [PATCH 224/404] net: vlan: Replace BUG() with WARN_ON_ONCE() in vlan_dev_* stubs [ Upstream commit 60a8b1a5d0824afda869f18dc0ecfe72f8dfda42 ] When CONFIG_VLAN_8021Q=n, a set of stub helpers are used, three of these helpers use BUG() unconditionally. This code should not be reached, as callers of these functions should always check for is_vlan_dev() first, but the usage of BUG() is not recommended, replace it with WARN_ON() instead. Reviewed-by: Alex Lazar Reviewed-by: Dragos Tatulea Signed-off-by: Gal Pressman Link: https://patch.msgid.link/20250616132626.1749331-3-gal@nvidia.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- include/linux/if_vlan.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index b3dae069bcd9..52ce74226ba2 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -240,19 +240,19 @@ vlan_for_each(struct net_device *dev, static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev) { - BUG(); + WARN_ON_ONCE(1); return NULL; } static inline u16 vlan_dev_vlan_id(const struct net_device *dev) { - BUG(); + WARN_ON_ONCE(1); return 0; } static inline __be16 vlan_dev_vlan_proto(const struct net_device *dev) { - BUG(); + WARN_ON_ONCE(1); return 0; } From 3650c263cadc62616245ca99a420ba7aeddf9687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Sat, 14 Jun 2025 09:59:59 +0200 Subject: [PATCH 225/404] net: dsa: b53: fix b53_imp_vlan_setup for BCM5325 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit c00df1018791185ea398f78af415a2a0aaa0c79c ] CPU port should be B53_CPU_PORT instead of B53_CPU_PORT_25 for B53_PVLAN_PORT_MASK register. Reviewed-by: Florian Fainelli Signed-off-by: Álvaro Fernández Rojas Link: https://patch.msgid.link/20250614080000.1884236-14-noltari@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/dsa/b53/b53_common.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index d41c9006a028..1816a5b56d51 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -502,6 +502,10 @@ void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) unsigned int i; u16 pvlan; + /* BCM5325 CPU port is at 8 */ + if ((is5325(dev) || is5365(dev)) && cpu_port == B53_CPU_PORT_25) + cpu_port = B53_CPU_PORT; + /* Enable the IMP port to be in the same VLAN as the other ports * on a per-port basis such that we only have Port i and IMP in * the same VLAN. From 91f81e2866bd5824dd2b9bdd4a110ff6ea041523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Sat, 14 Jun 2025 09:59:53 +0200 Subject: [PATCH 226/404] net: dsa: b53: prevent SWITCH_CTRL access on BCM5325 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 22ccaaca43440e90a3b68d2183045b42247dc4be ] BCM5325 doesn't implement SWITCH_CTRL register so we should avoid reading or writing it. Reviewed-by: Florian Fainelli Signed-off-by: Álvaro Fernández Rojas Link: https://patch.msgid.link/20250614080000.1884236-8-noltari@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/dsa/b53/b53_common.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 1816a5b56d51..43726157dfe2 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -337,11 +337,12 @@ static void b53_set_forwarding(struct b53_device *dev, int enable) b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); - /* Include IMP port in dumb forwarding mode - */ - b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, &mgmt); - mgmt |= B53_MII_DUMB_FWDG_EN; - b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt); + if (!is5325(dev)) { + /* Include IMP port in dumb forwarding mode */ + b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, &mgmt); + mgmt |= B53_MII_DUMB_FWDG_EN; + b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt); + } /* Look at B53_UC_FWD_EN and B53_MC_FWD_EN to decide whether * frames should be flooded or not. From eae64c4900d729db32c511228146e61bafa9a583 Mon Sep 17 00:00:00 2001 From: Hari Kalavakunta Date: Tue, 10 Jun 2025 12:33:38 -0700 Subject: [PATCH 227/404] net: ncsi: Fix buffer overflow in fetching version id [ Upstream commit 8e16170ae972c7fed132bc928914a2ffb94690fc ] In NC-SI spec v1.2 section 8.4.44.2, the firmware name doesn't need to be null terminated while its size occupies the full size of the field. Fix the buffer overflow issue by adding one additional byte for null terminator. Signed-off-by: Hari Kalavakunta Reviewed-by: Paul Fertser Link: https://patch.msgid.link/20250610193338.1368-1-kalavakunta.hari.prasad@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ncsi/internal.h | 2 +- net/ncsi/ncsi-rsp.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h index b723452768d4..67d5ee4dbc2a 100644 --- a/net/ncsi/internal.h +++ b/net/ncsi/internal.h @@ -86,7 +86,7 @@ struct ncsi_channel_version { u8 update; /* NCSI version update */ char alpha1; /* NCSI version alpha1 */ char alpha2; /* NCSI version alpha2 */ - u8 fw_name[12]; /* Firmware name string */ + u8 fw_name[12 + 1]; /* Firmware name string */ u32 fw_version; /* Firmware version */ u16 pci_ids[4]; /* PCI identification */ u32 mf_id; /* Manufacture ID */ diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c index b7d311f97905..41e4ed80f29a 100644 --- a/net/ncsi/ncsi-rsp.c +++ b/net/ncsi/ncsi-rsp.c @@ -782,6 +782,7 @@ static int ncsi_rsp_handler_gvi(struct ncsi_request *nr) ncv->alpha1 = rsp->alpha1; ncv->alpha2 = rsp->alpha2; memcpy(ncv->fw_name, rsp->fw_name, 12); + ncv->fw_name[12] = '\0'; ncv->fw_version = ntohl(rsp->fw_version); for (i = 0; i < ARRAY_SIZE(ncv->pci_ids); i++) ncv->pci_ids[i] = ntohs(rsp->pci_ids[i]); From ce72da68e89f26093d39f6ffe6b5c2f64613ae51 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Mon, 9 Jun 2025 07:39:33 -0700 Subject: [PATCH 228/404] uapi: in6: restore visibility of most IPv6 socket options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 31557b3487b349464daf42bc4366153743c1e727 ] A decade ago commit 6d08acd2d32e ("in6: fix conflict with glibc") hid the definitions of IPV6 options, because GCC was complaining about duplicates. The commit did not list the warnings seen, but trying to recreate them now I think they are (building iproute2): In file included from ./include/uapi/rdma/rdma_user_cm.h:39, from rdma.h:16, from res.h:9, from res-ctx.c:7: ../include/uapi/linux/in6.h:171:9: warning: ‘IPV6_ADD_MEMBERSHIP’ redefined 171 | #define IPV6_ADD_MEMBERSHIP 20 | ^~~~~~~~~~~~~~~~~~~ In file included from /usr/include/netinet/in.h:37, from rdma.h:13: /usr/include/bits/in.h:233:10: note: this is the location of the previous definition 233 | # define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP | ^~~~~~~~~~~~~~~~~~~ ../include/uapi/linux/in6.h:172:9: warning: ‘IPV6_DROP_MEMBERSHIP’ redefined 172 | #define IPV6_DROP_MEMBERSHIP 21 | ^~~~~~~~~~~~~~~~~~~~ /usr/include/bits/in.h:234:10: note: this is the location of the previous definition 234 | # define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP | ^~~~~~~~~~~~~~~~~~~~ Compilers don't complain about redefinition if the defines are identical, but here we have the kernel using the literal value, and glibc using an indirection (defining to a name of another define, with the same numerical value). Problem is, the commit in question hid all the IPV6 socket options, and glibc has a pretty sparse list. For instance it lacks Flow Label related options. Willem called this out in commit 3fb321fde22d ("selftests/net: ipv6 flowlabel"): /* uapi/glibc weirdness may leave this undefined */ #ifndef IPV6_FLOWINFO #define IPV6_FLOWINFO 11 #endif More interestingly some applications (socat) use a #ifdef IPV6_FLOWINFO to gate compilation of thier rudimentary flow label support. (For added confusion socat misspells it as IPV4_FLOWINFO in some places.) Hide only the two defines we know glibc has a problem with. If we discover more warnings we can hide more but we should avoid covering the entire block of defines for "IPV6 socket options". Link: https://patch.msgid.link/20250609143933.1654417-1-kuba@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- include/uapi/linux/in6.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h index 9f2273a08356..acd32dc630c3 100644 --- a/include/uapi/linux/in6.h +++ b/include/uapi/linux/in6.h @@ -151,7 +151,6 @@ struct in6_flowlabel_req { /* * IPV6 socket options */ -#if __UAPI_DEF_IPV6_OPTIONS #define IPV6_ADDRFORM 1 #define IPV6_2292PKTINFO 2 #define IPV6_2292HOPOPTS 3 @@ -168,8 +167,10 @@ struct in6_flowlabel_req { #define IPV6_MULTICAST_IF 17 #define IPV6_MULTICAST_HOPS 18 #define IPV6_MULTICAST_LOOP 19 +#if __UAPI_DEF_IPV6_OPTIONS #define IPV6_ADD_MEMBERSHIP 20 #define IPV6_DROP_MEMBERSHIP 21 +#endif #define IPV6_ROUTER_ALERT 22 #define IPV6_MTU_DISCOVER 23 #define IPV6_MTU 24 @@ -201,7 +202,6 @@ struct in6_flowlabel_req { #define IPV6_IPSEC_POLICY 34 #define IPV6_XFRM_POLICY 35 #define IPV6_HDRINCL 36 -#endif /* * Multicast: From bcef637358255709b687c78e3cb43cd4e343d384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Sat, 14 Jun 2025 09:59:54 +0200 Subject: [PATCH 229/404] net: dsa: b53: fix IP_MULTICAST_CTRL on BCM5325 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 044d5ce2788b165798bfd173548e61bf7b6baf4d ] BCM5325 doesn't implement B53_UC_FWD_EN, B53_MC_FWD_EN or B53_IPMC_FWD_EN. Reviewed-by: Florian Fainelli Signed-off-by: Álvaro Fernández Rojas Link: https://patch.msgid.link/20250614080000.1884236-9-noltari@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/dsa/b53/b53_common.c | 18 +++++++++++------- drivers/net/dsa/b53/b53_regs.h | 1 + 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 43726157dfe2..fea28b24a1a0 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -342,14 +342,18 @@ static void b53_set_forwarding(struct b53_device *dev, int enable) b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, &mgmt); mgmt |= B53_MII_DUMB_FWDG_EN; b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt); - } - /* Look at B53_UC_FWD_EN and B53_MC_FWD_EN to decide whether - * frames should be flooded or not. - */ - b53_read8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, &mgmt); - mgmt |= B53_UC_FWD_EN | B53_MC_FWD_EN | B53_IPMC_FWD_EN; - b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt); + /* Look at B53_UC_FWD_EN and B53_MC_FWD_EN to decide whether + * frames should be flooded or not. + */ + b53_read8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, &mgmt); + mgmt |= B53_UC_FWD_EN | B53_MC_FWD_EN | B53_IPMC_FWD_EN; + b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt); + } else { + b53_read8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, &mgmt); + mgmt |= B53_IP_MCAST_25; + b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt); + } } static void b53_enable_vlan(struct b53_device *dev, bool enable, diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h index b2c539a42154..ea6897c3f6f7 100644 --- a/drivers/net/dsa/b53/b53_regs.h +++ b/drivers/net/dsa/b53/b53_regs.h @@ -103,6 +103,7 @@ /* IP Multicast control (8 bit) */ #define B53_IP_MULTICAST_CTRL 0x21 +#define B53_IP_MCAST_25 BIT(0) #define B53_IPMC_FWD_EN BIT(1) #define B53_UC_FWD_EN BIT(6) #define B53_MC_FWD_EN BIT(7) From 86ae9f0efcc31e1b5609f9655df3d6e602d8b6fc Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 14 Jul 2025 16:47:53 +0800 Subject: [PATCH 230/404] vhost: fail early when __vhost_add_used() fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit b4ba1207d45adaafa2982c035898b36af2d3e518 ] This patch fails vhost_add_used_n() early when __vhost_add_used() fails to make sure used idx is not updated with stale used ring information. Reported-by: Eugenio Pérez Signed-off-by: Jason Wang Message-Id: <20250714084755.11921-2-jasowang@redhat.com> Signed-off-by: Michael S. Tsirkin Tested-by: Lei Yang Signed-off-by: Sasha Levin --- drivers/vhost/vhost.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 484818796978..8402255760b3 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -2422,6 +2422,9 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads, } r = __vhost_add_used_n(vq, heads, count); + if (r < 0) + return r; + /* Make sure buffer is written before we update index. */ smp_wmb(); if (vhost_put_used_idx(vq)) { From 9f69a595a2a13dd76e685507e8160ee46ba56d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 30 Dec 2024 20:54:11 +0100 Subject: [PATCH 231/404] cifs: Fix calling CIFSFindFirst() for root path without msearch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit b460249b9a1dab7a9f58483e5349d045ad6d585c ] To query root path (without msearch wildcard) it is needed to send pattern '\' instead of '' (empty string). This allows to use CIFSFindFirst() to query information about root path which is being used in followup changes. This change fixes the stat() syscall called on the root path on the mount. It is because stat() syscall uses the cifs_query_path_info() function and it can fallback to the CIFSFindFirst() usage with msearch=false. Signed-off-by: Pali Rohár Signed-off-by: Steve French Signed-off-by: Sasha Levin --- fs/cifs/cifssmb.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index f924f05b1829..ea444c8d0c40 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -4544,6 +4544,12 @@ findFirstRetry: pSMB->FileName[name_len] = 0; pSMB->FileName[name_len+1] = 0; name_len += 2; + } else if (!searchName[0]) { + pSMB->FileName[0] = CIFS_DIR_SEP(cifs_sb); + pSMB->FileName[1] = 0; + pSMB->FileName[2] = 0; + pSMB->FileName[3] = 0; + name_len = 4; } } else { name_len = copy_path_name(pSMB->FileName, searchName); @@ -4555,6 +4561,10 @@ findFirstRetry: pSMB->FileName[name_len] = '*'; pSMB->FileName[name_len+1] = 0; name_len += 2; + } else if (!searchName[0]) { + pSMB->FileName[0] = CIFS_DIR_SEP(cifs_sb); + pSMB->FileName[1] = 0; + name_len = 2; } } From 8085a7324d8ec448c4a764af7853e19bbd64e17a Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 17 Jul 2025 10:54:34 -0400 Subject: [PATCH 232/404] ext4: do not BUG when INLINE_DATA_FL lacks system.data xattr [ Upstream commit 099b847ccc6c1ad2f805d13cfbcc83f5b6d4bc42 ] A syzbot fuzzed image triggered a BUG_ON in ext4_update_inline_data() when an inode had the INLINE_DATA_FL flag set but was missing the system.data extended attribute. Since this can happen due to a maiciouly fuzzed file system, we shouldn't BUG, but rather, report it as a corrupted file system. Add similar replacements of BUG_ON with EXT4_ERROR_INODE() ii ext4_create_inline_data() and ext4_inline_data_truncate(). Reported-by: syzbot+544248a761451c0df72f@syzkaller.appspotmail.com Signed-off-by: Theodore Ts'o Signed-off-by: Sasha Levin --- fs/ext4/inline.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 7e8892dad2d7..626be0ec3c7a 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -296,7 +296,11 @@ static int ext4_create_inline_data(handle_t *handle, if (error) goto out; - BUG_ON(!is.s.not_found); + if (!is.s.not_found) { + EXT4_ERROR_INODE(inode, "unexpected inline data xattr"); + error = -EFSCORRUPTED; + goto out; + } error = ext4_xattr_ibody_set(handle, inode, &i, &is); if (error) { @@ -347,7 +351,11 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode, if (error) goto out; - BUG_ON(is.s.not_found); + if (is.s.not_found) { + EXT4_ERROR_INODE(inode, "missing inline data xattr"); + error = -EFSCORRUPTED; + goto out; + } len -= EXT4_MIN_INLINE_DATA_SIZE; value = kzalloc(len, GFP_NOFS); @@ -1978,7 +1986,12 @@ int ext4_inline_data_truncate(struct inode *inode, int *has_inline) if ((err = ext4_xattr_ibody_find(inode, &i, &is)) != 0) goto out_error; - BUG_ON(is.s.not_found); + if (is.s.not_found) { + EXT4_ERROR_INODE(inode, + "missing inline data xattr"); + err = -EFSCORRUPTED; + goto out_error; + } value_len = le32_to_cpu(is.s.here->e_value_size); value = kmalloc(value_len, GFP_NOFS); From f53af99f441ee79599d8df6113a7144d74cf9153 Mon Sep 17 00:00:00 2001 From: Showrya M N Date: Fri, 27 Jun 2025 16:53:29 +0530 Subject: [PATCH 233/404] scsi: libiscsi: Initialize iscsi_conn->dd_data only if memory is allocated [ Upstream commit 3ea3a256ed81f95ab0f3281a0e234b01a9cae605 ] In case of an ib_fast_reg_mr allocation failure during iSER setup, the machine hits a panic because iscsi_conn->dd_data is initialized unconditionally, even when no memory is allocated (dd_size == 0). This leads invalid pointer dereference during connection teardown. Fix by setting iscsi_conn->dd_data only if memory is actually allocated. Panic trace: ------------ iser: iser_create_fastreg_desc: Failed to allocate ib_fast_reg_mr err=-12 iser: iser_alloc_rx_descriptors: failed allocating rx descriptors / data buffers BUG: unable to handle page fault for address: fffffffffffffff8 RIP: 0010:swake_up_locked.part.5+0xa/0x40 Call Trace: complete+0x31/0x40 iscsi_iser_conn_stop+0x88/0xb0 [ib_iser] iscsi_stop_conn+0x66/0xc0 [scsi_transport_iscsi] iscsi_if_stop_conn+0x14a/0x150 [scsi_transport_iscsi] iscsi_if_rx+0x1135/0x1834 [scsi_transport_iscsi] ? netlink_lookup+0x12f/0x1b0 ? netlink_deliver_tap+0x2c/0x200 netlink_unicast+0x1ab/0x280 netlink_sendmsg+0x257/0x4f0 ? _copy_from_user+0x29/0x60 sock_sendmsg+0x5f/0x70 Signed-off-by: Showrya M N Signed-off-by: Potnuri Bharat Teja Link: https://lore.kernel.org/r/20250627112329.19763-1-showrya@chelsio.com Reviewed-by: Chris Leech Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/libiscsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index f3cee64c6d12..9b94218ff04c 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2893,7 +2893,8 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, conn = cls_conn->dd_data; memset(conn, 0, sizeof(*conn) + dd_size); - conn->dd_data = cls_conn->dd_data + sizeof(*conn); + if (dd_size) + conn->dd_data = cls_conn->dd_data + sizeof(*conn); conn->session = session; conn->cls_conn = cls_conn; conn->c_stage = ISCSI_CONN_INITIAL_STAGE; From 6ade15765ef3f94fba05d40fd213e24b5afd4acb Mon Sep 17 00:00:00 2001 From: Amir Mohammad Jahangirzad Date: Sun, 8 Jun 2025 20:05:59 +0330 Subject: [PATCH 234/404] fs/orangefs: use snprintf() instead of sprintf() [ Upstream commit cdfa1304657d6f23be8fd2bb0516380a3c89034e ] sprintf() is discouraged for use with bounded destination buffers as it does not prevent buffer overflows when the formatted output exceeds the destination buffer size. snprintf() is a safer alternative as it limits the number of bytes written and ensures NUL-termination. Replace sprintf() with snprintf() for copying the debug string into a temporary buffer, using ORANGEFS_MAX_DEBUG_STRING_LEN as the maximum size to ensure safe formatting and prevent memory corruption in edge cases. EDIT: After this patch sat on linux-next for a few days, Dan Carpenter saw it and suggested that I use scnprintf instead of snprintf. I made the change and retested. Signed-off-by: Amir Mohammad Jahangirzad Signed-off-by: Mike Marshall Signed-off-by: Sasha Levin --- fs/orangefs/orangefs-debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c index b57140ebfad0..cd4bfd92ebd6 100644 --- a/fs/orangefs/orangefs-debugfs.c +++ b/fs/orangefs/orangefs-debugfs.c @@ -354,7 +354,7 @@ static ssize_t orangefs_debug_read(struct file *file, goto out; mutex_lock(&orangefs_debug_lock); - sprintf_ret = sprintf(buf, "%s", (char *)file->private_data); + sprintf_ret = scnprintf(buf, ORANGEFS_MAX_DEBUG_STRING_LEN, "%s", (char *)file->private_data); mutex_unlock(&orangefs_debug_lock); read_ret = simple_read_from_buffer(ubuf, count, ppos, buf, sprintf_ret); From 790f6baa432e67bfb7576bf0f989234d6d14ad1e Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Thu, 17 Jul 2025 18:55:02 +0200 Subject: [PATCH 235/404] watchdog: dw_wdt: Fix default timeout [ Upstream commit ac3dbb91e0167d017f44701dd51c1efe30d0c256 ] The Synopsys Watchdog driver sets the default timeout to 30 seconds, but on some devices this is not a valid timeout. E.g. on RK3588 the actual timeout being used is 44 seconds instead. Once the watchdog is started the value is updated accordingly, but it would be better to expose a sensible timeout to userspace without the need to first start the watchdog. Signed-off-by: Sebastian Reichel Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20250717-dw-wdt-fix-initial-timeout-v1-1-86dc864d48dd@kernel.org Signed-off-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Signed-off-by: Sasha Levin --- drivers/watchdog/dw_wdt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index fef7c61f5555..72dc5f4f6eb8 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -289,6 +289,8 @@ static int dw_wdt_drv_probe(struct platform_device *pdev) } else { wdd->timeout = DW_WDT_DEFAULT_SECONDS; watchdog_init_timeout(wdd, 0, dev); + /* Limit timeout value to hardware constraints. */ + dw_wdt_set_timeout(wdd, wdd->timeout); } platform_set_drvdata(pdev, dw_wdt); From 52f0795880e325fd13d937c545a875fbe5b5d3c8 Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Thu, 3 Jul 2025 21:06:32 +0800 Subject: [PATCH 236/404] MIPS: vpe-mt: add missing prototypes for vpe_{alloc,start,stop,free} [ Upstream commit 844615dd0f2d95c018ec66b943e08af22b62aff3 ] These functions are exported but their prototypes are not defined. This patch adds the missing function prototypes to fix the following compilation warnings: arch/mips/kernel/vpe-mt.c:180:7: error: no previous prototype for 'vpe_alloc' [-Werror=missing-prototypes] 180 | void *vpe_alloc(void) | ^~~~~~~~~ arch/mips/kernel/vpe-mt.c:198:5: error: no previous prototype for 'vpe_start' [-Werror=missing-prototypes] 198 | int vpe_start(void *vpe, unsigned long start) | ^~~~~~~~~ arch/mips/kernel/vpe-mt.c:208:5: error: no previous prototype for 'vpe_stop' [-Werror=missing-prototypes] 208 | int vpe_stop(void *vpe) | ^~~~~~~~ arch/mips/kernel/vpe-mt.c:229:5: error: no previous prototype for 'vpe_free' [-Werror=missing-prototypes] 229 | int vpe_free(void *vpe) | ^~~~~~~~ Signed-off-by: Shiji Yang Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/include/asm/vpe.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/mips/include/asm/vpe.h b/arch/mips/include/asm/vpe.h index 012731546cf6..3de6b0ff1627 100644 --- a/arch/mips/include/asm/vpe.h +++ b/arch/mips/include/asm/vpe.h @@ -126,4 +126,12 @@ void cleanup_tc(struct tc *tc); int __init vpe_module_init(void); void __exit vpe_module_exit(void); + +#ifdef CONFIG_MIPS_VPE_LOADER_MT +void *vpe_alloc(void); +int vpe_start(void *vpe, unsigned long start); +int vpe_stop(void *vpe); +int vpe_free(void *vpe); +#endif /* CONFIG_MIPS_VPE_LOADER_MT */ + #endif /* _ASM_VPE_H */ From 684c92bb08a25ed3c0356bc7eb532ed5b19588dd Mon Sep 17 00:00:00 2001 From: jackysliu <1972843537@qq.com> Date: Tue, 24 Jun 2025 19:58:24 +0800 Subject: [PATCH 237/404] scsi: bfa: Double-free fix [ Upstream commit add4c4850363d7c1b72e8fce9ccb21fdd2cf5dc9 ] When the bfad_im_probe() function fails during initialization, the memory pointed to by bfad->im is freed without setting bfad->im to NULL. Subsequently, during driver uninstallation, when the state machine enters the bfad_sm_stopping state and calls the bfad_im_probe_undo() function, it attempts to free the memory pointed to by bfad->im again, thereby triggering a double-free vulnerability. Set bfad->im to NULL if probing fails. Signed-off-by: jackysliu <1972843537@qq.com> Link: https://lore.kernel.org/r/tencent_3BB950D6D2D470976F55FC879206DE0B9A09@qq.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/bfa/bfad_im.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 22f06be2606f..6dcf1094e01b 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -707,6 +707,7 @@ bfad_im_probe(struct bfad_s *bfad) if (bfad_thread_workq(bfad) != BFA_STATUS_OK) { kfree(im); + bfad->im = NULL; return BFA_STATUS_FAILED; } From 89fff8e3d6710fc32507b8e19eb5afa9fb79b896 Mon Sep 17 00:00:00 2001 From: Lizhi Xu Date: Fri, 13 Jun 2025 11:05:34 +0800 Subject: [PATCH 238/404] jfs: truncate good inode pages when hard link is 0 [ Upstream commit 2d91b3765cd05016335cd5df5e5c6a29708ec058 ] The fileset value of the inode copy from the disk by the reproducer is AGGR_RESERVED_I. When executing evict, its hard link number is 0, so its inode pages are not truncated. This causes the bugon to be triggered when executing clear_inode() because nrpages is greater than 0. Reported-by: syzbot+6e516bb515d93230bc7b@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=6e516bb515d93230bc7b Signed-off-by: Lizhi Xu Signed-off-by: Dave Kleikamp Signed-off-by: Sasha Levin --- fs/jfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 62c4a5450cda..6d353fbe67c0 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -145,9 +145,9 @@ void jfs_evict_inode(struct inode *inode) if (!inode->i_nlink && !is_bad_inode(inode)) { dquot_initialize(inode); + truncate_inode_pages_final(&inode->i_data); if (JFS_IP(inode)->fileset == FILESYSTEM_I) { struct inode *ipimap = JFS_SBI(inode->i_sb)->ipimap; - truncate_inode_pages_final(&inode->i_data); if (test_cflag(COMMIT_Freewmap, inode)) jfs_free_zero_link(inode); From 9f896c3d0192241d6438be6963682ace8203f502 Mon Sep 17 00:00:00 2001 From: Edward Adam Davis Date: Wed, 4 Jun 2025 14:48:43 +0800 Subject: [PATCH 239/404] jfs: Regular file corruption check [ Upstream commit 2d04df8116426b6c7b9f8b9b371250f666a2a2fb ] The reproducer builds a corrupted file on disk with a negative i_size value. Add a check when opening this file to avoid subsequent operation failures. Reported-by: syzbot+630f6d40b3ccabc8e96e@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=630f6d40b3ccabc8e96e Tested-by: syzbot+630f6d40b3ccabc8e96e@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis Signed-off-by: Dave Kleikamp Signed-off-by: Sasha Levin --- fs/jfs/file.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 930d2701f206..44872daeca01 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -44,6 +44,9 @@ static int jfs_open(struct inode *inode, struct file *file) { int rc; + if (S_ISREG(inode->i_mode) && inode->i_size < 0) + return -EIO; + if ((rc = dquot_file_open(inode, file))) return rc; From 5bdb9553fb134fd52ec208a8b378120670f6e784 Mon Sep 17 00:00:00 2001 From: Arnaud Lecomte Date: Thu, 24 Apr 2025 00:13:51 +0200 Subject: [PATCH 240/404] jfs: upper bound check of tree index in dbAllocAG [ Upstream commit c214006856ff52a8ff17ed8da52d50601d54f9ce ] When computing the tree index in dbAllocAG, we never check if we are out of bounds realative to the size of the stree. This could happen in a scenario where the filesystem metadata are corrupted. Reported-by: syzbot+cffd18309153948f3c3e@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=cffd18309153948f3c3e Tested-by: syzbot+cffd18309153948f3c3e@syzkaller.appspotmail.com Signed-off-by: Arnaud Lecomte Signed-off-by: Dave Kleikamp Signed-off-by: Sasha Levin --- fs/jfs/jfs_dmap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 15f885d2fa3d..17c4e7bdf283 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -1457,6 +1457,12 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results) (1 << (L2LPERCTL - (bmp->db_agheight << 1))) / bmp->db_agwidth; ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1)); + if (ti < 0 || ti >= le32_to_cpu(dcp->nleafs)) { + jfs_error(bmp->db_ipbmap->i_sb, "Corrupt dmapctl page\n"); + release_metapage(mp); + return -EIO; + } + /* dmap control page trees fan-out by 4 and a single allocation * group may be described by 1 or 2 subtrees within the ag level * dmap control page, depending upon the ag size. examine the ag's From ab18e48a503230d675e824a0d68a108bdff42503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Wed, 11 Jun 2025 13:28:26 +0200 Subject: [PATCH 241/404] MIPS: Don't crash in stack_top() for tasks without ABI or vDSO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit e9f4a6b3421e936c3ee9d74710243897d74dbaa2 ] Not all tasks have an ABI associated or vDSO mapped, for example kthreads never do. If such a task ever ends up calling stack_top(), it will derefence the NULL ABI pointer and crash. This can for example happen when using kunit: mips_stack_top+0x28/0xc0 arch_pick_mmap_layout+0x190/0x220 kunit_vm_mmap_init+0xf8/0x138 __kunit_add_resource+0x40/0xa8 kunit_vm_mmap+0x88/0xd8 usercopy_test_init+0xb8/0x240 kunit_try_run_case+0x5c/0x1a8 kunit_generic_run_threadfn_adapter+0x28/0x50 kthread+0x118/0x240 ret_from_kernel_thread+0x14/0x1c Only dereference the ABI point if it is set. The GIC page is also included as it is specific to the vDSO. Also move the randomization adjustment into the same conditional. Signed-off-by: Thomas Weißschuh Reviewed-by: David Gow Reviewed-by: Huacai Chen Signed-off-by: Thomas Bogendoerfer Signed-off-by: Sasha Levin --- arch/mips/kernel/process.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 339870ed92f7..42e95e6edd1d 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -654,18 +654,20 @@ unsigned long mips_stack_top(void) top -= PAGE_SIZE; /* Space for the VDSO, data page & GIC user page */ - top -= PAGE_ALIGN(current->thread.abi->vdso->size); - top -= PAGE_SIZE; - top -= mips_gic_present() ? PAGE_SIZE : 0; + if (current->thread.abi) { + top -= PAGE_ALIGN(current->thread.abi->vdso->size); + top -= PAGE_SIZE; + top -= mips_gic_present() ? PAGE_SIZE : 0; + + /* Space to randomize the VDSO base */ + if (current->flags & PF_RANDOMIZE) + top -= VDSO_RANDOMIZE_SIZE; + } /* Space for cache colour alignment */ if (cpu_has_dc_aliases) top -= shm_align_mask + 1; - /* Space to randomize the VDSO base */ - if (current->flags & PF_RANDOMIZE) - top -= VDSO_RANDOMIZE_SIZE; - return top; } From 9bba1a9994c523b44db64f63b564b4719ea2b7ef Mon Sep 17 00:00:00 2001 From: "Yury Norov [NVIDIA]" Date: Wed, 4 Jun 2025 15:39:38 -0400 Subject: [PATCH 242/404] RDMA: hfi1: fix possible divide-by-zero in find_hw_thread_mask() [ Upstream commit 59f7d2138591ef8f0e4e4ab5f1ab674e8181ad3a ] The function divides number of online CPUs by num_core_siblings, and later checks the divider by zero. This implies a possibility to get and divide-by-zero runtime error. Fix it by moving the check prior to division. This also helps to save one indentation level. Signed-off-by: Yury Norov [NVIDIA] Link: https://patch.msgid.link/20250604193947.11834-3-yury.norov@gmail.com Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/hw/hfi1/affinity.c | 44 +++++++++++++++------------ 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/affinity.c b/drivers/infiniband/hw/hfi1/affinity.c index 832b878fa67e..6933fbea2b46 100644 --- a/drivers/infiniband/hw/hfi1/affinity.c +++ b/drivers/infiniband/hw/hfi1/affinity.c @@ -1009,31 +1009,35 @@ static void find_hw_thread_mask(uint hw_thread_no, cpumask_var_t hw_thread_mask, struct hfi1_affinity_node_list *affinity) { int possible, curr_cpu, i; - uint num_cores_per_socket = node_affinity.num_online_cpus / + uint num_cores_per_socket; + + cpumask_copy(hw_thread_mask, &affinity->proc.mask); + + if (affinity->num_core_siblings == 0) + return; + + num_cores_per_socket = node_affinity.num_online_cpus / affinity->num_core_siblings / node_affinity.num_online_nodes; - cpumask_copy(hw_thread_mask, &affinity->proc.mask); - if (affinity->num_core_siblings > 0) { - /* Removing other siblings not needed for now */ - possible = cpumask_weight(hw_thread_mask); - curr_cpu = cpumask_first(hw_thread_mask); - for (i = 0; - i < num_cores_per_socket * node_affinity.num_online_nodes; - i++) - curr_cpu = cpumask_next(curr_cpu, hw_thread_mask); + /* Removing other siblings not needed for now */ + possible = cpumask_weight(hw_thread_mask); + curr_cpu = cpumask_first(hw_thread_mask); + for (i = 0; + i < num_cores_per_socket * node_affinity.num_online_nodes; + i++) + curr_cpu = cpumask_next(curr_cpu, hw_thread_mask); - for (; i < possible; i++) { - cpumask_clear_cpu(curr_cpu, hw_thread_mask); - curr_cpu = cpumask_next(curr_cpu, hw_thread_mask); - } - - /* Identifying correct HW threads within physical cores */ - cpumask_shift_left(hw_thread_mask, hw_thread_mask, - num_cores_per_socket * - node_affinity.num_online_nodes * - hw_thread_no); + for (; i < possible; i++) { + cpumask_clear_cpu(curr_cpu, hw_thread_mask); + curr_cpu = cpumask_next(curr_cpu, hw_thread_mask); } + + /* Identifying correct HW threads within physical cores */ + cpumask_shift_left(hw_thread_mask, hw_thread_mask, + num_cores_per_socket * + node_affinity.num_online_nodes * + hw_thread_no); } int hfi1_get_proc_affinity(int node) From 6711ce7e9de4eb1a541ef30638df1294ea4267f8 Mon Sep 17 00:00:00 2001 From: Justin Tee Date: Wed, 18 Jun 2025 12:21:28 -0700 Subject: [PATCH 243/404] scsi: lpfc: Check for hdwq null ptr when cleaning up lpfc_vport structure [ Upstream commit 6698796282e828733cde3329c887b4ae9e5545e9 ] If a call to lpfc_sli4_read_rev() from lpfc_sli4_hba_setup() fails, the resultant cleanup routine lpfc_sli4_vport_delete_fcp_xri_aborted() may occur before sli4_hba.hdwqs are allocated. This may result in a null pointer dereference when attempting to take the abts_io_buf_list_lock for the first hardware queue. Fix by adding a null ptr check on phba->sli4_hba.hdwq and early return because this situation means there must have been an error during port initialization. Signed-off-by: Justin Tee Link: https://lore.kernel.org/r/20250618192138.124116-4-justintee8345@gmail.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/lpfc/lpfc_scsi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index f238e0f41f07..1d58895b3943 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -469,6 +469,10 @@ lpfc_sli4_vport_delete_fcp_xri_aborted(struct lpfc_vport *vport) if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP)) return; + /* may be called before queues established if hba_setup fails */ + if (!phba->sli4_hba.hdwq) + return; + spin_lock_irqsave(&phba->hbalock, iflag); for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { qp = &phba->sli4_hba.hdwq[idx]; From 0f79837458caff7eb6521e1c6b32e9dccf6aa6cd Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Fri, 6 Jun 2025 14:27:47 +0900 Subject: [PATCH 244/404] scsi: mpt3sas: Correctly handle ATA device errors [ Upstream commit 15592a11d5a5c8411ac8494ec49736b658f6fbff ] With the ATA error model, an NCQ command failure always triggers an abort (termination) of all NCQ commands queued on the device. In such case, the SAT or the host must handle the failed command according to the command sense data and immediately retry all other NCQ commands that were aborted due to the failed NCQ command. For SAS HBAs controlled by the mpt3sas driver, NCQ command aborts are not handled by the HBA SAT and sent back to the host, with an ioc log information equal to 0x31080000 (IOC_LOGINFO_PREFIX_PL with the PL code PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR). The function _scsih_io_done() always forces a retry of commands terminated with the status MPI2_IOCSTATUS_SCSI_IOC_TERMINATED using the SCSI result DID_SOFT_ERROR, regardless of the log_info for the command. This correctly forces the retry of collateral NCQ abort commands, but with the retry counter for the command being incremented. If a command to an ATA device is subject to too many retries due to other NCQ commands failing (e.g. read commands trying to access unreadable sectors), the collateral NCQ abort commands may be terminated with an error as they run out of retries. This violates the SAT specification and causes hard-to-debug command errors. Solve this issue by modifying the handling of the MPI2_IOCSTATUS_SCSI_IOC_TERMINATED status to check if a command is for an ATA device and if the command loginfo indicates an NCQ collateral abort. If that is the case, force the command retry using the SCSI result DID_IMM_RETRY to avoid incrementing the command retry count. Signed-off-by: Damien Le Moal Link: https://lore.kernel.org/r/20250606052747.742998-3-dlemoal@kernel.org Tested-by: Yafang Shao Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 4731e464dfb9..3169b37a88b3 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -181,6 +181,14 @@ struct sense_info { #define MPT3SAS_PORT_ENABLE_COMPLETE (0xFFFD) #define MPT3SAS_ABRT_TASK_SET (0xFFFE) #define MPT3SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF) + +/* + * SAS Log info code for a NCQ collateral abort after an NCQ error: + * IOC_LOGINFO_PREFIX_PL | PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR + * See: drivers/message/fusion/lsi/mpi_log_sas.h + */ +#define IOC_LOGINFO_SATA_NCQ_FAIL_AFTER_ERR 0x31080000 + /** * struct fw_event_work - firmware event struct * @list: link list framework @@ -5327,6 +5335,17 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) scmd->result = DID_TRANSPORT_DISRUPTED << 16; goto out; } + if (log_info == IOC_LOGINFO_SATA_NCQ_FAIL_AFTER_ERR) { + /* + * This is a ATA NCQ command aborted due to another NCQ + * command failure. We must retry this command + * immediately but without incrementing its retry + * counter. + */ + WARN_ON_ONCE(xfer_cnt != 0); + scmd->result = DID_IMM_RETRY << 16; + break; + } if (log_info == 0x31110630) { if (scmd->retries > 2) { scmd->result = DID_NO_CONNECT << 16; From e0b208c4ded977c0f270e7021a84927c1fb23a11 Mon Sep 17 00:00:00 2001 From: Cheick Traore Date: Tue, 10 Jun 2025 16:30:39 +0200 Subject: [PATCH 245/404] pinctrl: stm32: Manage irq affinity settings [ Upstream commit 4c5cc2f65386e22166ce006efe515c667aa075e4 ] Trying to set the affinity of the interrupts associated to stm32 pinctrl results in a write error. Fill struct irq_chip::irq_set_affinity to use the default helper function. Signed-off-by: Cheick Traore Signed-off-by: Antonio Borneo Link: https://lore.kernel.org/20250610143042.295376-3-antonio.borneo@foss.st.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/stm32/pinctrl-stm32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 10595b43360b..2a9c2d94eb55 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -340,6 +340,7 @@ static struct irq_chip stm32_gpio_irq_chip = { .irq_set_wake = irq_chip_set_wake_parent, .irq_request_resources = stm32_gpio_irq_request_resources, .irq_release_resources = stm32_gpio_irq_release_resources, + .irq_set_affinity = IS_ENABLED(CONFIG_SMP) ? irq_chip_set_affinity_parent : NULL, }; static int stm32_gpio_domain_translate(struct irq_domain *d, From 321cb5a31c96806ab4cda4a1af9f079931dfc219 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 11 Jun 2025 19:37:15 +0100 Subject: [PATCH 246/404] media: tc358743: Check I2C succeeded during probe [ Upstream commit 303d81635e1d9c949b370215cc94526ed81f2e3d ] The probe for the TC358743 reads the CHIPID register from the device and compares it to the expected value of 0. If the I2C request fails then that also returns 0, so the driver loads thinking that the device is there. Generally I2C communications are reliable so there is limited need to check the return value on every transfer, therefore only amend the one read during probe to check for I2C errors. Signed-off-by: Dave Stevenson Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin --- drivers/media/i2c/tc358743.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index f4ebe93a495c..ce54d963457d 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -110,7 +110,7 @@ static inline struct tc358743_state *to_state(struct v4l2_subdev *sd) /* --------------- I2C --------------- */ -static void i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n) +static int i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n) { struct tc358743_state *state = to_state(sd); struct i2c_client *client = state->i2c_client; @@ -136,6 +136,7 @@ static void i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n) v4l2_err(sd, "%s: reading register 0x%x from 0x%x failed\n", __func__, reg, client->addr); } + return err != ARRAY_SIZE(msgs); } static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n) @@ -192,15 +193,24 @@ static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n) } } -static noinline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n) +static noinline u32 i2c_rdreg_err(struct v4l2_subdev *sd, u16 reg, u32 n, + int *err) { + int error; __le32 val = 0; - i2c_rd(sd, reg, (u8 __force *)&val, n); + error = i2c_rd(sd, reg, (u8 __force *)&val, n); + if (err) + *err = error; return le32_to_cpu(val); } +static inline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n) +{ + return i2c_rdreg_err(sd, reg, n, NULL); +} + static noinline void i2c_wrreg(struct v4l2_subdev *sd, u16 reg, u32 val, u32 n) { __le32 raw = cpu_to_le32(val); @@ -229,6 +239,13 @@ static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg) return i2c_rdreg(sd, reg, 2); } +static int i2c_rd16_err(struct v4l2_subdev *sd, u16 reg, u16 *value) +{ + int err; + *value = i2c_rdreg_err(sd, reg, 2, &err); + return err; +} + static void i2c_wr16(struct v4l2_subdev *sd, u16 reg, u16 val) { i2c_wrreg(sd, reg, val, 2); @@ -2041,6 +2058,7 @@ static int tc358743_probe(struct i2c_client *client) struct tc358743_platform_data *pdata = client->dev.platform_data; struct v4l2_subdev *sd; u16 irq_mask = MASK_HDMI_MSK | MASK_CSI_MSK; + u16 chipid; int err; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -2072,7 +2090,8 @@ static int tc358743_probe(struct i2c_client *client) sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; /* i2c access */ - if ((i2c_rd16(sd, CHIPID) & MASK_CHIPID) != 0) { + if (i2c_rd16_err(sd, CHIPID, &chipid) || + (chipid & MASK_CHIPID) != 0) { v4l2_info(sd, "not a TC358743 on address 0x%x\n", client->addr << 1); return -ENODEV; From bb0b1ac7f41bc396ede657c3c0a925edcb49e0f3 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 11 Jun 2025 19:37:16 +0100 Subject: [PATCH 247/404] media: tc358743: Return an appropriate colorspace from tc358743_set_fmt [ Upstream commit 377cc006a364dfdab2f3f221cfad63a9265200b8 ] When calling tc358743_set_fmt, the code was calling tc358743_get_fmt to choose a valid format. However that sets the colorspace based on information read back from the chip, not the colour format requested. The result was that if you called try or set format for UYVY when the current format was RGB3 then you would get told SRGB, and try RGB3 when current was UYVY and you would get told SMPTE170M. The value programmed in the VI_REP register for the colorspace is always set by this driver, therefore there is no need to read back the value, and never set to REC709. Return the colorspace based on the format set/tried instead. Signed-off-by: Dave Stevenson Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin --- drivers/media/i2c/tc358743.c | 44 ++++++++++++++---------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index ce54d963457d..26e9e95dd6ae 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1685,12 +1685,23 @@ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd, return 0; } +static u32 tc358743_g_colorspace(u32 code) +{ + switch (code) { + case MEDIA_BUS_FMT_RGB888_1X24: + return V4L2_COLORSPACE_SRGB; + case MEDIA_BUS_FMT_UYVY8_1X16: + return V4L2_COLORSPACE_SMPTE170M; + default: + return 0; + } +} + static int tc358743_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *format) { struct tc358743_state *state = to_state(sd); - u8 vi_rep = i2c_rd8(sd, VI_REP); if (format->pad != 0) return -EINVAL; @@ -1700,23 +1711,7 @@ static int tc358743_get_fmt(struct v4l2_subdev *sd, format->format.height = state->timings.bt.height; format->format.field = V4L2_FIELD_NONE; - switch (vi_rep & MASK_VOUT_COLOR_SEL) { - case MASK_VOUT_COLOR_RGB_FULL: - case MASK_VOUT_COLOR_RGB_LIMITED: - format->format.colorspace = V4L2_COLORSPACE_SRGB; - break; - case MASK_VOUT_COLOR_601_YCBCR_LIMITED: - case MASK_VOUT_COLOR_601_YCBCR_FULL: - format->format.colorspace = V4L2_COLORSPACE_SMPTE170M; - break; - case MASK_VOUT_COLOR_709_YCBCR_FULL: - case MASK_VOUT_COLOR_709_YCBCR_LIMITED: - format->format.colorspace = V4L2_COLORSPACE_REC709; - break; - default: - format->format.colorspace = 0; - break; - } + format->format.colorspace = tc358743_g_colorspace(format->format.code); return 0; } @@ -1730,19 +1725,14 @@ static int tc358743_set_fmt(struct v4l2_subdev *sd, u32 code = format->format.code; /* is overwritten by get_fmt */ int ret = tc358743_get_fmt(sd, cfg, format); - format->format.code = code; + if (code == MEDIA_BUS_FMT_RGB888_1X24 || + code == MEDIA_BUS_FMT_UYVY8_1X16) + format->format.code = code; + format->format.colorspace = tc358743_g_colorspace(format->format.code); if (ret) return ret; - switch (code) { - case MEDIA_BUS_FMT_RGB888_1X24: - case MEDIA_BUS_FMT_UYVY8_1X16: - break; - default: - return -EINVAL; - } - if (format->which == V4L2_SUBDEV_FORMAT_TRY) return 0; From 44070233222c60e28d5c2b917bc6bbbbce629809 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 11 Jun 2025 19:37:14 +0100 Subject: [PATCH 248/404] media: tc358743: Increase FIFO trigger level to 374 [ Upstream commit 86addd25314a1e77dbdcfddfeed0bab2f27da0e2 ] The existing fixed value of 16 worked for UYVY 720P60 over 2 lanes at 594MHz, or UYVY 1080P60 over 4 lanes. (RGB888 1080P60 needs 6 lanes at 594MHz). It doesn't allow for lower resolutions to work as the FIFO underflows. 374 is required for 1080P24 or 1080P30 UYVY over 2 lanes @ 972Mbit/s, but >374 means that the FIFO underflows on 1080P50 UYVY over 2 lanes @ 972Mbit/s. Whilst it would be nice to compute it, the required information isn't published by Toshiba. Signed-off-by: Dave Stevenson Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin --- drivers/media/i2c/tc358743.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 26e9e95dd6ae..2dad35568586 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1959,8 +1959,19 @@ static int tc358743_probe_of(struct tc358743_state *state) state->pdata.refclk_hz = clk_get_rate(refclk); state->pdata.ddc5v_delay = DDC5V_DELAY_100_MS; state->pdata.enable_hdcp = false; - /* A FIFO level of 16 should be enough for 2-lane 720p60 at 594 MHz. */ - state->pdata.fifo_level = 16; + /* + * Ideally the FIFO trigger level should be set based on the input and + * output data rates, but the calculations required are buried in + * Toshiba's register settings spreadsheet. + * A value of 16 works with a 594Mbps data rate for 720p60 (using 2 + * lanes) and 1080p60 (using 4 lanes), but fails when the data rate + * is increased, or a lower pixel clock is used that result in CSI + * reading out faster than the data is arriving. + * + * A value of 374 works with both those modes at 594Mbps, and with most + * modes on 972Mbps. + */ + state->pdata.fifo_level = 374; /* * The PLL input clock is obtained by dividing refclk by pll_prd. * It must be between 6 MHz and 40 MHz, lower frequency is better. From efeb58795508293e07e7e99398af7900bbd1b1a1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 22 May 2025 10:09:54 +0200 Subject: [PATCH 249/404] media: usb: hdpvr: disable zero-length read messages [ Upstream commit b5ae5a79825ba8037b0be3ef677a24de8c063abf ] This driver passes the length of an i2c_msg directly to usb_control_msg(). If the message is now a read and of length 0, it violates the USB protocol and a warning will be printed. Enable the I2C_AQ_NO_ZERO_LEN_READ quirk for this adapter thus forbidding 0-length read messages altogether. Signed-off-by: Wolfram Sang Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin --- drivers/media/usb/hdpvr/hdpvr-i2c.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/usb/hdpvr/hdpvr-i2c.c b/drivers/media/usb/hdpvr/hdpvr-i2c.c index 785c8508a46e..e6a190fe0e87 100644 --- a/drivers/media/usb/hdpvr/hdpvr-i2c.c +++ b/drivers/media/usb/hdpvr/hdpvr-i2c.c @@ -165,10 +165,16 @@ static const struct i2c_algorithm hdpvr_algo = { .functionality = hdpvr_functionality, }; +/* prevent invalid 0-length usb_control_msg */ +static const struct i2c_adapter_quirks hdpvr_quirks = { + .flags = I2C_AQ_NO_ZERO_LEN_READ, +}; + static const struct i2c_adapter hdpvr_i2c_adapter_template = { .name = "Hauppauge HD PVR I2C", .owner = THIS_MODULE, .algo = &hdpvr_algo, + .quirks = &hdpvr_quirks, }; static int hdpvr_activate_ir(struct hdpvr_device *dev) From bc07cae4f36bb18d5b6a9ed835c1278ca44ec82e Mon Sep 17 00:00:00 2001 From: Alex Guo Date: Sun, 15 Jun 2025 21:32:31 -0400 Subject: [PATCH 250/404] media: dvb-frontends: dib7090p: fix null-ptr-deref in dib7090p_rw_on_apb() [ Upstream commit ce5cac69b2edac3e3246fee03e8f4c2a1075238b ] In dib7090p_rw_on_apb, msg is controlled by user. When msg[0].buf is null and msg[0].len is zero, former checks on msg[0].buf would be passed. If accessing msg[0].buf[2] without sanity check, null pointer deref would happen. We add check on msg[0].len to prevent crash. Similar issue occurs when access msg[1].buf[0] and msg[1].buf[1]. Similar commit: commit 0ed554fd769a ("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()") Signed-off-by: Alex Guo Link: https://lore.kernel.org/r/20250616013231.730221-1-alexguo1023@gmail.com Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/dvb-frontends/dib7000p.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c index fd08a851a452..d31ce5c7104d 100644 --- a/drivers/media/dvb-frontends/dib7000p.c +++ b/drivers/media/dvb-frontends/dib7000p.c @@ -2261,8 +2261,12 @@ static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, u16 word; if (num == 1) { /* write */ + if (msg[0].len < 3) + return -EOPNOTSUPP; dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2]))); } else { + if (msg[1].len < 2) + return -EOPNOTSUPP; word = dib7000p_read_word(state, apb_address); msg[1].buf[0] = (word >> 8) & 0xff; msg[1].buf[1] = (word) & 0xff; From 7a41ecfc3415ebe3b4c44f96b3337691dcf431a3 Mon Sep 17 00:00:00 2001 From: Alex Guo Date: Sun, 15 Jun 2025 21:33:53 -0400 Subject: [PATCH 251/404] media: dvb-frontends: w7090p: fix null-ptr-deref in w7090p_tuner_write_serpar and w7090p_tuner_read_serpar [ Upstream commit ed0234c8458b3149f15e496b48a1c9874dd24a1b ] In w7090p_tuner_write_serpar, msg is controlled by user. When msg[0].buf is null and msg[0].len is zero, former checks on msg[0].buf would be passed. If accessing msg[0].buf[2] without sanity check, null pointer deref would happen. We add check on msg[0].len to prevent crash. Similar commit: commit 0ed554fd769a ("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()") Signed-off-by: Alex Guo Link: https://lore.kernel.org/r/20250616013353.738790-1-alexguo1023@gmail.com Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/dvb-frontends/dib7000p.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c index d31ce5c7104d..41dcbabdc193 100644 --- a/drivers/media/dvb-frontends/dib7000p.c +++ b/drivers/media/dvb-frontends/dib7000p.c @@ -2198,6 +2198,8 @@ static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_ms struct dib7000p_state *state = i2c_get_adapdata(i2c_adap); u8 n_overflow = 1; u16 i = 1000; + if (msg[0].len < 3) + return -EOPNOTSUPP; u16 serpar_num = msg[0].buf[0]; while (n_overflow == 1 && i) { @@ -2217,6 +2219,8 @@ static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg struct dib7000p_state *state = i2c_get_adapdata(i2c_adap); u8 n_overflow = 1, n_empty = 1; u16 i = 1000; + if (msg[0].len < 1 || msg[1].len < 2) + return -EOPNOTSUPP; u16 serpar_num = msg[0].buf[0]; u16 read_word; From 75996055eaa530a93957b3c2325d62e9c2f6d926 Mon Sep 17 00:00:00 2001 From: chenchangcheng Date: Sat, 10 May 2025 14:18:03 +0800 Subject: [PATCH 252/404] media: uvcvideo: Fix bandwidth issue for Alcor camera [ Upstream commit 9764401bf6f8a20eb11c2e78470f20fee91a9ea7 ] Some broken device return wrong dwMaxPayloadTransferSize fields as follows: [ 218.632537] uvcvideo: Device requested 2752512 B/frame bandwidth. [ 218.632598] uvcvideo: No fast enough alt setting for requested bandwidth. When dwMaxPayloadTransferSize is greater than maxpsize, it will prevent the camera from starting. So use the bandwidth of maxpsize. Signed-off-by: chenchangcheng Reviewed-by: Ricardo Ribalda Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20250510061803.811433-1-ccc194101@163.com Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin --- drivers/media/usb/uvc/uvc_video.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index e62afdee20db..d1510c1230d9 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -228,6 +228,15 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, ctrl->dwMaxPayloadTransferSize = bandwidth; } + + if (stream->intf->num_altsetting > 1 && + ctrl->dwMaxPayloadTransferSize > stream->maxpsize) { + dev_warn_ratelimited(&stream->intf->dev, + "UVC non compliance: the max payload transmission size (%u) exceeds the size of the ep max packet (%u). Using the max size.\n", + ctrl->dwMaxPayloadTransferSize, + stream->maxpsize); + ctrl->dwMaxPayloadTransferSize = stream->maxpsize; + } } static size_t uvc_video_ctrl_size(struct uvc_streaming *stream) From da16cbdafa356badc9d8798e09c729184f6a486d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 17 Jul 2025 14:00:47 +0200 Subject: [PATCH 253/404] i3c: add missing include to internal header [ Upstream commit 3b661ca549b9e5bb11d0bc97ada6110aac3282d2 ] LKP found a random config which failed to build because IO accessors were not defined: In file included from drivers/i3c/master.c:21: drivers/i3c/internals.h: In function 'i3c_writel_fifo': >> drivers/i3c/internals.h:35:9: error: implicit declaration of function 'writesl' [-Werror=implicit-function-declaration] Add the proper header to where the IO accessors are used. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202507150208.BZDzzJ5E-lkp@intel.com/ Signed-off-by: Wolfram Sang Reviewed-by: Frank Li Link: https://lore.kernel.org/r/20250717120046.9022-2-wsa+renesas@sang-engineering.com Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin --- drivers/i3c/internals.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i3c/internals.h b/drivers/i3c/internals.h index 86b7b44cfca2..1906c711f38a 100644 --- a/drivers/i3c/internals.h +++ b/drivers/i3c/internals.h @@ -9,6 +9,7 @@ #define I3C_INTERNALS_H #include +#include extern struct bus_type i3c_bus_type; From 76274030a16489aed207e759f6b257d25308890e Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 15 Jul 2025 16:36:55 -0500 Subject: [PATCH 254/404] PCI: pnv_php: Work around switches with broken presence detection [ Upstream commit 80f9fc2362797538ebd4fd70a1dfa838cc2c2cdb ] The Microsemi Switchtec PM8533 PFX 48xG3 [11f8:8533] PCIe switch system was observed to incorrectly assert the Presence Detect Set bit in its capabilities when tested on a Raptor Computing Systems Blackbird system, resulting in the hot insert path never attempting a rescan of the bus and any downstream devices not being re-detected. Work around this by additionally checking whether the PCIe data link is active or not when performing presence detection on downstream switches' ports, similar to the pciehp_hpc.c driver. Signed-off-by: Shawn Anastasio Signed-off-by: Timothy Pearson Signed-off-by: Bjorn Helgaas Signed-off-by: Madhavan Srinivasan Link: https://patch.msgid.link/505981576.1359853.1752615415117.JavaMail.zimbra@raptorengineeringinc.com Signed-off-by: Sasha Levin --- drivers/pci/hotplug/pnv_php.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c index 3687a99383c1..800964c81e06 100644 --- a/drivers/pci/hotplug/pnv_php.c +++ b/drivers/pci/hotplug/pnv_php.c @@ -395,6 +395,20 @@ static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state) return 0; } +static int pcie_check_link_active(struct pci_dev *pdev) +{ + u16 lnk_status; + int ret; + + ret = pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status); + if (ret == PCIBIOS_DEVICE_NOT_FOUND || PCI_POSSIBLE_ERROR(lnk_status)) + return -ENODEV; + + ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA); + + return ret; +} + static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state) { struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); @@ -407,6 +421,19 @@ static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state) */ ret = pnv_pci_get_presence_state(php_slot->id, &presence); if (ret >= 0) { + if (pci_pcie_type(php_slot->pdev) == PCI_EXP_TYPE_DOWNSTREAM && + presence == OPAL_PCI_SLOT_EMPTY) { + /* + * Similar to pciehp_hpc, check whether the Link Active + * bit is set to account for broken downstream bridges + * that don't properly assert Presence Detect State, as + * was observed on the Microsemi Switchtec PM8533 PFX + * [11f8:8533]. + */ + if (pcie_check_link_active(php_slot->pdev) > 0) + presence = OPAL_PCI_SLOT_PRESENT; + } + *state = presence; ret = 0; } else { From 1518eb08243d294d272d5517d983a87af887722b Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 4 Jul 2025 22:44:32 +0200 Subject: [PATCH 255/404] i3c: don't fail if GETHDRCAP is unsupported [ Upstream commit 447270cdb41b1c8c3621bb14b93a6749f942556e ] 'I3C_BCR_HDR_CAP' is still spec v1.0 and has been renamed to 'advanced capabilities' in v1.1 onwards. The ST pressure sensor LPS22DF does not have HDR, but has the 'advanced cap' bit set. The core still wants to get additional information using the CCC 'GETHDRCAP' (or GETCAPS in v1.1 onwards). Not all controllers support this CCC and will notify the upper layers about it. For instantiating the device, we can ignore this unsupported CCC as standard communication will work. Without this patch, the device will not be instantiated at all. Signed-off-by: Wolfram Sang Reviewed-by: Frank Li Link: https://lore.kernel.org/r/20250704204524.6124-1-wsa+renesas@sang-engineering.com Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin --- drivers/i3c/master.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index 8604c9e7b6ac..07478ddff622 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -1243,7 +1243,7 @@ static int i3c_master_retrieve_dev_info(struct i3c_dev_desc *dev) if (dev->info.bcr & I3C_BCR_HDR_CAP) { ret = i3c_master_gethdrcap_locked(master, &dev->info); - if (ret) + if (ret && ret != -ENOTSUPP) return ret; } From 6d150a17756e8978ba57ca95c10070a6ce142dfd Mon Sep 17 00:00:00 2001 From: Suchit Karunakaran Date: Sun, 27 Jul 2025 22:14:33 +0530 Subject: [PATCH 256/404] kconfig: lxdialog: replace strcpy() with strncpy() in inputbox.c [ Upstream commit 5ac726653a1029a2eccba93bbe59e01fc9725828 ] strcpy() performs no bounds checking and can lead to buffer overflows if the input string exceeds the destination buffer size. This patch replaces it with strncpy(), and null terminates the input string. Signed-off-by: Suchit Karunakaran Reviewed-by: Nicolas Schier Signed-off-by: Masahiro Yamada Signed-off-by: Sasha Levin --- scripts/kconfig/lxdialog/inputbox.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c index 1dcfb288ee63..327b60cdb8da 100644 --- a/scripts/kconfig/lxdialog/inputbox.c +++ b/scripts/kconfig/lxdialog/inputbox.c @@ -39,8 +39,10 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width if (!init) instr[0] = '\0'; - else - strcpy(instr, init); + else { + strncpy(instr, init, sizeof(dialog_input_result) - 1); + instr[sizeof(dialog_input_result) - 1] = '\0'; + } do_resize: if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN)) From 1bdd93389b6bca40802b2a783ff4fb66f36a6aa7 Mon Sep 17 00:00:00 2001 From: Shankari Anand Date: Thu, 26 Jun 2025 00:36:54 +0530 Subject: [PATCH 257/404] kconfig: nconf: Ensure null termination where strncpy is used [ Upstream commit f468992936894c9ce3b1659cf38c230d33b77a16 ] strncpy() does not guarantee null-termination if the source string is longer than the destination buffer. Ensure the buffer is explicitly null-terminated to prevent potential string overflows or undefined behavior. Signed-off-by: Shankari Anand Signed-off-by: Masahiro Yamada Acked-by: Randy Dunlap Tested-by: Randy Dunlap Tested-by: Nicolas Schier Acked-by: Nicolas Schier Signed-off-by: Sasha Levin --- scripts/kconfig/nconf.c | 2 ++ scripts/kconfig/nconf.gui.c | 1 + 2 files changed, 3 insertions(+) diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 331b2cc917ec..af56d27693d0 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -580,6 +580,8 @@ static void item_add_str(const char *fmt, ...) tmp_str, sizeof(k_menu_items[index].str)); + k_menu_items[index].str[sizeof(k_menu_items[index].str) - 1] = '\0'; + free_item(curses_menu_items[index]); curses_menu_items[index] = new_item( k_menu_items[index].str, diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 77f525a8617c..8b3e9bc893a7 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -398,6 +398,7 @@ int dialog_inputbox(WINDOW *main_window, x = (columns-win_cols)/2; strncpy(result, init, *result_len); + result[*result_len - 1] = '\0'; /* create the windows */ win = newwin(win_lines, win_cols, y, x); From ff139a1976c59985086277b0f4ba73ed4dc1ac99 Mon Sep 17 00:00:00 2001 From: Ranjan Kumar Date: Tue, 24 Jun 2025 11:46:49 +0530 Subject: [PATCH 258/404] scsi: Fix sas_user_scan() to handle wildcard and multi-channel scans [ Upstream commit 37c4e72b0651e7697eb338cd1fb09feef472cc1a ] sas_user_scan() did not fully process wildcard channel scans (SCAN_WILD_CARD) when a transport-specific user_scan() callback was present. Only channel 0 would be scanned via user_scan(), while the remaining channels were skipped, potentially missing devices. user_scan() invokes updated sas_user_scan() for channel 0, and if successful, iteratively scans remaining channels (1 to shost->max_channel) via scsi_scan_host_selected(). This ensures complete wildcard scanning without affecting transport-specific scanning behavior. Signed-off-by: Ranjan Kumar Link: https://lore.kernel.org/r/20250624061649.17990-1-ranjan.kumar@broadcom.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/scsi_scan.c | 2 +- drivers/scsi/scsi_transport_sas.c | 62 ++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index d236322ced30..175cc535fc96 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1686,7 +1686,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, return 0; } - +EXPORT_SYMBOL(scsi_scan_host_selected); static void scsi_sysfs_add_devices(struct Scsi_Host *shost) { struct scsi_device *sdev; diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 182fd25c7c43..0da3f7f1d03e 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -41,6 +41,8 @@ #include #include "scsi_sas_internal.h" +#include "scsi_priv.h" + struct sas_host_attrs { struct list_head rphy_list; struct mutex lock; @@ -1648,6 +1650,22 @@ int scsi_is_sas_rphy(const struct device *dev) } EXPORT_SYMBOL(scsi_is_sas_rphy); +static void scan_channel_zero(struct Scsi_Host *shost, uint id, u64 lun) +{ + struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); + struct sas_rphy *rphy; + + list_for_each_entry(rphy, &sas_host->rphy_list, list) { + if (rphy->identify.device_type != SAS_END_DEVICE || + rphy->scsi_target_id == -1) + continue; + + if (id == SCAN_WILD_CARD || id == rphy->scsi_target_id) { + scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id, + lun, SCSI_SCAN_MANUAL); + } + } +} /* * SCSI scan helper @@ -1657,23 +1675,41 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, uint id, u64 lun) { struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); - struct sas_rphy *rphy; + int res = 0; + int i; - mutex_lock(&sas_host->lock); - list_for_each_entry(rphy, &sas_host->rphy_list, list) { - if (rphy->identify.device_type != SAS_END_DEVICE || - rphy->scsi_target_id == -1) - continue; + switch (channel) { + case 0: + mutex_lock(&sas_host->lock); + scan_channel_zero(shost, id, lun); + mutex_unlock(&sas_host->lock); + break; - if ((channel == SCAN_WILD_CARD || channel == 0) && - (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) { - scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id, - lun, SCSI_SCAN_MANUAL); + case SCAN_WILD_CARD: + mutex_lock(&sas_host->lock); + scan_channel_zero(shost, id, lun); + mutex_unlock(&sas_host->lock); + + for (i = 1; i <= shost->max_channel; i++) { + res = scsi_scan_host_selected(shost, i, id, lun, + SCSI_SCAN_MANUAL); + if (res) + goto exit_scan; } - } - mutex_unlock(&sas_host->lock); + break; - return 0; + default: + if (channel < shost->max_channel) { + res = scsi_scan_host_selected(shost, channel, id, lun, + SCSI_SCAN_MANUAL); + } else { + res = -EINVAL; + } + break; + } + +exit_scan: + return res; } From 8732ba1ab7c9f367c65be106ceaaeb3a18b26e55 Mon Sep 17 00:00:00 2001 From: John Garry Date: Tue, 15 Jul 2025 11:15:35 +0000 Subject: [PATCH 259/404] scsi: aacraid: Stop using PCI_IRQ_AFFINITY [ Upstream commit dafeaf2c03e71255438ffe5a341d94d180e6c88e ] When PCI_IRQ_AFFINITY is set for calling pci_alloc_irq_vectors(), it means interrupts are spread around the available CPUs. It also means that the interrupts become managed, which means that an interrupt is shutdown when all the CPUs in the interrupt affinity mask go offline. Using managed interrupts in this way means that we should ensure that completions should not occur on HW queues where the associated interrupt is shutdown. This is typically achieved by ensuring only CPUs which are online can generate IO completion traffic to the HW queue which they are mapped to (so that they can also serve completion interrupts for that HW queue). The problem in the driver is that a CPU can generate completions to a HW queue whose interrupt may be shutdown, as the CPUs in the HW queue interrupt affinity mask may be offline. This can cause IOs to never complete and hang the system. The driver maintains its own CPU <-> HW queue mapping for submissions, see aac_fib_vector_assign(), but this does not reflect the CPU <-> HW queue interrupt affinity mapping. Commit 9dc704dcc09e ("scsi: aacraid: Reply queue mapping to CPUs based on IRQ affinity") tried to remedy this issue may mapping CPUs properly to HW queue interrupts. However this was later reverted in commit c5becf57dd56 ("Revert "scsi: aacraid: Reply queue mapping to CPUs based on IRQ affinity") - it seems that there were other reports of hangs. I guess that this was due to some implementation issue in the original commit or maybe a HW issue. Fix the very original hang by just not using managed interrupts by not setting PCI_IRQ_AFFINITY. In this way, all CPUs will be in each HW queue affinity mask, so should not create completion problems if any CPUs go offline. Signed-off-by: John Garry Link: https://lore.kernel.org/r/20250715111535.499853-1-john.g.garry@oracle.com Closes: https://lore.kernel.org/linux-scsi/20250618192427.3845724-1-jmeneghi@redhat.com/ Reviewed-by: John Meneghini Tested-by: John Meneghini Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/aacraid/comminit.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 8849eca08a49..6909affadf6f 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -482,8 +482,7 @@ void aac_define_int_mode(struct aac_dev *dev) pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX)) { min_msix = 2; i = pci_alloc_irq_vectors(dev->pdev, - min_msix, msi_count, - PCI_IRQ_MSIX | PCI_IRQ_AFFINITY); + min_msix, msi_count, PCI_IRQ_MSIX); if (i > 0) { dev->msi_enabled = 1; msi_count = i; From fb2ff258d4784b213ddf9dfef973b230edc8ff40 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Thu, 10 Jul 2025 05:57:26 -0700 Subject: [PATCH 260/404] ipmi: Use dev_warn_ratelimited() for incorrect message warnings [ Upstream commit ec50ec378e3fd83bde9b3d622ceac3509a60b6b5 ] During BMC firmware upgrades on live systems, the ipmi_msghandler generates excessive "BMC returned incorrect response" warnings while the BMC is temporarily offline. This can flood system logs in large deployments. Replace dev_warn() with dev_warn_ratelimited() to throttle these warnings and prevent log spam during BMC maintenance operations. Signed-off-by: Breno Leitao Message-ID: <20250710-ipmi_ratelimit-v1-1-6d417015ebe9@debian.org> Signed-off-by: Corey Minyard Signed-off-by: Sasha Levin --- drivers/char/ipmi/ipmi_msghandler.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 0833a2ac2f69..b8a13edee817 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -4302,10 +4302,10 @@ free_msg: * The NetFN and Command in the response is not even * marginally correct. */ - dev_warn(intf->si_dev, - "BMC returned incorrect response, expected netfn %x cmd %x, got netfn %x cmd %x\n", - (msg->data[0] >> 2) | 1, msg->data[1], - msg->rsp[0] >> 2, msg->rsp[1]); + dev_warn_ratelimited(intf->si_dev, + "BMC returned incorrect response, expected netfn %x cmd %x, got netfn %x cmd %x\n", + (msg->data[0] >> 2) | 1, msg->data[1], + msg->rsp[0] >> 2, msg->rsp[1]); /* Generate an error response for the message. */ msg->rsp[0] = msg->data[0] | (1 << 2); From dca7764741438e192d68b57b961ad65772695d4a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 25 Jun 2025 00:05:20 +0900 Subject: [PATCH 261/404] kconfig: gconf: avoid hardcoding model2 in on_treeview2_cursor_changed() [ Upstream commit cae9cdbcd9af044810bcceeb43a87accca47c71d ] The on_treeview2_cursor_changed() handler is connected to both the left and right tree views, but it hardcodes model2 (the GtkTreeModel of the right tree view). This is incorrect. Get the associated model from the view. Signed-off-by: Masahiro Yamada Signed-off-by: Sasha Levin --- scripts/kconfig/gconf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 9b10f1248da1..bd1fdbd949cc 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -980,13 +980,14 @@ on_treeview2_key_press_event(GtkWidget * widget, void on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data) { + GtkTreeModel *model = gtk_tree_view_get_model(treeview); GtkTreeSelection *selection; GtkTreeIter iter; struct menu *menu; selection = gtk_tree_view_get_selection(treeview); - if (gtk_tree_selection_get_selected(selection, &model2, &iter)) { - gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + if (gtk_tree_selection_get_selected(selection, &model, &iter)) { + gtk_tree_model_get(model, &iter, COL_MENU, &menu, -1); text_insert_help(menu); } } From 0589cc9733d88fd946fb19c734028831703a6d50 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 25 Jun 2025 00:04:55 +0900 Subject: [PATCH 262/404] kconfig: gconf: fix potential memory leak in renderer_edited() [ Upstream commit f72ed4c6a375e52a3f4b75615e4a89d29d8acea7 ] If gtk_tree_model_get_iter() fails, gtk_tree_path_free() is not called. Signed-off-by: Masahiro Yamada Acked-by: Randy Dunlap Signed-off-by: Sasha Levin --- scripts/kconfig/gconf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index bd1fdbd949cc..6eb71c75b765 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c @@ -786,7 +786,7 @@ static void renderer_edited(GtkCellRendererText * cell, struct symbol *sym; if (!gtk_tree_model_get_iter(model2, &iter, path)) - return; + goto free; gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); sym = menu->sym; @@ -798,6 +798,7 @@ static void renderer_edited(GtkCellRendererText * cell, update_tree(&rootmenu, NULL); +free: gtk_tree_path_free(path); } From 5b2775e5158f645b4c7443060b814b141581dadb Mon Sep 17 00:00:00 2001 From: "Yann E. MORIN" Date: Thu, 14 Nov 2013 00:53:32 +0100 Subject: [PATCH 263/404] kconfig: lxdialog: fix 'space' to (de)select options [ Upstream commit 694174f94ebeeb5ec5cc0e9de9b40c82057e1d95 ] In case a menu has comment without letters/numbers (eg. characters matching the regexp '^[^[:alpha:][:digit:]]+$', for example - or *), hitting space will cycle through those comments, rather than selecting/deselecting the currently-highlighted option. This is the behaviour of hitting any letter/digit: jump to the next option which prompt starts with that letter. The only letters that do not behave as such are 'y' 'm' and 'n'. Prompts that start with one of those three letters are instead matched on the first letter that is not 'y', 'm' or 'n'. Fix that by treating 'space' as we treat y/m/n, ie. as an action key, not as shortcut to jump to prompt. Signed-off-by: Yann E. MORIN Signed-off-by: Peter Korsgaard Signed-off-by: Cherniaev Andrei [masahiro: took from Buildroot, adjusted the commit subject] Signed-off-by: Masahiro Yamada Signed-off-by: Sasha Levin --- scripts/kconfig/lxdialog/menubox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c index 58c2f8afe59b..7e10e919fbdc 100644 --- a/scripts/kconfig/lxdialog/menubox.c +++ b/scripts/kconfig/lxdialog/menubox.c @@ -272,7 +272,7 @@ do_resize: if (key < 256 && isalpha(key)) key = tolower(key); - if (strchr("ynmh", key)) + if (strchr("ynmh ", key)) i = max_choice; else { for (i = choice + 1; i < max_choice; i++) { From a5635e801eff8133f4205da607ae6e463ce92dee Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Fri, 13 Jun 2025 19:06:26 -0500 Subject: [PATCH 264/404] ipmi: Fix strcpy source and destination the same [ Upstream commit 8ffcb7560b4a15faf821df95e3ab532b2b020f8c ] The source and destination of some strcpy operations was the same. Split out the part of the operations that needed to be done for those particular calls so the unnecessary copy wasn't done. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202506140756.EFXXvIP4-lkp@intel.com/ Signed-off-by: Corey Minyard Signed-off-by: Sasha Levin --- drivers/char/ipmi/ipmi_watchdog.c | 59 ++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index ccb62c480bdd..ac2099f3f41a 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -1192,14 +1192,8 @@ static struct ipmi_smi_watcher smi_watcher = { .smi_gone = ipmi_smi_gone }; -static int action_op(const char *inval, char *outval) +static int action_op_set_val(const char *inval) { - if (outval) - strcpy(outval, action); - - if (!inval) - return 0; - if (strcmp(inval, "reset") == 0) action_val = WDOG_TIMEOUT_RESET; else if (strcmp(inval, "none") == 0) @@ -1210,18 +1204,26 @@ static int action_op(const char *inval, char *outval) action_val = WDOG_TIMEOUT_POWER_DOWN; else return -EINVAL; - strcpy(action, inval); return 0; } -static int preaction_op(const char *inval, char *outval) +static int action_op(const char *inval, char *outval) { + int rv; + if (outval) - strcpy(outval, preaction); + strcpy(outval, action); if (!inval) return 0; + rv = action_op_set_val(inval); + if (!rv) + strcpy(action, inval); + return rv; +} +static int preaction_op_set_val(const char *inval) +{ if (strcmp(inval, "pre_none") == 0) preaction_val = WDOG_PRETIMEOUT_NONE; else if (strcmp(inval, "pre_smi") == 0) @@ -1234,18 +1236,26 @@ static int preaction_op(const char *inval, char *outval) preaction_val = WDOG_PRETIMEOUT_MSG_INT; else return -EINVAL; - strcpy(preaction, inval); return 0; } -static int preop_op(const char *inval, char *outval) +static int preaction_op(const char *inval, char *outval) { + int rv; + if (outval) - strcpy(outval, preop); + strcpy(outval, preaction); if (!inval) return 0; + rv = preaction_op_set_val(inval); + if (!rv) + strcpy(preaction, inval); + return 0; +} +static int preop_op_set_val(const char *inval) +{ if (strcmp(inval, "preop_none") == 0) preop_val = WDOG_PREOP_NONE; else if (strcmp(inval, "preop_panic") == 0) @@ -1254,7 +1264,22 @@ static int preop_op(const char *inval, char *outval) preop_val = WDOG_PREOP_GIVE_DATA; else return -EINVAL; - strcpy(preop, inval); + return 0; +} + +static int preop_op(const char *inval, char *outval) +{ + int rv; + + if (outval) + strcpy(outval, preop); + + if (!inval) + return 0; + + rv = preop_op_set_val(inval); + if (!rv) + strcpy(preop, inval); return 0; } @@ -1291,18 +1316,18 @@ static int __init ipmi_wdog_init(void) { int rv; - if (action_op(action, NULL)) { + if (action_op_set_val(action)) { action_op("reset", NULL); pr_info("Unknown action '%s', defaulting to reset\n", action); } - if (preaction_op(preaction, NULL)) { + if (preaction_op_set_val(preaction)) { preaction_op("pre_none", NULL); pr_info("Unknown preaction '%s', defaulting to none\n", preaction); } - if (preop_op(preop, NULL)) { + if (preop_op_set_val(preop)) { preop_op("preop_none", NULL); pr_info("Unknown preop '%s', defaulting to none\n", preop); } From a69c5d81d2ce738155480a0f9a27c4473a0951ac Mon Sep 17 00:00:00 2001 From: Buday Csaba Date: Mon, 28 Jul 2025 17:29:16 +0200 Subject: [PATCH 265/404] net: phy: smsc: add proper reset flags for LAN8710A MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 57ec5a8735dc5dccd1ee68afdb1114956a3fce0d ] According to the LAN8710A datasheet (Rev. B, section 3.8.5.1), a hardware reset is required after power-on, and the reference clock (REF_CLK) must be established before asserting reset. Signed-off-by: Buday Csaba Cc: Csókás Bence Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/20250728152916.46249-2-csokas.bence@prolan.hu Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/phy/smsc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index e387c219f17d..68bb94f970f6 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -306,6 +306,7 @@ static struct phy_driver smsc_phy_driver[] = { /* PHY_BASIC_FEATURES */ .flags = PHY_RST_AFTER_CLK_EN, + .flags = PHY_RST_AFTER_CLK_EN, .probe = smsc_phy_probe, /* basic functions */ From bd2810033c561282dec673b353b1f9923c2e6a7e Mon Sep 17 00:00:00 2001 From: Sergey Bashirov Date: Tue, 1 Jul 2025 15:21:48 +0300 Subject: [PATCH 266/404] pNFS: Fix stripe mapping in block/scsi layout [ Upstream commit 81438498a285759f31e843ac4800f82a5ce6521f ] Because of integer division, we need to carefully calculate the disk offset. Consider the example below for a stripe of 6 volumes, a chunk size of 4096, and an offset of 70000. chunk = div_u64(offset, dev->chunk_size) = 70000 / 4096 = 17 offset = chunk * dev->chunk_size = 17 * 4096 = 69632 disk_offset_wrong = div_u64(offset, dev->nr_children) = 69632 / 6 = 11605 disk_chunk = div_u64(chunk, dev->nr_children) = 17 / 6 = 2 disk_offset = disk_chunk * dev->chunk_size = 2 * 4096 = 8192 Signed-off-by: Sergey Bashirov Reviewed-by: Christoph Hellwig Link: https://lore.kernel.org/r/20250701122341.199112-1-sergeybashirov@gmail.com Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin --- fs/nfs/blocklayout/dev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/nfs/blocklayout/dev.c b/fs/nfs/blocklayout/dev.c index 6e3a14fdff9c..007d68a3a616 100644 --- a/fs/nfs/blocklayout/dev.c +++ b/fs/nfs/blocklayout/dev.c @@ -199,10 +199,11 @@ static bool bl_map_stripe(struct pnfs_block_dev *dev, u64 offset, struct pnfs_block_dev *child; u64 chunk; u32 chunk_idx; + u64 disk_chunk; u64 disk_offset; chunk = div_u64(offset, dev->chunk_size); - div_u64_rem(chunk, dev->nr_children, &chunk_idx); + disk_chunk = div_u64_rem(chunk, dev->nr_children, &chunk_idx); if (chunk_idx >= dev->nr_children) { dprintk("%s: invalid chunk idx %d (%lld/%lld)\n", @@ -215,7 +216,7 @@ static bool bl_map_stripe(struct pnfs_block_dev *dev, u64 offset, offset = chunk * dev->chunk_size; /* disk offset of the stripe */ - disk_offset = div_u64(offset, dev->nr_children); + disk_offset = disk_chunk * dev->chunk_size; child = &dev->children[chunk_idx]; child->map(child, disk_offset, map); From a0799e0bbac4200c7a1afefc1b7c5d67925ac2ce Mon Sep 17 00:00:00 2001 From: Sergey Bashirov Date: Wed, 2 Jul 2025 16:32:21 +0300 Subject: [PATCH 267/404] pNFS: Fix disk addr range check in block/scsi layout [ Upstream commit 7db6e66663681abda54f81d5916db3a3b8b1a13d ] At the end of the isect translation, disc_addr represents the physical disk offset. Thus, end calculated from disk_addr is also a physical disk offset. Therefore, range checking should be done using map->disk_offset, not map->start. Signed-off-by: Sergey Bashirov Reviewed-by: Christoph Hellwig Link: https://lore.kernel.org/r/20250702133226.212537-1-sergeybashirov@gmail.com Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin --- fs/nfs/blocklayout/blocklayout.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c index 9f10b90debec..4f929134fc63 100644 --- a/fs/nfs/blocklayout/blocklayout.c +++ b/fs/nfs/blocklayout/blocklayout.c @@ -171,8 +171,8 @@ do_add_page_to_bio(struct bio *bio, int npg, int rw, sector_t isect, /* limit length to what the device mapping allows */ end = disk_addr + *len; - if (end >= map->start + map->len) - *len = map->start + map->len - disk_addr; + if (end >= map->disk_offset + map->len) + *len = map->disk_offset + map->len - disk_addr; retry: if (!bio) { From 132f64482571d2548cbc3631cfe408f90e081fdd Mon Sep 17 00:00:00 2001 From: Sergey Bashirov Date: Mon, 30 Jun 2025 21:35:29 +0300 Subject: [PATCH 268/404] pNFS: Handle RPC size limit for layoutcommits [ Upstream commit d897d81671bc4615c80f4f3bd5e6b218f59df50c ] When there are too many block extents for a layoutcommit, they may not all fit into the maximum-sized RPC. This patch allows the generic pnfs code to properly handle -ENOSPC returned by the block/scsi layout driver and trigger additional layoutcommits if necessary. Co-developed-by: Konstantin Evtushenko Signed-off-by: Konstantin Evtushenko Signed-off-by: Sergey Bashirov Reviewed-by: Christoph Hellwig Link: https://lore.kernel.org/r/20250630183537.196479-5-sergeybashirov@gmail.com Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin --- fs/nfs/pnfs.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index d91576a587e4..992cdac8dbe9 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -3047,6 +3047,7 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync) struct nfs_inode *nfsi = NFS_I(inode); loff_t end_pos; int status; + bool mark_as_dirty = false; if (!pnfs_layoutcommit_outstanding(inode)) return 0; @@ -3098,19 +3099,23 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync) if (ld->prepare_layoutcommit) { status = ld->prepare_layoutcommit(&data->args); if (status) { - put_cred(data->cred); + if (status != -ENOSPC) + put_cred(data->cred); spin_lock(&inode->i_lock); set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags); if (end_pos > nfsi->layout->plh_lwb) nfsi->layout->plh_lwb = end_pos; - goto out_unlock; + if (status != -ENOSPC) + goto out_unlock; + spin_unlock(&inode->i_lock); + mark_as_dirty = true; } } status = nfs4_proc_layoutcommit(data, sync); out: - if (status) + if (status || mark_as_dirty) mark_inode_dirty_sync(inode); dprintk("<-- %s status %d\n", __func__, status); return status; From 579b85f893d9885162e1cabf99a4a088916e143e Mon Sep 17 00:00:00 2001 From: Sergey Bashirov Date: Mon, 30 Jun 2025 21:35:26 +0300 Subject: [PATCH 269/404] pNFS: Fix uninited ptr deref in block/scsi layout [ Upstream commit 9768797c219326699778fba9cd3b607b2f1e7950 ] The error occurs on the third attempt to encode extents. When function ext_tree_prepare_commit() reallocates a larger buffer to retry encoding extents, the "layoutupdate_pages" page array is initialized only after the retry loop. But ext_tree_free_commitdata() is called on every iteration and tries to put pages in the array, thus dereferencing uninitialized pointers. An additional problem is that there is no limit on the maximum possible buffer_size. When there are too many extents, the client may create a layoutcommit that is larger than the maximum possible RPC size accepted by the server. During testing, we observed two typical scenarios. First, one memory page for extents is enough when we work with small files, append data to the end of the file, or preallocate extents before writing. But when we fill a new large file without preallocating, the number of extents can be huge, and counting the number of written extents in ext_tree_encode_commit() does not help much. Since this number increases even more between unlocking and locking of ext_tree, the reallocated buffer may not be large enough again and again. Co-developed-by: Konstantin Evtushenko Signed-off-by: Konstantin Evtushenko Signed-off-by: Sergey Bashirov Reviewed-by: Christoph Hellwig Link: https://lore.kernel.org/r/20250630183537.196479-2-sergeybashirov@gmail.com Signed-off-by: Trond Myklebust Signed-off-by: Sasha Levin --- fs/nfs/blocklayout/extent_tree.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/fs/nfs/blocklayout/extent_tree.c b/fs/nfs/blocklayout/extent_tree.c index 7a57ff2528af..055ec818eaaa 100644 --- a/fs/nfs/blocklayout/extent_tree.c +++ b/fs/nfs/blocklayout/extent_tree.c @@ -552,6 +552,15 @@ static int ext_tree_encode_commit(struct pnfs_block_layout *bl, __be32 *p, return ret; } +/** + * ext_tree_prepare_commit - encode extents that need to be committed + * @arg: layout commit data + * + * Return values: + * %0: Success, all required extents are encoded + * %-ENOSPC: Some extents are encoded, but not all, due to RPC size limit + * %-ENOMEM: Out of memory, extents not encoded + */ int ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg) { @@ -568,12 +577,12 @@ ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg) start_p = page_address(arg->layoutupdate_page); arg->layoutupdate_pages = &arg->layoutupdate_page; -retry: - ret = ext_tree_encode_commit(bl, start_p + 1, buffer_size, &count, &arg->lastbytewritten); + ret = ext_tree_encode_commit(bl, start_p + 1, buffer_size, + &count, &arg->lastbytewritten); if (unlikely(ret)) { ext_tree_free_commitdata(arg, buffer_size); - buffer_size = ext_tree_layoutupdate_size(bl, count); + buffer_size = NFS_SERVER(arg->inode)->wsize; count = 0; arg->layoutupdate_pages = @@ -588,7 +597,8 @@ retry: return -ENOMEM; } - goto retry; + ret = ext_tree_encode_commit(bl, start_p + 1, buffer_size, + &count, &arg->lastbytewritten); } *start_p = cpu_to_be32(count); @@ -608,7 +618,7 @@ retry: } dprintk("%s found %zu ranges\n", __func__, count); - return 0; + return ret; } void From f3751c164156f4b99fe1d760008d389610cb8176 Mon Sep 17 00:00:00 2001 From: Meagan Lloyd Date: Wed, 11 Jun 2025 11:14:15 -0700 Subject: [PATCH 270/404] rtc: ds1307: remove clear of oscillator stop flag (OSF) in probe [ Upstream commit 48458654659c9c2e149c211d86637f1592470da5 ] In using CONFIG_RTC_HCTOSYS, rtc_hctosys() will sync the RTC time to the kernel time as long as rtc_read_time() succeeds. In some power loss situations, our supercapacitor-backed DS1342 RTC comes up with either an unpredictable future time or the default 01/01/00 from the datasheet. The oscillator stop flag (OSF) is set in these scenarios due to the power loss and can be used to determine the validity of the RTC data. Some chip types in the ds1307 driver already have OSF handling to determine whether .read_time provides valid RTC data or returns -EINVAL. This change removes the clear of the OSF in .probe as the OSF needs to be preserved to expand the OSF handling to the ds1341 chip type (note that DS1341 and DS1342 share a datasheet). Signed-off-by: Meagan Lloyd Reviewed-by: Tyler Hicks Acked-by: Rodolfo Giometti Link: https://lore.kernel.org/r/1749665656-30108-2-git-send-email-meaganlloyd@linux.microsoft.com Signed-off-by: Alexandre Belloni Signed-off-by: Sasha Levin --- drivers/rtc/rtc-ds1307.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index b371d1e48942..ff9785ff36e7 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1686,10 +1686,8 @@ static int ds1307_probe(struct i2c_client *client, regmap_write(ds1307->regmap, DS1337_REG_CONTROL, regs[0]); - /* oscillator fault? clear flag, and warn */ + /* oscillator fault? warn */ if (regs[1] & DS1337_BIT_OSF) { - regmap_write(ds1307->regmap, DS1337_REG_STATUS, - regs[1] & ~DS1337_BIT_OSF); dev_warn(ds1307->dev, "SET TIME!\n"); } break; From 896cbd432ede14b2e8119038c599c6c7ce2fd2f7 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Fri, 1 Aug 2025 18:52:02 +0000 Subject: [PATCH 271/404] scsi: lpfc: Remove redundant assignment to avoid memory leak [ Upstream commit eea6cafb5890db488fce1c69d05464214616d800 ] Remove the redundant assignment if kzalloc() succeeds to avoid memory leak. Fixes: bd2cdd5e400f ("scsi: lpfc: NVME Initiator: Add debugfs support") Signed-off-by: Jiasheng Jiang Link: https://lore.kernel.org/r/20250801185202.42631-1-jiashengjiangcool@gmail.com Reviewed-by: Justin Tee Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/lpfc/lpfc_debugfs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 291fccf02d45..f75431a948f3 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -5886,7 +5886,6 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) } phba->nvmeio_trc_on = 1; phba->nvmeio_trc_output_idx = 0; - phba->nvmeio_trc = NULL; } else { nvmeio_off: phba->nvmeio_trc_size = 0; From defdc6eef2d3ff55c661f91bdea4d3a0181b70a0 Mon Sep 17 00:00:00 2001 From: Jack Xiao Date: Mon, 11 Aug 2025 15:20:55 +0800 Subject: [PATCH 272/404] drm/amdgpu: fix incorrect vm flags to map bo [ Upstream commit 040bc6d0e0e9c814c9c663f6f1544ebaff6824a8 ] It should use vm flags instead of pte flags to specify bo vm attributes. Fixes: 7946340fa389 ("drm/amdgpu: Move csa related code to separate file") Signed-off-by: Jack Xiao Reviewed-by: Likun Gao Signed-off-by: Alex Deucher (cherry picked from commit b08425fa77ad2f305fe57a33dceb456be03b653f) Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c index 35a8d3c96fc9..2e811e963e35 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c @@ -94,8 +94,8 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, } r = amdgpu_vm_bo_map(adev, *bo_va, csa_addr, 0, size, - AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE | - AMDGPU_PTE_EXECUTABLE); + AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE | + AMDGPU_VM_PAGE_EXECUTABLE); if (r) { DRM_ERROR("failed to do bo_map on static CSA, err=%d\n", r); From 5546bf7a01bf14802ca0b9f5dbf6e656338dace8 Mon Sep 17 00:00:00 2001 From: Ricky Wu Date: Fri, 11 Jul 2025 22:01:43 +0800 Subject: [PATCH 273/404] misc: rtsx: usb: Ensure mmc child device is active when card is present commit 966c5cd72be8989c8a559ddef8e8ff07a37c5eb0 upstream. When a card is present in the reader, the driver currently defers autosuspend by returning -EAGAIN during the suspend callback to trigger USB remote wakeup signaling. However, this does not guarantee that the mmc child device has been resumed, which may cause issues if it remains suspended while the card is accessible. This patch ensures that all child devices, including the mmc host controller, are explicitly resumed before returning -EAGAIN. This fixes a corner case introduced by earlier remote wakeup handling, improving reliability of runtime PM when a card is inserted. Fixes: 883a87ddf2f1 ("misc: rtsx_usb: Use USB remote wakeup signaling for card insertion detection") Cc: stable@vger.kernel.org Signed-off-by: Ricky Wu Reviewed-by: Ulf Hansson Link: https://lore.kernel.org/r/20250711140143.2105224-1-ricky_wu@realtek.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/cardreader/rtsx_usb.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/misc/cardreader/rtsx_usb.c b/drivers/misc/cardreader/rtsx_usb.c index 8acf6e6aff31..5451089f07da 100644 --- a/drivers/misc/cardreader/rtsx_usb.c +++ b/drivers/misc/cardreader/rtsx_usb.c @@ -698,6 +698,12 @@ static void rtsx_usb_disconnect(struct usb_interface *intf) } #ifdef CONFIG_PM +static int rtsx_usb_resume_child(struct device *dev, void *data) +{ + pm_request_resume(dev); + return 0; +} + static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message) { struct rtsx_ucr *ucr = @@ -713,8 +719,10 @@ static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message) mutex_unlock(&ucr->dev_mutex); /* Defer the autosuspend if card exists */ - if (val & (SD_CD | MS_CD)) + if (val & (SD_CD | MS_CD)) { + device_for_each_child(&intf->dev, NULL, rtsx_usb_resume_child); return -EAGAIN; + } } else { /* There is an ongoing operation*/ return -EAGAIN; @@ -724,12 +732,6 @@ static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message) return 0; } -static int rtsx_usb_resume_child(struct device *dev, void *data) -{ - pm_request_resume(dev); - return 0; -} - static int rtsx_usb_resume(struct usb_interface *intf) { device_for_each_child(&intf->dev, NULL, rtsx_usb_resume_child); From fe67122ba781df44a1a9716eb1dfd751321ab512 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 22 Jul 2025 16:53:16 +0100 Subject: [PATCH 274/404] comedi: fix race between polling and detaching commit 35b6fc51c666fc96355be5cd633ed0fe4ccf68b2 upstream. syzbot reports a use-after-free in comedi in the below link, which is due to comedi gladly removing the allocated async area even though poll requests are still active on the wait_queue_head inside of it. This can cause a use-after-free when the poll entries are later triggered or removed, as the memory for the wait_queue_head has been freed. We need to check there are no tasks queued on any of the subdevices' wait queues before allowing the device to be detached by the `COMEDI_DEVCONFIG` ioctl. Tasks will read-lock `dev->attach_lock` before adding themselves to the subdevice wait queue, so fix the problem in the `COMEDI_DEVCONFIG` ioctl handler by write-locking `dev->attach_lock` before checking that all of the subdevices are safe to be deleted. This includes testing for any sleepers on the subdevices' wait queues. It remains locked until the device has been detached. This requires the `comedi_device_detach()` function to be refactored slightly, moving the bulk of it into new function `comedi_device_detach_locked()`. Note that the refactor of `comedi_device_detach()` results in `comedi_device_cancel_all()` now being called while `dev->attach_lock` is write-locked, which wasn't the case previously, but that does not matter. Thanks to Jens Axboe for diagnosing the problem and co-developing this patch. Cc: stable Fixes: 2f3fdcd7ce93 ("staging: comedi: add rw_semaphore to protect against device detachment") Link: https://lore.kernel.org/all/687bd5fe.a70a0220.693ce.0091.GAE@google.com/ Reported-by: syzbot+01523a0ae5600aef5895@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=01523a0ae5600aef5895 Co-developed-by: Jens Axboe Signed-off-by: Jens Axboe Signed-off-by: Ian Abbott Tested-by: Jens Axboe Link: https://lore.kernel.org/r/20250722155316.27432-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 33 ++++++++++++++++++------ drivers/staging/comedi/comedi_internal.h | 1 + drivers/staging/comedi/drivers.c | 13 +++++++--- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 8b2337f8303d..9d1db83209e2 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -781,6 +781,7 @@ static int is_device_busy(struct comedi_device *dev) struct comedi_subdevice *s; int i; + lockdep_assert_held_write(&dev->attach_lock); lockdep_assert_held(&dev->mutex); if (!dev->attached) return 0; @@ -789,7 +790,16 @@ static int is_device_busy(struct comedi_device *dev) s = &dev->subdevices[i]; if (s->busy) return 1; - if (s->async && comedi_buf_is_mmapped(s)) + if (!s->async) + continue; + if (comedi_buf_is_mmapped(s)) + return 1; + /* + * There may be tasks still waiting on the subdevice's wait + * queue, although they should already be about to be removed + * from it since the subdevice has no active async command. + */ + if (wq_has_sleeper(&s->async->wait_head)) return 1; } @@ -819,15 +829,22 @@ static int do_devconfig_ioctl(struct comedi_device *dev, return -EPERM; if (!arg) { - if (is_device_busy(dev)) - return -EBUSY; - if (dev->attached) { - struct module *driver_module = dev->driver->module; + int rc = 0; - comedi_device_detach(dev); - module_put(driver_module); + if (dev->attached) { + down_write(&dev->attach_lock); + if (is_device_busy(dev)) { + rc = -EBUSY; + } else { + struct module *driver_module = + dev->driver->module; + + comedi_device_detach_locked(dev); + module_put(driver_module); + } + up_write(&dev->attach_lock); } - return 0; + return rc; } if (copy_from_user(&it, arg, sizeof(it))) diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h index 515f293a5d26..43599c1b97b7 100644 --- a/drivers/staging/comedi/comedi_internal.h +++ b/drivers/staging/comedi/comedi_internal.h @@ -50,6 +50,7 @@ extern struct mutex comedi_drivers_list_lock; int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); +void comedi_device_detach_locked(struct comedi_device *dev); void comedi_device_detach(struct comedi_device *dev); int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index ced660663f0d..fd098e62a308 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -159,7 +159,7 @@ static void comedi_device_detach_cleanup(struct comedi_device *dev) int i; struct comedi_subdevice *s; - lockdep_assert_held(&dev->attach_lock); + lockdep_assert_held_write(&dev->attach_lock); lockdep_assert_held(&dev->mutex); if (dev->subdevices) { for (i = 0; i < dev->n_subdevices; i++) { @@ -196,16 +196,23 @@ static void comedi_device_detach_cleanup(struct comedi_device *dev) comedi_clear_hw_dev(dev); } -void comedi_device_detach(struct comedi_device *dev) +void comedi_device_detach_locked(struct comedi_device *dev) { + lockdep_assert_held_write(&dev->attach_lock); lockdep_assert_held(&dev->mutex); comedi_device_cancel_all(dev); - down_write(&dev->attach_lock); dev->attached = false; dev->detach_count++; if (dev->driver) dev->driver->detach(dev); comedi_device_detach_cleanup(dev); +} + +void comedi_device_detach(struct comedi_device *dev) +{ + lockdep_assert_held(&dev->mutex); + down_write(&dev->attach_lock); + comedi_device_detach_locked(dev); up_write(&dev->attach_lock); } From 0a364524871141649527ed6725efe5de19b48514 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 20 Jul 2025 22:01:36 -0700 Subject: [PATCH 275/404] thunderbolt: Fix copy+paste error in match_service_id() commit 5cc1f66cb23cccc704e3def27ad31ed479e934a5 upstream. The second instance of TBSVC_MATCH_PROTOCOL_VERSION seems to have been intended to be TBSVC_MATCH_PROTOCOL_REVISION. Fixes: d1ff70241a27 ("thunderbolt: Add support for XDomain discovery protocol") Cc: stable Signed-off-by: Eric Biggers Link: https://lore.kernel.org/r/20250721050136.30004-1-ebiggers@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/thunderbolt/domain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c index b7980c856898..43d0e50cd5bf 100644 --- a/drivers/thunderbolt/domain.c +++ b/drivers/thunderbolt/domain.c @@ -38,7 +38,7 @@ static bool match_service_id(const struct tb_service_id *id, return false; } - if (id->match_flags & TBSVC_MATCH_PROTOCOL_VERSION) { + if (id->match_flags & TBSVC_MATCH_PROTOCOL_REVISION) { if (id->protocol_revision != svc->prtcrevs) return false; } From 7684e16e724c76e0152fd8ab57e77c57120728a4 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Wed, 30 Jul 2025 19:18:37 +0100 Subject: [PATCH 276/404] btrfs: fix log tree replay failure due to file with 0 links and extents commit 0a32e4f0025a74c70dcab4478e9b29c22f5ecf2f upstream. If we log a new inode (not persisted in a past transaction) that has 0 links and extents, then log another inode with an higher inode number, we end up with failing to replay the log tree with -EINVAL. The steps for this are: 1) create new file A 2) write some data to file A 3) open an fd on file A 4) unlink file A 5) fsync file A using the previously open fd 6) create file B (has higher inode number than file A) 7) fsync file B 8) power fail before current transaction commits Now when attempting to mount the fs, the log replay will fail with -ENOENT at replay_one_extent() when attempting to replay the first extent of file A. The failure comes when trying to open the inode for file A in the subvolume tree, since it doesn't exist. Before commit 5f61b961599a ("btrfs: fix inode lookup error handling during log replay"), the returned error was -EIO instead of -ENOENT, since we converted any errors when attempting to read an inode during log replay to -EIO. The reason for this is that the log replay procedure fails to ignore the current inode when we are at the stage LOG_WALK_REPLAY_ALL, our current inode has 0 links and last inode we processed in the previous stage has a non 0 link count. In other words, the issue is that at replay_one_extent() we only update wc->ignore_cur_inode if the current replay stage is LOG_WALK_REPLAY_INODES. Fix this by updating wc->ignore_cur_inode whenever we find an inode item regardless of the current replay stage. This is a simple solution and easy to backport, but later we can do other alternatives like avoid logging extents or inode items other than the inode item for inodes with a link count of 0. The problem with the wc->ignore_cur_inode logic has been around since commit f2d72f42d5fa ("Btrfs: fix warning when replaying log after fsync of a tmpfile") but it only became frequent to hit since the more recent commit 5e85262e542d ("btrfs: fix fsync of files with no hard links not persisting deletion"), because we stopped skipping inodes with a link count of 0 when logging, while before the problem would only be triggered if trying to replay a log tree created with an older kernel which has a logged inode with 0 links. A test case for fstests will be submitted soon. Reported-by: Peter Jung Link: https://lore.kernel.org/linux-btrfs/fce139db-4458-4788-bb97-c29acf6cb1df@cachyos.org/ Reported-by: burneddi Link: https://lore.kernel.org/linux-btrfs/lh4W-Lwc0Mbk-QvBhhQyZxf6VbM3E8VtIvU3fPIQgweP_Q1n7wtlUZQc33sYlCKYd-o6rryJQfhHaNAOWWRKxpAXhM8NZPojzsJPyHMf2qY=@protonmail.com/#t Reported-by: Russell Haley Link: https://lore.kernel.org/linux-btrfs/598ecc75-eb80-41b3-83c2-f2317fbb9864@gmail.com/ Fixes: f2d72f42d5fa ("Btrfs: fix warning when replaying log after fsync of a tmpfile") CC: stable@vger.kernel.org # 5.4+ Reviewed-by: Boris Burkov Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/tree-log.c | 48 ++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 75bf490cd732..133ad448a9ad 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -274,8 +274,7 @@ struct walk_control { /* * Ignore any items from the inode currently being processed. Needs - * to be set every time we find a BTRFS_INODE_ITEM_KEY and we are in - * the LOG_WALK_REPLAY_INODES stage. + * to be set every time we find a BTRFS_INODE_ITEM_KEY. */ bool ignore_cur_inode; @@ -2604,23 +2603,30 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb, nritems = btrfs_header_nritems(eb); for (i = 0; i < nritems; i++) { + struct btrfs_inode_item *inode_item; + btrfs_item_key_to_cpu(eb, &key, i); - /* inode keys are done during the first stage */ - if (key.type == BTRFS_INODE_ITEM_KEY && - wc->stage == LOG_WALK_REPLAY_INODES) { - struct btrfs_inode_item *inode_item; - u32 mode; - - inode_item = btrfs_item_ptr(eb, i, - struct btrfs_inode_item); + if (key.type == BTRFS_INODE_ITEM_KEY) { + inode_item = btrfs_item_ptr(eb, i, struct btrfs_inode_item); /* - * If we have a tmpfile (O_TMPFILE) that got fsync'ed - * and never got linked before the fsync, skip it, as - * replaying it is pointless since it would be deleted - * later. We skip logging tmpfiles, but it's always - * possible we are replaying a log created with a kernel - * that used to log tmpfiles. + * An inode with no links is either: + * + * 1) A tmpfile (O_TMPFILE) that got fsync'ed and never + * got linked before the fsync, skip it, as replaying + * it is pointless since it would be deleted later. + * We skip logging tmpfiles, but it's always possible + * we are replaying a log created with a kernel that + * used to log tmpfiles; + * + * 2) A non-tmpfile which got its last link deleted + * while holding an open fd on it and later got + * fsynced through that fd. We always log the + * parent inodes when inode->last_unlink_trans is + * set to the current transaction, so ignore all the + * inode items for this inode. We will delete the + * inode when processing the parent directory with + * replay_dir_deletes(). */ if (btrfs_inode_nlink(eb, inode_item) == 0) { wc->ignore_cur_inode = true; @@ -2628,8 +2634,14 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb, } else { wc->ignore_cur_inode = false; } - ret = replay_xattr_deletes(wc->trans, root, log, - path, key.objectid); + } + + /* Inode keys are done during the first stage. */ + if (key.type == BTRFS_INODE_ITEM_KEY && + wc->stage == LOG_WALK_REPLAY_INODES) { + u32 mode; + + ret = replay_xattr_deletes(wc->trans, root, log, path, key.objectid); if (ret) break; mode = btrfs_inode_mode(eb, inode_item); From 8987732aaac685bbdde20bf923f9209b9e457a82 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 25 Jun 2025 00:39:33 -0700 Subject: [PATCH 277/404] parisc: Makefile: fix a typo in palo.conf commit 963f1b20a8d2a098954606b9725cd54336a2a86c upstream. Correct "objree" to "objtree". "objree" is not defined. Fixes: 75dd47472b92 ("kbuild: remove src and obj from the top Makefile") Signed-off-by: Randy Dunlap Cc: Masahiro Yamada Cc: "James E.J. Bottomley" Cc: Helge Deller Cc: linux-parisc@vger.kernel.org Signed-off-by: Helge Deller Cc: stable@vger.kernel.org # v5.3+ Signed-off-by: Greg Kroah-Hartman --- arch/parisc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 04460c2d2f8c..f5c8e3485c63 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -134,7 +134,7 @@ palo lifimage: vmlinuz fi @if test ! -f "$(PALOCONF)"; then \ cp $(srctree)/arch/parisc/defpalo.conf $(objtree)/palo.conf; \ - echo 'A generic palo config file ($(objree)/palo.conf) has been created for you.'; \ + echo 'A generic palo config file ($(objtree)/palo.conf) has been created for you.'; \ echo 'You should check it and re-run "make palo".'; \ echo 'WARNING: the "lifimage" file is now placed in this directory by default!'; \ false; \ From 9f1f4e95031f84867c5821540466d62f88dab8ca Mon Sep 17 00:00:00 2001 From: Waiman Long Date: Mon, 28 Jul 2025 15:02:48 -0400 Subject: [PATCH 278/404] mm/kmemleak: avoid soft lockup in __kmemleak_do_cleanup() commit d1534ae23c2b6be350c8ab060803fbf6e9682adc upstream. A soft lockup warning was observed on a relative small system x86-64 system with 16 GB of memory when running a debug kernel with kmemleak enabled. watchdog: BUG: soft lockup - CPU#8 stuck for 33s! [kworker/8:1:134] The test system was running a workload with hot unplug happening in parallel. Then kemleak decided to disable itself due to its inability to allocate more kmemleak objects. The debug kernel has its CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE set to 40,000. The soft lockup happened in kmemleak_do_cleanup() when the existing kmemleak objects were being removed and deleted one-by-one in a loop via a workqueue. In this particular case, there are at least 40,000 objects that need to be processed and given the slowness of a debug kernel and the fact that a raw_spinlock has to be acquired and released in __delete_object(), it could take a while to properly handle all these objects. As kmemleak has been disabled in this case, the object removal and deletion process can be further optimized as locking isn't really needed. However, it is probably not worth the effort to optimize for such an edge case that should rarely happen. So the simple solution is to call cond_resched() at periodic interval in the iteration loop to avoid soft lockup. Link: https://lkml.kernel.org/r/20250728190248.605750-1-longman@redhat.com Signed-off-by: Waiman Long Acked-by: Catalin Marinas Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/kmemleak.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mm/kmemleak.c b/mm/kmemleak.c index d8cde7292bf9..f1e0214942c0 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -1849,6 +1849,7 @@ static const struct file_operations kmemleak_fops = { static void __kmemleak_do_cleanup(void) { struct kmemleak_object *object, *tmp; + unsigned int cnt = 0; /* * Kmemleak has already been disabled, no need for RCU list traversal @@ -1857,6 +1858,10 @@ static void __kmemleak_do_cleanup(void) list_for_each_entry_safe(object, tmp, &object_list, object_list) { __remove_object(object); __delete_object(object); + + /* Call cond_resched() once per 64 iterations to avoid soft lockup */ + if (!(++cnt & 0x3f)) + cond_resched(); } } From 9ad554217c9b945031c73df4e8176a475e2dea57 Mon Sep 17 00:00:00 2001 From: Youngjun Lee Date: Tue, 10 Jun 2025 21:41:07 +0900 Subject: [PATCH 279/404] media: uvcvideo: Fix 1-byte out-of-bounds read in uvc_parse_format() commit 782b6a718651eda3478b1824b37a8b3185d2740c upstream. The buffer length check before calling uvc_parse_format() only ensured that the buffer has at least 3 bytes (buflen > 2), buf the function accesses buffer[3], requiring at least 4 bytes. This can lead to an out-of-bounds read if the buffer has exactly 3 bytes. Fix it by checking that the buffer has at least 4 bytes in uvc_parse_format(). Signed-off-by: Youngjun Lee Reviewed-by: Laurent Pinchart Fixes: c0efd232929c ("V4L/DVB (8145a): USB Video Class driver") Cc: stable@vger.kernel.org Reviewed-by: Ricardo Ribalda Link: https://lore.kernel.org/r/20250610124107.37360-1-yjjuny.lee@samsung.com Signed-off-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/uvc/uvc_driver.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 2c2ceb50500c..c0a8344c5533 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -452,6 +452,9 @@ static int uvc_parse_format(struct uvc_device *dev, unsigned int i, n; u8 ftype; + if (buflen < 4) + return -EINVAL; + format->type = buffer[2]; format->index = buffer[3]; From 17b95626ad390a9daf599423ef85358b34a6c7fd Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Mon, 7 Jul 2025 18:34:01 +0000 Subject: [PATCH 280/404] media: uvcvideo: Do not mark valid metadata as invalid commit bda2859bff0b9596a19648f3740c697ce4c71496 upstream. Currently, the driver performs a length check of the metadata buffer before the actual metadata size is known and before the metadata is decided to be copied. This results in valid metadata buffers being incorrectly marked as invalid. Move the length check to occur after the metadata size is determined and is decided to be copied. Cc: stable@vger.kernel.org Fixes: 088ead255245 ("media: uvcvideo: Add a metadata device node") Reviewed-by: Laurent Pinchart Reviewed-by: Hans de Goede Signed-off-by: Ricardo Ribalda Link: https://lore.kernel.org/r/20250707-uvc-meta-v8-1-ed17f8b1218b@chromium.org Signed-off-by: Hans de Goede Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/uvc/uvc_video.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index d1510c1230d9..40f1a1a5ea28 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -1309,12 +1309,6 @@ static void uvc_video_decode_meta(struct uvc_streaming *stream, if (!meta_buf || length == 2) return; - if (meta_buf->length - meta_buf->bytesused < - length + sizeof(meta->ns) + sizeof(meta->sof)) { - meta_buf->error = 1; - return; - } - has_pts = mem[1] & UVC_STREAM_PTS; has_scr = mem[1] & UVC_STREAM_SCR; @@ -1335,6 +1329,12 @@ static void uvc_video_decode_meta(struct uvc_streaming *stream, !memcmp(scr, stream->clock.last_scr, 6))) return; + if (meta_buf->length - meta_buf->bytesused < + length + sizeof(meta->ns) + sizeof(meta->sof)) { + meta_buf->error = 1; + return; + } + meta = (struct uvc_meta_buf *)((u8 *)meta_buf->mem + meta_buf->bytesused); local_irq_save(flags); time = uvc_video_get_time(); From 0b882f00655afefbc7729c6b5aec86f7a5473a3d Mon Sep 17 00:00:00 2001 From: Yunhui Cui Date: Wed, 23 Jul 2025 10:33:22 +0800 Subject: [PATCH 281/404] serial: 8250: fix panic due to PSLVERR commit 7f8fdd4dbffc05982b96caf586f77a014b2a9353 upstream. When the PSLVERR_RESP_EN parameter is set to 1, the device generates an error response if an attempt is made to read an empty RBR (Receive Buffer Register) while the FIFO is enabled. In serial8250_do_startup(), calling serial_port_out(port, UART_LCR, UART_LCR_WLEN8) triggers dw8250_check_lcr(), which invokes dw8250_force_idle() and serial8250_clear_and_reinit_fifos(). The latter function enables the FIFO via serial_out(p, UART_FCR, p->fcr). Execution proceeds to the serial_port_in(port, UART_RX). This satisfies the PSLVERR trigger condition. When another CPU (e.g., using printk()) is accessing the UART (UART is busy), the current CPU fails the check (value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR) in dw8250_check_lcr(), causing it to enter dw8250_force_idle(). Put serial_port_out(port, UART_LCR, UART_LCR_WLEN8) under the port->lock to fix this issue. Panic backtrace: [ 0.442336] Oops - unknown exception [#1] [ 0.442343] epc : dw8250_serial_in32+0x1e/0x4a [ 0.442351] ra : serial8250_do_startup+0x2c8/0x88e ... [ 0.442416] console_on_rootfs+0x26/0x70 Fixes: c49436b657d0 ("serial: 8250_dw: Improve unwritable LCR workaround") Link: https://lore.kernel.org/all/84cydt5peu.fsf@jogness.linutronix.de/T/ Signed-off-by: Yunhui Cui Reviewed-by: John Ogness Cc: stable Link: https://lore.kernel.org/r/20250723023322.464-2-cuiyunhui@bytedance.com [ Applied fix to serial8250_do_startup() instead of serial8250_initialize() ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 6b3ff20a0656..010c6be83ae1 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2296,9 +2296,8 @@ int serial8250_do_startup(struct uart_port *port) /* * Now, initialize the UART */ - serial_port_out(port, UART_LCR, UART_LCR_WLEN8); - spin_lock_irqsave(&port->lock, flags); + serial_port_out(port, UART_LCR, UART_LCR_WLEN8); if (up->port.flags & UPF_FOURPORT) { if (!up->port.irq) up->port.mctrl |= TIOCM_OUT1; From 8f5a65f5268abcd2a55b8020a0be21d1e02f1401 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 1 Jul 2025 17:30:01 -0500 Subject: [PATCH 282/404] cpufreq: armada-8k: Fix off by one in armada_8k_cpufreq_free_table() commit 4a26df233266a628157d7f0285451d8655defdfc upstream. The freq_tables[] array has num_possible_cpus() elements so, to avoid an out of bounds access, this loop should be capped at "< nb_cpus" instead of "<= nb_cpus". The freq_tables[] array is allocated in armada_8k_cpufreq_init(). Cc: stable@vger.kernel.org Fixes: f525a670533d ("cpufreq: ap806: add cpufreq driver for Armada 8K") Signed-off-by: Dan Carpenter Signed-off-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/armada-8k-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/armada-8k-cpufreq.c b/drivers/cpufreq/armada-8k-cpufreq.c index b0fc5e84f857..cab86a9be6bd 100644 --- a/drivers/cpufreq/armada-8k-cpufreq.c +++ b/drivers/cpufreq/armada-8k-cpufreq.c @@ -96,7 +96,7 @@ static void armada_8k_cpufreq_free_table(struct freq_table *freq_tables) { int opps_index, nb_cpus = num_possible_cpus(); - for (opps_index = 0 ; opps_index <= nb_cpus; opps_index++) { + for (opps_index = 0 ; opps_index < nb_cpus; opps_index++) { int i; /* If cpu_dev is NULL then we reached the end of the array */ From d1401dee656af19e63a7892783c4bc1954389742 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Fri, 28 Mar 2025 09:39:55 +1100 Subject: [PATCH 283/404] m68k: Fix lost column on framebuffer debug console commit 210a1ce8ed4391b64a888b3fb4b5611a13f5ccc7 upstream. Move the cursor position rightward after rendering the character, not before. This avoids complications that arise when the recursive console_putc call has to wrap the line and/or scroll the display. This also fixes the linewrap bug that crops off the rightmost column. When the cursor is at the bottom of the display, a linefeed will not move the cursor position further downward. Instead, the display scrolls upward. Avoid the repeated add/subtract sequence by way of a single subtraction at the initialization of console_struct_num_rows. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Finn Thain Tested-by: Stan Johnson Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/9d4e8c68a456d5f2bc254ac6f87a472d066ebd5e.1743115195.git.fthain@linux-m68k.org Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- arch/m68k/kernel/head.S | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S index 692cdcfb3520..41e34817bd02 100644 --- a/arch/m68k/kernel/head.S +++ b/arch/m68k/kernel/head.S @@ -3379,6 +3379,7 @@ L(console_clear_loop): movel %d4,%d1 /* screen height in pixels */ divul %a0@(FONT_DESC_HEIGHT),%d1 /* d1 = max num rows */ + subql #1,%d1 /* row range is 0 to num - 1 */ movel %d0,%a2@(Lconsole_struct_num_columns) movel %d1,%a2@(Lconsole_struct_num_rows) @@ -3525,15 +3526,14 @@ func_start console_putc,%a0/%a1/%d0-%d7 cmpib #10,%d7 jne L(console_not_lf) movel %a0@(Lconsole_struct_cur_row),%d0 - addil #1,%d0 - movel %d0,%a0@(Lconsole_struct_cur_row) movel %a0@(Lconsole_struct_num_rows),%d1 cmpl %d1,%d0 jcs 1f - subil #1,%d0 - movel %d0,%a0@(Lconsole_struct_cur_row) console_scroll + jra L(console_exit) 1: + addql #1,%d0 + movel %d0,%a0@(Lconsole_struct_cur_row) jra L(console_exit) L(console_not_lf): @@ -3560,12 +3560,6 @@ L(console_not_cr): */ L(console_not_home): movel %a0@(Lconsole_struct_cur_column),%d0 - addql #1,%a0@(Lconsole_struct_cur_column) - movel %a0@(Lconsole_struct_num_columns),%d1 - cmpl %d1,%d0 - jcs 1f - console_putc #'\n' /* recursion is OK! */ -1: movel %a0@(Lconsole_struct_cur_row),%d1 /* @@ -3612,6 +3606,23 @@ L(console_do_font_scanline): addq #1,%d1 dbra %d7,L(console_read_char_scanline) + /* + * Register usage in the code below: + * a0 = pointer to console globals + * d0 = cursor column + * d1 = cursor column limit + */ + + lea %pc@(L(console_globals)),%a0 + + movel %a0@(Lconsole_struct_cur_column),%d0 + addql #1,%d0 + movel %d0,%a0@(Lconsole_struct_cur_column) /* Update cursor pos */ + movel %a0@(Lconsole_struct_num_columns),%d1 + cmpl %d1,%d0 + jcs L(console_exit) + console_putc #'\n' /* Line wrap using tail recursion */ + L(console_exit): func_return console_putc From c280a4427add5c483bb63e7afe770e16d34995e9 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 22 Jul 2025 12:11:18 -0700 Subject: [PATCH 284/404] usb: atm: cxacru: Merge cxacru_upload_firmware() into cxacru_heavy_init() commit 8d1b02e5d7e3a6d2acffb1f4c094678fda9e3456 upstream. After a recent change in clang to expose uninitialized warnings from const variables [1], there is a warning in cxacru_heavy_init(): drivers/usb/atm/cxacru.c:1104:6: error: variable 'bp' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized] 1104 | if (instance->modem_type->boot_rom_patch) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/usb/atm/cxacru.c:1113:39: note: uninitialized use occurs here 1113 | cxacru_upload_firmware(instance, fw, bp); | ^~ drivers/usb/atm/cxacru.c:1104:2: note: remove the 'if' if its condition is always true 1104 | if (instance->modem_type->boot_rom_patch) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/usb/atm/cxacru.c:1095:32: note: initialize the variable 'bp' to silence this warning 1095 | const struct firmware *fw, *bp; | ^ | = NULL While the warning is technically correct that bp is conditionally passed uninitialized to cxacru_upload_firmware(), it is ultimately a false positive warning on the uninitialized use of bp because the same condition that initializes bp, instance->modem_type->boot_rom_patch, is the same one that gates the use of bp within cxacru_upload_firmware(). As this warning occurs in clang's frontend before inlining occurs, it cannot know that these conditions are indentical to avoid the warning. Manually inline cxacru_upload_firmware() into cxacru_heavy_init(), as that is its only callsite, so that clang can see that bp is initialized and used under the same condition, clearing up the warning without any functional changes to the code (LLVM was already doing this inlining later). Cc: stable@vger.kernel.org Fixes: 1b0e61465234 ("[PATCH] USB ATM: driver for the Conexant AccessRunner chipset cxacru") Closes: https://github.com/ClangBuiltLinux/linux/issues/2102 Link: https://github.com/llvm/llvm-project/commit/2464313eef01c5b1edf0eccf57a32cdee01472c7 [1] Signed-off-by: Nathan Chancellor Link: https://lore.kernel.org/r/20250722-usb-cxacru-fix-clang-21-uninit-warning-v2-1-6708a18decd2@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/cxacru.c | 172 +++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 90 deletions(-) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index a4d863f6cda7..58e5bc574e6a 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -984,94 +984,6 @@ cleanup: return ret; } -static void cxacru_upload_firmware(struct cxacru_data *instance, - const struct firmware *fw, - const struct firmware *bp) -{ - int ret; - struct usbatm_data *usbatm = instance->usbatm; - struct usb_device *usb_dev = usbatm->usb_dev; - __le16 signature[] = { usb_dev->descriptor.idVendor, - usb_dev->descriptor.idProduct }; - __le32 val; - - usb_dbg(usbatm, "%s\n", __func__); - - /* FirmwarePllFClkValue */ - val = cpu_to_le32(instance->modem_type->pll_f_clk); - ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4); - if (ret) { - usb_err(usbatm, "FirmwarePllFClkValue failed: %d\n", ret); - return; - } - - /* FirmwarePllBClkValue */ - val = cpu_to_le32(instance->modem_type->pll_b_clk); - ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4); - if (ret) { - usb_err(usbatm, "FirmwarePllBClkValue failed: %d\n", ret); - return; - } - - /* Enable SDRAM */ - val = cpu_to_le32(SDRAM_ENA); - ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4); - if (ret) { - usb_err(usbatm, "Enable SDRAM failed: %d\n", ret); - return; - } - - /* Firmware */ - usb_info(usbatm, "loading firmware\n"); - ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size); - if (ret) { - usb_err(usbatm, "Firmware upload failed: %d\n", ret); - return; - } - - /* Boot ROM patch */ - if (instance->modem_type->boot_rom_patch) { - usb_info(usbatm, "loading boot ROM patch\n"); - ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size); - if (ret) { - usb_err(usbatm, "Boot ROM patching failed: %d\n", ret); - return; - } - } - - /* Signature */ - ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) signature, 4); - if (ret) { - usb_err(usbatm, "Signature storing failed: %d\n", ret); - return; - } - - usb_info(usbatm, "starting device\n"); - if (instance->modem_type->boot_rom_patch) { - val = cpu_to_le32(BR_ADDR); - ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4); - } else { - ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0); - } - if (ret) { - usb_err(usbatm, "Passing control to firmware failed: %d\n", ret); - return; - } - - /* Delay to allow firmware to start up. */ - msleep_interruptible(1000); - - usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD)); - usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD)); - usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_DATA)); - usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_DATA)); - - ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0); - if (ret < 0) { - usb_err(usbatm, "modem failed to initialize: %d\n", ret); - return; - } -} static int cxacru_find_firmware(struct cxacru_data *instance, char *phase, const struct firmware **fw_p) @@ -1098,8 +1010,14 @@ static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, { const struct firmware *fw, *bp; struct cxacru_data *instance = usbatm_instance->driver_data; - int ret = cxacru_find_firmware(instance, "fw", &fw); + struct usbatm_data *usbatm = instance->usbatm; + struct usb_device *usb_dev = usbatm->usb_dev; + __le16 signature[] = { usb_dev->descriptor.idVendor, + usb_dev->descriptor.idProduct }; + __le32 val; + int ret; + ret = cxacru_find_firmware(instance, "fw", &fw); if (ret) { usb_warn(usbatm_instance, "firmware (cxacru-fw.bin) unavailable (system misconfigured?)\n"); return ret; @@ -1114,8 +1032,82 @@ static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, } } - cxacru_upload_firmware(instance, fw, bp); + /* FirmwarePllFClkValue */ + val = cpu_to_le32(instance->modem_type->pll_f_clk); + ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4); + if (ret) { + usb_err(usbatm, "FirmwarePllFClkValue failed: %d\n", ret); + goto done; + } + /* FirmwarePllBClkValue */ + val = cpu_to_le32(instance->modem_type->pll_b_clk); + ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4); + if (ret) { + usb_err(usbatm, "FirmwarePllBClkValue failed: %d\n", ret); + goto done; + } + + /* Enable SDRAM */ + val = cpu_to_le32(SDRAM_ENA); + ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4); + if (ret) { + usb_err(usbatm, "Enable SDRAM failed: %d\n", ret); + goto done; + } + + /* Firmware */ + usb_info(usbatm, "loading firmware\n"); + ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size); + if (ret) { + usb_err(usbatm, "Firmware upload failed: %d\n", ret); + goto done; + } + + /* Boot ROM patch */ + if (instance->modem_type->boot_rom_patch) { + usb_info(usbatm, "loading boot ROM patch\n"); + ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size); + if (ret) { + usb_err(usbatm, "Boot ROM patching failed: %d\n", ret); + goto done; + } + } + + /* Signature */ + ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) signature, 4); + if (ret) { + usb_err(usbatm, "Signature storing failed: %d\n", ret); + goto done; + } + + usb_info(usbatm, "starting device\n"); + if (instance->modem_type->boot_rom_patch) { + val = cpu_to_le32(BR_ADDR); + ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4); + } else { + ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0); + } + if (ret) { + usb_err(usbatm, "Passing control to firmware failed: %d\n", ret); + goto done; + } + + /* Delay to allow firmware to start up. */ + msleep_interruptible(1000); + + usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD)); + usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD)); + usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_DATA)); + usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_DATA)); + + ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0); + if (ret < 0) { + usb_err(usbatm, "modem failed to initialize: %d\n", ret); + goto done; + } + +done: if (instance->modem_type->boot_rom_patch) release_firmware(bp); release_firmware(fw); From 22ac4969dc37afff0bb8e2f978fae6dcfc5939bf Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 24 Jul 2025 11:19:08 +0200 Subject: [PATCH 285/404] usb: gadget: udc: renesas_usb3: fix device leak at unbind commit 868837b0a94c6b1b1fdbc04d3ba218ca83432393 upstream. Make sure to drop the reference to the companion device taken during probe when the driver is unbound. Fixes: 39facfa01c9f ("usb: gadget: udc: renesas_usb3: Add register of usb role switch") Cc: stable@vger.kernel.org # 4.19 Cc: Yoshihiro Shimoda Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20250724091910.21092-4-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/renesas_usb3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 2952e5feb2ee..90114c09a711 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -2551,6 +2551,7 @@ static int renesas_usb3_remove(struct platform_device *pdev) struct renesas_usb3 *usb3 = platform_get_drvdata(pdev); debugfs_remove_recursive(usb3->dentry); + put_device(usb3->host_dev); device_remove_file(&pdev->dev, &dev_attr_role); cancel_work_sync(&usb3->role_work); From 57df8e2a67f70a5ad20d148f298a9a1d3b525edc Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 24 Jul 2025 11:19:07 +0200 Subject: [PATCH 286/404] usb: dwc3: meson-g12a: fix device leaks at unbind commit 93b400f4951404d040197943a25d6fef9f8ccabb upstream. Make sure to drop the references taken to the child devices by of_find_device_by_node() during probe on driver unbind. Fixes: c99993376f72 ("usb: dwc3: Add Amlogic G12A DWC3 glue") Cc: stable@vger.kernel.org # 5.2 Cc: Neil Armstrong Signed-off-by: Johan Hovold Reviewed-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20250724091910.21092-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/dwc3-meson-g12a.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c index 8a3ec1a951fe..9bb1edb81d6e 100644 --- a/drivers/usb/dwc3/dwc3-meson-g12a.c +++ b/drivers/usb/dwc3/dwc3-meson-g12a.c @@ -529,6 +529,9 @@ static int dwc3_meson_g12a_remove(struct platform_device *pdev) usb_role_switch_unregister(priv->role_switch); + put_device(priv->switch_desc.udc); + put_device(priv->switch_desc.usb2_port); + of_platform_depopulate(dev); for (i = 0 ; i < PHY_COUNT ; ++i) { From 4a00513483a4e0a03a3e4d5c15261dd6b72fad58 Mon Sep 17 00:00:00 2001 From: Myrrh Periwinkle Date: Wed, 2 Jul 2025 21:17:57 +0700 Subject: [PATCH 287/404] vt: keyboard: Don't process Unicode characters in K_OFF mode commit b1cc2092ea7a52e2c435aee6d2b1bcb773202663 upstream. We don't process Unicode characters if the virtual terminal is in raw mode, so there's no reason why we shouldn't do the same for K_OFF (especially since people would expect K_OFF to actually turn off all VT key processing). Fixes: 9fc3de9c8356 ("vt: Add virtual console keyboard mode OFF") Signed-off-by: Myrrh Periwinkle Cc: stable Reviewed-by: Jiri Slaby Link: https://lore.kernel.org/r/20250702-vt-misc-unicode-fixes-v1-1-c27e143cc2eb@qtmlabs.xyz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/keyboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 0da9e0ab045b..91abd5c11659 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -1460,7 +1460,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) rc = atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNICODE, ¶m); if (rc != NOTIFY_STOP) - if (down && !raw_mode) + if (down && !(raw_mode || kbd->kbdmode == VC_OFF)) k_unicode(vc, keysym, !down); return; } From 8526b9684b32219fea08e81c2284ccaf9bfe2b67 Mon Sep 17 00:00:00 2001 From: Myrrh Periwinkle Date: Wed, 2 Jul 2025 21:17:58 +0700 Subject: [PATCH 288/404] vt: defkeymap: Map keycodes above 127 to K_HOLE commit b43cb4ff85da5cf29c4cd351ef1d7dd8210780f7 upstream. The maximum number of keycodes got bumped to 256 a very long time ago, but the default keymaps were never adjusted to match. This is causing the kernel to interpret keycodes above 127 as U+0000 if the shipped generated keymap is used. Fix this by mapping all keycodes above 127 to K_HOLE so the kernel ignores them. The contents of this patche were generated by rerunning `loadkeys --mktable --unicode` and only including the changes to map keycodes above 127 to K_HOLE. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Myrrh Periwinkle Cc: stable Reviewed-by: Jiri Slaby Link: https://lore.kernel.org/r/20250702-vt-misc-unicode-fixes-v1-2-c27e143cc2eb@qtmlabs.xyz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/defkeymap.c_shipped | 112 +++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/drivers/tty/vt/defkeymap.c_shipped b/drivers/tty/vt/defkeymap.c_shipped index c7095fb7d2d1..14e742b0d1c2 100644 --- a/drivers/tty/vt/defkeymap.c_shipped +++ b/drivers/tty/vt/defkeymap.c_shipped @@ -23,6 +23,22 @@ u_short plain_map[NR_KEYS] = { 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; u_short shift_map[NR_KEYS] = { @@ -42,6 +58,22 @@ u_short shift_map[NR_KEYS] = { 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; u_short altgr_map[NR_KEYS] = { @@ -61,6 +93,22 @@ u_short altgr_map[NR_KEYS] = { 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; u_short ctrl_map[NR_KEYS] = { @@ -80,6 +128,22 @@ u_short ctrl_map[NR_KEYS] = { 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; u_short shift_ctrl_map[NR_KEYS] = { @@ -99,6 +163,22 @@ u_short shift_ctrl_map[NR_KEYS] = { 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; u_short alt_map[NR_KEYS] = { @@ -118,6 +198,22 @@ u_short alt_map[NR_KEYS] = { 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; u_short ctrl_alt_map[NR_KEYS] = { @@ -137,6 +233,22 @@ u_short ctrl_alt_map[NR_KEYS] = { 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; ushort *key_maps[MAX_NR_KEYMAPS] = { From 4cddd68a2d27cfe115ac4532ed9ae3052191382e Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 2 Aug 2025 21:34:37 +0200 Subject: [PATCH 289/404] Revert "vgacon: Add check for vc_origin address range in vgacon_scroll()" commit e4fc307d8e24f122402907ebf585248cad52841d upstream. This reverts commit 864f9963ec6b4b76d104d595ba28110b87158003. The patch is wrong as it checks vc_origin against vc_screenbuf, while in text mode it should compare against vga_vram_base. As such it broke VGA text scrolling, which can be reproduced like this: (1) boot a kernel that is configured to use text mode VGA-console (2) type commands: ls -l /usr/bin | less -S (3) scroll up/down with cursor-down/up keys Reported-by: Jari Ruusu Cc: stable@vger.kernel.org Cc: Yi Yang Cc: GONG Ruiqi Signed-off-by: Helge Deller Signed-off-by: Greg Kroah-Hartman --- drivers/video/console/vgacon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 6a7c0ea1184e..23f15f42e5cb 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1198,7 +1198,7 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b, c->vc_screenbuf_size - delta); c->vc_origin = vga_vram_end - c->vc_screenbuf_size; vga_rolled_over = 0; - } else if (oldo - delta >= (unsigned long)c->vc_screenbuf) + } else c->vc_origin -= delta; c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; scr_memsetw((u16 *) (c->vc_origin), c->vc_video_erase_char, From 0b92af41f7021d45f9e800e85f4806a54535a1b6 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Wed, 16 Jul 2025 19:36:42 -0600 Subject: [PATCH 290/404] ext4: check fast symlink for ea_inode correctly commit b4cc4a4077268522e3d0d34de4b2dc144e2330fa upstream. The check for a fast symlink in the presence of only an external xattr inode is incorrect. If a fast symlink does not have an xattr block (i_file_acl == 0), but does have an external xattr inode that increases inode i_blocks, then the check for a fast symlink will incorrectly fail and __ext4_iget()->ext4_ind_check_inode() will report the inode is corrupt when it "validates" i_data[] on the next read: # ln -s foo /mnt/tmp/bar # setfattr -h -n trusted.test \ -v "$(yes | head -n 4000)" /mnt/tmp/bar # umount /mnt/tmp # mount /mnt/tmp # ls -l /mnt/tmp ls: cannot access '/mnt/tmp/bar': Structure needs cleaning total 4 ? l?????????? ? ? ? ? ? bar # dmesg | tail -1 EXT4-fs error (device dm-8): __ext4_iget:5098: inode #24578: block 7303014: comm ls: invalid block (note that "block 7303014" = 0x6f6f66 = "foo" in LE order). ext4_inode_is_fast_symlink() should check the superblock EXT4_FEATURE_INCOMPAT_EA_INODE feature flag, not the inode EXT4_EA_INODE_FL, since the latter is only set on the xattr inode itself, and not on the inode that uses this xattr. Cc: stable@vger.kernel.org Fixes: fc82228a5e38 ("ext4: support fast symlinks from ext3 file systems") Signed-off-by: Andreas Dilger Reviewed-by: Li Dongyang Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin Reviewed-on: https://review.whamcloud.com/59879 Lustre-bug-id: https://jira.whamcloud.com/browse/LU-19121 Link: https://patch.msgid.link/20250717063709.757077-1-adilger@dilger.ca Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8f020c719b18..fe54c84a1df0 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -150,7 +150,7 @@ static int ext4_meta_trans_blocks(struct inode *inode, int lblocks, */ int ext4_inode_is_fast_symlink(struct inode *inode) { - if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) { + if (!ext4_has_feature_ea_inode(inode->i_sb)) { int ea_blocks = EXT4_I(inode)->i_file_acl ? EXT4_CLUSTER_SIZE(inode->i_sb) >> 9 : 0; From 4381083b7a10b8e293bfd6b21f6e48483af9e20e Mon Sep 17 00:00:00 2001 From: Ojaswin Mujoo Date: Tue, 5 Aug 2025 14:00:30 +0530 Subject: [PATCH 291/404] ext4: fix fsmap end of range reporting with bigalloc commit bae76c035bf0852844151e68098c9b7cd63ef238 upstream. With bigalloc enabled, the logic to report last extent has a bug since we try to use cluster units instead of block units. This can cause an issue where extra incorrect entries might be returned back to the user. This was flagged by generic/365 with 64k bs and -O bigalloc. ** Details of issue ** The issue was noticed on 5G 64k blocksize FS with -O bigalloc which has only 1 bg. $ xfs_io -c "fsmap -d" /mnt/scratch 0: 253:48 [0..127]: static fs metadata 128 /* sb */ 1: 253:48 [128..255]: special 102:1 128 /* gdt */ 3: 253:48 [256..383]: special 102:3 128 /* block bitmap */ 4: 253:48 [384..2303]: unknown 1920 /* flex bg empty space */ 5: 253:48 [2304..2431]: special 102:4 128 /* inode bitmap */ 6: 253:48 [2432..4351]: unknown 1920 /* flex bg empty space */ 7: 253:48 [4352..6911]: inodes 2560 8: 253:48 [6912..538623]: unknown 531712 9: 253:48 [538624..10485759]: free space 9947136 The issue can be seen with: $ xfs_io -c "fsmap -d 0 3" /mnt/scratch 0: 253:48 [0..127]: static fs metadata 128 1: 253:48 [384..2047]: unknown 1664 Only the first entry was expected to be returned but we get 2. This is because: ext4_getfsmap_datadev() first_cluster, last_cluster = 0 ... info->gfi_last = true; ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster + 1, 0, info); fsb = C2B(1) = 16 fslen = 0 ... /* Merge in any relevant extents from the meta_list */ list_for_each_entry_safe(p, tmp, &info->gfi_meta_list, fmr_list) { ... // since fsb = 16, considers all metadata which starts before 16 blockno iter 1: error = ext4_getfsmap_helper(sb, info, p); // p = sb (0,1), nop info->gfi_next_fsblk = 1 iter 2: error = ext4_getfsmap_helper(sb, info, p); // p = gdt (1,2), nop info->gfi_next_fsblk = 2 iter 3: error = ext4_getfsmap_helper(sb, info, p); // p = blk bitmap (2,3), nop info->gfi_next_fsblk = 3 iter 4: error = ext4_getfsmap_helper(sb, info, p); // p = ino bitmap (18,19) if (rec_blk > info->gfi_next_fsblk) { // (18 > 3) // emits an extra entry ** BUG ** } } Fix this by directly calling ext4_getfsmap_datadev() with a dummy record that has fmr_physical set to (end_fsb + 1) instead of last_cluster + 1. By using the block instead of cluster we get the correct behavior. Replacing ext4_getfsmap_datadev_helper() with ext4_getfsmap_helper() is okay since the gfi_lastfree and metadata checks in ext4_getfsmap_datadev_helper() are anyways redundant when we only want to emit the last allocated block of the range, as we have already taken care of emitting metadata and any last free blocks. Cc: stable@kernel.org Reported-by: Disha Goel Fixes: 4a622e4d477b ("ext4: fix FS_IOC_GETFSMAP handling") Signed-off-by: Ojaswin Mujoo Reviewed-by: Darrick J. Wong Link: https://patch.msgid.link/e7472c8535c9c5ec10f425f495366864ea12c9da.1754377641.git.ojaswin@linux.ibm.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/fsmap.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c index dfd314ee3423..f48f0e1fb60c 100644 --- a/fs/ext4/fsmap.c +++ b/fs/ext4/fsmap.c @@ -526,6 +526,7 @@ static int ext4_getfsmap_datadev(struct super_block *sb, ext4_group_t end_ag; ext4_grpblk_t first_cluster; ext4_grpblk_t last_cluster; + struct ext4_fsmap irec; int error = 0; bofs = le32_to_cpu(sbi->s_es->s_first_data_block); @@ -609,10 +610,18 @@ static int ext4_getfsmap_datadev(struct super_block *sb, goto err; } - /* Report any gaps at the end of the bg */ + /* + * The dummy record below will cause ext4_getfsmap_helper() to report + * any allocated blocks at the end of the range. + */ + irec.fmr_device = 0; + irec.fmr_physical = end_fsb + 1; + irec.fmr_length = 0; + irec.fmr_owner = EXT4_FMR_OWN_FREE; + irec.fmr_flags = 0; + info->gfi_last = true; - error = ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster + 1, - 0, info); + error = ext4_getfsmap_helper(sb, info, &irec); if (error) goto err; From 9b12755135c1cccbe609778b89eb350db5770da9 Mon Sep 17 00:00:00 2001 From: Ojaswin Mujoo Date: Tue, 5 Aug 2025 14:00:31 +0530 Subject: [PATCH 292/404] ext4: fix reserved gdt blocks handling in fsmap commit 3ffbdd1f1165f1b2d6a94d1b1aabef57120deaf7 upstream. In some cases like small FSes with no meta_bg and where the resize doesn't need extra gdt blocks as it can fit in the current one, s_reserved_gdt_blocks is set as 0, which causes fsmap to emit a 0 length entry, which is incorrect. $ mkfs.ext4 -b 65536 -O bigalloc /dev/sda 5G $ mount /dev/sda /mnt/scratch $ xfs_io -c "fsmap -d" /mnt/scartch 0: 253:48 [0..127]: static fs metadata 128 1: 253:48 [128..255]: special 102:1 128 2: 253:48 [256..255]: special 102:2 0 <---- 0 len entry 3: 253:48 [256..383]: special 102:3 128 Fix this by adding a check for this case. Cc: stable@kernel.org Fixes: 0c9ec4beecac ("ext4: support GETFSMAP ioctls") Signed-off-by: Ojaswin Mujoo Reviewed-by: Darrick J. Wong Link: https://patch.msgid.link/08781b796453a5770112aa96ad14c864fbf31935.1754377641.git.ojaswin@linux.ibm.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/fsmap.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c index f48f0e1fb60c..bdc194b8f4de 100644 --- a/fs/ext4/fsmap.c +++ b/fs/ext4/fsmap.c @@ -393,6 +393,14 @@ static unsigned int ext4_getfsmap_find_sb(struct super_block *sb, /* Reserved GDT blocks */ if (!ext4_has_feature_meta_bg(sb) || metagroup < first_meta_bg) { len = le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks); + + /* + * mkfs.ext4 can set s_reserved_gdt_blocks as 0 in some cases, + * check for that. + */ + if (!len) + return 0; + error = ext4_getfsmap_fill(meta_list, fsb, len, EXT4_FMR_OWN_RESV_GDT); if (error) From 328cb4737c0c861fff180bfbd09517198860c814 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Tue, 29 Jul 2025 18:28:07 +0900 Subject: [PATCH 293/404] ata: libata-scsi: Fix ata_to_sense_error() status handling commit cf3fc037623c54de48d2ec1a1ee686e2d1de2d45 upstream. Commit 8ae720449fca ("libata: whitespace fixes in ata_to_sense_error()") inadvertantly added the entry 0x40 (ATA_DRDY) to the stat_table array in the function ata_to_sense_error(). This entry ties a failed qc which has a status filed equal to ATA_DRDY to the sense key ILLEGAL REQUEST with the additional sense code UNALIGNED WRITE COMMAND. This entry will be used to generate a failed qc sense key and sense code when the qc is missing sense data and there is no match for the qc error field in the sense_table array of ata_to_sense_error(). As a result, for a failed qc for which we failed to get sense data (e.g. read log 10h failed if qc is an NCQ command, or REQUEST SENSE EXT command failed for the non-ncq case, the user very often end up seeing the completely misleading "unaligned write command" error, even if qc was not a write command. E.g.: sd 0:0:0:0: [sda] tag#12 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=0s sd 0:0:0:0: [sda] tag#12 Sense Key : Illegal Request [current] sd 0:0:0:0: [sda] tag#12 Add. Sense: Unaligned write command sd 0:0:0:0: [sda] tag#12 CDB: Read(10) 28 00 00 00 10 00 00 00 08 00 I/O error, dev sda, sector 4096 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 0 Fix this by removing the ATA_DRDY entry from the stat_table array so that we default to always returning ABORTED COMMAND without any additional sense code, since we do not know any better. The entry 0x08 (ATA_DRQ) is also removed since signaling ABORTED COMMAND with a parity error is also misleading (as a parity error would likely be signaled through a bus error). So for this case, also default to returning ABORTED COMMAND without any additional sense code. With this, the previous example error case becomes: sd 0:0:0:0: [sda] tag#17 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=0s sd 0:0:0:0: [sda] tag#17 Sense Key : Aborted Command [current] sd 0:0:0:0: [sda] tag#17 Add. Sense: No additional sense information sd 0:0:0:0: [sda] tag#17 CDB: Read(10) 28 00 00 00 10 00 00 00 08 00 I/O error, dev sda, sector 4096 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 0 Together with these fixes, refactor stat_table to make it more readable by putting the entries comments in front of the entries and using the defined status bits macros instead of hardcoded values. Reported-by: Lorenz Brun Reported-by: Brandon Schwartz Fixes: 8ae720449fca ("libata: whitespace fixes in ata_to_sense_error()") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal Reviewed-by: Hannes Reinecke Reviewed-by: Martin K. Petersen Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-scsi.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index c621c98c6057..35c87e7e4ddf 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -984,18 +984,14 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, {0xFF, 0xFF, 0xFF, 0xFF}, // END mark }; static const unsigned char stat_table[][4] = { - /* Must be first because BUSY means no other bits valid */ - {0x80, ABORTED_COMMAND, 0x47, 0x00}, - // Busy, fake parity for now - {0x40, ILLEGAL_REQUEST, 0x21, 0x04}, - // Device ready, unaligned write command - {0x20, HARDWARE_ERROR, 0x44, 0x00}, - // Device fault, internal target failure - {0x08, ABORTED_COMMAND, 0x47, 0x00}, - // Timed out in xfer, fake parity for now - {0x04, RECOVERED_ERROR, 0x11, 0x00}, - // Recovered ECC error Medium error, recovered - {0xFF, 0xFF, 0xFF, 0xFF}, // END mark + /* Busy: must be first because BUSY means no other bits valid */ + { ATA_BUSY, ABORTED_COMMAND, 0x00, 0x00 }, + /* Device fault: INTERNAL TARGET FAILURE */ + { ATA_DF, HARDWARE_ERROR, 0x44, 0x00 }, + /* Corrected data error */ + { ATA_CORR, RECOVERED_ERROR, 0x00, 0x00 }, + + { 0xFF, 0xFF, 0xFF, 0xFF }, /* END mark */ }; /* From 3525cec1135fc67efda1eb9093c20f8197e28d10 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 16 Jun 2025 14:09:32 +0200 Subject: [PATCH 294/404] zynq_fpga: use sgtable-based scatterlist wrappers commit 37e00703228ab44d0aacc32a97809a4f6f58df1b upstream. Use common wrappers operating directly on the struct sg_table objects to fix incorrect use of statterlists related calls. dma_unmap_sg() function has to be called with the number of elements originally passed to the dma_map_sg() function, not the one returned in sgtable's nents. CC: stable@vger.kernel.org Fixes: 425902f5c8e3 ("fpga zynq: Use the scatterlist interface") Signed-off-by: Marek Szyprowski Reviewed-by: Jason Gunthorpe Reviewed-by: Xu Yilun Link: https://lore.kernel.org/r/20250616120932.1090614-1-m.szyprowski@samsung.com Signed-off-by: Xu Yilun Signed-off-by: Greg Kroah-Hartman --- drivers/fpga/zynq-fpga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c index 31ef38e38537..733ab4056ee3 100644 --- a/drivers/fpga/zynq-fpga.c +++ b/drivers/fpga/zynq-fpga.c @@ -406,7 +406,7 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, struct sg_table *sgt) } priv->dma_nelms = - dma_map_sg(mgr->dev.parent, sgt->sgl, sgt->nents, DMA_TO_DEVICE); + dma_map_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0); if (priv->dma_nelms == 0) { dev_err(&mgr->dev, "Unable to DMA map (TO_DEVICE)\n"); return -ENOMEM; @@ -478,7 +478,7 @@ out_clk: clk_disable(priv->clk); out_free: - dma_unmap_sg(mgr->dev.parent, sgt->sgl, sgt->nents, DMA_TO_DEVICE); + dma_unmap_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0); return err; } From 1d7f9ad781e9a6ae9b459face9aa152d244a4558 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 15 Jul 2025 19:45:23 -0700 Subject: [PATCH 295/404] wifi: brcmsmac: Remove const from tbl_ptr parameter in wlc_lcnphy_common_read_table() commit 81284e86bf8849f8e98e8ead3ff5811926b2107f upstream. A new warning in clang [1] complains that diq_start in wlc_lcnphy_tx_iqlo_cal() is passed uninitialized as a const pointer to wlc_lcnphy_common_read_table(): drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c:2728:13: error: variable 'diq_start' is uninitialized when passed as a const pointer argument here [-Werror,-Wuninitialized-const-pointer] 2728 | &diq_start, 1, 16, 69); | ^~~~~~~~~ The table pointer passed to wlc_lcnphy_common_read_table() should not be considered constant, as wlc_phy_read_table() is ultimately going to update it. Remove the const qualifier from the tbl_ptr to clear up the warning. Cc: stable@vger.kernel.org Closes: https://github.com/ClangBuiltLinux/linux/issues/2108 Fixes: 5b435de0d786 ("net: wireless: add brcm80211 drivers") Link: https://github.com/llvm/llvm-project/commit/00dacf8c22f065cb52efb14cd091d441f19b319e [1] Signed-off-by: Nathan Chancellor Acked-by: Arend van Spriel > Link: https://patch.msgid.link/20250715-brcmsmac-fix-uninit-const-pointer-v1-1-16e6a51a8ef4@kernel.org Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c index 1e597e5de5f1..b4f6f8682fa9 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c @@ -974,7 +974,7 @@ void wlc_lcnphy_read_table(struct brcms_phy *pi, struct phytbl_info *pti) static void wlc_lcnphy_common_read_table(struct brcms_phy *pi, u32 tbl_id, - const u16 *tbl_ptr, u32 tbl_len, + u16 *tbl_ptr, u32 tbl_len, u32 tbl_width, u32 tbl_offset) { struct phytbl_info tab; From d198239d2cd21f2b84ff75abff428f9d62a5f145 Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Mon, 28 Jul 2025 15:41:44 -0400 Subject: [PATCH 296/404] pwm: imx-tpm: Reset counter if CMOD is 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 65c6f742ab14ab1a2679fba72b82dcc0289d96f1 upstream. As per the i.MX93 TRM, section 67.3.2.1 "MOD register update", the value of the TPM counter does NOT get updated when writing MOD.MOD unless SC.CMOD != 0. Therefore, with the current code, assuming the following sequence: 1) pwm_disable() 2) pwm_apply_might_sleep() /* period is changed here */ 3) pwm_enable() and assuming only one channel is active, if CNT.COUNT is higher than the MOD.MOD value written during the pwm_apply_might_sleep() call then, when re-enabling the PWM during pwm_enable(), the counter will end up resetting after UINT32_MAX - CNT.COUNT + MOD.MOD cycles instead of MOD.MOD cycles as normally expected. Fix this problem by forcing a reset of the TPM counter before MOD.MOD is written. Fixes: 738a1cfec2ed ("pwm: Add i.MX TPM PWM driver support") Cc: stable@vger.kernel.org Signed-off-by: Laurentiu Mihalcea Link: https://lore.kernel.org/r/20250728194144.22884-1-laurentiumihalcea111@gmail.com Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/pwm/pwm-imx-tpm.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/pwm/pwm-imx-tpm.c b/drivers/pwm/pwm-imx-tpm.c index 77492bf0551c..f61cb8496c3a 100644 --- a/drivers/pwm/pwm-imx-tpm.c +++ b/drivers/pwm/pwm-imx-tpm.c @@ -204,6 +204,15 @@ static int pwm_imx_tpm_apply_hw(struct pwm_chip *chip, val |= FIELD_PREP(PWM_IMX_TPM_SC_PS, p->prescale); writel(val, tpm->base + PWM_IMX_TPM_SC); + /* + * if the counter is disabled (CMOD == 0), programming the new + * period length (MOD) will not reset the counter (CNT). If + * CNT.COUNT happens to be bigger than the new MOD value then + * the counter will end up being reset way too late. Therefore, + * manually reset it to 0. + */ + if (!cmod) + writel(0x0, tpm->base + PWM_IMX_TPM_CNT); /* * set period count: * if the PWM is disabled (CMOD[1:0] = 2b00), then MOD register From 4a389f6dc95840b4f7eba4e0a117f5b08992a6c2 Mon Sep 17 00:00:00 2001 From: Thomas Fourier Date: Mon, 7 Jul 2025 09:39:37 +0200 Subject: [PATCH 297/404] mtd: rawnand: fsmc: Add missing check after DMA map commit 6c4dab38431fee3d39a841d66ba6f2890b31b005 upstream. The DMA map functions can fail and should be tested for errors. Fixes: 4774fb0a48aa ("mtd: nand/fsmc: Add DMA support") Cc: stable@vger.kernel.org Signed-off-by: Thomas Fourier Rule: add Link: https://lore.kernel.org/stable/20250702065806.20983-2-fourier.thomas%40gmail.com Signed-off-by: Miquel Raynal Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/nand/raw/fsmc_nand.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c index bccadf8f27fa..c44b64542818 100644 --- a/drivers/mtd/nand/raw/fsmc_nand.c +++ b/drivers/mtd/nand/raw/fsmc_nand.c @@ -492,6 +492,8 @@ static int dma_xfer(struct fsmc_nand_data *host, void *buffer, int len, dma_dev = chan->device; dma_addr = dma_map_single(dma_dev->dev, buffer, len, direction); + if (dma_mapping_error(dma_dev->dev, dma_addr)) + return -EINVAL; if (direction == DMA_TO_DEVICE) { dma_src = dma_addr; From 80ea6e6904fb2ba4ccb5d909579988466ec65358 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Tue, 24 Jun 2025 20:45:43 +0900 Subject: [PATCH 298/404] PCI: endpoint: Fix configfs group list head handling commit d79123d79a8154b4318529b7b2ff7e15806f480b upstream. Doing a list_del() on the epf_group field of struct pci_epf_driver in pci_epf_remove_cfs() is not correct as this field is a list head, not a list entry. This list_del() call triggers a KASAN warning when an endpoint function driver which has a configfs attribute group is torn down: ================================================================== BUG: KASAN: slab-use-after-free in pci_epf_remove_cfs+0x17c/0x198 Write of size 8 at addr ffff00010f4a0d80 by task rmmod/319 CPU: 3 UID: 0 PID: 319 Comm: rmmod Not tainted 6.16.0-rc2 #1 NONE Hardware name: Radxa ROCK 5B (DT) Call trace: show_stack+0x2c/0x84 (C) dump_stack_lvl+0x70/0x98 print_report+0x17c/0x538 kasan_report+0xb8/0x190 __asan_report_store8_noabort+0x20/0x2c pci_epf_remove_cfs+0x17c/0x198 pci_epf_unregister_driver+0x18/0x30 nvmet_pci_epf_cleanup_module+0x24/0x30 [nvmet_pci_epf] __arm64_sys_delete_module+0x264/0x424 invoke_syscall+0x70/0x260 el0_svc_common.constprop.0+0xac/0x230 do_el0_svc+0x40/0x58 el0_svc+0x48/0xdc el0t_64_sync_handler+0x10c/0x138 el0t_64_sync+0x198/0x19c ... Remove this incorrect list_del() call from pci_epf_remove_cfs(). Fixes: ef1433f717a2 ("PCI: endpoint: Create configfs entry for each pci_epf_device_id table entry") Signed-off-by: Damien Le Moal Signed-off-by: Manivannan Sadhasivam Reviewed-by: Niklas Cassel Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250624114544.342159-2-dlemoal@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/pci/endpoint/pci-epf-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index fb1306de8f40..71372cef1a68 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c @@ -155,7 +155,6 @@ static void pci_epf_remove_cfs(struct pci_epf_driver *driver) mutex_lock(&pci_epf_mutex); list_for_each_entry_safe(group, tmp, &driver->epf_group, group_entry) pci_ep_cfs_remove_epf_group(group); - list_del(&driver->epf_group); mutex_unlock(&pci_epf_mutex); } From f6419ccc880c9dfe713f16fffc477b3f3f7f1650 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Tue, 24 Jun 2025 20:45:44 +0900 Subject: [PATCH 299/404] PCI: endpoint: Fix configfs group removal on driver teardown commit 910bdb8197f9322790c738bb32feaa11dba26909 upstream. An endpoint driver configfs attributes group is added to the epf_group list of struct pci_epf_driver by pci_epf_add_cfs() but an added group is not removed from this list when the attribute group is unregistered with pci_ep_cfs_remove_epf_group(). Add the missing list_del() call in pci_ep_cfs_remove_epf_group() to correctly remove the attribute group from the driver list. With this change, once the loop over all attribute groups in pci_epf_remove_cfs() completes, the driver epf_group list should be empty. Add a WARN_ON() to make sure of that. Fixes: ef1433f717a2 ("PCI: endpoint: Create configfs entry for each pci_epf_device_id table entry") Signed-off-by: Damien Le Moal Signed-off-by: Manivannan Sadhasivam Reviewed-by: Niklas Cassel Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250624114544.342159-3-dlemoal@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/pci/endpoint/pci-ep-cfs.c | 1 + drivers/pci/endpoint/pci-epf-core.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index d1288a0bd530..98d54c78f08d 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -480,6 +480,7 @@ void pci_ep_cfs_remove_epf_group(struct config_group *group) if (IS_ERR_OR_NULL(group)) return; + list_del(&group->group_entry); configfs_unregister_default_group(group); } EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group); diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index 71372cef1a68..3d76bebe96c1 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c @@ -155,6 +155,7 @@ static void pci_epf_remove_cfs(struct pci_epf_driver *driver) mutex_lock(&pci_epf_mutex); list_for_each_entry_safe(group, tmp, &driver->epf_group, group_entry) pci_ep_cfs_remove_epf_group(group); + WARN_ON(!list_empty(&driver->epf_group)); mutex_unlock(&pci_epf_mutex); } From f683d611518d30334813eecf9a8c687453e2800e Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Tue, 12 Aug 2025 14:37:52 +0800 Subject: [PATCH 300/404] jbd2: prevent softlockup in jbd2_log_do_checkpoint() commit 9d98cf4632258720f18265a058e62fde120c0151 upstream. Both jbd2_log_do_checkpoint() and jbd2_journal_shrink_checkpoint_list() periodically release j_list_lock after processing a batch of buffers to avoid long hold times on the j_list_lock. However, since both functions contend for j_list_lock, the combined time spent waiting and processing can be significant. jbd2_journal_shrink_checkpoint_list() explicitly calls cond_resched() when need_resched() is true to avoid softlockups during prolonged operations. But jbd2_log_do_checkpoint() only exits its loop when need_resched() is true, relying on potentially sleeping functions like __flush_batch() or wait_on_buffer() to trigger rescheduling. If those functions do not sleep, the kernel may hit a softlockup. watchdog: BUG: soft lockup - CPU#3 stuck for 156s! [kworker/u129:2:373] CPU: 3 PID: 373 Comm: kworker/u129:2 Kdump: loaded Not tainted 6.6.0+ #10 Hardware name: Huawei TaiShan 2280 /BC11SPCD, BIOS 1.27 06/13/2017 Workqueue: writeback wb_workfn (flush-7:2) pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : native_queued_spin_lock_slowpath+0x358/0x418 lr : jbd2_log_do_checkpoint+0x31c/0x438 [jbd2] Call trace: native_queued_spin_lock_slowpath+0x358/0x418 jbd2_log_do_checkpoint+0x31c/0x438 [jbd2] __jbd2_log_wait_for_space+0xfc/0x2f8 [jbd2] add_transaction_credits+0x3bc/0x418 [jbd2] start_this_handle+0xf8/0x560 [jbd2] jbd2__journal_start+0x118/0x228 [jbd2] __ext4_journal_start_sb+0x110/0x188 [ext4] ext4_do_writepages+0x3dc/0x740 [ext4] ext4_writepages+0xa4/0x190 [ext4] do_writepages+0x94/0x228 __writeback_single_inode+0x48/0x318 writeback_sb_inodes+0x204/0x590 __writeback_inodes_wb+0x54/0xf8 wb_writeback+0x2cc/0x3d8 wb_do_writeback+0x2e0/0x2f8 wb_workfn+0x80/0x2a8 process_one_work+0x178/0x3e8 worker_thread+0x234/0x3b8 kthread+0xf0/0x108 ret_from_fork+0x10/0x20 So explicitly call cond_resched() in jbd2_log_do_checkpoint() to avoid softlockup. Cc: stable@kernel.org Signed-off-by: Baokun Li Link: https://patch.msgid.link/20250812063752.912130-1-libaokun@huaweicloud.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/jbd2/checkpoint.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index c09d1bdffb91..faf9b98f6d5e 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -321,6 +321,7 @@ restart: retry: if (batch_count) __flush_batch(journal, &batch_count); + cond_resched(); spin_lock(&journal->j_list_lock); goto restart; } From 31f339e3c657c9d66d469e97daa8ecbc136f358e Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Thu, 31 Jul 2025 13:18:32 +0100 Subject: [PATCH 301/404] soc/tegra: pmc: Ensure power-domains are in a known state commit b6bcbce3359619d05bf387d4f5cc3af63668dbaa upstream. After commit 13a4b7fb6260 ("pmdomain: core: Leave powered-on genpds on until late_initcall_sync") was applied, the Tegra210 Jetson TX1 board failed to boot. Looking into this issue, before this commit was applied, if any of the Tegra power-domains were in 'on' state when the kernel booted, they were being turned off by the genpd core before any driver had chance to request them. This was purely by luck and a consequence of the power-domains being turned off earlier during boot. After this commit was applied, any power-domains in the 'on' state are kept on for longer during boot and therefore, may never transitioned to the off state before they are requested/used. The hang on the Tegra210 Jetson TX1 is caused because devices in some power-domains are accessed without the power-domain being turned off and on, indicating that the power-domain is not in a completely on state. >From reviewing the Tegra PMC driver code, if a power-domain is in the 'on' state there is no guarantee that all the necessary clocks associated with the power-domain are on and even if they are they would not have been requested via the clock framework and so could be turned off later. Some power-domains also have a 'clamping' register that needs to be configured as well. In short, if a power-domain is already 'on' it is difficult to know if it has been configured correctly. Given that the power-domains happened to be switched off during boot previously, to ensure that they are in a good known state on boot, fix this by switching off any power-domains that are on initially when registering the power-domains with the genpd framework. Note that commit 05cfb988a4d0 ("soc/tegra: pmc: Initialise resets associated with a power partition") updated the tegra_powergate_of_get_resets() function to pass the 'off' to ensure that the resets for the power-domain are in the correct state on boot. However, now that we may power off a domain on boot, if it is on, it is better to move this logic into the tegra_powergate_add() function so that there is a single place where we are handling the initial state of the power-domain. Fixes: a38045121bf4 ("soc/tegra: pmc: Add generic PM domain support") Signed-off-by: Jon Hunter Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250731121832.213671-1-jonathanh@nvidia.com Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/soc/tegra/pmc.c | 51 +++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index d11320a4dfcf..8023ebac671b 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -950,7 +950,7 @@ err: } static int tegra_powergate_of_get_resets(struct tegra_powergate *pg, - struct device_node *np, bool off) + struct device_node *np) { struct device *dev = pg->pmc->dev; int err; @@ -965,22 +965,6 @@ static int tegra_powergate_of_get_resets(struct tegra_powergate *pg, err = reset_control_acquire(pg->reset); if (err < 0) { pr_err("failed to acquire resets: %d\n", err); - goto out; - } - - if (off) { - err = reset_control_assert(pg->reset); - } else { - err = reset_control_deassert(pg->reset); - if (err < 0) - goto out; - - reset_control_release(pg->reset); - } - -out: - if (err) { - reset_control_release(pg->reset); reset_control_put(pg->reset); } @@ -1025,20 +1009,43 @@ static int tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) goto set_available; } - err = tegra_powergate_of_get_resets(pg, np, off); + err = tegra_powergate_of_get_resets(pg, np); if (err < 0) { dev_err(dev, "failed to get resets for %pOFn: %d\n", np, err); goto remove_clks; } - if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) { - if (off) - WARN_ON(tegra_powergate_power_up(pg, true)); + /* + * If the power-domain is off, then ensure the resets are asserted. + * If the power-domain is on, then power down to ensure that when is + * it turned on the power-domain, clocks and resets are all in the + * expected state. + */ + if (off) { + err = reset_control_assert(pg->reset); + if (err) { + pr_err("failed to assert resets: %d\n", err); + goto remove_resets; + } + } else { + err = tegra_powergate_power_down(pg); + if (err) { + dev_err(dev, "failed to turn off PM domain %s: %d\n", + pg->genpd.name, err); + goto remove_resets; + } + } + /* + * If PM_GENERIC_DOMAINS is not enabled, power-on + * the domain and skip the genpd registration. + */ + if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) { + WARN_ON(tegra_powergate_power_up(pg, true)); goto remove_resets; } - err = pm_genpd_init(&pg->genpd, NULL, off); + err = pm_genpd_init(&pg->genpd, NULL, true); if (err < 0) { dev_err(dev, "failed to initialise PM domain %pOFn: %d\n", np, err); From 21950b842fe23e75127543b6eb906f36f258a876 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 28 May 2025 23:22:14 +0300 Subject: [PATCH 302/404] media: gspca: Add bounds checking to firmware parser commit aef89c0b2417da79cb2062a95476288f9f203ab0 upstream. This sd_init() function reads the firmware. The firmware data holds a series of records and the function reads each record and sends the data to the device. The request_ihex_firmware() function calls ihex_validate_fw() which ensures that the total length of all the records won't read out of bounds of the fw->data[]. However, a potential issue is if there is a single very large record (larger than PAGE_SIZE) and that would result in memory corruption. Generally we trust the firmware, but it's always better to double check. Fixes: 49b61ec9b5af ("[media] gspca: Add new vicam subdriver") Cc: stable@vger.kernel.org Signed-off-by: Dan Carpenter Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/gspca/vicam.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/gspca/vicam.c b/drivers/media/usb/gspca/vicam.c index d98343fd33fe..91e177aa8136 100644 --- a/drivers/media/usb/gspca/vicam.c +++ b/drivers/media/usb/gspca/vicam.c @@ -227,6 +227,7 @@ static int sd_init(struct gspca_dev *gspca_dev) const struct ihex_binrec *rec; const struct firmware *fw; u8 *firmware_buf; + int len; ret = request_ihex_firmware(&fw, VICAM_FIRMWARE, &gspca_dev->dev->dev); @@ -241,9 +242,14 @@ static int sd_init(struct gspca_dev *gspca_dev) goto exit; } for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) { - memcpy(firmware_buf, rec->data, be16_to_cpu(rec->len)); + len = be16_to_cpu(rec->len); + if (len > PAGE_SIZE) { + ret = -EINVAL; + break; + } + memcpy(firmware_buf, rec->data, len); ret = vicam_control_msg(gspca_dev, 0xff, 0, 0, firmware_buf, - be16_to_cpu(rec->len)); + len); if (ret < 0) break; } From cf55b84f8d1792dee1765fc0cce7823f51b39b1c Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Thu, 27 Feb 2025 15:44:51 +0800 Subject: [PATCH 303/404] media: imx: fix a potential memory leak in imx_media_csc_scaler_device_init() commit fc5f8aec77704373ee804b5dba0e0e5029c0f180 upstream. Add video_device_release() in label 'err_m2m' to release the memory allocated by video_device_alloc() and prevent potential memory leaks. Remove the reduntant code in label 'err_m2m'. Fixes: a8ef0488cc59 ("media: imx: add csc/scaler mem2mem device") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li Reviewed-by: Dan Carpenter Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/staging/media/imx/imx-media-csc-scaler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/imx/imx-media-csc-scaler.c b/drivers/staging/media/imx/imx-media-csc-scaler.c index 135e1e64c244..dacab4e077b4 100644 --- a/drivers/staging/media/imx/imx-media-csc-scaler.c +++ b/drivers/staging/media/imx/imx-media-csc-scaler.c @@ -911,7 +911,7 @@ imx_media_csc_scaler_device_init(struct imx_media_dev *md) return &priv->vdev; err_m2m: - video_set_drvdata(vfd, NULL); + video_device_release(vfd); err_vfd: kfree(priv); return ERR_PTR(ret); From c35e7c7a004ef379a1ae7c7486d4829419acad1d Mon Sep 17 00:00:00 2001 From: Ludwig Disterhof Date: Mon, 28 Apr 2025 20:16:50 +0200 Subject: [PATCH 304/404] media: usbtv: Lock resolution while streaming commit 7e40e0bb778907b2441bff68d73c3eb6b6cd319f upstream. When an program is streaming (ffplay) and another program (qv4l2) changes the TV standard from NTSC to PAL, the kernel crashes due to trying to copy to unmapped memory. Changing from NTSC to PAL increases the resolution in the usbtv struct, but the video plane buffer isn't adjusted, so it overflows. Fixes: 0e0fe3958fdd13d ("[media] usbtv: Add support for PAL video source") Cc: stable@vger.kernel.org Signed-off-by: Ludwig Disterhof Signed-off-by: Hans Verkuil [hverkuil: call vb2_is_busy instead of vb2_is_streaming] Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/usbtv/usbtv-video.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c index b249f037900c..d62a960bb5e7 100644 --- a/drivers/media/usb/usbtv/usbtv-video.c +++ b/drivers/media/usb/usbtv/usbtv-video.c @@ -73,6 +73,10 @@ static int usbtv_configure_for_norm(struct usbtv *usbtv, v4l2_std_id norm) } if (params) { + if (vb2_is_busy(&usbtv->vb2q) && + (usbtv->width != params->cap_width || + usbtv->height != params->cap_height)) + return -EBUSY; usbtv->width = params->cap_width; usbtv->height = params->cap_height; usbtv->n_chunks = usbtv->width * usbtv->height From aca1b4f7afdcd0de4ab7d788b01ba149c6de0f91 Mon Sep 17 00:00:00 2001 From: Zhang Shurong Date: Sun, 6 Jul 2025 00:31:09 +0800 Subject: [PATCH 305/404] media: ov2659: Fix memory leaks in ov2659_probe() commit 76142b137b968d47b35cdd8d1dc924677d319c8b upstream. ov2659_probe() doesn't properly free control handler resources in failure paths, causing memory leaks. Add v4l2_ctrl_handler_free() to prevent these memory leaks and reorder the ctrl_handler assignment for better code flow. Fixes: c4c0283ab3cd ("[media] media: i2c: add support for omnivision's ov2659 sensor") Cc: stable@vger.kernel.org Signed-off-by: Zhang Shurong Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/i2c/ov2659.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index e1ff38009cf0..2d1f132a4a87 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1432,14 +1432,15 @@ static int ov2659_probe(struct i2c_client *client) V4L2_CID_TEST_PATTERN, ARRAY_SIZE(ov2659_test_pattern_menu) - 1, 0, 0, ov2659_test_pattern_menu); - ov2659->sd.ctrl_handler = &ov2659->ctrls; if (ov2659->ctrls.error) { dev_err(&client->dev, "%s: control initialization error %d\n", __func__, ov2659->ctrls.error); + v4l2_ctrl_handler_free(&ov2659->ctrls); return ov2659->ctrls.error; } + ov2659->sd.ctrl_handler = &ov2659->ctrls; sd = &ov2659->sd; client->flags |= I2C_CLIENT_SCCB; #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API From 0520c89f6280d2b60ab537d5743601185ee7d8ab Mon Sep 17 00:00:00 2001 From: Vedang Nagar Date: Mon, 19 May 2025 12:42:21 +0530 Subject: [PATCH 306/404] media: venus: Add a check for packet size after reading from shared memory commit 49befc830daa743e051a65468c05c2ff9e8580e6 upstream. Add a check to ensure that the packet size does not exceed the number of available words after reading the packet header from shared memory. This ensures that the size provided by the firmware is safe to process and prevent potential out-of-bounds memory access. Fixes: d96d3f30c0f2 ("[media] media: venus: hfi: add Venus HFI files") Cc: stable@vger.kernel.org Signed-off-by: Vedang Nagar Co-developed-by: Dikshita Agarwal Signed-off-by: Dikshita Agarwal Reviewed-by: Bryan O'Donoghue Signed-off-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/qcom/venus/hfi_venus.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c index 1b37d77bf998..33d9d50e79cd 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus.c +++ b/drivers/media/platform/qcom/venus/hfi_venus.c @@ -240,6 +240,7 @@ static int venus_write_queue(struct venus_hfi_device *hdev, static int venus_read_queue(struct venus_hfi_device *hdev, struct iface_queue *queue, void *pkt, u32 *tx_req) { + struct hfi_pkt_hdr *pkt_hdr = NULL; struct hfi_queue_header *qhdr; u32 dwords, new_rd_idx; u32 rd_idx, wr_idx, type, qsize; @@ -305,6 +306,9 @@ static int venus_read_queue(struct venus_hfi_device *hdev, memcpy(pkt, rd_ptr, len); memcpy(pkt + len, queue->qmem.kva, new_rd_idx << 2); } + pkt_hdr = (struct hfi_pkt_hdr *)(pkt); + if ((pkt_hdr->size >> 2) != dwords) + return -EINVAL; } else { /* bad packet received, dropping */ new_rd_idx = qhdr->write_idx; From c4ebc06918f8d07a7ee6d149604c109eacde8df8 Mon Sep 17 00:00:00 2001 From: Jiayi Li Date: Mon, 4 Aug 2025 09:36:04 +0800 Subject: [PATCH 307/404] memstick: Fix deadlock by moving removing flag earlier commit 99d7ab8db9d8230b243f5ed20ba0229e54cc0dfa upstream. The existing memstick core patch: commit 62c59a8786e6 ("memstick: Skip allocating card when removing host") sets host->removing in memstick_remove_host(),but still exists a critical time window where memstick_check can run after host->eject is set but before removing is set. In the rtsx_usb_ms driver, the problematic sequence is: rtsx_usb_ms_drv_remove: memstick_check: host->eject = true cancel_work_sync(handle_req) if(!host->removing) ... memstick_alloc_card() memstick_set_rw_addr() memstick_new_req() rtsx_usb_ms_request() if(!host->eject) skip schedule_work wait_for_completion() memstick_remove_host: [blocks indefinitely] host->removing = true flush_workqueue() [block] 1. rtsx_usb_ms_drv_remove sets host->eject = true 2. cancel_work_sync(&host->handle_req) runs 3. memstick_check work may be executed here <-- danger window 4. memstick_remove_host sets removing = 1 During this window (step 3), memstick_check calls memstick_alloc_card, which may indefinitely waiting for mrq_complete completion that will never occur because rtsx_usb_ms_request sees eject=true and skips scheduling work, memstick_set_rw_addr waits forever for completion. This causes a deadlock when memstick_remove_host tries to flush_workqueue, waiting for memstick_check to complete, while memstick_check is blocked waiting for mrq_complete completion. Fix this by setting removing=true at the start of rtsx_usb_ms_drv_remove, before any work cancellation. This ensures memstick_check will see the removing flag immediately and exit early, avoiding the deadlock. Fixes: 62c59a8786e6 ("memstick: Skip allocating card when removing host") Signed-off-by: Jiayi Li Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250804013604.1311218-1-lijiayi@kylinos.cn Signed-off-by: Ulf Hansson Signed-off-by: Greg Kroah-Hartman --- drivers/memstick/core/memstick.c | 1 - drivers/memstick/host/rtsx_usb_ms.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index e03118b8d1c4..e24ab362e51a 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -550,7 +550,6 @@ EXPORT_SYMBOL(memstick_add_host); */ void memstick_remove_host(struct memstick_host *host) { - host->removing = 1; flush_workqueue(workqueue); mutex_lock(&host->lock); if (host->card) diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c index dec279845a75..43ec4948daa2 100644 --- a/drivers/memstick/host/rtsx_usb_ms.c +++ b/drivers/memstick/host/rtsx_usb_ms.c @@ -812,6 +812,7 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev) int err; host->eject = true; + msh->removing = true; cancel_work_sync(&host->handle_req); cancel_delayed_work_sync(&host->poll_card); From b0e2eee1205fae9fb44790b860840dff411219b2 Mon Sep 17 00:00:00 2001 From: Phillip Lougher Date: Mon, 11 Aug 2025 23:37:40 +0100 Subject: [PATCH 308/404] squashfs: fix memory leak in squashfs_fill_super commit b64700d41bdc4e9f82f1346c15a3678ebb91a89c upstream. If sb_min_blocksize returns 0, squashfs_fill_super exits without freeing allocated memory (sb->s_fs_info). Fix this by moving the call to sb_min_blocksize to before memory is allocated. Link: https://lkml.kernel.org/r/20250811223740.110392-1-phillip@squashfs.org.uk Fixes: 734aa85390ea ("Squashfs: check return result of sb_min_blocksize") Signed-off-by: Phillip Lougher Reported-by: Scott GUO Closes: https://lore.kernel.org/all/20250811061921.3807353-1-scott_gzh@163.com Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/squashfs/super.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 545207683ddd..702d7d298695 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c @@ -74,10 +74,15 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc) unsigned short flags; unsigned int fragments; u64 lookup_table_start, xattr_id_table_start, next_table; - int err; + int err, devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE); TRACE("Entered squashfs_fill_superblock\n"); + if (!devblksize) { + errorf(fc, "squashfs: unable to set blocksize\n"); + return -EINVAL; + } + sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL); if (sb->s_fs_info == NULL) { ERROR("Failed to allocate squashfs_sb_info\n"); @@ -85,12 +90,7 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc) } msblk = sb->s_fs_info; - msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE); - if (!msblk->devblksize) { - errorf(fc, "squashfs: unable to set blocksize\n"); - return -EINVAL; - } - + msblk->devblksize = devblksize; msblk->devblksize_log2 = ffz(~msblk->devblksize); mutex_init(&msblk->meta_index_mutex); From cfed22d53c1d5e8c84024a8501298f404ce47a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Thu, 31 Jul 2025 11:43:52 +0200 Subject: [PATCH 309/404] drm/amd/display: Fix fractional fb divider in set_pixel_clock_v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 10507478468f165ea681605d133991ed05cdff62 upstream. For later VBIOS versions, the fractional feedback divider is calculated as the remainder of dividing the feedback divider by a factor, which is set to 1000000. For reference, see: - calculate_fb_and_fractional_fb_divider - calc_pll_max_vco_construct However, in case of old VBIOS versions that have set_pixel_clock_v3, they only have 1 byte available for the fractional feedback divider, and it's expected to be set to the remainder from dividing the feedback divider by 10. For reference see the legacy display code: - amdgpu_pll_compute - amdgpu_atombios_crtc_program_pll This commit fixes set_pixel_clock_v3 by dividing the fractional feedback divider passed to the function by 100000. Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)") Signed-off-by: Timur Kristóf Acked-by: Alex Deucher Reviewed-by: Rodrigo Siqueira Reviewed-by: Alex Hung Signed-off-by: Alex Deucher (cherry picked from commit 027e7acc7e17802ebf28e1edb88a404836ad50d6) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/display/dc/bios/command_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c index 0d2e13627c64..1a448397ae0b 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c @@ -992,7 +992,7 @@ static enum bp_result set_pixel_clock_v3( allocation.sPCLKInput.usFbDiv = cpu_to_le16((uint16_t)bp_params->feedback_divider); allocation.sPCLKInput.ucFracFbDiv = - (uint8_t)bp_params->fractional_feedback_divider; + (uint8_t)(bp_params->fractional_feedback_divider / 100000); allocation.sPCLKInput.ucPostDiv = (uint8_t)bp_params->pixel_clock_post_divider; From 3fe19a2cf22818206df5e87478214717ab856009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Thu, 31 Jul 2025 11:43:48 +0200 Subject: [PATCH 310/404] drm/amd/display: Find first CRTC and its line time in dce110_fill_display_configs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 669f73a26f6112eedbadac53a2f2707ac6d0b9c8 upstream. dce110_fill_display_configs is shared between DCE 6-11, and finding the first CRTC and its line time is relevant to DCE 6 too. Move the code to find it from DCE 11 specific code. Signed-off-by: Timur Kristóf Acked-by: Alex Deucher Reviewed-by: Rodrigo Siqueira Reviewed-by: Alex Hung Signed-off-by: Alex Deucher (cherry picked from commit 4ab09785f8d5d03df052827af073d5c508ff5f63) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- .../dc/clk_mgr/dce110/dce110_clk_mgr.c | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c index b1e657e137a9..56a7266fed20 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c @@ -120,9 +120,12 @@ void dce110_fill_display_configs( const struct dc_state *context, struct dm_pp_display_configuration *pp_display_cfg) { + struct dc *dc = context->clk_mgr->ctx->dc; int j; int num_cfgs = 0; + pp_display_cfg->crtc_index = dc->res_pool->res_cap->num_timing_generator; + for (j = 0; j < context->stream_count; j++) { int k; @@ -164,6 +167,23 @@ void dce110_fill_display_configs( cfg->v_refresh /= stream->timing.h_total; cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2) / stream->timing.v_total; + + /* Find first CRTC index and calculate its line time. + * This is necessary for DPM on SI GPUs. + */ + if (cfg->pipe_idx < pp_display_cfg->crtc_index) { + const struct dc_crtc_timing *timing = + &context->streams[0]->timing; + + pp_display_cfg->crtc_index = cfg->pipe_idx; + pp_display_cfg->line_time_in_us = + timing->h_total * 10000 / timing->pix_clk_100hz; + } + } + + if (!num_cfgs) { + pp_display_cfg->crtc_index = 0; + pp_display_cfg->line_time_in_us = 0; } pp_display_cfg->display_count = num_cfgs; @@ -231,16 +251,6 @@ void dce11_pplib_apply_display_requirements( dce110_fill_display_configs(context, pp_display_cfg); - /* TODO: is this still applicable?*/ - if (pp_display_cfg->display_count == 1) { - const struct dc_crtc_timing *timing = - &context->streams[0]->timing; - - pp_display_cfg->crtc_index = - pp_display_cfg->disp_configs[0].pipe_idx; - pp_display_cfg->line_time_in_us = timing->h_total * 10000 / timing->pix_clk_100hz; - } - if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); } From 70a09115da586bf662c3bae9c0c4a1b99251fad9 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Mon, 11 Aug 2025 22:18:30 +0800 Subject: [PATCH 311/404] fs/buffer: fix use-after-free when call bh_read() helper [ Upstream commit 7375f22495e7cd1c5b3b5af9dcc4f6dffe34ce49 ] There's issue as follows: BUG: KASAN: stack-out-of-bounds in end_buffer_read_sync+0xe3/0x110 Read of size 8 at addr ffffc9000168f7f8 by task swapper/3/0 CPU: 3 UID: 0 PID: 0 Comm: swapper/3 Not tainted 6.16.0-862.14.0.6.x86_64 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) Call Trace: dump_stack_lvl+0x55/0x70 print_address_description.constprop.0+0x2c/0x390 print_report+0xb4/0x270 kasan_report+0xb8/0xf0 end_buffer_read_sync+0xe3/0x110 end_bio_bh_io_sync+0x56/0x80 blk_update_request+0x30a/0x720 scsi_end_request+0x51/0x2b0 scsi_io_completion+0xe3/0x480 ? scsi_device_unbusy+0x11e/0x160 blk_complete_reqs+0x7b/0x90 handle_softirqs+0xef/0x370 irq_exit_rcu+0xa5/0xd0 sysvec_apic_timer_interrupt+0x6e/0x90 Above issue happens when do ntfs3 filesystem mount, issue may happens as follows: mount IRQ ntfs_fill_super read_cache_page do_read_cache_folio filemap_read_folio mpage_read_folio do_mpage_readpage ntfs_get_block_vbo bh_read submit_bh wait_on_buffer(bh); blk_complete_reqs scsi_io_completion scsi_end_request blk_update_request end_bio_bh_io_sync end_buffer_read_sync __end_buffer_read_notouch unlock_buffer wait_on_buffer(bh);--> return will return to caller put_bh --> trigger stack-out-of-bounds In the mpage_read_folio() function, the stack variable 'map_bh' is passed to ntfs_get_block_vbo(). Once unlock_buffer() unlocks and wait_on_buffer() returns to continue processing, the stack variable is likely to be reclaimed. Consequently, during the end_buffer_read_sync() process, calling put_bh() may result in stack overrun. If the bh is not allocated on the stack, it belongs to a folio. Freeing a buffer head which belongs to a folio is done by drop_buffers() which will fail to free buffers which are still locked. So it is safe to call put_bh() before __end_buffer_read_notouch(). Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Ye Bin Link: https://lore.kernel.org/20250811141830.343774-1-yebin@huaweicloud.com Reviewed-by: Matthew Wilcox (Oracle) Signed-off-by: Christian Brauner Signed-off-by: Sasha Levin --- fs/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/buffer.c b/fs/buffer.c index 4ec88d08d04e..e0da5e56e499 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -161,8 +161,8 @@ static void __end_buffer_read_notouch(struct buffer_head *bh, int uptodate) */ void end_buffer_read_sync(struct buffer_head *bh, int uptodate) { - __end_buffer_read_notouch(bh, uptodate); put_bh(bh); + __end_buffer_read_notouch(bh, uptodate); } EXPORT_SYMBOL(end_buffer_read_sync); From ce750f697c19f0bfe13e48babaa113f93b990ad0 Mon Sep 17 00:00:00 2001 From: Pavel Tikhomirov Date: Thu, 15 Jul 2021 13:07:13 +0300 Subject: [PATCH 312/404] move_mount: allow to add a mount into an existing group [ Upstream commit 9ffb14ef61bab83fa818736bf3e7e6b6e182e8e2 ] Previously a sharing group (shared and master ids pair) can be only inherited when mount is created via bindmount. This patch adds an ability to add an existing private mount into an existing sharing group. With this functionality one can first create the desired mount tree from only private mounts (without the need to care about undesired mount propagation or mount creation order implied by sharing group dependencies), and next then setup any desired mount sharing between those mounts in tree as needed. This allows CRIU to restore any set of mount namespaces, mount trees and sharing group trees for a container. We have many issues with restoring mounts in CRIU related to sharing groups and propagation: - reverse sharing groups vs mount tree order requires complex mounts reordering which mostly implies also using some temporary mounts (please see https://lkml.org/lkml/2021/3/23/569 for more info) - mount() syscall creates tons of mounts due to propagation - mount re-parenting due to propagation - "Mount Trap" due to propagation - "Non Uniform" propagation, meaning that with different tricks with mount order and temporary children-"lock" mounts one can create mount trees which can't be restored without those tricks (see https://www.linuxplumbersconf.org/event/7/contributions/640/) With this new functionality we can resolve all the problems with propagation at once. Link: https://lore.kernel.org/r/20210715100714.120228-1-ptikhomirov@virtuozzo.com Cc: Eric W. Biederman Cc: Alexander Viro Cc: Christian Brauner Cc: Mattias Nissler Cc: Aleksa Sarai Cc: Andrei Vagin Cc: linux-fsdevel@vger.kernel.org Cc: linux-api@vger.kernel.org Cc: lkml Co-developed-by: Andrei Vagin Acked-by: Christian Brauner Signed-off-by: Pavel Tikhomirov Signed-off-by: Andrei Vagin Signed-off-by: Christian Brauner Stable-dep-of: cffd0441872e ("use uniform permission checks for all mount propagation changes") Signed-off-by: Sasha Levin --- fs/namespace.c | 77 +++++++++++++++++++++++++++++++++++++- include/uapi/linux/mount.h | 3 +- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index ee5a87061f20..3c1afe60d438 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2624,6 +2624,78 @@ out: return ret; } +static int do_set_group(struct path *from_path, struct path *to_path) +{ + struct mount *from, *to; + int err; + + from = real_mount(from_path->mnt); + to = real_mount(to_path->mnt); + + namespace_lock(); + + err = -EINVAL; + /* To and From must be mounted */ + if (!is_mounted(&from->mnt)) + goto out; + if (!is_mounted(&to->mnt)) + goto out; + + err = -EPERM; + /* We should be allowed to modify mount namespaces of both mounts */ + if (!ns_capable(from->mnt_ns->user_ns, CAP_SYS_ADMIN)) + goto out; + if (!ns_capable(to->mnt_ns->user_ns, CAP_SYS_ADMIN)) + goto out; + + err = -EINVAL; + /* To and From paths should be mount roots */ + if (from_path->dentry != from_path->mnt->mnt_root) + goto out; + if (to_path->dentry != to_path->mnt->mnt_root) + goto out; + + /* Setting sharing groups is only allowed across same superblock */ + if (from->mnt.mnt_sb != to->mnt.mnt_sb) + goto out; + + /* From mount root should be wider than To mount root */ + if (!is_subdir(to->mnt.mnt_root, from->mnt.mnt_root)) + goto out; + + /* From mount should not have locked children in place of To's root */ + if (has_locked_children(from, to->mnt.mnt_root)) + goto out; + + /* Setting sharing groups is only allowed on private mounts */ + if (IS_MNT_SHARED(to) || IS_MNT_SLAVE(to)) + goto out; + + /* From should not be private */ + if (!IS_MNT_SHARED(from) && !IS_MNT_SLAVE(from)) + goto out; + + if (IS_MNT_SLAVE(from)) { + struct mount *m = from->mnt_master; + + list_add(&to->mnt_slave, &m->mnt_slave_list); + to->mnt_master = m; + } + + if (IS_MNT_SHARED(from)) { + to->mnt_group_id = from->mnt_group_id; + list_add(&to->mnt_share, &from->mnt_share); + lock_mount_hash(); + set_mnt_shared(to); + unlock_mount_hash(); + } + + err = 0; +out: + namespace_unlock(); + return err; +} + static int do_move_mount(struct path *old_path, struct path *new_path) { struct mnt_namespace *ns; @@ -3583,7 +3655,10 @@ SYSCALL_DEFINE5(move_mount, if (ret < 0) goto out_to; - ret = do_move_mount(&from_path, &to_path); + if (flags & MOVE_MOUNT_SET_GROUP) + ret = do_set_group(&from_path, &to_path); + else + ret = do_move_mount(&from_path, &to_path); out_to: path_put(&to_path); diff --git a/include/uapi/linux/mount.h b/include/uapi/linux/mount.h index 96a0240f23fe..535ca707dfd7 100644 --- a/include/uapi/linux/mount.h +++ b/include/uapi/linux/mount.h @@ -70,7 +70,8 @@ #define MOVE_MOUNT_T_SYMLINKS 0x00000010 /* Follow symlinks on to path */ #define MOVE_MOUNT_T_AUTOMOUNTS 0x00000020 /* Follow automounts on to path */ #define MOVE_MOUNT_T_EMPTY_PATH 0x00000040 /* Empty to path permitted */ -#define MOVE_MOUNT__MASK 0x00000077 +#define MOVE_MOUNT_SET_GROUP 0x00000100 /* Set sharing group instead */ +#define MOVE_MOUNT__MASK 0x00000177 /* * fsopen() flags. From 3e3e50ce2edda1d03c249720bb0b3914cbd2654a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 14 Aug 2025 01:44:31 -0400 Subject: [PATCH 313/404] use uniform permission checks for all mount propagation changes [ Upstream commit cffd0441872e7f6b1fce5e78fb1c99187a291330 ] do_change_type() and do_set_group() are operating on different aspects of the same thing - propagation graph. The latter asks for mounts involved to be mounted in namespace(s) the caller has CAP_SYS_ADMIN for. The former is a mess - originally it didn't even check that mount *is* mounted. That got fixed, but the resulting check turns out to be too strict for userland - in effect, we check that mount is in our namespace, having already checked that we have CAP_SYS_ADMIN there. What we really need (in both cases) is * only touch mounts that are mounted. That's a must-have constraint - data corruption happens if it get violated. * don't allow to mess with a namespace unless you already have enough permissions to do so (i.e. CAP_SYS_ADMIN in its userns). That's an equivalent of what do_set_group() does; let's extract that into a helper (may_change_propagation()) and use it in both do_set_group() and do_change_type(). Fixes: 12f147ddd6de "do_change_type(): refuse to operate on unmounted/not ours mounts" Acked-by: Andrei Vagin Reviewed-by: Pavel Tikhomirov Tested-by: Pavel Tikhomirov Reviewed-by: Christian Brauner Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- fs/namespace.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 3c1afe60d438..c87f847c959d 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2210,6 +2210,19 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp) return attach_recursive_mnt(mnt, p, mp, false); } +static int may_change_propagation(const struct mount *m) +{ + struct mnt_namespace *ns = m->mnt_ns; + + // it must be mounted in some namespace + if (IS_ERR_OR_NULL(ns)) // is_mounted() + return -EINVAL; + // and the caller must be admin in userns of that namespace + if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN)) + return -EPERM; + return 0; +} + /* * Sanity check the flags to change_mnt_propagation. */ @@ -2246,10 +2259,10 @@ static int do_change_type(struct path *path, int ms_flags) return -EINVAL; namespace_lock(); - if (!check_mnt(mnt)) { - err = -EINVAL; + err = may_change_propagation(mnt); + if (err) goto out_unlock; - } + if (type == MS_SHARED) { err = invent_group_ids(mnt, recurse); if (err) @@ -2634,18 +2647,11 @@ static int do_set_group(struct path *from_path, struct path *to_path) namespace_lock(); - err = -EINVAL; - /* To and From must be mounted */ - if (!is_mounted(&from->mnt)) + err = may_change_propagation(from); + if (err) goto out; - if (!is_mounted(&to->mnt)) - goto out; - - err = -EPERM; - /* We should be allowed to modify mount namespaces of both mounts */ - if (!ns_capable(from->mnt_ns->user_ns, CAP_SYS_ADMIN)) - goto out; - if (!ns_capable(to->mnt_ns->user_ns, CAP_SYS_ADMIN)) + err = may_change_propagation(to); + if (err) goto out; err = -EINVAL; From e4c2515a04d61e67b1a8bed6cb05c27f7678d811 Mon Sep 17 00:00:00 2001 From: Xu Yilun Date: Wed, 6 Aug 2025 15:06:05 +0800 Subject: [PATCH 314/404] fpga: zynq_fpga: Fix the wrong usage of dma_map_sgtable() commit 1ca61060de92a4320d73adfe5dc8d335653907ac upstream. dma_map_sgtable() returns only 0 or the error code. Read sgt->nents to get the number of mapped segments. Fixes: 37e00703228a ("zynq_fpga: use sgtable-based scatterlist wrappers") Reported-by: Pavel Pisa Closes: https://lore.kernel.org/linux-fpga/202508041548.22955.pisa@fel.cvut.cz/ Reviewed-by: Jason Gunthorpe Reviewed-by: Marek Szyprowski Signed-off-by: Xu Yilun Tested-by: Pavel Pisa Link: https://lore.kernel.org/r/20250806070605.1920909-2-yilun.xu@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/fpga/zynq-fpga.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c index 733ab4056ee3..efd5c2920c6d 100644 --- a/drivers/fpga/zynq-fpga.c +++ b/drivers/fpga/zynq-fpga.c @@ -405,12 +405,12 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, struct sg_table *sgt) } } - priv->dma_nelms = - dma_map_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0); - if (priv->dma_nelms == 0) { + err = dma_map_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0); + if (err) { dev_err(&mgr->dev, "Unable to DMA map (TO_DEVICE)\n"); - return -ENOMEM; + return err; } + priv->dma_nelms = sgt->nents; /* enable clock */ err = clk_enable(priv->clk); From 12064e1880fc9202be75ff668205b1703d92f74f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 22 Aug 2025 18:36:06 -0400 Subject: [PATCH 315/404] ftrace: Also allocate and copy hash for reading of filter files commit bfb336cf97df7b37b2b2edec0f69773e06d11955 upstream. Currently the reader of set_ftrace_filter and set_ftrace_notrace just adds the pointer to the global tracer hash to its iterator. Unlike the writer that allocates a copy of the hash, the reader keeps the pointer to the filter hashes. This is problematic because this pointer is static across function calls that release the locks that can update the global tracer hashes. This can cause UAF and similar bugs. Allocate and copy the hash for reading the filter files like it is done for the writers. This not only fixes UAF bugs, but also makes the code a bit simpler as it doesn't have to differentiate when to free the iterator's hash between writers and readers. Cc: stable@vger.kernel.org Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Nathan Chancellor Cc: Linus Torvalds Link: https://lore.kernel.org/20250822183606.12962cc3@batman.local.home Fixes: c20489dad156 ("ftrace: Assign iter->hash to filter or notrace hashes on seq read") Closes: https://lore.kernel.org/all/20250813023044.2121943-1-wutengda@huaweicloud.com/ Closes: https://lore.kernel.org/all/20250822192437.GA458494@ax162/ Reported-by: Tengda Wu Tested-by: Tengda Wu Tested-by: Nathan Chancellor Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ftrace.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 03a14d939ac3..718291af1063 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -3650,13 +3650,17 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag, } else { iter->hash = alloc_and_copy_ftrace_hash(size_bits, hash); } + } else { + if (hash) + iter->hash = alloc_and_copy_ftrace_hash(hash->size_bits, hash); + else + iter->hash = EMPTY_HASH; + } - if (!iter->hash) { - trace_parser_put(&iter->parser); - goto out_unlock; - } - } else - iter->hash = hash; + if (!iter->hash) { + trace_parser_put(&iter->parser); + goto out_unlock; + } ret = 0; @@ -5117,9 +5121,6 @@ int ftrace_regex_release(struct inode *inode, struct file *file) ret = ftrace_hash_move_and_update_ops(iter->ops, orig_hash, iter->hash, filter_hash); mutex_unlock(&ftrace_lock); - } else { - /* For read only, the hash is the ops hash */ - iter->hash = NULL; } mutex_unlock(&iter->ops->func_hash->regex_lock); From 04318dbadadd3014839aa14670ccc6c71d6634fa Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 22 Jul 2025 15:54:21 -0500 Subject: [PATCH 316/404] iio: proximity: isl29501: fix buffered read on big-endian systems commit de18e978d0cda23e4c102e18092b63a5b0b3a800 upstream. Fix passing a u32 value as a u16 buffer scan item. This works on little- endian systems, but not on big-endian systems. A new local variable is introduced for getting the register value and the array is changed to a struct to make the data layout more explicit rather than just changing the type and having to recalculate the proper length needed for the timestamp. Fixes: 1c28799257bc ("iio: light: isl29501: Add support for the ISL29501 ToF sensor.") Signed-off-by: David Lechner Link: https://patch.msgid.link/20250722-iio-use-more-iio_declare_buffer_with_ts-7-v2-1-d3ebeb001ed3@baylibre.com Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/iio/proximity/isl29501.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/iio/proximity/isl29501.c b/drivers/iio/proximity/isl29501.c index 56d6e9f927f4..49a19f22a3ec 100644 --- a/drivers/iio/proximity/isl29501.c +++ b/drivers/iio/proximity/isl29501.c @@ -938,12 +938,18 @@ static irqreturn_t isl29501_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct isl29501_private *isl29501 = iio_priv(indio_dev); const unsigned long *active_mask = indio_dev->active_scan_mask; - u32 buffer[4] __aligned(8) = {}; /* 1x16-bit + naturally aligned ts */ + u32 value; + struct { + u16 data; + aligned_s64 ts; + } scan = { }; - if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask)) - isl29501_register_read(isl29501, REG_DISTANCE, buffer); + if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask)) { + isl29501_register_read(isl29501, REG_DISTANCE, &value); + scan.data = value; + } - iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp); + iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp); iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; From deef90c5a489a21e8691806586da0840f7a473cf Mon Sep 17 00:00:00 2001 From: Miao Li Date: Fri, 1 Aug 2025 16:27:28 +0800 Subject: [PATCH 317/404] usb: quirks: Add DELAY_INIT quick for another SanDisk 3.2Gen1 Flash Drive commit e664036cf36480414936cd91f4cfa2179a3d8367 upstream. Another SanDisk 3.2Gen1 Flash Drive also need DELAY_INIT quick, or it will randomly work incorrectly on Huawei hisi platforms when doing reboot test. Signed-off-by: Miao Li Cc: stable Link: https://lore.kernel.org/r/20250801082728.469406-1-limiao870622@163.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 5f6ba422c463..75a4d162c58b 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -368,6 +368,7 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM }, /* SanDisk Corp. SanDisk 3.2Gen1 */ + { USB_DEVICE(0x0781, 0x5596), .driver_info = USB_QUIRK_DELAY_INIT }, { USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT }, /* SanDisk Extreme 55AE */ From eb2223e2c8a5c89cf0d451945e7ccf738b997631 Mon Sep 17 00:00:00 2001 From: Mael GUERIN Date: Wed, 6 Aug 2025 18:44:03 +0200 Subject: [PATCH 318/404] USB: storage: Add unusual-devs entry for Novatek NTK96550-based camera commit 6ca8af3c8fb584f3424a827f554ff74f898c27cd upstream. Add the US_FL_BULK_IGNORE_TAG quirk for Novatek NTK96550-based camera to fix USB resets after sending SCSI vendor commands due to CBW and CSW tags difference, leading to undesired slowness while communicating with the device. Please find below the copy of /sys/kernel/debug/usb/devices with my device plugged in (listed as TechSys USB mass storage here, the underlying chipset being the Novatek NTK96550-based camera): T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0603 ProdID=8611 Rev= 0.01 S: Manufacturer=TechSys S: Product=USB Mass Storage S: SerialNumber=966110000000100 C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Mael GUERIN Cc: stable Acked-by: Alan Stern Link: https://lore.kernel.org/r/20250806164406.43450-1-mael.guerin@murena.io Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index a6dc2faae85d..3857d41edcdd 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -934,6 +934,13 @@ UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_SANE_SENSE ), +/* Added by Maël GUERIN */ +UNUSUAL_DEV( 0x0603, 0x8611, 0x0000, 0xffff, + "Novatek", + "NTK96550-based camera", + USB_SC_SCSI, USB_PR_BULK, NULL, + US_FL_BULK_IGNORE_TAG ), + /* * Reported by Hanno Boeck * Taken from the Lycoris Kernel From a648cc7c4946ec31b395e5b9009c460de7c3abd0 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Wed, 13 Aug 2025 16:52:49 +0200 Subject: [PATCH 319/404] usb: storage: realtek_cr: Use correct byte order for bcs->Residue commit 98da66a70ad2396e5a508c4245367797ebc052ce upstream. Since 'bcs->Residue' has the data type '__le32', convert it to the correct byte order of the CPU using this driver when assigning it to the local variable 'residue'. Cc: stable Fixes: 50a6cb932d5c ("USB: usb_storage: add ums-realtek driver") Suggested-by: Alan Stern Acked-by: Alan Stern Signed-off-by: Thorsten Blum Link: https://lore.kernel.org/r/20250813145247.184717-3-thorsten.blum@linux.dev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/realtek_cr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 0c423916d7bf..a026c6cb6e68 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -252,7 +252,7 @@ static int rts51x_bulk_transport(struct us_data *us, u8 lun, return USB_STOR_TRANSPORT_ERROR; } - residue = bcs->Residue; + residue = le32_to_cpu(bcs->Residue); if (bcs->Tag != us->tag) return USB_STOR_TRANSPORT_ERROR; From f93fb614d3f4890fdb75b56c63f0a794a2618bb7 Mon Sep 17 00:00:00 2001 From: Zenm Chen Date: Thu, 14 Aug 2025 00:24:15 +0800 Subject: [PATCH 320/404] USB: storage: Ignore driver CD mode for Realtek multi-mode Wi-Fi dongles commit a3dc32c635bae0ae569f489e00de0e8f015bfc25 upstream. Many Realtek USB Wi-Fi dongles released in recent years have two modes: one is driver CD mode which has Windows driver onboard, another one is Wi-Fi mode. Add the US_FL_IGNORE_DEVICE quirk for these multi-mode devices. Otherwise, usb_modeswitch may fail to switch them to Wi-Fi mode. Currently there are only two USB IDs known to be used by these multi-mode Wi-Fi dongles: 0bda:1a2b and 0bda:a192. Information about Mercury MW310UH in /sys/kernel/debug/usb/devices. T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 12 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0bda ProdID=a192 Rev= 2.00 S: Manufacturer=Realtek S: Product=DISK C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none) E: Ad=8a(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Information about D-Link AX9U rev. A1 in /sys/kernel/debug/usb/devices. T: Bus=03 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 55 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0bda ProdID=1a2b Rev= 0.00 S: Manufacturer=Realtek S: Product=DISK C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none) E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Cc: stable Signed-off-by: Zenm Chen Acked-by: Alan Stern Link: https://lore.kernel.org/r/20250813162415.2630-1-zenmchen@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 3857d41edcdd..509e4e155f41 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1490,6 +1490,28 @@ UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_WP_DETECT ), +/* + * Reported by Zenm Chen + * Ignore driver CD mode, otherwise usb_modeswitch may fail to switch + * the device into Wi-Fi mode. + */ +UNUSUAL_DEV( 0x0bda, 0x1a2b, 0x0000, 0xffff, + "Realtek", + "DISK", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_DEVICE ), + +/* + * Reported by Zenm Chen + * Ignore driver CD mode, otherwise usb_modeswitch may fail to switch + * the device into Wi-Fi mode. + */ +UNUSUAL_DEV( 0x0bda, 0xa192, 0x0000, 0xffff, + "Realtek", + "DISK", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_DEVICE ), + UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, "Maxtor", "USB to SATA", From 0c1699135dc696c1af9b0f76bb814c27d36112bd Mon Sep 17 00:00:00 2001 From: Kuen-Han Tsai Date: Thu, 7 Aug 2025 17:06:55 +0800 Subject: [PATCH 321/404] usb: dwc3: Ignore late xferNotReady event to prevent halt timeout commit 58577118cc7cec9eb7c1836bf88f865ff2c5e3a3 upstream. During a device-initiated disconnect, the End Transfer command resets the event filter, allowing a new xferNotReady event to be generated before the controller is fully halted. Processing this late event incorrectly triggers a Start Transfer, which prevents the controller from halting and results in a DSTS.DEVCTLHLT bit polling timeout. Ignore the late xferNotReady event if the controller is already in a disconnected state. Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver") Cc: stable Signed-off-by: Kuen-Han Tsai Acked-by: Thinh Nguyen Link: https://lore.kernel.org/r/20250807090700.2397190-1-khtsai@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/gadget.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 76316205483b..73608332d78d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2937,6 +2937,15 @@ static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep, static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep, const struct dwc3_event_depevt *event) { + /* + * During a device-initiated disconnect, a late xferNotReady event can + * be generated after the End Transfer command resets the event filter, + * but before the controller is halted. Ignore it to prevent a new + * transfer from starting. + */ + if (!dep->dwc->connected) + return; + dwc3_gadget_endpoint_frame_from_event(dep, event); (void) __dwc3_gadget_start_isoc(dep); } From d9f193f323c0fdc1e0266a1692996e7b3b10f140 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 11 Aug 2025 16:51:46 -0700 Subject: [PATCH 322/404] ARM: 9448/1: Use an absolute path to unified.h in KBUILD_AFLAGS commit 87c4e1459e80bf65066f864c762ef4dc932fad4b upstream. After commit d5c8d6e0fa61 ("kbuild: Update assembler calls to use proper flags and language target"), which updated as-instr to use the 'assembler-with-cpp' language option, the Kbuild version of as-instr always fails internally for arch/arm with : fatal error: asm/unified.h: No such file or directory compilation terminated. because '-include' flags are now taken into account by the compiler driver and as-instr does not have '$(LINUXINCLUDE)', so unified.h is not found. This went unnoticed at the time of the Kbuild change because the last use of as-instr in Kbuild that arch/arm could reach was removed in 5.7 by commit 541ad0150ca4 ("arm: Remove 32bit KVM host support") but a stable backport of the Kbuild change to before that point exposed this potential issue if one were to be reintroduced. Follow the general pattern of '-include' paths throughout the tree and make unified.h absolute using '$(srctree)' to ensure KBUILD_AFLAGS can be used independently. Closes: https://lore.kernel.org/CACo-S-1qbCX4WAVFA63dWfHtrRHZBTyyr2js8Lx=Az03XHTTHg@mail.gmail.com/ Cc: stable@vger.kernel.org Fixes: d5c8d6e0fa61 ("kbuild: Update assembler calls to use proper flags and language target") Reported-by: KernelCI bot Reviewed-by: Masahiro Yamada Signed-off-by: Nathan Chancellor Signed-off-by: Russell King (Oracle) [nathan: Fix conflicts] Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- arch/arm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 4f098edfbf20..cb33ed8de5f8 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -136,7 +136,7 @@ endif # Need -Uarm for gcc < 3.x KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm -KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float +KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include $(srctree)/arch/arm/include/asm/unified.h -msoft-float CHECKFLAGS += -D__arm__ From 678a7813ca285305796bb188e76da9f7db9ac5b4 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 11 Aug 2025 16:51:47 -0700 Subject: [PATCH 323/404] kbuild: Update assembler calls to use proper flags and language target commit d5c8d6e0fa61401a729e9eb6a9c7077b2d3aebb0 upstream. as-instr uses KBUILD_AFLAGS, but as-option uses KBUILD_CFLAGS. This can cause as-option to fail unexpectedly when CONFIG_WERROR is set, because clang will emit -Werror,-Wunused-command-line-argument for various -m and -f flags in KBUILD_CFLAGS for assembler sources. Callers of as-option and as-instr should be adding flags to KBUILD_AFLAGS / aflags-y, not KBUILD_CFLAGS / cflags-y. Use KBUILD_AFLAGS in all macros to clear up the initial problem. Unfortunately, -Wunused-command-line-argument can still be triggered with clang by the presence of warning flags or macro definitions because '-x assembler' is used, instead of '-x assembler-with-cpp', which will consume these flags. Switch to '-x assembler-with-cpp' in places where '-x assembler' is used, as the compiler is always used as the driver for out of line assembler sources in the kernel. Finally, add -Werror to these macros so that they behave consistently whether or not CONFIG_WERROR is set. [nathan: Reworded and expanded on problems in commit message Use '-x assembler-with-cpp' in a couple more places] Link: https://github.com/ClangBuiltLinux/linux/issues/1699 Suggested-by: Masahiro Yamada Signed-off-by: Nick Desaulniers Signed-off-by: Nathan Chancellor Tested-by: Linux Kernel Functional Testing Tested-by: Anders Roxell Signed-off-by: Masahiro Yamada Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- scripts/Kbuild.include | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 82eb69f07b35..11f905b95e65 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -99,16 +99,16 @@ try-run = $(shell set -e; \ fi) # as-option -# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,) +# Usage: aflags-y += $(call as-option,-Wa$(comma)-isa=foo,) as-option = $(call try-run,\ - $(CC) $(KBUILD_CFLAGS) $(1) -c -x assembler /dev/null -o "$$TMP",$(1),$(2)) + $(CC) -Werror $(KBUILD_AFLAGS) $(1) -c -x assembler-with-cpp /dev/null -o "$$TMP",$(1),$(2)) # as-instr -# Usage: cflags-y += $(call as-instr,instr,option1,option2) +# Usage: aflags-y += $(call as-instr,instr,option1,option2) as-instr = $(call try-run,\ - printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3)) + printf "%b\n" "$(1)" | $(CC) -Werror $(KBUILD_AFLAGS) -c -x assembler-with-cpp -o "$$TMP" -,$(2),$(3)) # __cc-option # Usage: MY_CFLAGS += $(call __cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586) From 3a1f21551fe057de1c62589419e7dbecc07ec44f Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 11 Aug 2025 16:51:48 -0700 Subject: [PATCH 324/404] mips: Include KBUILD_CPPFLAGS in CHECKFLAGS invocation commit 08f6554ff90ef189e6b8f0303e57005bddfdd6a7 upstream. A future change will move CLANG_FLAGS from KBUILD_{A,C}FLAGS to KBUILD_CPPFLAGS so that '--target' is available while preprocessing. When that occurs, the following error appears when building ARCH=mips with clang (tip of tree error shown): clang: error: unsupported option '-mabi=' for target 'x86_64-pc-linux-gnu' Add KBUILD_CPPFLAGS in the CHECKFLAGS invocation to keep everything working after the move. Signed-off-by: Nathan Chancellor Signed-off-by: Masahiro Yamada Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- arch/mips/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 4542258027a7..cc6f8265f28c 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -319,7 +319,7 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables KBUILD_LDFLAGS += -m $(ld-emul) ifdef CONFIG_MIPS -CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ +CHECKFLAGS += $(shell $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') endif From dfd69889c9905a0ed5b7f4a6813ecb9444ad1af3 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 11 Aug 2025 16:51:49 -0700 Subject: [PATCH 325/404] kbuild: Add CLANG_FLAGS to as-instr commit cff6e7f50bd315e5b39c4e46c704ac587ceb965f upstream. A future change will move CLANG_FLAGS from KBUILD_{A,C}FLAGS to KBUILD_CPPFLAGS so that '--target' is available while preprocessing. When that occurs, the following errors appear multiple times when building ARCH=powerpc powernv_defconfig: ld.lld: error: vmlinux.a(arch/powerpc/kernel/head_64.o):(.text+0x12d4): relocation R_PPC64_ADDR16_HI out of range: -4611686018409717520 is not in [-2147483648, 2147483647]; references '__start___soft_mask_table' ld.lld: error: vmlinux.a(arch/powerpc/kernel/head_64.o):(.text+0x12e8): relocation R_PPC64_ADDR16_HI out of range: -4611686018409717392 is not in [-2147483648, 2147483647]; references '__stop___soft_mask_table' Diffing the .o.cmd files reveals that -DHAVE_AS_ATHIGH=1 is not present anymore, because as-instr only uses KBUILD_AFLAGS, which will no longer contain '--target'. Mirror Kconfig's as-instr and add CLANG_FLAGS explicitly to the invocation to ensure the target information is always present. Signed-off-by: Nathan Chancellor Signed-off-by: Masahiro Yamada Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- scripts/Kbuild.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 11f905b95e65..b01d3108596b 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -108,7 +108,7 @@ as-option = $(call try-run,\ # Usage: aflags-y += $(call as-instr,instr,option1,option2) as-instr = $(call try-run,\ - printf "%b\n" "$(1)" | $(CC) -Werror $(KBUILD_AFLAGS) -c -x assembler-with-cpp -o "$$TMP" -,$(2),$(3)) + printf "%b\n" "$(1)" | $(CC) -Werror $(CLANG_FLAGS) $(KBUILD_AFLAGS) -c -x assembler-with-cpp -o "$$TMP" -,$(2),$(3)) # __cc-option # Usage: MY_CFLAGS += $(call __cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586) From cbf2b29dce6b67e63fe3426481c0a83d6136f20b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 11 Aug 2025 16:51:50 -0700 Subject: [PATCH 326/404] kbuild: add $(CLANG_FLAGS) to KBUILD_CPPFLAGS commit feb843a469fb0ab00d2d23cfb9bcc379791011bb upstream. When preprocessing arch/*/kernel/vmlinux.lds.S, the target triple is not passed to $(CPP) because we add it only to KBUILD_{C,A}FLAGS. As a result, the linker script is preprocessed with predefined macros for the build host instead of the target. Assuming you use an x86 build machine, compare the following: $ clang -dM -E -x c /dev/null $ clang -dM -E -x c /dev/null -target aarch64-linux-gnu There is no actual problem presumably because our linker scripts do not rely on such predefined macros, but it is better to define correct ones. Move $(CLANG_FLAGS) to KBUILD_CPPFLAGS, so that all *.c, *.S, *.lds.S will be processed with the proper target triple. [Note] After the patch submission, we got an actual problem that needs this commit. (CBL issue 1859) Link: https://github.com/ClangBuiltLinux/linux/issues/1859 Reported-by: Tom Rini Signed-off-by: Masahiro Yamada Reviewed-by: Nathan Chancellor Tested-by: Nathan Chancellor Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f65e282f4a3f..16a23aaaa547 100644 --- a/Makefile +++ b/Makefile @@ -568,8 +568,7 @@ ifneq ($(LLVM_IAS),1) CLANG_FLAGS += -no-integrated-as endif CLANG_FLAGS += -Werror=unknown-warning-option -KBUILD_CFLAGS += $(CLANG_FLAGS) -KBUILD_AFLAGS += $(CLANG_FLAGS) +KBUILD_CPPFLAGS += $(CLANG_FLAGS) export CLANG_FLAGS endif From 16ecad3f8b93a96b1f7413fe30bb805967e71cf0 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 11 Aug 2025 16:51:51 -0700 Subject: [PATCH 327/404] kbuild: Add KBUILD_CPPFLAGS to as-option invocation commit 43fc0a99906e04792786edf8534d8d58d1e9de0c upstream. After commit feb843a469fb ("kbuild: add $(CLANG_FLAGS) to KBUILD_CPPFLAGS"), there is an error while building certain PowerPC assembly files with clang: arch/powerpc/lib/copypage_power7.S: Assembler messages: arch/powerpc/lib/copypage_power7.S:34: Error: junk at end of line: `0b01000' arch/powerpc/lib/copypage_power7.S:35: Error: junk at end of line: `0b01010' arch/powerpc/lib/copypage_power7.S:37: Error: junk at end of line: `0b01000' arch/powerpc/lib/copypage_power7.S:38: Error: junk at end of line: `0b01010' arch/powerpc/lib/copypage_power7.S:40: Error: junk at end of line: `0b01010' clang: error: assembler command failed with exit code 1 (use -v to see invocation) as-option only uses KBUILD_AFLAGS, so after removing CLANG_FLAGS from KBUILD_AFLAGS, there is no more '--target=' or '--prefix=' flags. As a result of those missing flags, the host target will be tested during as-option calls and likely fail, meaning necessary flags may not get added when building assembly files, resulting in errors like seen above. Add KBUILD_CPPFLAGS to as-option invocations to clear up the errors. This should have been done in commit d5c8d6e0fa61 ("kbuild: Update assembler calls to use proper flags and language target"), which switched from using the assembler target to the assembler-with-cpp target, so flags that affect preprocessing are passed along in all relevant tests. as-option now mirrors cc-option. Fixes: feb843a469fb ("kbuild: add $(CLANG_FLAGS) to KBUILD_CPPFLAGS") Reported-by: Linux Kernel Functional Testing Closes: https://lore.kernel.org/CA+G9fYs=koW9WardsTtora+nMgLR3raHz-LSLr58tgX4T5Mxag@mail.gmail.com/ Signed-off-by: Nathan Chancellor Tested-by: Naresh Kamboju Signed-off-by: Masahiro Yamada Signed-off-by: Nathan Chancellor Signed-off-by: Greg Kroah-Hartman --- scripts/Kbuild.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index b01d3108596b..4d2b8e659747 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -102,7 +102,7 @@ try-run = $(shell set -e; \ # Usage: aflags-y += $(call as-option,-Wa$(comma)-isa=foo,) as-option = $(call try-run,\ - $(CC) -Werror $(KBUILD_AFLAGS) $(1) -c -x assembler-with-cpp /dev/null -o "$$TMP",$(1),$(2)) + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(1) -c -x assembler-with-cpp /dev/null -o "$$TMP",$(1),$(2)) # as-instr # Usage: aflags-y += $(call as-instr,instr,option1,option2) From 6f38c6380c3b38a05032b8881e41137385a6ce02 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 28 Jul 2025 13:21:56 +0100 Subject: [PATCH 328/404] comedi: Fix initialization of data for instructions that write to subdevice [ Upstream commit 46d8c744136ce2454aa4c35c138cc06817f92b8e ] Some Comedi subdevice instruction handlers are known to access instruction data elements beyond the first `insn->n` elements in some cases. The `do_insn_ioctl()` and `do_insnlist_ioctl()` functions allocate at least `MIN_SAMPLES` (16) data elements to deal with this, but they do not initialize all of that. For Comedi instruction codes that write to the subdevice, the first `insn->n` data elements are copied from user-space, but the remaining elements are left uninitialized. That could be a problem if the subdevice instruction handler reads the uninitialized data. Ensure that the first `MIN_SAMPLES` elements are initialized before calling these instruction handlers, filling the uncopied elements with 0. For `do_insnlist_ioctl()`, the same data buffer elements are used for handling a list of instructions, so ensure the first `MIN_SAMPLES` elements are initialized for each instruction that writes to the subdevice. Fixes: ed9eccbe8970 ("Staging: add comedi core") Cc: stable@vger.kernel.org # 5.13+ Signed-off-by: Ian Abbott Link: https://lore.kernel.org/r/20250707161439.88385-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman [ Reworked for before commit bac42fb21259 ("comedi: get rid of compat_alloc_user_space() mess in COMEDI_CMD{,TEST} compat") ] Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 9d1db83209e2..49eba2e672eb 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1584,21 +1584,27 @@ static int do_insnlist_ioctl(struct comedi_device *dev, } for (i = 0; i < insnlist.n_insns; ++i) { + unsigned int n = insns[i].n; + if (insns[i].insn & INSN_MASK_WRITE) { if (copy_from_user(data, insns[i].data, - insns[i].n * sizeof(unsigned int))) { + n * sizeof(unsigned int))) { dev_dbg(dev->class_dev, "copy_from_user failed\n"); ret = -EFAULT; goto error; } + if (n < MIN_SAMPLES) { + memset(&data[n], 0, (MIN_SAMPLES - n) * + sizeof(unsigned int)); + } } ret = parse_insn(dev, insns + i, data, file); if (ret < 0) goto error; if (insns[i].insn & INSN_MASK_READ) { if (copy_to_user(insns[i].data, data, - insns[i].n * sizeof(unsigned int))) { + n * sizeof(unsigned int))) { dev_dbg(dev->class_dev, "copy_to_user failed\n"); ret = -EFAULT; @@ -1665,6 +1671,10 @@ static int do_insn_ioctl(struct comedi_device *dev, ret = -EFAULT; goto error; } + if (insn.n < MIN_SAMPLES) { + memset(&data[insn.n], 0, + (MIN_SAMPLES - insn.n) * sizeof(unsigned int)); + } } ret = parse_insn(dev, &insn, data, file); if (ret < 0) From 454d732dfd0aef7d7aa950c409215ca06d717e93 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 28 Jul 2025 13:18:20 +0100 Subject: [PATCH 329/404] comedi: Fail COMEDI_INSNLIST ioctl if n_insns is too large [ Upstream commit 08ae4b20f5e82101d77326ecab9089e110f224cc ] The handling of the `COMEDI_INSNLIST` ioctl allocates a kernel buffer to hold the array of `struct comedi_insn`, getting the length from the `n_insns` member of the `struct comedi_insnlist` supplied by the user. The allocation will fail with a WARNING and a stack dump if it is too large. Avoid that by failing with an `-EINVAL` error if the supplied `n_insns` value is unreasonable. Define the limit on the `n_insns` value in the `MAX_INSNS` macro. Set this to the same value as `MAX_SAMPLES` (65536), which is the maximum allowed sum of the values of the member `n` in the array of `struct comedi_insn`, and sensible comedi instructions will have an `n` of at least 1. Reported-by: syzbot+d6995b62e5ac7d79557a@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=d6995b62e5ac7d79557a Fixes: ed9eccbe8970 ("Staging: add comedi core") Tested-by: Ian Abbott Cc: stable@vger.kernel.org # 5.13+ Signed-off-by: Ian Abbott Link: https://lore.kernel.org/r/20250704120405.83028-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman [ Reworked for before commit bac42fb21259 ("comedi: get rid of compat_alloc_user_space() mess in COMEDI_CMD{,TEST} compat") ] Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_compat32.c | 3 +++ drivers/staging/comedi/comedi_fops.c | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c index 36a3564ba1fb..2f444e2b92c2 100644 --- a/drivers/staging/comedi/comedi_compat32.c +++ b/drivers/staging/comedi/comedi_compat32.c @@ -360,6 +360,9 @@ static int compat_insnlist(struct file *file, unsigned long arg) if (err) return -EFAULT; + if (n_insns > 65536) /* See MAX_INSNS in comedi_fops.c */ + return -EINVAL; + /* Allocate user memory to copy insnlist and insns into. */ s = compat_alloc_user_space(offsetof(struct combined_insnlist, insn[n_insns])); diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 49eba2e672eb..219a36216e50 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1519,6 +1519,16 @@ out: return ret; } +#define MAX_INSNS 65536 +static int check_insnlist_len(struct comedi_device *dev, unsigned int n_insns) +{ + if (n_insns > MAX_INSNS) { + dev_dbg(dev->class_dev, "insnlist length too large\n"); + return -EINVAL; + } + return 0; +} + /* * COMEDI_INSNLIST ioctl * synchronous instruction list @@ -1551,6 +1561,9 @@ static int do_insnlist_ioctl(struct comedi_device *dev, if (copy_from_user(&insnlist, arg, sizeof(insnlist))) return -EFAULT; + ret = check_insnlist_len(dev, insnlist.n_insns); + if (ret) + return ret; insns = kcalloc(insnlist.n_insns, sizeof(*insns), GFP_KERNEL); if (!insns) { ret = -ENOMEM; From 8e8b5f12ee4ab6f5d252c9ca062a4ada9554e6d9 Mon Sep 17 00:00:00 2001 From: Li Zhong Date: Fri, 2 Sep 2022 00:37:30 -0700 Subject: [PATCH 330/404] ACPI: processor: idle: Check acpi_fetch_acpi_dev() return value commit 2437513a814b3e93bd02879740a8a06e52e2cf7d upstream. The return value of acpi_fetch_acpi_dev() could be NULL, which would cause a NULL pointer dereference to occur in acpi_device_hid(). Signed-off-by: Li Zhong [ rjw: Subject and changelog edits, added empty line after if () ] Signed-off-by: Rafael J. Wysocki Signed-off-by: Teddy Astie Signed-off-by: Yann Sionneau Reported-by: Dillon C Tested-by: Dillon C Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/processor_idle.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 92db8b0622b2..e6bba26caf3c 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -1228,7 +1228,9 @@ static int acpi_processor_get_lpi_info(struct acpi_processor *pr) status = acpi_get_parent(handle, &pr_ahandle); while (ACPI_SUCCESS(status)) { - acpi_bus_get_device(pr_ahandle, &d); + if (acpi_bus_get_device(pr_ahandle, &d)) + break; + handle = pr_ahandle; if (strcmp(acpi_device_hid(d), ACPI_PROCESSOR_CONTAINER_HID)) From 607b3426547701efcc4f3d39ce05137497601909 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sun, 13 Jul 2025 16:31:01 +0200 Subject: [PATCH 331/404] PCI/ACPI: Fix runtime PM ref imbalance on Hot-Plug Capable ports commit 6cff20ce3b92ffbf2fc5eb9e5a030b3672aa414a upstream. pci_bridge_d3_possible() is called from both pcie_portdrv_probe() and pcie_portdrv_remove() to determine whether runtime power management shall be enabled (on probe) or disabled (on remove) on a PCIe port. The underlying assumption is that pci_bridge_d3_possible() always returns the same value, else a runtime PM reference imbalance would occur. That assumption is not given if the PCIe port is inaccessible on remove due to hot-unplug: pci_bridge_d3_possible() calls pciehp_is_native(), which accesses Config Space to determine whether the port is Hot-Plug Capable. An inaccessible port returns "all ones", which is converted to "all zeroes" by pcie_capability_read_dword(). Hence the port no longer seems Hot-Plug Capable on remove even though it was on probe. The resulting runtime PM ref imbalance causes warning messages such as: pcieport 0000:02:04.0: Runtime PM usage count underflow! Avoid the Config Space access (and thus the runtime PM ref imbalance) by caching the Hot-Plug Capable bit in struct pci_dev. The struct already contains an "is_hotplug_bridge" flag, which however is not only set on Hot-Plug Capable PCIe ports, but also Conventional PCI Hot-Plug bridges and ACPI slots. The flag identifies bridges which are allocated additional MMIO and bus number resources to allow for hierarchy expansion. The kernel is somewhat sloppily using "is_hotplug_bridge" in a number of places to identify Hot-Plug Capable PCIe ports, even though the flag encompasses other devices. Subsequent commits replace these occurrences with the new flag to clearly delineate Hot-Plug Capable PCIe ports from other kinds of hotplug bridges. Document the existing "is_hotplug_bridge" and the new "is_pciehp" flag and document the (non-obvious) requirement that pci_bridge_d3_possible() always returns the same value across the entire lifetime of a bridge, including its hot-removal. Fixes: 5352a44a561d ("PCI: pciehp: Make pciehp_is_native() stricter") Reported-by: Laurent Bigonville Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220216 Reported-by: Mario Limonciello Closes: https://lore.kernel.org/r/20250609020223.269407-3-superm1@kernel.org/ Link: https://lore.kernel.org/all/20250620025535.3425049-3-superm1@kernel.org/T/#u Signed-off-by: Lukas Wunner Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki Cc: stable@vger.kernel.org # v4.18+ Link: https://patch.msgid.link/fe5dcc3b2e62ee1df7905d746bde161eb1b3291c.1752390101.git.lukas@wunner.de [ Adjust surrounding documentation changes ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-acpi.c | 4 +--- drivers/pci/pci.c | 8 ++++++-- drivers/pci/probe.c | 2 +- include/linux/pci.h | 1 + 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 86dc5ae17c6d..07d1508e6dc5 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -791,13 +791,11 @@ int pci_acpi_program_hp_params(struct pci_dev *dev) bool pciehp_is_native(struct pci_dev *bridge) { const struct pci_host_bridge *host; - u32 slot_cap; if (!IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)) return false; - pcie_capability_read_dword(bridge, PCI_EXP_SLTCAP, &slot_cap); - if (!(slot_cap & PCI_EXP_SLTCAP_HPC)) + if (!bridge->is_pciehp) return false; if (pcie_ports_native) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 050fb376d1c5..11aa5cf9bd1f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2646,8 +2646,12 @@ static const struct dmi_system_id bridge_d3_blacklist[] = { * pci_bridge_d3_possible - Is it possible to put the bridge into D3 * @bridge: Bridge to check * - * This function checks if it is possible to move the bridge to D3. - * Currently we only allow D3 for recent enough PCIe ports and Thunderbolt. + * Currently we only allow D3 for some PCIe ports and for Thunderbolt. + * + * Return: Whether it is possible to move the bridge to D3. + * + * The return value is guaranteed to be constant across the entire lifetime + * of the bridge, including its hot-removal. */ bool pci_bridge_d3_possible(struct pci_dev *bridge) { diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index cae7ca18a69d..aa726740514b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1479,7 +1479,7 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev) pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, ®32); if (reg32 & PCI_EXP_SLTCAP_HPC) - pdev->is_hotplug_bridge = 1; + pdev->is_hotplug_bridge = pdev->is_pciehp = 1; } static void set_pcie_thunderbolt(struct pci_dev *dev) diff --git a/include/linux/pci.h b/include/linux/pci.h index f2f92eb950cc..d24d709e5625 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -415,6 +415,7 @@ struct pci_dev { unsigned int is_virtfn:1; unsigned int reset_fn:1; unsigned int is_hotplug_bridge:1; + unsigned int is_pciehp:1; unsigned int shpc_managed:1; /* SHPC owned by shpchp */ unsigned int is_thunderbolt:1; /* Thunderbolt controller */ /* From 4251ee9dcc4b36e14a143270f6951aa19a8a9072 Mon Sep 17 00:00:00 2001 From: John Ernberg Date: Wed, 23 Jul 2025 10:25:35 +0000 Subject: [PATCH 332/404] net: usbnet: Avoid potential RCU stall on LINK_CHANGE event commit 0d9cfc9b8cb17dbc29a98792d36ec39a1cf1395f upstream. The Gemalto Cinterion PLS83-W modem (cdc_ether) is emitting confusing link up and down events when the WWAN interface is activated on the modem-side. Interrupt URBs will in consecutive polls grab: * Link Connected * Link Disconnected * Link Connected Where the last Connected is then a stable link state. When the system is under load this may cause the unlink_urbs() work in __handle_link_change() to not complete before the next usbnet_link_change() call turns the carrier on again, allowing rx_submit() to queue new SKBs. In that event the URB queue is filled faster than it can drain, ending up in a RCU stall: rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 0-.... } 33108 jiffies s: 201 root: 0x1/. rcu: blocking rcu_node structures (internal RCU debug): Sending NMI from CPU 1 to CPUs 0: NMI backtrace for cpu 0 Call trace: arch_local_irq_enable+0x4/0x8 local_bh_enable+0x18/0x20 __netdev_alloc_skb+0x18c/0x1cc rx_submit+0x68/0x1f8 [usbnet] rx_alloc_submit+0x4c/0x74 [usbnet] usbnet_bh+0x1d8/0x218 [usbnet] usbnet_bh_tasklet+0x10/0x18 [usbnet] tasklet_action_common+0xa8/0x110 tasklet_action+0x2c/0x34 handle_softirqs+0x2cc/0x3a0 __do_softirq+0x10/0x18 ____do_softirq+0xc/0x14 call_on_irq_stack+0x24/0x34 do_softirq_own_stack+0x18/0x20 __irq_exit_rcu+0xa8/0xb8 irq_exit_rcu+0xc/0x30 el1_interrupt+0x34/0x48 el1h_64_irq_handler+0x14/0x1c el1h_64_irq+0x68/0x6c _raw_spin_unlock_irqrestore+0x38/0x48 xhci_urb_dequeue+0x1ac/0x45c [xhci_hcd] unlink1+0xd4/0xdc [usbcore] usb_hcd_unlink_urb+0x70/0xb0 [usbcore] usb_unlink_urb+0x24/0x44 [usbcore] unlink_urbs.constprop.0.isra.0+0x64/0xa8 [usbnet] __handle_link_change+0x34/0x70 [usbnet] usbnet_deferred_kevent+0x1c0/0x320 [usbnet] process_scheduled_works+0x2d0/0x48c worker_thread+0x150/0x1dc kthread+0xd8/0xe8 ret_from_fork+0x10/0x20 Get around the problem by delaying the carrier on to the scheduled work. This needs a new flag to keep track of the necessary action. The carrier ok check cannot be removed as it remains required for the LINK_RESET event flow. Fixes: 4b49f58fff00 ("usbnet: handle link change") Cc: stable@vger.kernel.org Signed-off-by: John Ernberg Link: https://patch.msgid.link/20250723102526.1305339-1-john.ernberg@actia.se Signed-off-by: Jakub Kicinski [ adjust context in header ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/usbnet.c | 11 ++++++++--- include/linux/usb/usbnet.h | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 1e8f395c8639..2957e3a0080c 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1106,6 +1106,9 @@ static void __handle_link_change(struct usbnet *dev) * tx queue is stopped by netcore after link becomes off */ } else { + if (test_and_clear_bit(EVENT_LINK_CARRIER_ON, &dev->flags)) + netif_carrier_on(dev->net); + /* submitting URBs for reading packets */ tasklet_schedule(&dev->bh); } @@ -1978,10 +1981,12 @@ EXPORT_SYMBOL(usbnet_manage_power); void usbnet_link_change(struct usbnet *dev, bool link, bool need_reset) { /* update link after link is reseted */ - if (link && !need_reset) - netif_carrier_on(dev->net); - else + if (link && !need_reset) { + set_bit(EVENT_LINK_CARRIER_ON, &dev->flags); + } else { + clear_bit(EVENT_LINK_CARRIER_ON, &dev->flags); netif_carrier_off(dev->net); + } if (need_reset && link) usbnet_defer_kevent(dev, EVENT_LINK_RESET); diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index fc6ed1311589..83ca77818822 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -83,6 +83,7 @@ struct usbnet { # define EVENT_LINK_CHANGE 11 # define EVENT_SET_RX_MODE 12 # define EVENT_NO_IP_ALIGN 13 +# define EVENT_LINK_CARRIER_ON 14 u32 rx_speed; /* in bps - NOT Mbps */ u32 tx_speed; /* in bps - NOT Mbps */ }; From 7262154d34359f4ffad6af2c456cf683c951a261 Mon Sep 17 00:00:00 2001 From: Ammar Faizi Date: Wed, 6 Aug 2025 07:31:05 +0700 Subject: [PATCH 333/404] net: usbnet: Fix the wrong netif_carrier_on() call commit 8466d393700f9ccef68134d3349f4e0a087679b9 upstream. The commit referenced in the Fixes tag causes usbnet to malfunction (identified via git bisect). Post-commit, my external RJ45 LAN cable fails to connect. Linus also reported the same issue after pulling that commit. The code has a logic error: netif_carrier_on() is only called when the link is already on. Fix this by moving the netif_carrier_on() call outside the if-statement entirely. This ensures it is always called when EVENT_LINK_CARRIER_ON is set and properly clears it regardless of the link state. Cc: stable@vger.kernel.org Cc: Armando Budianto Reviewed-by: Simon Horman Suggested-by: Linus Torvalds Link: https://lore.kernel.org/all/CAHk-=wjqL4uF0MG_c8+xHX1Vv8==sPYQrtzbdA3kzi96284nuQ@mail.gmail.com Closes: https://lore.kernel.org/netdev/CAHk-=wjKh8X4PT_mU1kD4GQrbjivMfPn-_hXa6han_BTDcXddw@mail.gmail.com Closes: https://lore.kernel.org/netdev/0752dee6-43d6-4e1f-81d2-4248142cccd2@gnuweeb.org Fixes: 0d9cfc9b8cb1 ("net: usbnet: Avoid potential RCU stall on LINK_CHANGE event") Signed-off-by: Ammar Faizi Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/usbnet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 2957e3a0080c..87c0bcfef480 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1097,6 +1097,9 @@ static void __handle_link_change(struct usbnet *dev) if (!test_bit(EVENT_DEV_OPEN, &dev->flags)) return; + if (test_and_clear_bit(EVENT_LINK_CARRIER_ON, &dev->flags)) + netif_carrier_on(dev->net); + if (!netif_carrier_ok(dev->net)) { /* kill URBs for reading packets to save bus bandwidth */ unlink_urbs(dev, &dev->rxq); @@ -1106,9 +1109,6 @@ static void __handle_link_change(struct usbnet *dev) * tx queue is stopped by netcore after link becomes off */ } else { - if (test_and_clear_bit(EVENT_LINK_CARRIER_ON, &dev->flags)) - netif_carrier_on(dev->net); - /* submitting URBs for reading packets */ tasklet_schedule(&dev->bh); } From 35370d3b44efe194fd5ad55bac987e629597d782 Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Tue, 29 Jul 2025 15:31:23 -0400 Subject: [PATCH 334/404] ice: Fix a null pointer dereference in ice_copy_and_init_pkg() [ Upstream commit 4ff12d82dac119b4b99b5a78b5af3bf2474c0a36 ] Add check for the return value of devm_kmemdup() to prevent potential null pointer dereference. Fixes: c76488109616 ("ice: Implement Dynamic Device Personalization (DDP) download") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li Reviewed-by: Michal Swiatkowski Reviewed-by: Aleksandr Loktionov Reviewed-by: Simon Horman Tested-by: Rinitha S (A Contingent worker at Intel) Signed-off-by: Tony Nguyen [ applied the patch to ice_flex_pipe.c instead of ice_ddp.c ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/intel/ice/ice_flex_pipe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c index 6cfe8eb7f47d..14fba20ab7f3 100644 --- a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c +++ b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c @@ -753,6 +753,8 @@ enum ice_status ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len) return ICE_ERR_PARAM; buf_copy = devm_kmemdup(ice_hw_to_dev(hw), buf, len, GFP_KERNEL); + if (!buf_copy) + return ICE_ERR_NO_MEMORY; status = ice_init_pkg(hw, buf_copy, len); if (status) { From 0e0d8c68f3d34d8f1aa04292721db90550189f85 Mon Sep 17 00:00:00 2001 From: "Lin.Cao" Date: Tue, 29 Jul 2025 13:14:55 -0400 Subject: [PATCH 335/404] drm/sched: Remove optimization that causes hang when killing dependent jobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 15f77764e90a713ee3916ca424757688e4f565b9 ] When application A submits jobs and application B submits a job with a dependency on A's fence, the normal flow wakes up the scheduler after processing each job. However, the optimization in drm_sched_entity_add_dependency_cb() uses a callback that only clears dependencies without waking up the scheduler. When application A is killed before its jobs can run, the callback gets triggered but only clears the dependency without waking up the scheduler, causing the scheduler to enter sleep state and application B to hang. Remove the optimization by deleting drm_sched_entity_clear_dep() and its usage, ensuring the scheduler is always woken up when dependencies are cleared. Fixes: 777dbd458c89 ("drm/amdgpu: drop a dummy wakeup scheduler") Cc: stable@vger.kernel.org # v4.6+ Signed-off-by: Lin.Cao Reviewed-by: Christian König Signed-off-by: Philipp Stanner Link: https://lore.kernel.org/r/20250717084453.921097-1-lincao12@amd.com [ adjusted context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/scheduler/sched_entity.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 57f9baad9e36..d9b20bb7c7f5 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -327,19 +327,6 @@ void drm_sched_entity_destroy(struct drm_sched_entity *entity) } EXPORT_SYMBOL(drm_sched_entity_destroy); -/** - * drm_sched_entity_clear_dep - callback to clear the entities dependency - */ -static void drm_sched_entity_clear_dep(struct dma_fence *f, - struct dma_fence_cb *cb) -{ - struct drm_sched_entity *entity = - container_of(cb, struct drm_sched_entity, cb); - - entity->dependency = NULL; - dma_fence_put(f); -} - /** * drm_sched_entity_clear_dep - callback to clear the entities dependency and * wake up scheduler @@ -350,7 +337,8 @@ static void drm_sched_entity_wakeup(struct dma_fence *f, struct drm_sched_entity *entity = container_of(cb, struct drm_sched_entity, cb); - drm_sched_entity_clear_dep(f, cb); + entity->dependency = NULL; + dma_fence_put(f); drm_sched_wakeup(entity->rq->sched); } @@ -426,13 +414,6 @@ static bool drm_sched_entity_add_dependency_cb(struct drm_sched_entity *entity) fence = dma_fence_get(&s_fence->scheduled); dma_fence_put(entity->dependency); entity->dependency = fence; - if (!dma_fence_add_callback(fence, &entity->cb, - drm_sched_entity_clear_dep)) - return true; - - /* Ignore it when it is already scheduled */ - dma_fence_put(fence); - return false; } if (!dma_fence_add_callback(entity->dependency, &entity->cb, From a773caa6b41590b2a7a82c463bf61f8b12548c0b Mon Sep 17 00:00:00 2001 From: Miaohe Lin Date: Tue, 29 Jul 2025 11:13:25 -0400 Subject: [PATCH 336/404] mm/zsmalloc.c: convert to use kmem_cache_zalloc in cache_alloc_zspage() [ Upstream commit f0231305acd53375c6cf736971bf5711105dd6bb ] We always memset the zspage allocated via cache_alloc_zspage. So it's more convenient to use kmem_cache_zalloc in cache_alloc_zspage than caller do it manually. Link: https://lkml.kernel.org/r/20210114120032.25885-1-linmiaohe@huawei.com Signed-off-by: Miaohe Lin Reviewed-by: Sergey Senozhatsky Cc: Minchan Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Stable-dep-of: 694d6b99923e ("mm/zsmalloc: do not pass __GFP_MOVABLE if CONFIG_COMPACTION=n") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- mm/zsmalloc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index 6b100f02ee43..eae16c6b6fc6 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -357,7 +357,7 @@ static void cache_free_handle(struct zs_pool *pool, unsigned long handle) static struct zspage *cache_alloc_zspage(struct zs_pool *pool, gfp_t flags) { - return kmem_cache_alloc(pool->zspage_cachep, + return kmem_cache_zalloc(pool->zspage_cachep, flags & ~(__GFP_HIGHMEM|__GFP_MOVABLE)); } @@ -1067,7 +1067,6 @@ static struct zspage *alloc_zspage(struct zs_pool *pool, if (!zspage) return NULL; - memset(zspage, 0, sizeof(struct zspage)); zspage->magic = ZSPAGE_MAGIC; migrate_lock_init(zspage); From 6ae674a29858db3244eadc4cef4eee738136fbed Mon Sep 17 00:00:00 2001 From: Harry Yoo Date: Tue, 29 Jul 2025 11:13:26 -0400 Subject: [PATCH 337/404] mm/zsmalloc: do not pass __GFP_MOVABLE if CONFIG_COMPACTION=n [ Upstream commit 694d6b99923eb05a8fd188be44e26077d19f0e21 ] Commit 48b4800a1c6a ("zsmalloc: page migration support") added support for migrating zsmalloc pages using the movable_operations migration framework. However, the commit did not take into account that zsmalloc supports migration only when CONFIG_COMPACTION is enabled. Tracing shows that zsmalloc was still passing the __GFP_MOVABLE flag even when compaction is not supported. This can result in unmovable pages being allocated from movable page blocks (even without stealing page blocks), ZONE_MOVABLE and CMA area. Possible user visible effects: - Some ZONE_MOVABLE memory can be not actually movable - CMA allocation can fail because of this - Increased memory fragmentation due to ignoring the page mobility grouping feature I'm not really sure who uses kernels without compaction support, though :( To fix this, clear the __GFP_MOVABLE flag when !IS_ENABLED(CONFIG_COMPACTION). Link: https://lkml.kernel.org/r/20250704103053.6913-1-harry.yoo@oracle.com Fixes: 48b4800a1c6a ("zsmalloc: page migration support") Signed-off-by: Harry Yoo Acked-by: David Hildenbrand Reviewed-by: Sergey Senozhatsky Cc: Minchan Kim Cc: Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- mm/zsmalloc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index eae16c6b6fc6..b379deb0a10c 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -1067,6 +1067,9 @@ static struct zspage *alloc_zspage(struct zs_pool *pool, if (!zspage) return NULL; + if (!IS_ENABLED(CONFIG_COMPACTION)) + gfp &= ~__GFP_MOVABLE; + zspage->magic = ZSPAGE_MAGIC; migrate_lock_init(zspage); From 44e904a1ad09e84039058dcbbb1b9ea5b8d7d75d Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 24 Jul 2025 13:50:53 -0400 Subject: [PATCH 338/404] f2fs: fix to do sanity check on ino and xnid [ Upstream commit 061cf3a84bde038708eb0f1d065b31b7c2456533 ] syzbot reported a f2fs bug as below: INFO: task syz-executor140:5308 blocked for more than 143 seconds. Not tainted 6.14.0-rc7-syzkaller-00069-g81e4f8d68c66 #0 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:syz-executor140 state:D stack:24016 pid:5308 tgid:5308 ppid:5306 task_flags:0x400140 flags:0x00000006 Call Trace: context_switch kernel/sched/core.c:5378 [inline] __schedule+0x190e/0x4c90 kernel/sched/core.c:6765 __schedule_loop kernel/sched/core.c:6842 [inline] schedule+0x14b/0x320 kernel/sched/core.c:6857 io_schedule+0x8d/0x110 kernel/sched/core.c:7690 folio_wait_bit_common+0x839/0xee0 mm/filemap.c:1317 __folio_lock mm/filemap.c:1664 [inline] folio_lock include/linux/pagemap.h:1163 [inline] __filemap_get_folio+0x147/0xb40 mm/filemap.c:1917 pagecache_get_page+0x2c/0x130 mm/folio-compat.c:87 find_get_page_flags include/linux/pagemap.h:842 [inline] f2fs_grab_cache_page+0x2b/0x320 fs/f2fs/f2fs.h:2776 __get_node_page+0x131/0x11b0 fs/f2fs/node.c:1463 read_xattr_block+0xfb/0x190 fs/f2fs/xattr.c:306 lookup_all_xattrs fs/f2fs/xattr.c:355 [inline] f2fs_getxattr+0x676/0xf70 fs/f2fs/xattr.c:533 __f2fs_get_acl+0x52/0x870 fs/f2fs/acl.c:179 f2fs_acl_create fs/f2fs/acl.c:375 [inline] f2fs_init_acl+0xd7/0x9b0 fs/f2fs/acl.c:418 f2fs_init_inode_metadata+0xa0f/0x1050 fs/f2fs/dir.c:539 f2fs_add_inline_entry+0x448/0x860 fs/f2fs/inline.c:666 f2fs_add_dentry+0xba/0x1e0 fs/f2fs/dir.c:765 f2fs_do_add_link+0x28c/0x3a0 fs/f2fs/dir.c:808 f2fs_add_link fs/f2fs/f2fs.h:3616 [inline] f2fs_mknod+0x2e8/0x5b0 fs/f2fs/namei.c:766 vfs_mknod+0x36d/0x3b0 fs/namei.c:4191 unix_bind_bsd net/unix/af_unix.c:1286 [inline] unix_bind+0x563/0xe30 net/unix/af_unix.c:1379 __sys_bind_socket net/socket.c:1817 [inline] __sys_bind+0x1e4/0x290 net/socket.c:1848 __do_sys_bind net/socket.c:1853 [inline] __se_sys_bind net/socket.c:1851 [inline] __x64_sys_bind+0x7a/0x90 net/socket.c:1851 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f Let's dump and check metadata of corrupted inode, it shows its xattr_nid is the same to its i_ino. dump.f2fs -i 3 chaseyu.img.raw i_xattr_nid [0x 3 : 3] So that, during mknod in the corrupted directory, it tries to get and lock inode page twice, result in deadlock. - f2fs_mknod - f2fs_add_inline_entry - f2fs_get_inode_page --- lock dir's inode page - f2fs_init_acl - f2fs_acl_create(dir,..) - __f2fs_get_acl - f2fs_getxattr - lookup_all_xattrs - __get_node_page --- try to lock dir's inode page In order to fix this, let's add sanity check on ino and xnid. Cc: stable@vger.kernel.org Reported-by: syzbot+cc448dcdc7ae0b4e4ffa@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-f2fs-devel/67e06150.050a0220.21942d.0005.GAE@google.com Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim [ add set_sbi_flag(sbi, SBI_NEED_FSCK) to match error handling pattern ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/inode.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 03444ebc741b..ce4f4a67134f 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -221,6 +221,13 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page) return false; } + if (ino_of_node(node_page) == fi->i_xattr_nid) { + set_sbi_flag(sbi, SBI_NEED_FSCK); + f2fs_warn(sbi, "%s: corrupted inode i_ino=%lx, xnid=%x, run fsck to fix.", + __func__, inode->i_ino, fi->i_xattr_nid); + return false; + } + if (f2fs_sb_has_flexible_inline_xattr(sbi) && !f2fs_has_extra_attr(inode)) { set_sbi_flag(sbi, SBI_NEED_FSCK); From 19e7a5810794bb1c1861e249e0fa84af3875c70a Mon Sep 17 00:00:00 2001 From: Zhang Lixu Date: Thu, 24 Jul 2025 12:33:27 -0400 Subject: [PATCH 339/404] iio: hid-sensor-prox: Fix incorrect OFFSET calculation [ Upstream commit 79dabbd505210e41c88060806c92c052496dd61c ] The OFFSET calculation in the prox_read_raw() was incorrectly using the unit exponent, which is intended for SCALE calculations. Remove the incorrect OFFSET calculation and set it to a fixed value of 0. Cc: stable@vger.kernel.org Fixes: 39a3a0138f61 ("iio: hid-sensors: Added Proximity Sensor Driver") Signed-off-by: Zhang Lixu Acked-by: Srinivas Pandruvada Link: https://patch.msgid.link/20250331055022.1149736-4-lixu.zhang@intel.com Signed-off-by: Jonathan Cameron [ adapted prox_attr array access to single structure member access ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/iio/light/hid-sensor-prox.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c index 70da928e0d16..9c6c71218cf2 100644 --- a/drivers/iio/light/hid-sensor-prox.c +++ b/drivers/iio/light/hid-sensor-prox.c @@ -103,8 +103,7 @@ static int prox_read_raw(struct iio_dev *indio_dev, ret_type = prox_state->scale_precision; break; case IIO_CHAN_INFO_OFFSET: - *val = hid_sensor_convert_exponent( - prox_state->prox_attr.unit_expo); + *val = 0; ret_type = IIO_VAL_INT; break; case IIO_CHAN_INFO_SAMP_FREQ: From 3dbc0ed94799bf99eef2acd4b7551a790cae5803 Mon Sep 17 00:00:00 2001 From: Yazen Ghannam Date: Wed, 23 Jul 2025 00:24:51 -0400 Subject: [PATCH 340/404] x86/mce/amd: Add default names for MCA banks and blocks [ Upstream commit d66e1e90b16055d2f0ee76e5384e3f119c3c2773 ] Ensure that sysfs init doesn't fail for new/unrecognized bank types or if a bank has additional blocks available. Most MCA banks have a single thresholding block, so the block takes the same name as the bank. Unified Memory Controllers (UMCs) are a special case where there are two blocks and each has a unique name. However, the microarchitecture allows for five blocks. Any new MCA bank types with more than one block will be missing names for the extra blocks. The MCE sysfs will fail to initialize in this case. Fixes: 87a6d4091bd7 ("x86/mce/AMD: Update sysfs bank names for SMCA systems") Signed-off-by: Yazen Ghannam Signed-off-by: Borislav Petkov (AMD) Cc: stable@vger.kernel.org Link: https://lore.kernel.org/20250624-wip-mca-updates-v4-3-236dd74f645f@amd.com Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- arch/x86/kernel/cpu/mce/amd.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c index 816b3d0512ba..ad71f5a7faf0 100644 --- a/arch/x86/kernel/cpu/mce/amd.c +++ b/arch/x86/kernel/cpu/mce/amd.c @@ -1180,13 +1180,20 @@ static const char *get_name(unsigned int bank, struct threshold_block *b) } bank_type = smca_get_bank_type(bank); - if (bank_type >= N_SMCA_BANK_TYPES) - return NULL; if (b && bank_type == SMCA_UMC) { if (b->block < ARRAY_SIZE(smca_umc_block_names)) return smca_umc_block_names[b->block]; - return NULL; + } + + if (b && b->block) { + snprintf(buf_mcatype, MAX_MCATYPE_NAME_LEN, "th_block_%u", b->block); + return buf_mcatype; + } + + if (bank_type >= N_SMCA_BANK_TYPES) { + snprintf(buf_mcatype, MAX_MCATYPE_NAME_LEN, "th_bank_%u", bank); + return buf_mcatype; } if (smca_banks[bank].hwid->count == 1) From 1bd9246548a19637e404b9a1ce56c00a1cdc5dad Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 22 Jul 2025 18:58:38 -0400 Subject: [PATCH 341/404] usb: hub: avoid warm port reset during USB3 disconnect [ Upstream commit f59f93cd1d720809466c7fd5aa16a236156c672b ] During disconnect USB-3 ports often go via SS.Inactive link error state before the missing terminations are noticed, and link finally goes to RxDetect state Avoid immediately warm-resetting ports in SS.Inactive state. Let ports settle for a while and re-read the link status a few times 20ms apart to see if the ports transitions out of SS.Inactive. According to USB 3.x spec 7.5.2, a port in SS.Inactive should automatically check for missing far-end receiver termination every 12 ms (SSInactiveQuietTimeout) The futile multiple warm reset retries of a disconnected device takes a lot of time, also the resetting of a removed devices has caused cases where the reset bit got stuck for a long time on xHCI roothub. This lead to issues in detecting new devices connected to the same port shortly after. Tested-by: Mark Pearson Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20211210111653.1378381-1-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 2521106fc732 ("usb: hub: Don't try to recover devices lost during warm reset.") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index a854fed13165..0bc8710943cf 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2788,6 +2788,8 @@ static unsigned hub_is_wusb(struct usb_hub *hub) #define SET_CONFIG_TRIES (2 * (use_both_schemes + 1)) #define USE_NEW_SCHEME(i, scheme) ((i) / 2 == (int)(scheme)) +#define DETECT_DISCONNECT_TRIES 5 + #define HUB_ROOT_RESET_TIME 60 /* times are in msec */ #define HUB_SHORT_RESET_TIME 10 #define HUB_BH_RESET_TIME 50 @@ -5422,6 +5424,7 @@ static void port_event(struct usb_hub *hub, int port1) struct usb_device *udev = port_dev->child; struct usb_device *hdev = hub->hdev; u16 portstatus, portchange; + int i = 0; connect_change = test_bit(port1, hub->change_bits); clear_bit(port1, hub->event_bits); @@ -5498,17 +5501,27 @@ static void port_event(struct usb_hub *hub, int port1) connect_change = 1; /* - * Warm reset a USB3 protocol port if it's in - * SS.Inactive state. + * Avoid trying to recover a USB3 SS.Inactive port with a warm reset if + * the device was disconnected. A 12ms disconnect detect timer in + * SS.Inactive state transitions the port to RxDetect automatically. + * SS.Inactive link error state is common during device disconnect. */ - if (hub_port_warm_reset_required(hub, port1, portstatus)) { - dev_dbg(&port_dev->dev, "do warm reset\n"); - if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION) + while (hub_port_warm_reset_required(hub, port1, portstatus)) { + if ((i++ < DETECT_DISCONNECT_TRIES) && udev) { + u16 unused; + + msleep(20); + hub_port_status(hub, port1, &portstatus, &unused); + dev_dbg(&port_dev->dev, "Wait for inactive link disconnect detect\n"); + continue; + } else if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION) || udev->state == USB_STATE_NOTATTACHED) { + dev_dbg(&port_dev->dev, "do warm reset, port only\n"); if (hub_port_reset(hub, port1, NULL, HUB_BH_RESET_TIME, true) < 0) hub_port_disable(hub, port1, 1); } else { + dev_dbg(&port_dev->dev, "do warm reset, full device\n"); usb_unlock_port(port_dev); usb_lock_device(udev); usb_reset_device(udev); @@ -5516,6 +5529,7 @@ static void port_event(struct usb_hub *hub, int port1) usb_lock_port(port_dev); connect_change = 0; } + break; } if (connect_change) From b25dad547b447d7800e3516a05c7a38e822fdff3 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 22 Jul 2025 18:58:39 -0400 Subject: [PATCH 342/404] usb: hub: Don't try to recover devices lost during warm reset. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 2521106fc732b0b75fd3555c689b1ed1d29d273c ] Hub driver warm-resets ports in SS.Inactive or Compliance mode to recover a possible connected device. The port reset code correctly detects if a connection is lost during reset, but hub driver port_event() fails to take this into account in some cases. port_event() ends up using stale values and assumes there is a connected device, and will try all means to recover it, including power-cycling the port. Details: This case was triggered when xHC host was suspended with DbC (Debug Capability) enabled and connected. DbC turns one xHC port into a simple usb debug device, allowing debugging a system with an A-to-A USB debug cable. xhci DbC code disables DbC when xHC is system suspended to D3, and enables it back during resume. We essentially end up with two hosts connected to each other during suspend, and, for a short while during resume, until DbC is enabled back. The suspended xHC host notices some activity on the roothub port, but can't train the link due to being suspended, so xHC hardware sets a CAS (Cold Attach Status) flag for this port to inform xhci host driver that the port needs to be warm reset once xHC resumes. CAS is xHCI specific, and not part of USB specification, so xhci driver tells usb core that the port has a connection and link is in compliance mode. Recovery from complinace mode is similar to CAS recovery. xhci CAS driver support that fakes a compliance mode connection was added in commit 8bea2bd37df0 ("usb: Add support for root hub port status CAS") Once xHCI resumes and DbC is enabled back, all activity on the xHC roothub host side port disappears. The hub driver will anyway think port has a connection and link is in compliance mode, and hub driver will try to recover it. The port power-cycle during recovery seems to cause issues to the active DbC connection. Fix this by clearing connect_change flag if hub_port_reset() returns -ENOTCONN, thus avoiding the whole unnecessary port recovery and initialization attempt. Cc: stable@vger.kernel.org Fixes: 8bea2bd37df0 ("usb: Add support for root hub port status CAS") Tested-by: Łukasz Bartosik Signed-off-by: Mathias Nyman Acked-by: Alan Stern Link: https://lore.kernel.org/r/20250623133947.3144608-1-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0bc8710943cf..1a2039d1b342 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -5425,6 +5425,7 @@ static void port_event(struct usb_hub *hub, int port1) struct usb_device *hdev = hub->hdev; u16 portstatus, portchange; int i = 0; + int err; connect_change = test_bit(port1, hub->change_bits); clear_bit(port1, hub->event_bits); @@ -5517,8 +5518,11 @@ static void port_event(struct usb_hub *hub, int port1) } else if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION) || udev->state == USB_STATE_NOTATTACHED) { dev_dbg(&port_dev->dev, "do warm reset, port only\n"); - if (hub_port_reset(hub, port1, NULL, - HUB_BH_RESET_TIME, true) < 0) + err = hub_port_reset(hub, port1, NULL, + HUB_BH_RESET_TIME, true); + if (!udev && err == -ENOTCONN) + connect_change = 0; + else if (err < 0) hub_port_disable(hub, port1, 1); } else { dev_dbg(&port_dev->dev, "do warm reset, full device\n"); From e70f5ee4c8824736332351b703c46f9469ed7f6c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 22 Jul 2025 10:13:20 -0400 Subject: [PATCH 343/404] tracing: Add down_write(trace_event_sem) when adding trace event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit b5e8acc14dcb314a9b61ff19dcd9fdd0d88f70df ] When a module is loaded, it adds trace events defined by the module. It may also need to modify the modules trace printk formats to replace enum names with their values. If two modules are loaded at the same time, the adding of the event to the ftrace_events list can corrupt the walking of the list in the code that is modifying the printk format strings and crash the kernel. The addition of the event should take the trace_event_sem for write while it adds the new event. Also add a lockdep_assert_held() on that semaphore in __trace_add_event_dirs() as it iterates the list. Cc: stable@vger.kernel.org Cc: Mathieu Desnoyers Acked-by: Masami Hiramatsu (Google) Link: https://lore.kernel.org/20250718223158.799bfc0c@batman.local.home Reported-by: Fusheng Huang(黄富生) Closes: https://lore.kernel.org/all/20250717105007.46ccd18f@batman.local.home/ Fixes: 110bf2b764eb6 ("tracing: add protection around module events unload") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace_events.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 77df1e28fa32..eae997f277b6 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2109,7 +2109,10 @@ __register_event(struct trace_event_call *call, struct module *mod) if (ret < 0) return ret; + down_write(&trace_event_sem); list_add(&call->list, &ftrace_events); + up_write(&trace_event_sem); + call->mod = mod; return 0; @@ -2489,6 +2492,8 @@ __trace_add_event_dirs(struct trace_array *tr) struct trace_event_call *call; int ret; + lockdep_assert_held(&trace_event_sem); + list_for_each_entry(call, &ftrace_events, list) { ret = __trace_add_new_event(call, tr); if (ret < 0) From 11cfbcfeac7a415db6c6a150b4308f500fd0fb0a Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Tue, 22 Jul 2025 09:48:27 -0400 Subject: [PATCH 344/404] pmdomain: governor: Consider CPU latency tolerance from pm_domain_cpu_gov [ Upstream commit 500ba33284416255b9a5b50ace24470b6fe77ea5 ] pm_domain_cpu_gov is selecting a cluster idle state but does not consider latency tolerance of child CPUs. This results in deeper cluster idle state whose latency does not meet latency tolerance requirement. Select deeper idle state only if global and device latency tolerance of all child CPUs meet. Test results on SM8750 with 300 usec PM-QoS on CPU0 which is less than domain idle state entry (2150) + exit (1983) usec latency mentioned in devicetree, demonstrate the issue. # echo 300 > /sys/devices/system/cpu/cpu0/power/pm_qos_resume_latency_us Before: (Usage is incrementing) ====== # cat /sys/kernel/debug/pm_genpd/power-domain-cluster0/idle_states State Time Spent(ms) Usage Rejected Above Below S0 29817 537 8 270 0 # cat /sys/kernel/debug/pm_genpd/power-domain-cluster0/idle_states State Time Spent(ms) Usage Rejected Above Below S0 30348 542 8 271 0 After: (Usage is not incrementing due to latency tolerance) ====== # cat /sys/kernel/debug/pm_genpd/power-domain-cluster0/idle_states State Time Spent(ms) Usage Rejected Above Below S0 39319 626 14 307 0 # cat /sys/kernel/debug/pm_genpd/power-domain-cluster0/idle_states State Time Spent(ms) Usage Rejected Above Below S0 39319 626 14 307 0 Signed-off-by: Maulik Shah Fixes: e94999688e3a ("PM / Domains: Add genpd governor for CPUs") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250709-pmdomain_qos-v2-1-976b12257899@oss.qualcomm.com Signed-off-by: Ulf Hansson [ replaced cpu_latency_qos_limit() with pm_qos_request(PM_QOS_CPU_DMA_LATENCY) ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/base/power/domain_governor.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c index 490ed7deb99a..35f2e961756b 100644 --- a/drivers/base/power/domain_governor.c +++ b/drivers/base/power/domain_governor.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -254,6 +255,8 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd) struct generic_pm_domain *genpd = pd_to_genpd(pd); struct cpuidle_device *dev; ktime_t domain_wakeup, next_hrtimer; + struct device *cpu_dev; + s64 cpu_constraint, global_constraint; s64 idle_duration_ns; int cpu, i; @@ -264,6 +267,7 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd) if (!(genpd->flags & GENPD_FLAG_CPU_DOMAIN)) return true; + global_constraint = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); /* * Find the next wakeup for any of the online CPUs within the PM domain * and its subdomains. Note, we only need the genpd->cpus, as it already @@ -277,8 +281,16 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd) if (ktime_before(next_hrtimer, domain_wakeup)) domain_wakeup = next_hrtimer; } + + cpu_dev = get_cpu_device(cpu); + if (cpu_dev) { + cpu_constraint = dev_pm_qos_raw_resume_latency(cpu_dev); + if (cpu_constraint < global_constraint) + global_constraint = cpu_constraint; + } } + global_constraint *= NSEC_PER_USEC; /* The minimum idle duration is from now - until the next wakeup. */ idle_duration_ns = ktime_to_ns(ktime_sub(domain_wakeup, ktime_get())); if (idle_duration_ns <= 0) @@ -291,8 +303,10 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd) */ i = genpd->state_idx; do { - if (idle_duration_ns >= (genpd->states[i].residency_ns + - genpd->states[i].power_off_latency_ns)) { + if ((idle_duration_ns >= (genpd->states[i].residency_ns + + genpd->states[i].power_off_latency_ns)) && + (global_constraint >= (genpd->states[i].power_on_latency_ns + + genpd->states[i].power_off_latency_ns))) { genpd->state_idx = i; return true; } From 3f252a73e81aa01660cb426735eab932e6182e8d Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 15 Aug 2025 16:27:45 -0400 Subject: [PATCH 345/404] nfsd: handle get_client_locked() failure in nfsd4_setclientid_confirm() [ Upstream commit 908e4ead7f757504d8b345452730636e298cbf68 ] Lei Lu recently reported that nfsd4_setclientid_confirm() did not check the return value from get_client_locked(). a SETCLIENTID_CONFIRM could race with a confirmed client expiring and fail to get a reference. That could later lead to a UAF. Fix this by getting a reference early in the case where there is an extant confirmed client. If that fails then treat it as if there were no confirmed client found at all. In the case where the unconfirmed client is expiring, just fail and return the result from get_client_locked(). Reported-by: lei lu Closes: https://lore.kernel.org/linux-nfs/CAEBF3_b=UvqzNKdnfD_52L05Mqrqui9vZ2eFamgAbV0WG+FNWQ@mail.gmail.com/ Fixes: d20c11d86d8f ("nfsd: Protect session creation and client confirm using client_lock") Cc: stable@vger.kernel.org Signed-off-by: Jeff Layton Signed-off-by: Chuck Lever [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/nfsd/nfs4state.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 1fd81ccf0c71..933de78918e3 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3956,10 +3956,16 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, } status = nfs_ok; if (conf) { /* case 1: callback update */ - old = unconf; - unhash_client_locked(old); - nfsd4_change_callback(conf, &unconf->cl_cb_conn); - } else { /* case 3: normal case; new or rebooted client */ + if (get_client_locked(conf) == nfs_ok) { + old = unconf; + unhash_client_locked(old); + nfsd4_change_callback(conf, &unconf->cl_cb_conn); + } else { + conf = NULL; + } + } + + if (!conf) { /* case 3: normal case; new or rebooted client */ old = find_confirmed_client_by_name(&unconf->cl_name, nn); if (old) { status = nfserr_clid_inuse; @@ -3975,10 +3981,14 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, goto out; } } + status = get_client_locked(unconf); + if (status != nfs_ok) { + old = NULL; + goto out; + } move_to_confirmed(unconf); conf = unconf; } - get_client_locked(conf); spin_unlock(&nn->client_lock); nfsd4_probe_callback(conf); spin_lock(&nn->client_lock); From 69683d17f3da72e70743a1e547e18cb96ac8f2a0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 14 Aug 2025 12:53:56 -0400 Subject: [PATCH 346/404] mm/hmm: move pmd_to_hmm_pfn_flags() to the respective #ifdeffery [ Upstream commit 188cb385bbf04d486df3e52f28c47b3961f5f0c0 ] When pmd_to_hmm_pfn_flags() is unused, it prevents kernel builds with clang, `make W=1` and CONFIG_TRANSPARENT_HUGEPAGE=n: mm/hmm.c:186:29: warning: unused function 'pmd_to_hmm_pfn_flags' [-Wunused-function] Fix this by moving the function to the respective existing ifdeffery for its the only user. See also: 6863f5643dd7 ("kbuild: allow Clang to find unused static inline functions for W=1 build") Link: https://lkml.kernel.org/r/20250710082403.664093-1-andriy.shevchenko@linux.intel.com Fixes: 992de9a8b751 ("mm/hmm: allow to mirror vma of a file on a DAX backed filesystem") Signed-off-by: Andy Shevchenko Reviewed-by: Leon Romanovsky Reviewed-by: Alistair Popple Cc: Andriy Shevchenko Cc: Bill Wendling Cc: Jerome Glisse Cc: Justin Stitt Cc: Nathan Chancellor Cc: Signed-off-by: Andrew Morton [ Minor context adjustment ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- mm/hmm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/hmm.c b/mm/hmm.c index 902f5fa6bf93..e0dccfc8db60 100644 --- a/mm/hmm.c +++ b/mm/hmm.c @@ -392,6 +392,7 @@ static int hmm_vma_walk_hole(unsigned long addr, unsigned long end, return hmm_vma_walk_hole_(addr, end, fault, write_fault, walk); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE static inline uint64_t pmd_to_hmm_pfn_flags(struct hmm_range *range, pmd_t pmd) { if (pmd_protnone(pmd)) @@ -401,7 +402,6 @@ static inline uint64_t pmd_to_hmm_pfn_flags(struct hmm_range *range, pmd_t pmd) range->flags[HMM_PFN_VALID]; } -#ifdef CONFIG_TRANSPARENT_HUGEPAGE static int hmm_vma_handle_pmd(struct mm_walk *walk, unsigned long addr, unsigned long end, uint64_t *pfns, pmd_t pmd) { From 550e12ef14b81fedea028b182139450c410c0eda Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Wed, 13 Aug 2025 12:42:19 -0400 Subject: [PATCH 347/404] x86/fpu: Delay instruction pointer fixup until after warning [ Upstream commit 1cec9ac2d071cfd2da562241aab0ef701355762a ] Right now, if XRSTOR fails a console message like this is be printed: Bad FPU state detected at restore_fpregs_from_fpstate+0x9a/0x170, reinitializing FPU registers. However, the text location (...+0x9a in this case) is the instruction *AFTER* the XRSTOR. The highlighted instruction in the "Code:" dump also points one instruction late. The reason is that the "fixup" moves RIP up to pass the bad XRSTOR and keep on running after returning from the #GP handler. But it does this fixup before warning. The resulting warning output is nonsensical because it looks like the non-FPU-related instruction is #GP'ing. Do not fix up RIP until after printing the warning. Do this by using the more generic and standard ex_handler_default(). Fixes: d5c8028b4788 ("x86/fpu: Reinitialize FPU registers if restoring FPU state fails") Signed-off-by: Dave Hansen Reviewed-by: Chao Gao Acked-by: Alison Schofield Acked-by: Peter Zijlstra (Intel) Cc:stable@vger.kernel.org Link: https://lore.kernel.org/all/20250624210148.97126F9E%40davehans-spike.ostc.intel.com [ adapted ex_handler_default() call ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- arch/x86/mm/extable.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c index 30bb0bd3b1b8..ae7e056d0007 100644 --- a/arch/x86/mm/extable.c +++ b/arch/x86/mm/extable.c @@ -59,13 +59,12 @@ __visible bool ex_handler_fprestore(const struct exception_table_entry *fixup, unsigned long error_code, unsigned long fault_addr) { - regs->ip = ex_fixup_addr(fixup); - WARN_ONCE(1, "Bad FPU state detected at %pB, reinitializing FPU registers.", (void *)instruction_pointer(regs)); __copy_kernel_to_fpregs(&init_fpstate, -1); - return true; + + return ex_handler_default(fixup, regs, trapnr, error_code, fault_addr); } EXPORT_SYMBOL_GPL(ex_handler_fprestore); From 55e0bf41e9f86b5a4b30ed6410ce35864829afea Mon Sep 17 00:00:00 2001 From: "Geoffrey D. Bennett" Date: Wed, 13 Aug 2025 10:44:47 -0400 Subject: [PATCH 348/404] ALSA: scarlett2: Add retry on -EPROTO from scarlett2_usb_tx() [ Upstream commit 8a15ca0ca51399b652b1bbb23b590b220cf03d62 ] During communication with Focusrite Scarlett Gen 2/3/4 USB audio interfaces, -EPROTO is sometimes returned from scarlett2_usb_tx(), snd_usb_ctl_msg() which can cause initialisation and control operations to fail intermittently. This patch adds up to 5 retries in scarlett2_usb(), with a delay starting at 5ms and doubling each time. This follows the same approach as the fix for usb_set_interface() in endpoint.c (commit f406005e162b ("ALSA: usb-audio: Add retry on -EPROTO from usb_set_interface()")), which resolved similar -EPROTO issues during device initialisation, and is the same approach as in fcp.c:fcp_usb(). Fixes: 9e4d5c1be21f ("ALSA: usb-audio: Scarlett Gen 2 mixer interface") Closes: https://github.com/geoffreybennett/linux-fcp/issues/41 Cc: stable@vger.kernel.org Signed-off-by: Geoffrey D. Bennett Link: https://patch.msgid.link/aIdDO6ld50WQwNim@m.b4.vu Signed-off-by: Takashi Iwai [ Applied retry logic around snd_usb_ctl_msg() instead of scarlett2_usb_tx() ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- sound/usb/mixer_scarlett_gen2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c index 6d8ef3aa99b5..3b225430bfad 100644 --- a/sound/usb/mixer_scarlett_gen2.c +++ b/sound/usb/mixer_scarlett_gen2.c @@ -118,6 +118,8 @@ #define SCARLETT2_MIXER_MAX_VALUE \ ((SCARLETT2_MIXER_MAX_DB - SCARLETT2_MIXER_MIN_DB) * 2) +#include + /* map from (dB + 80) * 2 to mixer value * for dB in 0 .. 172: int(8192 * pow(10, ((dB - 160) / 2 / 20))) */ @@ -591,6 +593,8 @@ static int scarlett2_usb( u16 req_buf_size = sizeof(struct scarlett2_usb_packet) + req_size; u16 resp_buf_size = sizeof(struct scarlett2_usb_packet) + resp_size; struct scarlett2_usb_packet *req = NULL, *resp = NULL; + int retries = 0; + const int max_retries = 5; int err = 0; req = kmalloc(req_buf_size, GFP_KERNEL); @@ -614,6 +618,7 @@ static int scarlett2_usb( if (req_size) memcpy(req->data, req_data, req_size); +retry: err = snd_usb_ctl_msg(mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0), SCARLETT2_USB_VENDOR_SPECIFIC_CMD_REQ, @@ -624,6 +629,10 @@ static int scarlett2_usb( req_buf_size); if (err != req_buf_size) { + if (err == -EPROTO && ++retries <= max_retries) { + msleep(5 * (1 << (retries - 1))); + goto retry; + } usb_audio_err( mixer->chip, "Scarlett Gen 2 USB request result cmd %x was %d\n", From 6742e3425abdf6005bf8e3ca5e5d86865773846d Mon Sep 17 00:00:00 2001 From: He Zhe Date: Tue, 19 Aug 2025 11:26:12 -0400 Subject: [PATCH 349/404] mm/kmemleak: turn kmemleak_lock and object->lock to raw_spinlock_t [ Upstream commit 8c96f1bc6fc49c724c4cdd22d3e99260263b7384 ] kmemleak_lock as a rwlock on RT can possibly be acquired in atomic context which does work. Since the kmemleak operation is performed in atomic context make it a raw_spinlock_t so it can also be acquired on RT. This is used for debugging and is not enabled by default in a production like environment (where performance/latency matters) so it makes sense to make it a raw_spinlock_t instead trying to get rid of the atomic context. Turn also the kmemleak_object->lock into raw_spinlock_t which is acquired (nested) while the kmemleak_lock is held. The time spent in "echo scan > kmemleak" slightly improved on 64core box with this patch applied after boot. [bigeasy@linutronix.de: redo the description, update comments. Merge the individual bits: He Zhe did the kmemleak_lock, Liu Haitao the ->lock and Yongxin Liu forwarded Liu's patch.] Link: http://lkml.kernel.org/r/20191219170834.4tah3prf2gdothz4@linutronix.de Link: https://lkml.kernel.org/r/20181218150744.GB20197@arrakis.emea.arm.com Link: https://lkml.kernel.org/r/1542877459-144382-1-git-send-email-zhe.he@windriver.com Link: https://lkml.kernel.org/r/20190927082230.34152-1-yongxin.liu@windriver.com Signed-off-by: He Zhe Signed-off-by: Liu Haitao Signed-off-by: Yongxin Liu Signed-off-by: Sebastian Andrzej Siewior Acked-by: Catalin Marinas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Stable-dep-of: 47b0f6d8f0d2 ("mm/kmemleak: avoid deadlock by moving pr_warn() outside kmemleak_lock") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- mm/kmemleak.c | 112 +++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/mm/kmemleak.c b/mm/kmemleak.c index f1e0214942c0..55df2f6b1fd3 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -13,7 +13,7 @@ * * The following locks and mutexes are used by kmemleak: * - * - kmemleak_lock (rwlock): protects the object_list modifications and + * - kmemleak_lock (raw_spinlock_t): protects the object_list modifications and * accesses to the object_tree_root. The object_list is the main list * holding the metadata (struct kmemleak_object) for the allocated memory * blocks. The object_tree_root is a red black tree used to look-up @@ -22,13 +22,13 @@ * object_tree_root in the create_object() function called from the * kmemleak_alloc() callback and removed in delete_object() called from the * kmemleak_free() callback - * - kmemleak_object.lock (spinlock): protects a kmemleak_object. Accesses to - * the metadata (e.g. count) are protected by this lock. Note that some - * members of this structure may be protected by other means (atomic or - * kmemleak_lock). This lock is also held when scanning the corresponding - * memory block to avoid the kernel freeing it via the kmemleak_free() - * callback. This is less heavyweight than holding a global lock like - * kmemleak_lock during scanning + * - kmemleak_object.lock (raw_spinlock_t): protects a kmemleak_object. + * Accesses to the metadata (e.g. count) are protected by this lock. Note + * that some members of this structure may be protected by other means + * (atomic or kmemleak_lock). This lock is also held when scanning the + * corresponding memory block to avoid the kernel freeing it via the + * kmemleak_free() callback. This is less heavyweight than holding a global + * lock like kmemleak_lock during scanning. * - scan_mutex (mutex): ensures that only one thread may scan the memory for * unreferenced objects at a time. The gray_list contains the objects which * are already referenced or marked as false positives and need to be @@ -135,7 +135,7 @@ struct kmemleak_scan_area { * (use_count) and freed using the RCU mechanism. */ struct kmemleak_object { - spinlock_t lock; + raw_spinlock_t lock; unsigned int flags; /* object status flags */ struct list_head object_list; struct list_head gray_list; @@ -191,8 +191,8 @@ static int mem_pool_free_count = ARRAY_SIZE(mem_pool); static LIST_HEAD(mem_pool_free_list); /* search tree for object boundaries */ static struct rb_root object_tree_root = RB_ROOT; -/* rw_lock protecting the access to object_list and object_tree_root */ -static DEFINE_RWLOCK(kmemleak_lock); +/* protecting the access to object_list and object_tree_root */ +static DEFINE_RAW_SPINLOCK(kmemleak_lock); /* allocation caches for kmemleak internal data */ static struct kmem_cache *object_cache; @@ -426,7 +426,7 @@ static struct kmemleak_object *mem_pool_alloc(gfp_t gfp) } /* slab allocation failed, try the memory pool */ - write_lock_irqsave(&kmemleak_lock, flags); + raw_spin_lock_irqsave(&kmemleak_lock, flags); object = list_first_entry_or_null(&mem_pool_free_list, typeof(*object), object_list); if (object) @@ -435,7 +435,7 @@ static struct kmemleak_object *mem_pool_alloc(gfp_t gfp) object = &mem_pool[--mem_pool_free_count]; else pr_warn_once("Memory pool empty, consider increasing CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE\n"); - write_unlock_irqrestore(&kmemleak_lock, flags); + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); return object; } @@ -453,9 +453,9 @@ static void mem_pool_free(struct kmemleak_object *object) } /* add the object to the memory pool free list */ - write_lock_irqsave(&kmemleak_lock, flags); + raw_spin_lock_irqsave(&kmemleak_lock, flags); list_add(&object->object_list, &mem_pool_free_list); - write_unlock_irqrestore(&kmemleak_lock, flags); + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); } /* @@ -514,9 +514,9 @@ static struct kmemleak_object *find_and_get_object(unsigned long ptr, int alias) struct kmemleak_object *object; rcu_read_lock(); - read_lock_irqsave(&kmemleak_lock, flags); + raw_spin_lock_irqsave(&kmemleak_lock, flags); object = lookup_object(ptr, alias); - read_unlock_irqrestore(&kmemleak_lock, flags); + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); /* check whether the object is still available */ if (object && !get_object(object)) @@ -546,11 +546,11 @@ static struct kmemleak_object *find_and_remove_object(unsigned long ptr, int ali unsigned long flags; struct kmemleak_object *object; - write_lock_irqsave(&kmemleak_lock, flags); + raw_spin_lock_irqsave(&kmemleak_lock, flags); object = lookup_object(ptr, alias); if (object) __remove_object(object); - write_unlock_irqrestore(&kmemleak_lock, flags); + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); return object; } @@ -585,7 +585,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, INIT_LIST_HEAD(&object->object_list); INIT_LIST_HEAD(&object->gray_list); INIT_HLIST_HEAD(&object->area_list); - spin_lock_init(&object->lock); + raw_spin_lock_init(&object->lock); atomic_set(&object->use_count, 1); object->flags = OBJECT_ALLOCATED; object->pointer = ptr; @@ -617,7 +617,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, /* kernel backtrace */ object->trace_len = __save_stack_trace(object->trace); - write_lock_irqsave(&kmemleak_lock, flags); + raw_spin_lock_irqsave(&kmemleak_lock, flags); untagged_ptr = (unsigned long)kasan_reset_tag((void *)ptr); min_addr = min(min_addr, untagged_ptr); @@ -649,7 +649,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, list_add_tail_rcu(&object->object_list, &object_list); out: - write_unlock_irqrestore(&kmemleak_lock, flags); + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); return object; } @@ -667,9 +667,9 @@ static void __delete_object(struct kmemleak_object *object) * Locking here also ensures that the corresponding memory block * cannot be freed when it is being scanned. */ - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); object->flags &= ~OBJECT_ALLOCATED; - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); put_object(object); } @@ -739,9 +739,9 @@ static void paint_it(struct kmemleak_object *object, int color) { unsigned long flags; - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); __paint_it(object, color); - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); } static void paint_ptr(unsigned long ptr, int color) @@ -803,7 +803,7 @@ static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) if (scan_area_cache) area = kmem_cache_alloc(scan_area_cache, gfp_kmemleak_mask(gfp)); - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); if (!area) { pr_warn_once("Cannot allocate a scan area, scanning the full object\n"); /* mark the object for full scan to avoid false positives */ @@ -825,7 +825,7 @@ static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) hlist_add_head(&area->node, &object->area_list); out_unlock: - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); put_object(object); } @@ -847,9 +847,9 @@ static void object_set_excess_ref(unsigned long ptr, unsigned long excess_ref) return; } - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); object->excess_ref = excess_ref; - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); put_object(object); } @@ -869,9 +869,9 @@ static void object_no_scan(unsigned long ptr) return; } - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); object->flags |= OBJECT_NO_SCAN; - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); put_object(object); } @@ -1031,9 +1031,9 @@ void __ref kmemleak_update_trace(const void *ptr) return; } - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); object->trace_len = __save_stack_trace(object->trace); - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); put_object(object); } @@ -1238,7 +1238,7 @@ static void scan_block(void *_start, void *_end, unsigned long flags; unsigned long untagged_ptr; - read_lock_irqsave(&kmemleak_lock, flags); + raw_spin_lock_irqsave(&kmemleak_lock, flags); for (ptr = start; ptr < end; ptr++) { struct kmemleak_object *object; unsigned long pointer; @@ -1273,7 +1273,7 @@ static void scan_block(void *_start, void *_end, * previously acquired in scan_object(). These locks are * enclosed by scan_mutex. */ - spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); + raw_spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); /* only pass surplus references (object already gray) */ if (color_gray(object)) { excess_ref = object->excess_ref; @@ -1282,7 +1282,7 @@ static void scan_block(void *_start, void *_end, excess_ref = 0; update_refs(object); } - spin_unlock(&object->lock); + raw_spin_unlock(&object->lock); if (excess_ref) { object = lookup_object(excess_ref, 0); @@ -1291,12 +1291,12 @@ static void scan_block(void *_start, void *_end, if (object == scanned) /* circular reference, ignore */ continue; - spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); + raw_spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); update_refs(object); - spin_unlock(&object->lock); + raw_spin_unlock(&object->lock); } } - read_unlock_irqrestore(&kmemleak_lock, flags); + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); } /* @@ -1329,7 +1329,7 @@ static void scan_object(struct kmemleak_object *object) * Once the object->lock is acquired, the corresponding memory block * cannot be freed (the same lock is acquired in delete_object). */ - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); if (object->flags & OBJECT_NO_SCAN) goto out; if (!(object->flags & OBJECT_ALLOCATED)) @@ -1349,9 +1349,9 @@ static void scan_object(struct kmemleak_object *object) if (start >= end) break; - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); cond_resched(); - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); } while (object->flags & OBJECT_ALLOCATED); } else hlist_for_each_entry(area, &object->area_list, node) @@ -1359,7 +1359,7 @@ static void scan_object(struct kmemleak_object *object) (void *)(area->start + area->size), object); out: - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); } /* @@ -1413,7 +1413,7 @@ static void kmemleak_scan(void) /* prepare the kmemleak_object's */ rcu_read_lock(); list_for_each_entry_rcu(object, &object_list, object_list) { - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); #ifdef DEBUG /* * With a few exceptions there should be a maximum of @@ -1430,7 +1430,7 @@ static void kmemleak_scan(void) if (color_gray(object) && get_object(object)) list_add_tail(&object->gray_list, &gray_list); - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); } rcu_read_unlock(); @@ -1498,14 +1498,14 @@ static void kmemleak_scan(void) */ rcu_read_lock(); list_for_each_entry_rcu(object, &object_list, object_list) { - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); if (color_white(object) && (object->flags & OBJECT_ALLOCATED) && update_checksum(object) && get_object(object)) { /* color it gray temporarily */ object->count = object->min_count; list_add_tail(&object->gray_list, &gray_list); } - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); } rcu_read_unlock(); @@ -1525,7 +1525,7 @@ static void kmemleak_scan(void) */ rcu_read_lock(); list_for_each_entry_rcu(object, &object_list, object_list) { - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); if (unreferenced_object(object) && !(object->flags & OBJECT_REPORTED)) { object->flags |= OBJECT_REPORTED; @@ -1535,7 +1535,7 @@ static void kmemleak_scan(void) new_leaks++; } - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); } rcu_read_unlock(); @@ -1687,10 +1687,10 @@ static int kmemleak_seq_show(struct seq_file *seq, void *v) struct kmemleak_object *object = v; unsigned long flags; - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object)) print_unreferenced(seq, object); - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); return 0; } @@ -1720,9 +1720,9 @@ static int dump_str_object_info(const char *str) return -EINVAL; } - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); dump_object_info(object); - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); put_object(object); return 0; @@ -1741,11 +1741,11 @@ static void kmemleak_clear(void) rcu_read_lock(); list_for_each_entry_rcu(object, &object_list, object_list) { - spin_lock_irqsave(&object->lock, flags); + raw_spin_lock_irqsave(&object->lock, flags); if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object)) __paint_it(object, KMEMLEAK_GREY); - spin_unlock_irqrestore(&object->lock, flags); + raw_spin_unlock_irqrestore(&object->lock, flags); } rcu_read_unlock(); From c7b6ea0ede687e7460e593c5ea478f50aa41682a Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Tue, 19 Aug 2025 11:26:13 -0400 Subject: [PATCH 350/404] mm/kmemleak: avoid deadlock by moving pr_warn() outside kmemleak_lock [ Upstream commit 47b0f6d8f0d2be4d311a49e13d2fd5f152f492b2 ] When netpoll is enabled, calling pr_warn_once() while holding kmemleak_lock in mem_pool_alloc() can cause a deadlock due to lock inversion with the netconsole subsystem. This occurs because pr_warn_once() may trigger netpoll, which eventually leads to __alloc_skb() and back into kmemleak code, attempting to reacquire kmemleak_lock. This is the path for the deadlock. mem_pool_alloc() -> raw_spin_lock_irqsave(&kmemleak_lock, flags); -> pr_warn_once() -> netconsole subsystem -> netpoll -> __alloc_skb -> __create_object -> raw_spin_lock_irqsave(&kmemleak_lock, flags); Fix this by setting a flag and issuing the pr_warn_once() after kmemleak_lock is released. Link: https://lkml.kernel.org/r/20250731-kmemleak_lock-v1-1-728fd470198f@debian.org Fixes: c5665868183f ("mm: kmemleak: use the memory pool for early allocations") Signed-off-by: Breno Leitao Reported-by: Jakub Kicinski Acked-by: Catalin Marinas Cc: Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- mm/kmemleak.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 55df2f6b1fd3..a7fc6b23c37e 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -417,6 +417,7 @@ static struct kmemleak_object *mem_pool_alloc(gfp_t gfp) { unsigned long flags; struct kmemleak_object *object; + bool warn = false; /* try the slab allocator first */ if (object_cache) { @@ -434,8 +435,10 @@ static struct kmemleak_object *mem_pool_alloc(gfp_t gfp) else if (mem_pool_free_count) object = &mem_pool[--mem_pool_free_count]; else - pr_warn_once("Memory pool empty, consider increasing CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE\n"); + warn = true; raw_spin_unlock_irqrestore(&kmemleak_lock, flags); + if (warn) + pr_warn_once("Memory pool empty, consider increasing CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE\n"); return object; } From 46ce8549441cfdae2cf51da27facab4d32827c5c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 18 Aug 2025 19:13:57 -0400 Subject: [PATCH 351/404] USB: cdc-acm: do not log successful probe on later errors [ Upstream commit 79579411826647fd573dbe301c4d933bc90e4be7 ] Do not log the successful-probe message until the tty device has been registered. Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20210322155318.9837-9-johan@kernel.org Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 64690a90cd7c ("cdc-acm: fix race between initial clearing halt and open") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 59a354822413..51f2caf0fb3e 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1520,8 +1520,6 @@ skip_countries: acm->nb_index = 0; acm->nb_size = 0; - dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); - acm->line.dwDTERate = cpu_to_le32(9600); acm->line.bDataBits = 8; acm_set_line(acm, &acm->line); @@ -1541,6 +1539,8 @@ skip_countries: usb_clear_halt(usb_dev, acm->out); } + dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); + return 0; alloc_fail6: if (!acm->combined_interfaces) { From 0e35cac65aae4a86aff56d48ba951fd39f1cb9ba Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 18 Aug 2025 19:13:58 -0400 Subject: [PATCH 352/404] cdc-acm: fix race between initial clearing halt and open [ Upstream commit 64690a90cd7c6db16d3af8616be1f4bf8d492850 ] On the devices that need their endpoints to get an initial clear_halt, this needs to be done before the devices can be opened. That means it needs to be before the devices are registered. Fixes: 15bf722e6f6c0 ("cdc-acm: Add support of ATOL FPrint fiscal printers") Cc: stable Signed-off-by: Oliver Neukum Link: https://lore.kernel.org/r/20250717141259.2345605-1-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 51f2caf0fb3e..4730089a771b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1527,6 +1527,12 @@ skip_countries: usb_driver_claim_interface(&acm_driver, data_interface, acm); usb_set_intfdata(data_interface, acm); + if (quirks & CLEAR_HALT_CONDITIONS) { + /* errors intentionally ignored */ + usb_clear_halt(usb_dev, acm->in); + usb_clear_halt(usb_dev, acm->out); + } + tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor, &control_interface->dev); if (IS_ERR(tty_dev)) { @@ -1534,11 +1540,6 @@ skip_countries: goto alloc_fail6; } - if (quirks & CLEAR_HALT_CONDITIONS) { - usb_clear_halt(usb_dev, acm->in); - usb_clear_halt(usb_dev, acm->out); - } - dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); return 0; From 2cbf9f514ed17812748fe24f41443bcd39cd8982 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Mon, 18 Aug 2025 19:08:42 -0400 Subject: [PATCH 353/404] usb: typec: fusb302: cache PD RX state [ Upstream commit 1e61f6ab08786d66a11cfc51e13d6f08a6b06c56 ] This patch fixes a race condition communication error, which ends up in PD hard resets when losing the race. Some systems, like the Radxa ROCK 5B are powered through USB-C without any backup power source and use a FUSB302 chip to do the PD negotiation. This means it is quite important to avoid hard resets, since that effectively kills the system's power-supply. I've found the following race condition while debugging unplanned power loss during booting the board every now and then: 1. lots of TCPM/FUSB302/PD initialization stuff 2. TCPM ends up in SNK_WAIT_CAPABILITIES (tcpm_set_pd_rx is enabled here) 3. the remote PD source does not send anything, so TCPM does a SOFT RESET 4. TCPM ends up in SNK_WAIT_CAPABILITIES for the second time (tcpm_set_pd_rx is enabled again, even though it is still on) At this point I've seen broken CRC good messages being send by the FUSB302 with a logic analyzer sniffing the CC lines. Also it looks like messages are being lost and things generally going haywire with one of the two sides doing a hard reset once a broken CRC good message was send to the bus. I think the system is running into a race condition, that the FIFOs are being cleared and/or the automatic good CRC message generation flag is being updated while a message is already arriving. Let's avoid this by caching the PD RX enabled state, as we have already processed anything in the FIFOs and are in a good state. As a side effect that this also optimizes I2C bus usage :) As far as I can tell the problem theoretically also exists when TCPM enters SNK_WAIT_CAPABILITIES the first time, but I believe this is less critical for the following reason: On devices like the ROCK 5B, which are powered through a TCPM backed USB-C port, the bootloader must have done some prior PD communication (initial communication must happen within 5 seconds after plugging the USB-C plug). This means the first time the kernel TCPM state machine reaches SNK_WAIT_CAPABILITIES, the remote side is not sending messages actively. On other devices a hard reset simply adds some extra delay and things should be good afterwards. Fixes: c034a43e72dda ("staging: typec: Fairchild FUSB302 Type-c chip driver") Cc: stable Signed-off-by: Sebastian Reichel Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20250704-fusb302-race-condition-fix-v1-1-239012c0e27a@kernel.org Signed-off-by: Greg Kroah-Hartman [ replaced str_on_off(on) with ternary operator ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tcpm/fusb302.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c index 5e661bae3997..9d242c5213e1 100644 --- a/drivers/usb/typec/tcpm/fusb302.c +++ b/drivers/usb/typec/tcpm/fusb302.c @@ -104,6 +104,7 @@ struct fusb302_chip { bool vconn_on; bool vbus_on; bool charge_on; + bool pd_rx_on; bool vbus_present; enum typec_cc_polarity cc_polarity; enum typec_cc_status cc1; @@ -841,6 +842,11 @@ static int tcpm_set_pd_rx(struct tcpc_dev *dev, bool on) int ret = 0; mutex_lock(&chip->lock); + if (chip->pd_rx_on == on) { + fusb302_log(chip, "pd is already %s", on ? "on" : "off"); + goto done; + } + ret = fusb302_pd_rx_flush(chip); if (ret < 0) { fusb302_log(chip, "cannot flush pd rx buffer, ret=%d", ret); @@ -863,6 +869,8 @@ static int tcpm_set_pd_rx(struct tcpc_dev *dev, bool on) on ? "on" : "off", ret); goto done; } + + chip->pd_rx_on = on; fusb302_log(chip, "pd := %s", on ? "on" : "off"); done: mutex_unlock(&chip->lock); From 46c44bb4c0832fa69f5863bb0963f58f8d37d659 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 16 Aug 2025 22:28:10 -0400 Subject: [PATCH 354/404] NFSv4: Fix nfs4_bitmap_copy_adjust() [ Upstream commit a71029b86752e8d40301af235a6bbf4896cc1402 ] Don't remove flags from the set retrieved from the cache_validity. We do want to retrieve all attributes that are listed as being invalid, whether or not there is a delegation set. Signed-off-by: Trond Myklebust Stable-dep-of: b01f21cacde9 ("NFS: Fix the setting of capabilities when automounting a new filesystem") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/nfs/nfs4proc.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 3477da3c2190..2145360d81ac 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -282,7 +282,7 @@ const u32 nfs4_fs_locations_bitmap[3] = { }; static void nfs4_bitmap_copy_adjust(__u32 *dst, const __u32 *src, - struct inode *inode) + struct inode *inode, unsigned long flags) { unsigned long cache_validity; @@ -290,22 +290,19 @@ static void nfs4_bitmap_copy_adjust(__u32 *dst, const __u32 *src, if (!inode || !nfs4_have_delegation(inode, FMODE_READ)) return; - cache_validity = READ_ONCE(NFS_I(inode)->cache_validity); - if (!(cache_validity & NFS_INO_REVAL_FORCED)) - cache_validity &= ~(NFS_INO_INVALID_CHANGE - | NFS_INO_INVALID_SIZE); + cache_validity = READ_ONCE(NFS_I(inode)->cache_validity) | flags; + /* Remove the attributes over which we have full control */ + dst[1] &= ~FATTR4_WORD1_RAWDEV; if (!(cache_validity & NFS_INO_INVALID_SIZE)) dst[0] &= ~FATTR4_WORD0_SIZE; if (!(cache_validity & NFS_INO_INVALID_CHANGE)) dst[0] &= ~FATTR4_WORD0_CHANGE; -} -static void nfs4_bitmap_copy_adjust_setattr(__u32 *dst, - const __u32 *src, struct inode *inode) -{ - nfs4_bitmap_copy_adjust(dst, src, inode); + if (!(cache_validity & NFS_INO_INVALID_OTHER)) + dst[1] &= ~(FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | + FATTR4_WORD1_OWNER_GROUP); } static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dentry, @@ -3333,12 +3330,15 @@ static int nfs4_do_setattr(struct inode *inode, const struct cred *cred, .inode = inode, .stateid = &arg.stateid, }; + unsigned long adjust_flags = NFS_INO_INVALID_CHANGE; int err; + if (sattr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) + adjust_flags |= NFS_INO_INVALID_OTHER; + do { - nfs4_bitmap_copy_adjust_setattr(bitmask, - nfs4_bitmask(server, olabel), - inode); + nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, olabel), + inode, adjust_flags); err = _nfs4_do_setattr(inode, &arg, &res, cred, ctx); switch (err) { @@ -4143,8 +4143,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, .rpc_resp = &res, }; - nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, label), inode); - + nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, label), inode, 0); nfs_fattr_init(fattr); return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); } @@ -4732,8 +4731,8 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct } nfs4_inode_make_writeable(inode); - nfs4_bitmap_copy_adjust_setattr(bitmask, nfs4_bitmask(server, res.label), inode); - + nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, res.label), inode, + NFS_INO_INVALID_CHANGE); status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); if (!status) { update_changeattr(dir, &res.cinfo, res.fattr->time_start, 0); From 51e2e0849ad2b874c16149575ab8327546f09185 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 16 Aug 2025 22:28:11 -0400 Subject: [PATCH 355/404] NFS: Fix up handling of outstanding layoutcommit in nfs_update_inode() [ Upstream commit 709fa5769914b377af87962bbe4ff81ffb019b2d ] If there is an outstanding layoutcommit, then the list of attributes whose values are expected to change is not the full set. So let's be explicit about the full list. Signed-off-by: Trond Myklebust Stable-dep-of: b01f21cacde9 ("NFS: Fix the setting of capabilities when automounting a new filesystem") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/nfs/inode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 0dc53732b5c9..4f0d2fc810e4 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1869,7 +1869,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) nfs_wcc_update_inode(inode, fattr); if (pnfs_layoutcommit_outstanding(inode)) { - nfsi->cache_validity |= save_cache_validity & NFS_INO_INVALID_ATTR; + nfsi->cache_validity |= + save_cache_validity & + (NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME | + NFS_INO_INVALID_MTIME | NFS_INO_INVALID_SIZE | + NFS_INO_REVAL_FORCED); cache_revalidated = false; } From 95eb0d97ab98a10e966125c1f274e7d0fc0992b3 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 16 Aug 2025 22:28:12 -0400 Subject: [PATCH 356/404] NFS: Fix the setting of capabilities when automounting a new filesystem [ Upstream commit b01f21cacde9f2878492cf318fee61bf4ccad323 ] Capabilities cannot be inherited when we cross into a new filesystem. They need to be reset to the minimal defaults, and then probed for again. Fixes: 54ceac451598 ("NFS: Share NFS superblocks per-protocol per-server per-FSID") Cc: stable@vger.kernel.org Reviewed-by: Benjamin Coddington Signed-off-by: Trond Myklebust [ adapted to older fs_context-less API structures ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/nfs/client.c | 44 ++++++++++++++++++++++++++++++++++++++++---- fs/nfs/internal.h | 1 + fs/nfs/nfs4client.c | 13 +------------ fs/nfs/nfs4proc.c | 2 ++ 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 323cef064f2a..bdece12af53e 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -646,6 +646,42 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp, } EXPORT_SYMBOL_GPL(nfs_init_client); +static void nfs4_server_set_init_caps(struct nfs_server *server) +{ +#if IS_ENABLED(CONFIG_NFS_V4) + /* Set the basic capabilities */ + server->caps = server->nfs_client->cl_mvops->init_caps; + if (server->flags & NFS_MOUNT_NORDIRPLUS) + server->caps &= ~NFS_CAP_READDIRPLUS; + + /* + * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower + * authentication. + */ + if (nfs4_disable_idmapping && + server->client->cl_auth->au_flavor == RPC_AUTH_UNIX) + server->caps |= NFS_CAP_UIDGID_NOMAP; +#endif +} + +void nfs_server_set_init_caps(struct nfs_server *server) +{ + switch (server->nfs_client->rpc_ops->version) { + case 2: + server->caps = NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS; + break; + case 3: + server->caps = NFS_CAP_HARDLINKS | NFS_CAP_SYMLINKS; + if (!(server->flags & NFS_MOUNT_NORDIRPLUS)) + server->caps |= NFS_CAP_READDIRPLUS; + break; + default: + nfs4_server_set_init_caps(server); + break; + } +} +EXPORT_SYMBOL_GPL(nfs_server_set_init_caps); + /* * Create a version 2 or 3 client */ @@ -683,9 +719,6 @@ static int nfs_init_server(struct nfs_server *server, /* Initialise the client representation from the mount data */ server->flags = data->flags; server->options = data->options; - server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID| - NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP| - NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME; if (data->rsize) server->rsize = nfs_block_size(data->rsize, NULL); @@ -710,6 +743,8 @@ static int nfs_init_server(struct nfs_server *server, if (error < 0) goto error; + nfs_server_set_init_caps(server); + /* Preserve the values of mount_server-related mount options */ if (data->mount_server.addrlen) { memcpy(&server->mountd_address, &data->mount_server.address, @@ -834,7 +869,6 @@ void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *sour target->acregmax = source->acregmax; target->acdirmin = source->acdirmin; target->acdirmax = source->acdirmax; - target->caps = source->caps; target->options = source->options; target->auth_info = source->auth_info; target->port = source->port; @@ -1042,6 +1076,8 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, if (error < 0) goto out_free_server; + nfs_server_set_init_caps(server); + /* probe the filesystem info for this server filesystem */ error = nfs_probe_fsinfo(server, fh, fattr_fsinfo); if (error < 0) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index bfb53756654d..46fc42d575ce 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -172,6 +172,7 @@ nfs4_find_client_sessionid(struct net *, const struct sockaddr *, struct nfs4_sessionid *, u32); extern struct nfs_server *nfs_create_server(struct nfs_mount_info *, struct nfs_subversion *); +extern void nfs_server_set_init_caps(struct nfs_server *); extern struct nfs_server *nfs4_create_server( struct nfs_mount_info *, struct nfs_subversion *); diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 1f4bdcda3fda..eeab44727a76 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -1011,18 +1011,7 @@ static int nfs4_server_common_setup(struct nfs_server *server, if (error < 0) goto out; - /* Set the basic capabilities */ - server->caps |= server->nfs_client->cl_mvops->init_caps; - if (server->flags & NFS_MOUNT_NORDIRPLUS) - server->caps &= ~NFS_CAP_READDIRPLUS; - /* - * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower - * authentication. - */ - if (nfs4_disable_idmapping && - server->client->cl_auth->au_flavor == RPC_AUTH_UNIX) - server->caps |= NFS_CAP_UIDGID_NOMAP; - + nfs_server_set_init_caps(server); /* Probe the root fh to retrieve its FSID and filehandle */ error = nfs4_get_rootfh(server, mntfh, auth_probe); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2145360d81ac..5f8de86b2798 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3884,6 +3884,8 @@ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) .interruptible = true, }; int err; + + nfs_server_set_init_caps(server); do { err = nfs4_handle_exception(server, _nfs4_server_capabilities(server, fhandle), From 07dad577076f93a3628597fa62838876c76fea93 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Aug 2025 12:14:13 -0400 Subject: [PATCH 357/404] usb: musb: omap2430: fix device leak at unbind [ Upstream commit 1473e9e7679bd4f5a62d1abccae894fb86de280f ] Make sure to drop the reference to the control device taken by of_find_device_by_node() during probe when the driver is unbound. Fixes: 8934d3e4d0e7 ("usb: musb: omap2430: Don't use omap_get_control_dev()") Cc: stable@vger.kernel.org # 3.13 Cc: Roger Quadros Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20250724091910.21092-5-johan@kernel.org Signed-off-by: Greg Kroah-Hartman [ Removed populate_irqs-related goto changes ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/omap2430.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 8def19fc5025..76b7ac1103ab 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -476,13 +476,13 @@ static int omap2430_probe(struct platform_device *pdev) ARRAY_SIZE(musb_resources)); if (ret) { dev_err(&pdev->dev, "failed to add resources\n"); - goto err2; + goto err_put_control_otghs; } ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); if (ret) { dev_err(&pdev->dev, "failed to add platform_data\n"); - goto err2; + goto err_put_control_otghs; } pm_runtime_enable(glue->dev); @@ -497,7 +497,9 @@ static int omap2430_probe(struct platform_device *pdev) err3: pm_runtime_disable(glue->dev); - +err_put_control_otghs: + if (!IS_ERR(glue->control_otghs)) + put_device(glue->control_otghs); err2: platform_device_put(musb); @@ -511,6 +513,8 @@ static int omap2430_remove(struct platform_device *pdev) platform_device_unregister(glue->musb); pm_runtime_disable(glue->dev); + if (!IS_ERR(glue->control_otghs)) + put_device(glue->control_otghs); return 0; } From 7d5b525070f82b69601d99b2f6e250ca5a45cd35 Mon Sep 17 00:00:00 2001 From: Meagan Lloyd Date: Wed, 20 Aug 2025 16:06:04 -0700 Subject: [PATCH 358/404] rtc: ds1307: handle oscillator stop flag (OSF) for ds1341 [ Upstream commit 523923cfd5d622b8f4ba893fdaf29fa6adeb8c3e ] In using CONFIG_RTC_HCTOSYS, rtc_hctosys() will sync the RTC time to the kernel time as long as rtc_read_time() succeeds. In some power loss situations, our supercapacitor-backed DS1342 RTC comes up with either an unpredictable future time or the default 01/01/00 from the datasheet. The oscillator stop flag (OSF) is set in these scenarios due to the power loss and can be used to determine the validity of the RTC data. This change expands the oscillator stop flag (OSF) handling that has already been implemented for some chips to the ds1341 chip (DS1341 and DS1342 share a datasheet). This handling manages the validity of the RTC data in .read_time and .set_time based on the OSF. Signed-off-by: Meagan Lloyd Reviewed-by: Tyler Hicks Acked-by: Rodolfo Giometti Link: https://lore.kernel.org/r/1749665656-30108-3-git-send-email-meaganlloyd@linux.microsoft.com Signed-off-by: Alexandre Belloni [ Git was trying to insert the code above the ds_1388 case statement block (in each respective function) which don't exist in the v5.4.296 rtc-ds1307 driver, thus a manual fixup was required. ] Signed-off-by: Meagan Lloyd Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-ds1307.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index ff9785ff36e7..bf79208b8a45 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -252,6 +252,13 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) if (tmp & DS1340_BIT_OSF) return -EINVAL; break; + case ds_1341: + ret = regmap_read(ds1307->regmap, DS1337_REG_STATUS, &tmp); + if (ret) + return ret; + if (tmp & DS1337_BIT_OSF) + return -EINVAL; + break; case mcp794xx: if (!(tmp & MCP794XX_BIT_ST)) return -EINVAL; @@ -343,6 +350,10 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) regmap_update_bits(ds1307->regmap, DS1340_REG_FLAG, DS1340_BIT_OSF, 0); break; + case ds_1341: + regmap_update_bits(ds1307->regmap, DS1337_REG_STATUS, + DS1337_BIT_OSF, 0); + break; case mcp794xx: /* * these bits were cleared when preparing the date/time From 1096eb63ecfc8df90b70cd068e6de0c2ff204dfd Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Fri, 22 Aug 2025 14:49:39 -0400 Subject: [PATCH 359/404] soc: qcom: mdt_loader: Ensure we don't read past the ELF header [ Upstream commit 9f9967fed9d066ed3dae9372b45ffa4f6fccfeef ] When the MDT loader is used in remoteproc, the ELF header is sanitized beforehand, but that's not necessary the case for other clients. Validate the size of the firmware buffer to ensure that we don't read past the end as we iterate over the header. e_phentsize and e_shentsize are validated as well, to ensure that the assumptions about step size in the traversal are valid. Fixes: 2aad40d911ee ("remoteproc: Move qcom_mdt_loader into drivers/soc/qcom") Cc: stable@vger.kernel.org Reported-by: Doug Anderson Signed-off-by: Bjorn Andersson Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250610-mdt-loader-validation-and-fixes-v2-1-f7073e9ab899@oss.qualcomm.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/soc/qcom/mdt_loader.c | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index 6034cd8992b0..c2bbde533e66 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -12,11 +12,43 @@ #include #include #include +#include #include #include #include #include +static bool mdt_header_valid(const struct firmware *fw) +{ + const struct elf32_hdr *ehdr; + size_t phend; + size_t shend; + + if (fw->size < sizeof(*ehdr)) + return false; + + ehdr = (struct elf32_hdr *)fw->data; + + if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) + return false; + + if (ehdr->e_phentsize != sizeof(struct elf32_phdr)) + return false; + + phend = size_add(size_mul(sizeof(struct elf32_phdr), ehdr->e_phnum), ehdr->e_phoff); + if (phend > fw->size) + return false; + + if (ehdr->e_shentsize != sizeof(struct elf32_shdr)) + return false; + + shend = size_add(size_mul(sizeof(struct elf32_shdr), ehdr->e_shnum), ehdr->e_shoff); + if (shend > fw->size) + return false; + + return true; +} + static bool mdt_phdr_valid(const struct elf32_phdr *phdr) { if (phdr->p_type != PT_LOAD) @@ -46,6 +78,9 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw) phys_addr_t max_addr = 0; int i; + if (!mdt_header_valid(fw)) + return -EINVAL; + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr + 1); @@ -92,6 +127,9 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len) size_t ehdr_size; void *data; + if (!mdt_header_valid(fw)) + return ERR_PTR(-EINVAL); + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr + 1); @@ -151,6 +189,9 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, if (!fw || !mem_region || !mem_phys || !mem_size) return -EINVAL; + if (!mdt_header_valid(fw)) + return -EINVAL; + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr + 1); From 685ac66793d35683bedee654c06d07460ea06d7e Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Thu, 21 Aug 2025 14:26:54 -0400 Subject: [PATCH 360/404] ata: Fix SATA_MOBILE_LPM_POLICY description in Kconfig [ Upstream commit ed62a62a18bc144f73eadf866ae46842e8f6606e ] Improve the description of the possible default SATA link power management policies and add the missing description for policy 5. No functional changes. Fixes: a5ec5a7bfd1f ("ata: ahci: Support state with min power but Partial low power state") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal Reviewed-by: Hannes Reinecke Reviewed-by: Niklas Cassel [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/ata/Kconfig | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index a6beb2c5a692..dbde78feda31 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -92,22 +92,39 @@ config SATA_AHCI config SATA_MOBILE_LPM_POLICY int "Default SATA Link Power Management policy for mobile chipsets" - range 0 4 + range 0 5 default 0 depends on SATA_AHCI help Select the Default SATA Link Power Management (LPM) policy to use for mobile / laptop variants of chipsets / "South Bridges". - The value set has the following meanings: - 0 => Keep firmware settings - 1 => Maximum performance - 2 => Medium power - 3 => Medium power with Device Initiated PM enabled - 4 => Minimum power + Each policy combines power saving states and features: + - Partial: The Phy logic is powered but is in a reduced power + state. The exit latency from this state is no longer than + 10us). + - Slumber: The Phy logic is powered but is in an even lower power + state. The exit latency from this state is potentially + longer, but no longer than 10ms. + - DevSleep: The Phy logic may be powered down. The exit latency from + this state is no longer than 20 ms, unless otherwise + specified by DETO in the device Identify Device Data log. + - HIPM: Host Initiated Power Management (host automatically + transitions to partial and slumber). + - DIPM: Device Initiated Power Management (device automatically + transitions to partial and slumber). - Note "Minimum power" is known to cause issues, including disk - corruption, with some disks and should not be used. + The possible values for the default SATA link power management + policies are: + 0 => Keep firmware settings + 1 => No power savings (maximum performance) + 2 => HIPM (Partial) + 3 => HIPM (Partial) and DIPM (Partial and Slumber) + 4 => HIPM (Partial and DevSleep) and DIPM (Partial and Slumber) + 5 => HIPM (Slumber and DevSleep) and DIPM (Partial and Slumber) + + Excluding the value 0, higher values represent policies with higher + power savings. config SATA_AHCI_PLATFORM tristate "Platform AHCI SATA support" From fad9206d7a2a9bcbacbc02d6cc6c26769226d2ce Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 Aug 2025 21:59:11 -0400 Subject: [PATCH 361/404] media: v4l2-ctrls: always copy the controls on completion [ Upstream commit c3bf5129f33923c92bf3bddaf4359b7b25ecb4ba ] When v4l2_ctrl_request_complete() is called and there is no control handler object found in the request, then create such an object so that all controls at completion state can be stored and are available to userspace. Otherwise any attempt by userspace to read the completed request data will fail. If allocating the control handler object failed, then indicate that by returning ENOMEM when attempting to get the controls from the completed request instead of returning ENOENT. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Stable-dep-of: 5a0400aca5fa ("media: v4l2-ctrls: Don't reset handler's error in v4l2_ctrl_handler_free()") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/v4l2-core/v4l2-ctrls.c | 36 ++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 7ac7a5063fb2..4e64d9e61381 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -3529,8 +3529,19 @@ v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl, obj = media_request_object_find(req, &req_ops, hdl); if (obj) return obj; + /* + * If there are no controls in this completed request, + * then that can only happen if: + * + * 1) no controls were present in the queued request, and + * 2) v4l2_ctrl_request_complete() could not allocate a + * control handler object to store the completed state in. + * + * So return ENOMEM to indicate that there was an out-of-memory + * error. + */ if (!set) - return ERR_PTR(-ENOENT); + return ERR_PTR(-ENOMEM); new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL); if (!new_hdl) @@ -3541,8 +3552,8 @@ v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl, if (!ret) ret = v4l2_ctrl_request_bind(req, new_hdl, hdl); if (ret) { + v4l2_ctrl_handler_free(new_hdl); kfree(new_hdl); - return ERR_PTR(ret); } @@ -4113,8 +4124,25 @@ void v4l2_ctrl_request_complete(struct media_request *req, * wants to leave the controls unchanged. */ obj = media_request_object_find(req, &req_ops, main_hdl); - if (!obj) - return; + if (!obj) { + int ret; + + /* Create a new request so the driver can return controls */ + hdl = kzalloc(sizeof(*hdl), GFP_KERNEL); + if (!hdl) + return; + + ret = v4l2_ctrl_handler_init(hdl, (main_hdl->nr_of_buckets - 1) * 8); + if (!ret) + ret = v4l2_ctrl_request_bind(req, hdl, main_hdl); + if (ret) { + v4l2_ctrl_handler_free(hdl); + kfree(hdl); + return; + } + hdl->request_is_queued = true; + obj = media_request_object_find(req, &req_ops, main_hdl); + } hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); list_for_each_entry(ref, &hdl->ctrl_refs, node) { From 93c8931aef1fdce27e2cb619c373817e5cb9f031 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 22 Aug 2025 21:59:12 -0400 Subject: [PATCH 362/404] media: v4l2-ctrls: Don't reset handler's error in v4l2_ctrl_handler_free() [ Upstream commit 5a0400aca5fa7c6b8ba456c311a460e733571c88 ] It's a common pattern in drivers to free the control handler's resources and then return the handler's error code on drivers' error handling paths. Alas, the v4l2_ctrl_handler_free() function also zeroes the error field, effectively indicating successful return to the caller. There's no apparent need to touch the error field while releasing the control handler's resources and cleaning up stale pointers. Not touching the handler's error field is a more certain way to address this problem than changing all the users, in which case the pattern would be likely to re-emerge in new drivers. Do just that, don't touch the control handler's error field in v4l2_ctrl_handler_free(). Fixes: 0996517cf8ea ("V4L/DVB: v4l2: Add new control handling framework") Cc: stable@vger.kernel.org Signed-off-by: Sakari Ailus Reviewed-by: Hans Verkuil Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil [ v4l2-ctrls.c => v4l2-ctrls-core.c ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/v4l2-core/v4l2-ctrls.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 4e64d9e61381..d17b40bebf6f 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -2187,7 +2187,6 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) kvfree(hdl->buckets); hdl->buckets = NULL; hdl->cached = NULL; - hdl->error = 0; mutex_unlock(hdl->lock); mutex_destroy(&hdl->_lock); } From 2964dbe631fd21ad7873b1752b895548d3c12496 Mon Sep 17 00:00:00 2001 From: Gui-Dong Han Date: Fri, 22 Aug 2025 21:45:18 -0400 Subject: [PATCH 363/404] media: rainshadow-cec: fix TOCTOU race condition in rain_interrupt() [ Upstream commit 7af160aea26c7dc9e6734d19306128cce156ec40 ] In the interrupt handler rain_interrupt(), the buffer full check on rain->buf_len is performed before acquiring rain->buf_lock. This creates a Time-of-Check to Time-of-Use (TOCTOU) race condition, as rain->buf_len is concurrently accessed and modified in the work handler rain_irq_work_handler() under the same lock. Multiple interrupt invocations can race, with each reading buf_len before it becomes full and then proceeding. This can lead to both interrupts attempting to write to the buffer, incrementing buf_len beyond its capacity (DATA_SIZE) and causing a buffer overflow. Fix this bug by moving the spin_lock() to before the buffer full check. This ensures that the check and the subsequent buffer modification are performed atomically, preventing the race condition. An corresponding spin_unlock() is added to the overflow path to correctly release the lock. This possible bug was found by an experimental static analysis tool developed by our team. Fixes: 0f314f6c2e77 ("[media] rainshadow-cec: new RainShadow Tech HDMI CEC driver") Cc: stable@vger.kernel.org Signed-off-by: Gui-Dong Han Signed-off-by: Hans Verkuil [ drivers/media/cec/usb/rainshadow/ => drivers/media/usb/rainshadow-cec/ ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/usb/rainshadow-cec/rainshadow-cec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c index ee870ea1a886..6f8d6797c614 100644 --- a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c +++ b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c @@ -171,11 +171,12 @@ static irqreturn_t rain_interrupt(struct serio *serio, unsigned char data, { struct rain *rain = serio_get_drvdata(serio); + spin_lock(&rain->buf_lock); if (rain->buf_len == DATA_SIZE) { + spin_unlock(&rain->buf_lock); dev_warn_once(rain->dev, "buffer overflow\n"); return IRQ_HANDLED; } - spin_lock(&rain->buf_lock); rain->buf_len++; rain->buf[rain->buf_wr_idx] = data; rain->buf_wr_idx = (rain->buf_wr_idx + 1) & 0xff; From f070b3171eb1f74e2321d2c4513552b852e619ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 22 Aug 2025 15:05:25 -0400 Subject: [PATCH 364/404] pwm: mediatek: Implement .apply() callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 758de66f4bd2cac2b1d71db917c65c3d611d4e74 ] To eventually get rid of all legacy drivers convert this driver to the modern world implementing .apply(). This just pushed a variant of pwm_apply_legacy() into the driver that was slightly simplified because the driver doesn't provide a .set_polarity() callback. Signed-off-by: Uwe Kleine-König Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Thierry Reding Stable-dep-of: f21d136caf81 ("pwm: mediatek: Fix duty and period setting") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pwm/pwm-mediatek.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c index 3cf766d892db..69616224a5fa 100644 --- a/drivers/pwm/pwm-mediatek.c +++ b/drivers/pwm/pwm-mediatek.c @@ -210,10 +210,33 @@ static void pwm_mediatek_disable(struct pwm_chip *chip, struct pwm_device *pwm) pwm_mediatek_clk_disable(chip, pwm); } +static int pwm_mediatek_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) +{ + int err; + + if (state->polarity != PWM_POLARITY_NORMAL) + return -EINVAL; + + if (!state->enabled) { + if (pwm->state.enabled) + pwm_mediatek_disable(chip, pwm); + + return 0; + } + + err = pwm_mediatek_config(pwm->chip, pwm, state->duty_cycle, state->period); + if (err) + return err; + + if (!pwm->state.enabled) + err = pwm_mediatek_enable(chip, pwm); + + return err; +} + static const struct pwm_ops pwm_mediatek_ops = { - .config = pwm_mediatek_config, - .enable = pwm_mediatek_enable, - .disable = pwm_mediatek_disable, + .apply = pwm_mediatek_apply, .owner = THIS_MODULE, }; From 2c8e684df27f4fe3754dd7f65f4587c4b9383c3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 22 Aug 2025 15:05:26 -0400 Subject: [PATCH 365/404] pwm: mediatek: Handle hardware enable and clock enable separately MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 704d918341c378c5f9505dfdf32d315e256d3846 ] Stop handling the clocks in pwm_mediatek_enable() and pwm_mediatek_disable(). This is a preparing change for the next commit that requires that clocks and the enable bit are handled separately. Also move these two functions a bit further up in the source file to make them usable in pwm_mediatek_config(), which is needed in the next commit, too. Signed-off-by: Uwe Kleine-König Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/55c94fe2917ece152ee1e998f4675642a7716f13.1753717973.git.u.kleine-koenig@baylibre.com Cc: stable@vger.kernel.org Signed-off-by: Uwe Kleine-König Stable-dep-of: f21d136caf81 ("pwm: mediatek: Fix duty and period setting") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pwm/pwm-mediatek.c | 60 ++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c index 69616224a5fa..203e5c13a0d1 100644 --- a/drivers/pwm/pwm-mediatek.c +++ b/drivers/pwm/pwm-mediatek.c @@ -119,6 +119,26 @@ static inline void pwm_mediatek_writel(struct pwm_mediatek_chip *chip, writel(value, chip->regs + pwm_mediatek_reg_offset[num] + offset); } +static void pwm_mediatek_enable(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip); + u32 value; + + value = readl(pc->regs); + value |= BIT(pwm->hwpwm); + writel(value, pc->regs); +} + +static void pwm_mediatek_disable(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip); + u32 value; + + value = readl(pc->regs); + value &= ~BIT(pwm->hwpwm); + writel(value, pc->regs); +} + static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns) { @@ -181,35 +201,6 @@ out: return ret; } -static int pwm_mediatek_enable(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip); - u32 value; - int ret; - - ret = pwm_mediatek_clk_enable(chip, pwm); - if (ret < 0) - return ret; - - value = readl(pc->regs); - value |= BIT(pwm->hwpwm); - writel(value, pc->regs); - - return 0; -} - -static void pwm_mediatek_disable(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip); - u32 value; - - value = readl(pc->regs); - value &= ~BIT(pwm->hwpwm); - writel(value, pc->regs); - - pwm_mediatek_clk_disable(chip, pwm); -} - static int pwm_mediatek_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { @@ -219,8 +210,10 @@ static int pwm_mediatek_apply(struct pwm_chip *chip, struct pwm_device *pwm, return -EINVAL; if (!state->enabled) { - if (pwm->state.enabled) + if (pwm->state.enabled) { pwm_mediatek_disable(chip, pwm); + pwm_mediatek_clk_disable(chip, pwm); + } return 0; } @@ -229,8 +222,11 @@ static int pwm_mediatek_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (err) return err; - if (!pwm->state.enabled) - err = pwm_mediatek_enable(chip, pwm); + if (!pwm->state.enabled) { + err = pwm_mediatek_clk_enable(chip, pwm); + if (!err) + pwm_mediatek_enable(chip, pwm); + } return err; } From e1fe95f933e01ba4a9a7cf1942ba091826cfd4d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 22 Aug 2025 15:05:27 -0400 Subject: [PATCH 366/404] pwm: mediatek: Fix duty and period setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit f21d136caf8171f94159d975ea4620c164431bd9 ] The period generated by the hardware is (PWMDWIDTH + 1) << CLKDIV) / freq according to my tests with a signal analyser and also the documentation. The current algorithm doesn't consider the `+ 1` part and so configures slightly too high periods. The same issue exists for the duty cycle setting. So subtract 1 from both the register values for period and duty cycle. If period is 0, bail out, if duty_cycle is 0, just disable the PWM which results in a constant low output. Fixes: caf065f8fd58 ("pwm: Add MediaTek PWM support") Signed-off-by: Uwe Kleine-König Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/6d1fa87a76f8020bfe3171529b8e19baffceab10.1753717973.git.u.kleine-koenig@baylibre.com Cc: stable@vger.kernel.org Signed-off-by: Uwe Kleine-König Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/pwm/pwm-mediatek.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c index 203e5c13a0d1..c2235daa5bcd 100644 --- a/drivers/pwm/pwm-mediatek.c +++ b/drivers/pwm/pwm-mediatek.c @@ -168,7 +168,10 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm, do_div(resolution, clk_rate); cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution); - while (cnt_period > 8191) { + if (!cnt_period) + return -EINVAL; + + while (cnt_period > 8192) { resolution *= 2; clkdiv++; cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, @@ -191,9 +194,16 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm, } cnt_duty = DIV_ROUND_CLOSEST_ULL((u64)duty_ns * 1000, resolution); + pwm_mediatek_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | clkdiv); - pwm_mediatek_writel(pc, pwm->hwpwm, reg_width, cnt_period); - pwm_mediatek_writel(pc, pwm->hwpwm, reg_thres, cnt_duty); + pwm_mediatek_writel(pc, pwm->hwpwm, reg_width, cnt_period - 1); + + if (cnt_duty) { + pwm_mediatek_writel(pc, pwm->hwpwm, reg_thres, cnt_duty - 1); + pwm_mediatek_enable(chip, pwm); + } else { + pwm_mediatek_disable(chip, pwm); + } out: pwm_mediatek_clk_disable(chip, pwm); @@ -222,11 +232,8 @@ static int pwm_mediatek_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (err) return err; - if (!pwm->state.enabled) { + if (!pwm->state.enabled) err = pwm_mediatek_clk_enable(chip, pwm); - if (!err) - pwm_mediatek_enable(chip, pwm); - } return err; } From 2402adce8da4e7396b63b5ffa71e1fa16e5fe5c4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Sat, 23 Aug 2025 10:44:36 -0400 Subject: [PATCH 367/404] drm/dp: Change AUX DPCD probe address from DPCD_REV to LANE0_1_STATUS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit a40c5d727b8111b5db424a1e43e14a1dcce1e77f ] Reading DPCD registers has side-effects in general. In particular accessing registers outside of the link training register range (0x102-0x106, 0x202-0x207, 0x200c-0x200f, 0x2216) is explicitly forbidden by the DP v2.1 Standard, see 3.6.5.1 DPTX AUX Transaction Handling Mandates 3.6.7.4 128b/132b DP Link Layer LTTPR Link Training Mandates Based on my tests, accessing the DPCD_REV register during the link training of an UHBR TBT DP tunnel sink leads to link training failures. Solve the above by using the DP_LANE0_1_STATUS (0x202) register for the DPCD register access quirk. Cc: Cc: Ville Syrjälä Cc: Jani Nikula Acked-by: Jani Nikula Signed-off-by: Imre Deak Link: https://lore.kernel.org/r/20250605082850.65136-2-imre.deak@intel.com [ Call to drm_dp_dpcd_access() instead of drm_dp_dpcd_probe() ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_dp_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index ffc68d305afe..4eabef5b86d0 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -280,7 +280,7 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset, * We just have to do it before any DPCD access and hope that the * monitor doesn't power down exactly after the throw away read. */ - ret = drm_dp_dpcd_access(aux, DP_AUX_NATIVE_READ, DP_DPCD_REV, buffer, + ret = drm_dp_dpcd_access(aux, DP_AUX_NATIVE_READ, DP_LANE0_1_STATUS, buffer, 1); if (ret != 1) goto out; From 6242f1a36109cc7f9d1236c228543e841fa83a6d Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Sat, 23 Aug 2025 08:54:54 -0400 Subject: [PATCH 368/404] media: venus: vdec: Clamp param smaller than 1fps and bigger than 240. [ Upstream commit 377dc500d253f0b26732b2cb062e89668aef890a ] The driver uses "whole" fps in all its calculations (e.g. in load_per_instance()). Those calculation expect an fps bigger than 1, and not big enough to overflow. Clamp the value if the user provides a param that will result in an invalid fps. Reported-by: Hans Verkuil Closes: https://lore.kernel.org/linux-media/f11653a7-bc49-48cd-9cdb-1659147453e4@xs4all.nl/T/#m91cd962ac942834654f94c92206e2f85ff7d97f0 Fixes: 7472c1c69138 ("[media] media: venus: vdec: add video decoder files") Cc: stable@vger.kernel.org Tested-by: Bryan O'Donoghue # qrb5615-rb5 Reviewed-by: Bryan O'Donoghue Signed-off-by: Ricardo Ribalda [bod: Change "parm" to "param"] Signed-off-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil [ Adjust context in header ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/qcom/venus/core.h | 2 ++ drivers/media/platform/qcom/venus/vdec.c | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 922cb7e64bfa..03512858c868 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -16,6 +16,8 @@ #define VIDC_CLKS_NUM_MAX 4 +#define VENUS_MAX_FPS 240 + struct freq_tbl { unsigned int load; unsigned long freq; diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index a0a67b7132b8..551462e64082 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -418,11 +418,10 @@ static int vdec_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC; do_div(us_per_frame, timeperframe->denominator); - if (!us_per_frame) - return -EINVAL; - + us_per_frame = clamp(us_per_frame, 1, USEC_PER_SEC); fps = (u64)USEC_PER_SEC; do_div(fps, us_per_frame); + fps = min(VENUS_MAX_FPS, fps); inst->fps = fps; inst->timeperframe = *timeperframe; From 7e23a595f1162dbff1ba009765e118e2c064bbab Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Sat, 23 Aug 2025 00:50:18 -0400 Subject: [PATCH 369/404] media: qcom: camss: cleanup media device allocated resource on error path [ Upstream commit 69080ec3d0daba8a894025476c98ab16b5a505a4 ] A call to media_device_init() requires media_device_cleanup() counterpart to complete cleanup and release any allocated resources. This has been done in the driver .remove() right from the beginning, but error paths on .probe() shall also be fixed. Fixes: a1d7c116fcf7 ("media: camms: Add core files") Cc: stable@vger.kernel.org Signed-off-by: Vladimir Zapolskiy Reviewed-by: Bryan O'Donoghue Signed-off-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil [ err_genpd_cleanup => err_cleanup ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/qcom/camss/camss.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 2db9229d5601..adf3de3e017f 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -888,7 +888,7 @@ static int camss_probe(struct platform_device *pdev) ret = v4l2_device_register(camss->dev, &camss->v4l2_dev); if (ret < 0) { dev_err(dev, "Failed to register V4L2 device: %d\n", ret); - goto err_cleanup; + goto err_media_device_cleanup; } ret = camss_register_entities(camss); @@ -945,6 +945,8 @@ err_register_subdevs: camss_unregister_entities(camss); err_register_entities: v4l2_device_unregister(&camss->v4l2_dev); +err_media_device_cleanup: + media_device_cleanup(&camss->media_dev); err_cleanup: v4l2_async_notifier_cleanup(&camss->notifier); err_free: From 18c2b2bd982b8546312c9a7895515672169f28e0 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Sat, 23 Aug 2025 00:50:14 -0400 Subject: [PATCH 370/404] media: venus: protect against spurious interrupts during probe [ Upstream commit 3200144a2fa4209dc084a19941b9b203b43580f0 ] Make sure the interrupt handler is initialized before the interrupt is registered. If the IRQ is registered before hfi_create(), it's possible that an interrupt fires before the handler setup is complete, leading to a NULL dereference. This error condition has been observed during system boot on Rb3Gen2. Fixes: af2c3834c8ca ("[media] media: venus: adding core part and helper functions") Cc: stable@vger.kernel.org Signed-off-by: Jorge Ramirez-Ortiz Reviewed-by: Bryan O'Donoghue Reviewed-by: Vikash Garodia Reviewed-by: Dikshita Agarwal Tested-by: Dikshita Agarwal # RB5 Signed-off-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil [ kept hfi_isr_thread instead of venus_isr_thread ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/qcom/venus/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index f003c57a1645..42088120128f 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -267,13 +267,13 @@ static int venus_probe(struct platform_device *pdev) mutex_init(&core->lock); INIT_DELAYED_WORK(&core->work, venus_sys_error_handler); - ret = devm_request_threaded_irq(dev, core->irq, hfi_isr, hfi_isr_thread, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - "venus", core); + ret = hfi_create(core, &venus_core_ops); if (ret) return ret; - ret = hfi_create(core, &venus_core_ops); + ret = devm_request_threaded_irq(dev, core->irq, hfi_isr, hfi_isr_thread, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "venus", core); if (ret) return ret; From ee4d13f5407cbdf1216cc258f45492075713889a Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Sat, 23 Aug 2025 00:23:11 -0400 Subject: [PATCH 371/404] f2fs: fix to avoid out-of-boundary access in dnode page [ Upstream commit 77de19b6867f2740cdcb6c9c7e50d522b47847a4 ] As Jiaming Zhang reported: __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x1c1/0x2a0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0x17e/0x800 mm/kasan/report.c:480 kasan_report+0x147/0x180 mm/kasan/report.c:593 data_blkaddr fs/f2fs/f2fs.h:3053 [inline] f2fs_data_blkaddr fs/f2fs/f2fs.h:3058 [inline] f2fs_get_dnode_of_data+0x1a09/0x1c40 fs/f2fs/node.c:855 f2fs_reserve_block+0x53/0x310 fs/f2fs/data.c:1195 prepare_write_begin fs/f2fs/data.c:3395 [inline] f2fs_write_begin+0xf39/0x2190 fs/f2fs/data.c:3594 generic_perform_write+0x2c7/0x910 mm/filemap.c:4112 f2fs_buffered_write_iter fs/f2fs/file.c:4988 [inline] f2fs_file_write_iter+0x1ec8/0x2410 fs/f2fs/file.c:5216 new_sync_write fs/read_write.c:593 [inline] vfs_write+0x546/0xa90 fs/read_write.c:686 ksys_write+0x149/0x250 fs/read_write.c:738 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xf3/0x3d0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f The root cause is in the corrupted image, there is a dnode has the same node id w/ its inode, so during f2fs_get_dnode_of_data(), it tries to access block address in dnode at offset 934, however it parses the dnode as inode node, so that get_dnode_addr() returns 360, then it tries to access page address from 360 + 934 * 4 = 4096 w/ 4 bytes. To fix this issue, let's add sanity check for node id of all direct nodes during f2fs_get_dnode_of_data(). Cc: stable@kernel.org Reported-by: Jiaming Zhang Closes: https://groups.google.com/g/syzkaller/c/-ZnaaOOfO3M Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim [ replaced f2fs_err_ratelimited() with f2fs_err() ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/f2fs/node.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index d629b3c6546c..86ddd5a3d748 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -764,6 +764,16 @@ int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) for (i = 1; i <= level; i++) { bool done = false; + if (nids[i] && nids[i] == dn->inode->i_ino) { + err = -EFSCORRUPTED; + f2fs_err(sbi, + "inode mapping table is corrupted, run fsck to fix it, " + "ino:%lu, nid:%u, level:%d, offset:%d", + dn->inode->i_ino, nids[i], level, offset[level]); + set_sbi_flag(sbi, SBI_NEED_FSCK); + goto release_pages; + } + if (!nids[i] && mode == ALLOC_NODE) { /* alloc new node */ if (!f2fs_alloc_nid(sbi, &(nids[i]))) { From 8226db2309e20928d04b33707289f82c00ca71ed Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Fri, 22 Aug 2025 23:41:51 -0400 Subject: [PATCH 372/404] media: venus: hfi: explicitly release IRQ during teardown [ Upstream commit 640803003cd903cea73dc6a86bf6963e238e2b3f ] Ensure the IRQ is disabled - and all pending handlers completed - before dismantling the interrupt routing and clearing related pointers. This prevents any possibility of the interrupt triggering after the handler context has been invalidated. Fixes: d96d3f30c0f2 ("[media] media: venus: hfi: add Venus HFI files") Cc: stable@vger.kernel.org Signed-off-by: Jorge Ramirez-Ortiz Reviewed-by: Dikshita Agarwal Tested-by: Dikshita Agarwal # RB5 Reviewed-by: Bryan O'Donoghue Signed-off-by: Bryan O'Donoghue Signed-off-by: Hans Verkuil [ Adjust context ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/media/platform/qcom/venus/hfi_venus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c index 33d9d50e79cd..328c257b7849 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus.c +++ b/drivers/media/platform/qcom/venus/hfi_venus.c @@ -1608,6 +1608,7 @@ void venus_hfi_destroy(struct venus_core *core) mutex_destroy(&hdev->lock); kfree(hdev); core->priv = NULL; + disable_irq(core->irq); core->ops = NULL; } From d5514a1d67fcb4a0e2bf949f7e0a047350588997 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Tue, 19 Aug 2025 10:57:54 -0400 Subject: [PATCH 373/404] btrfs: populate otime when logging an inode item [ Upstream commit 1ef94169db0958d6de39f9ea6e063ce887342e2d ] [TEST FAILURE WITH EXPERIMENTAL FEATURES] When running test case generic/508, the test case will fail with the new btrfs shutdown support: generic/508 - output mismatch (see /home/adam/xfstests/results//generic/508.out.bad) # --- tests/generic/508.out 2022-05-11 11:25:30.806666664 +0930 # +++ /home/adam/xfstests/results//generic/508.out.bad 2025-07-02 14:53:22.401824212 +0930 # @@ -1,2 +1,6 @@ # QA output created by 508 # Silence is golden # +Before: # +After : stat.btime = Thu Jan 1 09:30:00 1970 # +Before: # +After : stat.btime = Wed Jul 2 14:53:22 2025 # ... # (Run 'diff -u /home/adam/xfstests/tests/generic/508.out /home/adam/xfstests/results//generic/508.out.bad' to see the entire diff) Ran: generic/508 Failures: generic/508 Failed 1 of 1 tests Please note that the test case requires shutdown support, thus the test case will be skipped using the current upstream kernel, as it doesn't have shutdown ioctl support. [CAUSE] The direct cause the 0 time stamp in the log tree: leaf 30507008 items 2 free space 16057 generation 9 owner TREE_LOG leaf 30507008 flags 0x1(WRITTEN) backref revision 1 checksum stored e522548d checksum calced e522548d fs uuid 57d45451-481e-43e4-aa93-289ad707a3a0 chunk uuid d52bd3fd-5163-4337-98a7-7986993ad398 item 0 key (257 INODE_ITEM 0) itemoff 16123 itemsize 160 generation 9 transid 9 size 0 nbytes 0 block group 0 mode 100644 links 1 uid 0 gid 0 rdev 0 sequence 1 flags 0x0(none) atime 1751432947.492000000 (2025-07-02 14:39:07) ctime 1751432947.492000000 (2025-07-02 14:39:07) mtime 1751432947.492000000 (2025-07-02 14:39:07) otime 0.0 (1970-01-01 09:30:00) <<< But the old fs tree has all the correct time stamp: btrfs-progs v6.12 fs tree key (FS_TREE ROOT_ITEM 0) leaf 30425088 items 2 free space 16061 generation 5 owner FS_TREE leaf 30425088 flags 0x1(WRITTEN) backref revision 1 checksum stored 48f6c57e checksum calced 48f6c57e fs uuid 57d45451-481e-43e4-aa93-289ad707a3a0 chunk uuid d52bd3fd-5163-4337-98a7-7986993ad398 item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160 generation 3 transid 0 size 0 nbytes 16384 block group 0 mode 40755 links 1 uid 0 gid 0 rdev 0 sequence 0 flags 0x0(none) atime 1751432947.0 (2025-07-02 14:39:07) ctime 1751432947.0 (2025-07-02 14:39:07) mtime 1751432947.0 (2025-07-02 14:39:07) otime 1751432947.0 (2025-07-02 14:39:07) <<< The root cause is that fill_inode_item() in tree-log.c is only populating a/c/m time, not the otime (or btime in statx output). Part of the reason is that, the vfs inode only has a/c/m time, no native btime support yet. [FIX] Thankfully btrfs has its otime stored in btrfs_inode::i_otime_sec and btrfs_inode::i_otime_nsec. So what we really need is just fill the otime time stamp in fill_inode_item() of tree-log.c There is another fill_inode_item() in inode.c, which is doing the proper otime population. Fixes: 94edf4ae43a5 ("Btrfs: don't bother committing delayed inode updates when fsyncing") CC: stable@vger.kernel.org Reviewed-by: Filipe Manana Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba [ adapted token-based API and timespec64 field structure ] Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/tree-log.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 133ad448a9ad..ed9911946638 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -3953,6 +3953,11 @@ static void fill_inode_item(struct btrfs_trans_handle *trans, btrfs_set_token_timespec_nsec(leaf, &item->ctime, inode->i_ctime.tv_nsec, &token); + btrfs_set_token_timespec_sec(leaf, &item->otime, + BTRFS_I(inode)->i_otime.tv_sec, &token); + btrfs_set_token_timespec_nsec(leaf, &item->otime, + BTRFS_I(inode)->i_otime.tv_nsec, &token); + btrfs_set_token_inode_nbytes(leaf, item, inode_get_bytes(inode), &token); From fcf09d75c308c10dde799c9492735436d1d0245d Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Thu, 3 Apr 2025 14:10:24 -0700 Subject: [PATCH 374/404] sch_drr: make drr_qlen_notify() idempotent commit df008598b3a00be02a8051fde89ca0fbc416bd55 upstream. drr_qlen_notify() always deletes the DRR class from its active list with list_del(), therefore, it is not idempotent and not friendly to its callers, like fq_codel_dequeue(). Let's make it idempotent to ease qdisc_tree_reduce_backlog() callers' life. Also change other list_del()'s to list_del_init() just to be extra safe. Reported-by: Gerrard Tai Signed-off-by: Cong Wang Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250403211033.166059-3-xiyou.wangcong@gmail.com Acked-by: Jamal Hadi Salim Signed-off-by: Paolo Abeni Signed-off-by: Siddh Raman Pant Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_drr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index 1a0571806342..088084eb393e 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c @@ -111,6 +111,7 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (cl == NULL) return -ENOBUFS; + INIT_LIST_HEAD(&cl->alist); cl->common.classid = classid; cl->quantum = quantum; cl->qdisc = qdisc_create_dflt(sch->dev_queue, @@ -234,7 +235,7 @@ static void drr_qlen_notify(struct Qdisc *csh, unsigned long arg) { struct drr_class *cl = (struct drr_class *)arg; - list_del(&cl->alist); + list_del_init(&cl->alist); } static int drr_dump_class(struct Qdisc *sch, unsigned long arg, @@ -401,7 +402,7 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch) if (unlikely(skb == NULL)) goto out; if (cl->qdisc->q.qlen == 0) - list_del(&cl->alist); + list_del_init(&cl->alist); bstats_update(&cl->bstats, skb); qdisc_bstats_update(sch, skb); @@ -442,7 +443,7 @@ static void drr_reset_qdisc(struct Qdisc *sch) for (i = 0; i < q->clhash.hashsize; i++) { hlist_for_each_entry(cl, &q->clhash.hash[i], common.hnode) { if (cl->qdisc->q.qlen) - list_del(&cl->alist); + list_del_init(&cl->alist); qdisc_reset(cl->qdisc); } } From 9a5fd5c2f4d4afdd5e405083ee53e0789ce76956 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Thu, 3 Apr 2025 14:10:25 -0700 Subject: [PATCH 375/404] sch_hfsc: make hfsc_qlen_notify() idempotent commit 51eb3b65544c9efd6a1026889ee5fb5aa62da3bb upstream. hfsc_qlen_notify() is not idempotent either and not friendly to its callers, like fq_codel_dequeue(). Let's make it idempotent to ease qdisc_tree_reduce_backlog() callers' life: 1. update_vf() decreases cl->cl_nactive, so we can check whether it is non-zero before calling it. 2. eltree_remove() always removes RB node cl->el_node, but we can use RB_EMPTY_NODE() + RB_CLEAR_NODE() to make it safe. Reported-by: Gerrard Tai Signed-off-by: Cong Wang Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250403211033.166059-4-xiyou.wangcong@gmail.com Acked-by: Jamal Hadi Salim Signed-off-by: Paolo Abeni Signed-off-by: Siddh Raman Pant Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_hfsc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 0f57dd39b6b8..5cb789c7c82d 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -209,7 +209,10 @@ eltree_insert(struct hfsc_class *cl) static inline void eltree_remove(struct hfsc_class *cl) { - rb_erase(&cl->el_node, &cl->sched->eligible); + if (!RB_EMPTY_NODE(&cl->el_node)) { + rb_erase(&cl->el_node, &cl->sched->eligible); + RB_CLEAR_NODE(&cl->el_node); + } } static inline void @@ -1230,7 +1233,8 @@ hfsc_qlen_notify(struct Qdisc *sch, unsigned long arg) /* vttree is now handled in update_vf() so that update_vf(cl, 0, 0) * needs to be called explicitly to remove a class from vttree. */ - update_vf(cl, 0, 0); + if (cl->cl_nactive) + update_vf(cl, 0, 0); if (cl->cl_flags & HFSC_RSC) eltree_remove(cl); } From 4f9cd311b7e9eb28c5eda0031537b1e59617aec8 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Thu, 3 Apr 2025 14:10:26 -0700 Subject: [PATCH 376/404] sch_qfq: make qfq_qlen_notify() idempotent commit 55f9eca4bfe30a15d8656f915922e8c98b7f0728 upstream. qfq_qlen_notify() always deletes its class from its active list with list_del_init() _and_ calls qfq_deactivate_agg() when the whole list becomes empty. To make it idempotent, just skip everything when it is not in the active list. Also change other list_del()'s to list_del_init() just to be extra safe. Reported-by: Gerrard Tai Signed-off-by: Cong Wang Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250403211033.166059-5-xiyou.wangcong@gmail.com Acked-by: Jamal Hadi Salim Signed-off-by: Paolo Abeni Signed-off-by: Siddh Raman Pant Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_qfq.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index be04fcfcc585..511f344dbb77 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -348,7 +348,7 @@ static void qfq_deactivate_class(struct qfq_sched *q, struct qfq_class *cl) struct qfq_aggregate *agg = cl->agg; - list_del(&cl->alist); /* remove from RR queue of the aggregate */ + list_del_init(&cl->alist); /* remove from RR queue of the aggregate */ if (list_empty(&agg->active)) /* agg is now inactive */ qfq_deactivate_agg(q, agg); } @@ -482,6 +482,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, cl->common.classid = classid; cl->deficit = lmax; + INIT_LIST_HEAD(&cl->alist); cl->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid, NULL); @@ -1001,7 +1002,7 @@ static struct sk_buff *agg_dequeue(struct qfq_aggregate *agg, cl->deficit -= (int) len; if (cl->qdisc->q.qlen == 0) /* no more packets, remove from list */ - list_del(&cl->alist); + list_del_init(&cl->alist); else if (cl->deficit < qdisc_pkt_len(cl->qdisc->ops->peek(cl->qdisc))) { cl->deficit += agg->lmax; list_move_tail(&cl->alist, &agg->active); @@ -1433,6 +1434,8 @@ static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg) struct qfq_sched *q = qdisc_priv(sch); struct qfq_class *cl = (struct qfq_class *)arg; + if (list_empty(&cl->alist)) + return; qfq_deactivate_class(q, cl); } From 7a742a9506849d1c1aa71e36c89855ceddc7d58e Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Thu, 3 Apr 2025 14:16:31 -0700 Subject: [PATCH 377/404] codel: remove sch->q.qlen check before qdisc_tree_reduce_backlog() commit 342debc12183b51773b3345ba267e9263bdfaaef upstream. After making all ->qlen_notify() callbacks idempotent, now it is safe to remove the check of qlen!=0 from both fq_codel_dequeue() and codel_qdisc_dequeue(). Reported-by: Gerrard Tai Fixes: 4b549a2ef4be ("fq_codel: Fair Queue Codel AQM") Fixes: 76e3cc126bb2 ("codel: Controlled Delay AQM") Signed-off-by: Cong Wang Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250403211636.166257-1-xiyou.wangcong@gmail.com Acked-by: Jamal Hadi Salim Signed-off-by: Paolo Abeni Signed-off-by: Siddh Raman Pant Signed-off-by: Greg Kroah-Hartman --- net/sched/sch_codel.c | 5 +---- net/sched/sch_fq_codel.c | 6 ++---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c index 30169b3adbbb..d9eff03deada 100644 --- a/net/sched/sch_codel.c +++ b/net/sched/sch_codel.c @@ -95,10 +95,7 @@ static struct sk_buff *codel_qdisc_dequeue(struct Qdisc *sch) &q->stats, qdisc_pkt_len, codel_get_enqueue_time, drop_func, dequeue_func); - /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0, - * or HTB crashes. Defer it for next round. - */ - if (q->stats.drop_count && sch->q.qlen) { + if (q->stats.drop_count) { qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len); q->stats.drop_count = 0; q->stats.drop_len = 0; diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 30796bb54972..eb380b43d52c 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -315,10 +315,8 @@ begin: } qdisc_bstats_update(sch, skb); flow->deficit -= qdisc_pkt_len(skb); - /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0, - * or HTB crashes. Defer it for next round. - */ - if (q->cstats.drop_count && sch->q.qlen) { + + if (q->cstats.drop_count) { qdisc_tree_reduce_backlog(sch, q->cstats.drop_count, q->cstats.drop_len); q->cstats.drop_count = 0; From 6a8b539c3d4adb757af48158cd82912d4dc19c60 Mon Sep 17 00:00:00 2001 From: Lorenzo Stoakes Date: Tue, 29 Jul 2025 17:58:06 -0700 Subject: [PATCH 378/404] mm: drop the assumption that VM_SHARED always implies writable [ Upstream commit e8e17ee90eaf650c855adb0a3e5e965fd6692ff1 ] Patch series "permit write-sealed memfd read-only shared mappings", v4. The man page for fcntl() describing memfd file seals states the following about F_SEAL_WRITE:- Furthermore, trying to create new shared, writable memory-mappings via mmap(2) will also fail with EPERM. With emphasis on 'writable'. In turns out in fact that currently the kernel simply disallows all new shared memory mappings for a memfd with F_SEAL_WRITE applied, rendering this documentation inaccurate. This matters because users are therefore unable to obtain a shared mapping to a memfd after write sealing altogether, which limits their usefulness. This was reported in the discussion thread [1] originating from a bug report [2]. This is a product of both using the struct address_space->i_mmap_writable atomic counter to determine whether writing may be permitted, and the kernel adjusting this counter when any VM_SHARED mapping is performed and more generally implicitly assuming VM_SHARED implies writable. It seems sensible that we should only update this mapping if VM_MAYWRITE is specified, i.e. whether it is possible that this mapping could at any point be written to. If we do so then all we need to do to permit write seals to function as documented is to clear VM_MAYWRITE when mapping read-only. It turns out this functionality already exists for F_SEAL_FUTURE_WRITE - we can therefore simply adapt this logic to do the same for F_SEAL_WRITE. We then hit a chicken and egg situation in mmap_region() where the check for VM_MAYWRITE occurs before we are able to clear this flag. To work around this, perform this check after we invoke call_mmap(), with careful consideration of error paths. Thanks to Andy Lutomirski for the suggestion! [1]:https://lore.kernel.org/all/20230324133646.16101dfa666f253c4715d965@linux-foundation.org/ [2]:https://bugzilla.kernel.org/show_bug.cgi?id=217238 This patch (of 3): There is a general assumption that VMAs with the VM_SHARED flag set are writable. If the VM_MAYWRITE flag is not set, then this is simply not the case. Update those checks which affect the struct address_space->i_mmap_writable field to explicitly test for this by introducing [vma_]is_shared_maywrite() helper functions. This remains entirely conservative, as the lack of VM_MAYWRITE guarantees that the VMA cannot be written to. Link: https://lkml.kernel.org/r/cover.1697116581.git.lstoakes@gmail.com Link: https://lkml.kernel.org/r/d978aefefa83ec42d18dfa964ad180dbcde34795.1697116581.git.lstoakes@gmail.com Signed-off-by: Lorenzo Stoakes Suggested-by: Andy Lutomirski Reviewed-by: Jan Kara Cc: Alexander Viro Cc: Christian Brauner Cc: Hugh Dickins Cc: Matthew Wilcox (Oracle) Cc: Mike Kravetz Cc: Muchun Song Signed-off-by: Andrew Morton Cc: stable@vger.kernel.org Signed-off-by: Isaac J. Manjarres Signed-off-by: Greg Kroah-Hartman --- include/linux/fs.h | 4 ++-- include/linux/mm.h | 11 +++++++++++ kernel/fork.c | 2 +- mm/filemap.c | 2 +- mm/madvise.c | 2 +- mm/mmap.c | 10 +++++----- 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/include/linux/fs.h b/include/linux/fs.h index d3648a55590c..c5985d72d60e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -430,7 +430,7 @@ int pagecache_write_end(struct file *, struct address_space *mapping, * @host: Owner, either the inode or the block_device. * @i_pages: Cached pages. * @gfp_mask: Memory allocation flags to use for allocating pages. - * @i_mmap_writable: Number of VM_SHARED mappings. + * @i_mmap_writable: Number of VM_SHARED, VM_MAYWRITE mappings. * @nr_thps: Number of THPs in the pagecache (non-shmem only). * @i_mmap: Tree of private and shared mappings. * @i_mmap_rwsem: Protects @i_mmap and @i_mmap_writable. @@ -553,7 +553,7 @@ static inline int mapping_mapped(struct address_space *mapping) /* * Might pages of this file have been modified in userspace? - * Note that i_mmap_writable counts all VM_SHARED vmas: do_mmap_pgoff + * Note that i_mmap_writable counts all VM_SHARED, VM_MAYWRITE vmas: do_mmap_pgoff * marks vma as VM_SHARED if it is shared, and the file was opened for * writing i.e. vma may be mprotected writable even if now readonly. * diff --git a/include/linux/mm.h b/include/linux/mm.h index 4d3657b630db..47d56c96447a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -549,6 +549,17 @@ static inline bool vma_is_anonymous(struct vm_area_struct *vma) return !vma->vm_ops; } +static inline bool is_shared_maywrite(vm_flags_t vm_flags) +{ + return (vm_flags & (VM_SHARED | VM_MAYWRITE)) == + (VM_SHARED | VM_MAYWRITE); +} + +static inline bool vma_is_shared_maywrite(struct vm_area_struct *vma) +{ + return is_shared_maywrite(vma->vm_flags); +} + #ifdef CONFIG_SHMEM /* * The vma_is_shmem is not inline because it is used only by slow diff --git a/kernel/fork.c b/kernel/fork.c index e71f96bff1dc..ad3e6e91d828 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -566,7 +566,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, if (tmp->vm_flags & VM_DENYWRITE) atomic_dec(&inode->i_writecount); i_mmap_lock_write(mapping); - if (tmp->vm_flags & VM_SHARED) + if (vma_is_shared_maywrite(tmp)) atomic_inc(&mapping->i_mmap_writable); flush_dcache_mmap_lock(mapping); /* insert tmp into the share list, just after mpnt */ diff --git a/mm/filemap.c b/mm/filemap.c index f1ed0400c37c..af3efb23262b 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2876,7 +2876,7 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma) */ int generic_file_readonly_mmap(struct file *file, struct vm_area_struct *vma) { - if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) + if (vma_is_shared_maywrite(vma)) return -EINVAL; return generic_file_mmap(file, vma); } diff --git a/mm/madvise.c b/mm/madvise.c index ac8d68c488b5..3f5331c96ad5 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -839,7 +839,7 @@ static long madvise_remove(struct vm_area_struct *vma, return -EINVAL; } - if ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE)) + if (!vma_is_shared_maywrite(vma)) return -EACCES; offset = (loff_t)(start - vma->vm_start) diff --git a/mm/mmap.c b/mm/mmap.c index eeebbb20accf..cb712ae731cd 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -141,7 +141,7 @@ static void __remove_shared_vm_struct(struct vm_area_struct *vma, { if (vma->vm_flags & VM_DENYWRITE) atomic_inc(&file_inode(file)->i_writecount); - if (vma->vm_flags & VM_SHARED) + if (vma_is_shared_maywrite(vma)) mapping_unmap_writable(mapping); flush_dcache_mmap_lock(mapping); @@ -619,7 +619,7 @@ static void __vma_link_file(struct vm_area_struct *vma) if (vma->vm_flags & VM_DENYWRITE) atomic_dec(&file_inode(file)->i_writecount); - if (vma->vm_flags & VM_SHARED) + if (vma_is_shared_maywrite(vma)) atomic_inc(&mapping->i_mmap_writable); flush_dcache_mmap_lock(mapping); @@ -1785,7 +1785,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, if (error) goto free_vma; } - if (vm_flags & VM_SHARED) { + if (is_shared_maywrite(vm_flags)) { error = mapping_map_writable(file->f_mapping); if (error) goto allow_write_and_free_vma; @@ -1823,7 +1823,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, vma_link(mm, vma, prev, rb_link, rb_parent); /* Once vma denies write, undo our temporary denial count */ if (file) { - if (vm_flags & VM_SHARED) + if (is_shared_maywrite(vm_flags)) mapping_unmap_writable(file->f_mapping); if (vm_flags & VM_DENYWRITE) allow_write_access(file); @@ -1864,7 +1864,7 @@ unmap_and_free_vma: /* Undo any partial mapping done by a device driver. */ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); - if (vm_flags & VM_SHARED) + if (is_shared_maywrite(vm_flags)) mapping_unmap_writable(file->f_mapping); allow_write_and_free_vma: if (vm_flags & VM_DENYWRITE) From 55933e953857e06fbc8373020af4b87cef81376b Mon Sep 17 00:00:00 2001 From: Lorenzo Stoakes Date: Tue, 29 Jul 2025 17:58:07 -0700 Subject: [PATCH 379/404] mm: update memfd seal write check to include F_SEAL_WRITE [ Upstream commit 28464bbb2ddc199433383994bcb9600c8034afa1 ] The seal_check_future_write() function is called by shmem_mmap() or hugetlbfs_file_mmap() to disallow any future writable mappings of an memfd sealed this way. The F_SEAL_WRITE flag is not checked here, as that is handled via the mapping->i_mmap_writable mechanism and so any attempt at a mapping would fail before this could be run. However we intend to change this, meaning this check can be performed for F_SEAL_WRITE mappings also. The logic here is equally applicable to both flags, so update this function to accommodate both and rename it accordingly. Link: https://lkml.kernel.org/r/913628168ce6cce77df7d13a63970bae06a526e0.1697116581.git.lstoakes@gmail.com Signed-off-by: Lorenzo Stoakes Reviewed-by: Jan Kara Cc: Alexander Viro Cc: Andy Lutomirski Cc: Christian Brauner Cc: Hugh Dickins Cc: Matthew Wilcox (Oracle) Cc: Mike Kravetz Cc: Muchun Song Signed-off-by: Andrew Morton Cc: stable@vger.kernel.org Signed-off-by: Isaac J. Manjarres Signed-off-by: Greg Kroah-Hartman --- fs/hugetlbfs/inode.c | 2 +- include/linux/mm.h | 15 ++++++++------- mm/shmem.c | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 47b292f9b4f8..c18a47a86e8b 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -152,7 +152,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND; vma->vm_ops = &hugetlb_vm_ops; - ret = seal_check_future_write(info->seals, vma); + ret = seal_check_write(info->seals, vma); if (ret) return ret; diff --git a/include/linux/mm.h b/include/linux/mm.h index 47d56c96447a..57cba6e4fdcd 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2946,25 +2946,26 @@ static inline int pages_identical(struct page *page1, struct page *page2) } /** - * seal_check_future_write - Check for F_SEAL_FUTURE_WRITE flag and handle it + * seal_check_write - Check for F_SEAL_WRITE or F_SEAL_FUTURE_WRITE flags and + * handle them. * @seals: the seals to check * @vma: the vma to operate on * - * Check whether F_SEAL_FUTURE_WRITE is set; if so, do proper check/handling on - * the vma flags. Return 0 if check pass, or <0 for errors. + * Check whether F_SEAL_WRITE or F_SEAL_FUTURE_WRITE are set; if so, do proper + * check/handling on the vma flags. Return 0 if check pass, or <0 for errors. */ -static inline int seal_check_future_write(int seals, struct vm_area_struct *vma) +static inline int seal_check_write(int seals, struct vm_area_struct *vma) { - if (seals & F_SEAL_FUTURE_WRITE) { + if (seals & (F_SEAL_WRITE | F_SEAL_FUTURE_WRITE)) { /* * New PROT_WRITE and MAP_SHARED mmaps are not allowed when - * "future write" seal active. + * write seals are active. */ if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_WRITE)) return -EPERM; /* - * Since an F_SEAL_FUTURE_WRITE sealed memfd can be mapped as + * Since an F_SEAL_[FUTURE_]WRITE sealed memfd can be mapped as * MAP_SHARED and read-only, take care to not allow mprotect to * revert protections on such mappings. Do this only for shared * mappings. For private mappings, don't need to mask diff --git a/mm/shmem.c b/mm/shmem.c index 264229680ad7..8475d56f5977 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2215,7 +2215,7 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma) struct shmem_inode_info *info = SHMEM_I(file_inode(file)); int ret; - ret = seal_check_future_write(info->seals, vma); + ret = seal_check_write(info->seals, vma); if (ret) return ret; From f11d31371b4e2bfa8a55213aec0ae2e17bb17bf3 Mon Sep 17 00:00:00 2001 From: Lorenzo Stoakes Date: Tue, 29 Jul 2025 17:58:08 -0700 Subject: [PATCH 380/404] mm: perform the mapping_map_writable() check after call_mmap() [ Upstream commit 158978945f3173b8c1a88f8c5684a629736a57ac ] In order for a F_SEAL_WRITE sealed memfd mapping to have an opportunity to clear VM_MAYWRITE, we must be able to invoke the appropriate vm_ops->mmap() handler to do so. We would otherwise fail the mapping_map_writable() check before we had the opportunity to avoid it. This patch moves this check after the call_mmap() invocation. Only memfd actively denies write access causing a potential failure here (in memfd_add_seals()), so there should be no impact on non-memfd cases. This patch makes the userland-visible change that MAP_SHARED, PROT_READ mappings of an F_SEAL_WRITE sealed memfd mapping will now succeed. There is a delicate situation with cleanup paths assuming that a writable mapping must have occurred in circumstances where it may now not have. In order to ensure we do not accidentally mark a writable file unwritable by mistake, we explicitly track whether we have a writable mapping and unmap only if we do. [lstoakes@gmail.com: do not set writable_file_mapping in inappropriate case] Link: https://lkml.kernel.org/r/c9eb4cc6-7db4-4c2b-838d-43a0b319a4f0@lucifer.local Link: https://bugzilla.kernel.org/show_bug.cgi?id=217238 Link: https://lkml.kernel.org/r/55e413d20678a1bb4c7cce889062bbb07b0df892.1697116581.git.lstoakes@gmail.com Signed-off-by: Lorenzo Stoakes Reviewed-by: Jan Kara Cc: Alexander Viro Cc: Andy Lutomirski Cc: Christian Brauner Cc: Hugh Dickins Cc: Matthew Wilcox (Oracle) Cc: Mike Kravetz Cc: Muchun Song Signed-off-by: Andrew Morton Cc: stable@vger.kernel.org [isaacmanjarres: added error handling to cleanup the work done by the mmap() callback and removed unused label.] Signed-off-by: Isaac J. Manjarres Signed-off-by: Greg Kroah-Hartman --- mm/mmap.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index cb712ae731cd..e591a82a26a8 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1718,6 +1718,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, { struct mm_struct *mm = current->mm; struct vm_area_struct *vma, *prev; + bool writable_file_mapping = false; int error; struct rb_node **rb_link, *rb_parent; unsigned long charged = 0; @@ -1785,11 +1786,6 @@ unsigned long mmap_region(struct file *file, unsigned long addr, if (error) goto free_vma; } - if (is_shared_maywrite(vm_flags)) { - error = mapping_map_writable(file->f_mapping); - if (error) - goto allow_write_and_free_vma; - } /* ->mmap() can change vma->vm_file, but must guarantee that * vma_link() below can deny write-access if VM_DENYWRITE is set @@ -1801,6 +1797,14 @@ unsigned long mmap_region(struct file *file, unsigned long addr, if (error) goto unmap_and_free_vma; + if (vma_is_shared_maywrite(vma)) { + error = mapping_map_writable(file->f_mapping); + if (error) + goto close_and_free_vma; + + writable_file_mapping = true; + } + /* Can addr have changed?? * * Answer: Yes, several device drivers can do it in their @@ -1823,7 +1827,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, vma_link(mm, vma, prev, rb_link, rb_parent); /* Once vma denies write, undo our temporary denial count */ if (file) { - if (is_shared_maywrite(vm_flags)) + if (writable_file_mapping) mapping_unmap_writable(file->f_mapping); if (vm_flags & VM_DENYWRITE) allow_write_access(file); @@ -1858,15 +1862,17 @@ out: return addr; +close_and_free_vma: + if (vma->vm_ops && vma->vm_ops->close) + vma->vm_ops->close(vma); unmap_and_free_vma: vma->vm_file = NULL; fput(file); /* Undo any partial mapping done by a device driver. */ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); - if (is_shared_maywrite(vm_flags)) + if (writable_file_mapping) mapping_unmap_writable(file->f_mapping); -allow_write_and_free_vma: if (vm_flags & VM_DENYWRITE) allow_write_access(file); free_vma: From 306e2719c91cd022719368bc31407315e0da7ee6 Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Fri, 25 Jul 2025 00:56:12 +0530 Subject: [PATCH 381/404] net: sched: extract common action counters update code into function [ Upstream commit c8ecebd04cbb6badb46d42fe54282e7883ed63cc ] Currently, all implementations of tc_action_ops->stats_update() callback have almost exactly the same implementation of counters update code (besides gact which also updates drop counter). In order to simplify support for using both percpu-allocated and regular action counters depending on run-time flag in following patches, extract action counters update code into standalone function in act API. This commit doesn't change functionality. Signed-off-by: Vlad Buslov Acked-by: Jiri Pirko Signed-off-by: David S. Miller Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni Signed-off-by: Greg Kroah-Hartman --- include/net/act_api.h | 2 ++ net/sched/act_api.c | 14 ++++++++++++++ net/sched/act_ct.c | 6 +----- net/sched/act_gact.c | 10 +--------- net/sched/act_mirred.c | 5 +---- net/sched/act_police.c | 5 +---- net/sched/act_vlan.c | 5 +---- 7 files changed, 21 insertions(+), 26 deletions(-) diff --git a/include/net/act_api.h b/include/net/act_api.h index 4dabe4730f00..39374348510c 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -186,6 +186,8 @@ int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[], int bind, int ref); int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int); int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int); +void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets, + bool drop, bool hw); int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int); int tcf_action_check_ctrlact(int action, struct tcf_proto *tp, diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 52394e45bac5..b2a537f1a1ea 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -1032,6 +1032,20 @@ err: return err; } +void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets, + bool drop, bool hw) +{ + _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); + + if (drop) + this_cpu_ptr(a->cpu_qstats)->drops += packets; + + if (hw) + _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw), + bytes, packets); +} +EXPORT_SYMBOL(tcf_action_update_stats); + int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *p, int compat_mode) { diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c index 02d4491991b5..d72c9888fad2 100644 --- a/net/sched/act_ct.c +++ b/net/sched/act_ct.c @@ -917,11 +917,7 @@ static void tcf_stats_update(struct tc_action *a, u64 bytes, u32 packets, { struct tcf_ct *c = to_ct(a); - _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); - - if (hw) - _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw), - bytes, packets); + tcf_action_update_stats(a, bytes, packets, false, hw); c->tcf_tm.lastuse = max_t(u64, c->tcf_tm.lastuse, lastuse); } diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index faf68a44b845..d58a6c75349f 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -175,15 +175,7 @@ static void tcf_gact_stats_update(struct tc_action *a, u64 bytes, u32 packets, int action = READ_ONCE(gact->tcf_action); struct tcf_t *tm = &gact->tcf_tm; - _bstats_cpu_update(this_cpu_ptr(gact->common.cpu_bstats), bytes, - packets); - if (action == TC_ACT_SHOT) - this_cpu_ptr(gact->common.cpu_qstats)->drops += packets; - - if (hw) - _bstats_cpu_update(this_cpu_ptr(gact->common.cpu_bstats_hw), - bytes, packets); - + tcf_action_update_stats(a, bytes, packets, action == TC_ACT_SHOT, hw); tm->lastuse = max_t(u64, tm->lastuse, lastuse); } diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index e3f28cb03f7e..f38fd459ea45 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -324,10 +324,7 @@ static void tcf_stats_update(struct tc_action *a, u64 bytes, u32 packets, struct tcf_mirred *m = to_mirred(a); struct tcf_t *tm = &m->tcf_tm; - _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); - if (hw) - _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw), - bytes, packets); + tcf_action_update_stats(a, bytes, packets, false, hw); tm->lastuse = max_t(u64, tm->lastuse, lastuse); } diff --git a/net/sched/act_police.c b/net/sched/act_police.c index a7660b602237..b67da92955b1 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -306,10 +306,7 @@ static void tcf_police_stats_update(struct tc_action *a, struct tcf_police *police = to_police(a); struct tcf_t *tm = &police->tcf_tm; - _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); - if (hw) - _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw), - bytes, packets); + tcf_action_update_stats(a, bytes, packets, false, hw); tm->lastuse = max_t(u64, tm->lastuse, lastuse); } diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c index 7dc76c68ec52..43c5be18241b 100644 --- a/net/sched/act_vlan.c +++ b/net/sched/act_vlan.c @@ -308,10 +308,7 @@ static void tcf_vlan_stats_update(struct tc_action *a, u64 bytes, u32 packets, struct tcf_vlan *v = to_vlan(a); struct tcf_t *tm = &v->tcf_tm; - _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); - if (hw) - _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw), - bytes, packets); + tcf_action_update_stats(a, bytes, packets, false, hw); tm->lastuse = max_t(u64, tm->lastuse, lastuse); } From dc15bd56343cd1c7c106265757d0be619ec34bf8 Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Fri, 25 Jul 2025 00:56:13 +0530 Subject: [PATCH 382/404] net: sched: extract bstats update code into function [ Upstream commit 5e1ad95b630e652d3467d1fd1f0b5e5ea2c441e2 ] Extract common code that increments cpu_bstats counter into standalone act API function. Change hardware offloaded actions that use percpu counter allocation to use the new function instead of incrementing cpu_bstats directly. This commit doesn't change functionality. Signed-off-by: Vlad Buslov Acked-by: Jiri Pirko Signed-off-by: David S. Miller Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni Signed-off-by: Greg Kroah-Hartman --- include/net/act_api.h | 7 +++++++ net/sched/act_csum.c | 2 +- net/sched/act_ct.c | 2 +- net/sched/act_gact.c | 2 +- net/sched/act_mirred.c | 2 +- net/sched/act_tunnel_key.c | 2 +- net/sched/act_vlan.c | 2 +- 7 files changed, 13 insertions(+), 6 deletions(-) diff --git a/include/net/act_api.h b/include/net/act_api.h index 39374348510c..46009acb198b 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -186,6 +186,13 @@ int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[], int bind, int ref); int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int); int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int); + +static inline void tcf_action_update_bstats(struct tc_action *a, + struct sk_buff *skb) +{ + bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), skb); +} + void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets, bool drop, bool hw); int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int); diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index fa1b1fd10c44..e502e256ad67 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -577,7 +577,7 @@ static int tcf_csum_act(struct sk_buff *skb, const struct tc_action *a, params = rcu_dereference_bh(p->params); tcf_lastuse_update(&p->tcf_tm); - bstats_cpu_update(this_cpu_ptr(p->common.cpu_bstats), skb); + tcf_action_update_bstats(&p->common, skb); action = READ_ONCE(p->tcf_action); if (unlikely(action == TC_ACT_SHOT)) diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c index d72c9888fad2..0727a2516736 100644 --- a/net/sched/act_ct.c +++ b/net/sched/act_ct.c @@ -482,7 +482,7 @@ out_push: skb_push_rcsum(skb, nh_ofs); out: - bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), skb); + tcf_action_update_bstats(&c->common, skb); return retval; drop: diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index d58a6c75349f..ff78de432871 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -159,7 +159,7 @@ static int tcf_gact_act(struct sk_buff *skb, const struct tc_action *a, action = gact_rand[ptype](gact); } #endif - bstats_cpu_update(this_cpu_ptr(gact->common.cpu_bstats), skb); + tcf_action_update_bstats(&gact->common, skb); if (action == TC_ACT_SHOT) qstats_drop_inc(this_cpu_ptr(gact->common.cpu_qstats)); diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index f38fd459ea45..52830e0339f9 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -233,7 +233,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, } tcf_lastuse_update(&m->tcf_tm); - bstats_cpu_update(this_cpu_ptr(m->common.cpu_bstats), skb); + tcf_action_update_bstats(&m->common, skb); m_mac_header_xmit = READ_ONCE(m->tcfm_mac_header_xmit); m_eaction = READ_ONCE(m->tcfm_eaction); diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c index a5a2bf01eb9b..e5b0c13d6d58 100644 --- a/net/sched/act_tunnel_key.c +++ b/net/sched/act_tunnel_key.c @@ -31,7 +31,7 @@ static int tunnel_key_act(struct sk_buff *skb, const struct tc_action *a, params = rcu_dereference_bh(t->params); tcf_lastuse_update(&t->tcf_tm); - bstats_cpu_update(this_cpu_ptr(t->common.cpu_bstats), skb); + tcf_action_update_bstats(&t->common, skb); action = READ_ONCE(t->tcf_action); switch (params->tcft_action) { diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c index 43c5be18241b..ffa5df8765b7 100644 --- a/net/sched/act_vlan.c +++ b/net/sched/act_vlan.c @@ -29,7 +29,7 @@ static int tcf_vlan_act(struct sk_buff *skb, const struct tc_action *a, u16 tci; tcf_lastuse_update(&v->tcf_tm); - bstats_cpu_update(this_cpu_ptr(v->common.cpu_bstats), skb); + tcf_action_update_bstats(&v->common, skb); /* Ensure 'data' points at mac_header prior calling vlan manipulating * functions. From b7b56a5f5c6045504e3c74169950abb4c7a65889 Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Fri, 25 Jul 2025 00:56:14 +0530 Subject: [PATCH 383/404] net: sched: extract qstats update code into functions [ Upstream commit 26b537a88ca5b7399c7ab0656e06dbd9da9513c1 ] Extract common code that increments cpu_qstats counters into standalone act API functions. Change hardware offloaded actions that use percpu counter allocation to use the new functions instead of accessing cpu_qstats directly. This commit doesn't change functionality. Signed-off-by: Vlad Buslov Acked-by: Jiri Pirko Signed-off-by: David S. Miller Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni Signed-off-by: Greg Kroah-Hartman --- include/net/act_api.h | 16 ++++++++++++++++ net/sched/act_csum.c | 2 +- net/sched/act_ct.c | 2 +- net/sched/act_gact.c | 2 +- net/sched/act_mirred.c | 2 +- net/sched/act_vlan.c | 2 +- 6 files changed, 21 insertions(+), 5 deletions(-) diff --git a/include/net/act_api.h b/include/net/act_api.h index 46009acb198b..25d9a12118ba 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -193,6 +193,22 @@ static inline void tcf_action_update_bstats(struct tc_action *a, bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), skb); } +static inline struct gnet_stats_queue * +tcf_action_get_qstats(struct tc_action *a) +{ + return this_cpu_ptr(a->cpu_qstats); +} + +static inline void tcf_action_inc_drop_qstats(struct tc_action *a) +{ + qstats_drop_inc(this_cpu_ptr(a->cpu_qstats)); +} + +static inline void tcf_action_inc_overlimit_qstats(struct tc_action *a) +{ + qstats_overlimit_inc(this_cpu_ptr(a->cpu_qstats)); +} + void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets, bool drop, bool hw); int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int); diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index e502e256ad67..5a1f9c8be8b7 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -621,7 +621,7 @@ out: return action; drop: - qstats_drop_inc(this_cpu_ptr(p->common.cpu_qstats)); + tcf_action_inc_drop_qstats(&p->common); action = TC_ACT_SHOT; goto out; } diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c index 0727a2516736..077cef97527f 100644 --- a/net/sched/act_ct.c +++ b/net/sched/act_ct.c @@ -486,7 +486,7 @@ out: return retval; drop: - qstats_drop_inc(this_cpu_ptr(a->cpu_qstats)); + tcf_action_inc_drop_qstats(&c->common); return TC_ACT_SHOT; } diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index ff78de432871..ef08fd58f28a 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -161,7 +161,7 @@ static int tcf_gact_act(struct sk_buff *skb, const struct tc_action *a, #endif tcf_action_update_bstats(&gact->common, skb); if (action == TC_ACT_SHOT) - qstats_drop_inc(this_cpu_ptr(gact->common.cpu_qstats)); + tcf_action_inc_drop_qstats(&gact->common); tcf_lastuse_update(&gact->tcf_tm); diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 52830e0339f9..5602b5de194b 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -309,7 +309,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, if (err) { out: - qstats_overlimit_inc(this_cpu_ptr(m->common.cpu_qstats)); + tcf_action_inc_overlimit_qstats(&m->common); if (tcf_mirred_is_act_redirect(m_eaction)) retval = TC_ACT_SHOT; } diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c index ffa5df8765b7..b4b09c0c8589 100644 --- a/net/sched/act_vlan.c +++ b/net/sched/act_vlan.c @@ -88,7 +88,7 @@ out: return action; drop: - qstats_drop_inc(this_cpu_ptr(v->common.cpu_qstats)); + tcf_action_inc_drop_qstats(&v->common); return TC_ACT_SHOT; } From 4d6f20bf0fcd6c8d19efd15c58907898a7cc71c0 Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Fri, 25 Jul 2025 00:56:15 +0530 Subject: [PATCH 384/404] net: sched: don't expose action qstats to skb_tc_reinsert() [ Upstream commit ef816f3c49c1c404ababc50e10d4cbe5109da678 ] Previous commit introduced helper function for updating qstats and refactored set of actions to use the helpers, instead of modifying qstats directly. However, one of the affected action exposes its qstats to skb_tc_reinsert(), which then modifies it. Refactor skb_tc_reinsert() to return integer error code and don't increment overlimit qstats in case of error, and use the returned error code in tcf_mirred_act() to manually increment the overlimit counter with new helper function. Signed-off-by: Vlad Buslov Acked-by: Jiri Pirko Signed-off-by: David S. Miller [ skulkarni: Adjusted patch for file 'sch_generic.h' wrt the mainline commit ] Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni Signed-off-by: Greg Kroah-Hartman --- include/net/sch_generic.h | 12 ++---------- net/sched/act_mirred.c | 4 ++-- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 6d934ce54c8d..ee47d65b9b20 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -1320,17 +1320,9 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, void mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc, struct mini_Qdisc __rcu **p_miniq); -static inline void skb_tc_reinsert(struct sk_buff *skb, struct tcf_result *res) +static inline int skb_tc_reinsert(struct sk_buff *skb, struct tcf_result *res) { - struct gnet_stats_queue *stats = res->qstats; - int ret; - - if (res->ingress) - ret = netif_receive_skb(skb); - else - ret = dev_queue_xmit(skb); - if (ret && stats) - qstats_overlimit_inc(res->qstats); + return res->ingress ? netif_receive_skb(skb) : dev_queue_xmit(skb); } /* Make sure qdisc is no longer in SCHED state. */ diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 5602b5de194b..a7e924806c2c 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -295,8 +295,8 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, /* let's the caller reinsert the packet, if possible */ if (use_reinsert) { res->ingress = want_ingress; - res->qstats = this_cpu_ptr(m->common.cpu_qstats); - skb_tc_reinsert(skb, res); + if (skb_tc_reinsert(skb, res)) + tcf_action_inc_overlimit_qstats(&m->common); __this_cpu_dec(mirred_rec_level); return TC_ACT_CONSUMED; } From 7192eb73a085ef8cbc9fb6c0a72f6ffaadc3592d Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 25 Jul 2025 00:56:16 +0530 Subject: [PATCH 385/404] selftests: forwarding: tc_actions.sh: add matchall mirror test [ Upstream commit 075c8aa79d541ea08c67a2e6d955f6457e98c21c ] Add test for matchall classifier with mirred egress mirror action. Signed-off-by: Jiri Pirko Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni Signed-off-by: Greg Kroah-Hartman --- .../selftests/net/forwarding/tc_actions.sh | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh index 813d02d1939d..d9eca227136b 100755 --- a/tools/testing/selftests/net/forwarding/tc_actions.sh +++ b/tools/testing/selftests/net/forwarding/tc_actions.sh @@ -2,7 +2,8 @@ # SPDX-License-Identifier: GPL-2.0 ALL_TESTS="gact_drop_and_ok_test mirred_egress_redirect_test \ - mirred_egress_mirror_test gact_trap_test" + mirred_egress_mirror_test matchall_mirred_egress_mirror_test \ + gact_trap_test" NUM_NETIFS=4 source tc_common.sh source lib.sh @@ -50,6 +51,9 @@ switch_destroy() mirred_egress_test() { local action=$1 + local protocol=$2 + local classifier=$3 + local classifier_args=$4 RET=0 @@ -62,9 +66,9 @@ mirred_egress_test() tc_check_packets "dev $h2 ingress" 101 1 check_fail $? "Matched without redirect rule inserted" - tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \ - $tcflags dst_ip 192.0.2.2 action mirred egress $action \ - dev $swp2 + tc filter add dev $swp1 ingress protocol $protocol pref 1 handle 101 \ + $classifier $tcflags $classifier_args \ + action mirred egress $action dev $swp2 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ -t ip -q @@ -72,10 +76,11 @@ mirred_egress_test() tc_check_packets "dev $h2 ingress" 101 1 check_err $? "Did not match incoming $action packet" - tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower + tc filter del dev $swp1 ingress protocol $protocol pref 1 handle 101 \ + $classifier tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower - log_test "mirred egress $action ($tcflags)" + log_test "mirred egress $classifier $action ($tcflags)" } gact_drop_and_ok_test() @@ -187,12 +192,17 @@ cleanup() mirred_egress_redirect_test() { - mirred_egress_test "redirect" + mirred_egress_test "redirect" "ip" "flower" "dst_ip 192.0.2.2" } mirred_egress_mirror_test() { - mirred_egress_test "mirror" + mirred_egress_test "mirror" "ip" "flower" "dst_ip 192.0.2.2" +} + +matchall_mirred_egress_mirror_test() +{ + mirred_egress_test "mirror" "all" "matchall" "" } trap cleanup EXIT From 02ca042304e8dc9a56e28ae3f905cd038504a064 Mon Sep 17 00:00:00 2001 From: wenxu Date: Fri, 25 Jul 2025 00:56:17 +0530 Subject: [PATCH 386/404] net/sched: act_mirred: refactor the handle of xmit [ Upstream commit fa6d639930ee5cd3f932cc314f3407f07a06582d ] This one is prepare for the next patch. Signed-off-by: wenxu Signed-off-by: Jakub Kicinski [ skulkarni: Adjusted patch for file 'sch_generic.h' wrt the mainline commit ] Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni Signed-off-by: Greg Kroah-Hartman --- include/net/sch_generic.h | 5 ----- net/sched/act_mirred.c | 21 +++++++++++++++------ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index ee47d65b9b20..a9a68714b58f 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -1320,11 +1320,6 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, void mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc, struct mini_Qdisc __rcu **p_miniq); -static inline int skb_tc_reinsert(struct sk_buff *skb, struct tcf_result *res) -{ - return res->ingress ? netif_receive_skb(skb) : dev_queue_xmit(skb); -} - /* Make sure qdisc is no longer in SCHED state. */ static inline void qdisc_synchronize(const struct Qdisc *q) { diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index a7e924806c2c..9e094c984217 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -206,6 +206,18 @@ release_idr: return err; } +static int tcf_mirred_forward(bool want_ingress, struct sk_buff *skb) +{ + int err; + + if (!want_ingress) + err = dev_queue_xmit(skb); + else + err = netif_receive_skb(skb); + + return err; +} + static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res) { @@ -295,18 +307,15 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, /* let's the caller reinsert the packet, if possible */ if (use_reinsert) { res->ingress = want_ingress; - if (skb_tc_reinsert(skb, res)) + err = tcf_mirred_forward(res->ingress, skb); + if (err) tcf_action_inc_overlimit_qstats(&m->common); __this_cpu_dec(mirred_rec_level); return TC_ACT_CONSUMED; } } - if (!want_ingress) - err = dev_queue_xmit(skb2); - else - err = netif_receive_skb(skb2); - + err = tcf_mirred_forward(want_ingress, skb2); if (err) { out: tcf_action_inc_overlimit_qstats(&m->common); From cfae16e8f3e3b8a5fb22d202079b34493b2e9851 Mon Sep 17 00:00:00 2001 From: Davide Caratti Date: Fri, 25 Jul 2025 00:56:18 +0530 Subject: [PATCH 387/404] net/sched: act_mirred: better wording on protection against excessive stack growth [ Upstream commit 78dcdffe0418ac8f3f057f26fe71ccf4d8ed851f ] with commit e2ca070f89ec ("net: sched: protect against stack overflow in TC act_mirred"), act_mirred protected itself against excessive stack growth using per_cpu counter of nested calls to tcf_mirred_act(), and capping it to MIRRED_RECURSION_LIMIT. However, such protection does not detect recursion/loops in case the packet is enqueued to the backlog (for example, when the mirred target device has RPS or skb timestamping enabled). Change the wording from "recursion" to "nesting" to make it more clear to readers. CC: Jamal Hadi Salim Signed-off-by: Davide Caratti Reviewed-by: Marcelo Ricardo Leitner Acked-by: Jamal Hadi Salim Signed-off-by: Paolo Abeni [ skulkarni: Adjusted patch for file 'act_mirred.c' - hunk #4/4 wrt the mainline commit ] Stable-dep-of: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress") Signed-off-by: Shubham Kulkarni Signed-off-by: Greg Kroah-Hartman --- net/sched/act_mirred.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 9e094c984217..5181eac5860e 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -28,8 +28,8 @@ static LIST_HEAD(mirred_list); static DEFINE_SPINLOCK(mirred_list_lock); -#define MIRRED_RECURSION_LIMIT 4 -static DEFINE_PER_CPU(unsigned int, mirred_rec_level); +#define MIRRED_NEST_LIMIT 4 +static DEFINE_PER_CPU(unsigned int, mirred_nest_level); static bool tcf_mirred_is_act_redirect(int action) { @@ -225,7 +225,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, struct sk_buff *skb2 = skb; bool m_mac_header_xmit; struct net_device *dev; - unsigned int rec_level; + unsigned int nest_level; int retval, err = 0; bool use_reinsert; bool want_ingress; @@ -236,11 +236,11 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, int mac_len; bool at_nh; - rec_level = __this_cpu_inc_return(mirred_rec_level); - if (unlikely(rec_level > MIRRED_RECURSION_LIMIT)) { + nest_level = __this_cpu_inc_return(mirred_nest_level); + if (unlikely(nest_level > MIRRED_NEST_LIMIT)) { net_warn_ratelimited("Packet exceeded mirred recursion limit on dev %s\n", netdev_name(skb->dev)); - __this_cpu_dec(mirred_rec_level); + __this_cpu_dec(mirred_nest_level); return TC_ACT_SHOT; } @@ -310,7 +310,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, err = tcf_mirred_forward(res->ingress, skb); if (err) tcf_action_inc_overlimit_qstats(&m->common); - __this_cpu_dec(mirred_rec_level); + __this_cpu_dec(mirred_nest_level); return TC_ACT_CONSUMED; } } @@ -322,7 +322,7 @@ out: if (tcf_mirred_is_act_redirect(m_eaction)) retval = TC_ACT_SHOT; } - __this_cpu_dec(mirred_rec_level); + __this_cpu_dec(mirred_nest_level); return retval; } From 6b1a3968fb6b33c0a6e7c1f2caef09dddd2f6a6a Mon Sep 17 00:00:00 2001 From: Davide Caratti Date: Fri, 25 Jul 2025 00:56:19 +0530 Subject: [PATCH 388/404] act_mirred: use the backlog for nested calls to mirred ingress [ Upstream commit ca22da2fbd693b54dc8e3b7b54ccc9f7e9ba3640 ] William reports kernel soft-lockups on some OVS topologies when TC mirred egress->ingress action is hit by local TCP traffic [1]. The same can also be reproduced with SCTP (thanks Xin for verifying), when client and server reach themselves through mirred egress to ingress, and one of the two peers sends a "heartbeat" packet (from within a timer). Enqueueing to backlog proved to fix this soft lockup; however, as Cong noticed [2], we should preserve - when possible - the current mirred behavior that counts as "overlimits" any eventual packet drop subsequent to the mirred forwarding action [3]. A compromise solution might use the backlog only when tcf_mirred_act() has a nest level greater than one: change tcf_mirred_forward() accordingly. Also, add a kselftest that can reproduce the lockup and verifies TC mirred ability to account for further packet drops after TC mirred egress->ingress (when the nest level is 1). [1] https://lore.kernel.org/netdev/33dc43f587ec1388ba456b4915c75f02a8aae226.1663945716.git.dcaratti@redhat.com/ [2] https://lore.kernel.org/netdev/Y0w%2FWWY60gqrtGLp@pop-os.localdomain/ [3] such behavior is not guaranteed: for example, if RPS or skb RX timestamping is enabled on the mirred target device, the kernel can defer receiving the skb and return NET_RX_SUCCESS inside tcf_mirred_forward(). Reported-by: William Zhao CC: Xin Long Signed-off-by: Davide Caratti Reviewed-by: Marcelo Ricardo Leitner Acked-by: Jamal Hadi Salim Signed-off-by: Paolo Abeni [ skulkarni: Adjusted patch for file 'tc_actions.sh' wrt the mainline commit ] Signed-off-by: Shubham Kulkarni Signed-off-by: Greg Kroah-Hartman --- net/sched/act_mirred.c | 7 +++ .../selftests/net/forwarding/tc_actions.sh | 48 ++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 5181eac5860e..f1392de686ba 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -206,12 +206,19 @@ release_idr: return err; } +static bool is_mirred_nested(void) +{ + return unlikely(__this_cpu_read(mirred_nest_level) > 1); +} + static int tcf_mirred_forward(bool want_ingress, struct sk_buff *skb) { int err; if (!want_ingress) err = dev_queue_xmit(skb); + else if (is_mirred_nested()) + err = netif_rx(skb); else err = netif_receive_skb(skb); diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh index d9eca227136b..1e27031288c8 100755 --- a/tools/testing/selftests/net/forwarding/tc_actions.sh +++ b/tools/testing/selftests/net/forwarding/tc_actions.sh @@ -3,7 +3,7 @@ ALL_TESTS="gact_drop_and_ok_test mirred_egress_redirect_test \ mirred_egress_mirror_test matchall_mirred_egress_mirror_test \ - gact_trap_test" + gact_trap_test mirred_egress_to_ingress_tcp_test" NUM_NETIFS=4 source tc_common.sh source lib.sh @@ -153,6 +153,52 @@ gact_trap_test() log_test "trap ($tcflags)" } +mirred_egress_to_ingress_tcp_test() +{ + local tmpfile=$(mktemp) tmpfile1=$(mktemp) + + RET=0 + dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$tmpfile + tc filter add dev $h1 protocol ip pref 100 handle 100 egress flower \ + $tcflags ip_proto tcp src_ip 192.0.2.1 dst_ip 192.0.2.2 \ + action ct commit nat src addr 192.0.2.2 pipe \ + action ct clear pipe \ + action ct commit nat dst addr 192.0.2.1 pipe \ + action ct clear pipe \ + action skbedit ptype host pipe \ + action mirred ingress redirect dev $h1 + tc filter add dev $h1 protocol ip pref 101 handle 101 egress flower \ + $tcflags ip_proto icmp \ + action mirred ingress redirect dev $h1 + tc filter add dev $h1 protocol ip pref 102 handle 102 ingress flower \ + ip_proto icmp \ + action drop + + ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $tmpfile1 & + local rpid=$! + ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$tmpfile + wait -n $rpid + cmp -s $tmpfile $tmpfile1 + check_err $? "server output check failed" + + $MZ $h1 -c 10 -p 64 -a $h1mac -b $h1mac -A 192.0.2.1 -B 192.0.2.1 \ + -t icmp "ping,id=42,seq=5" -q + tc_check_packets "dev $h1 egress" 101 10 + check_err $? "didn't mirred redirect ICMP" + tc_check_packets "dev $h1 ingress" 102 10 + check_err $? "didn't drop mirred ICMP" + local overlimits=$(tc_rule_stats_get ${h1} 101 egress .overlimits) + test ${overlimits} = 10 + check_err $? "wrong overlimits, expected 10 got ${overlimits}" + + tc filter del dev $h1 egress protocol ip pref 100 handle 100 flower + tc filter del dev $h1 egress protocol ip pref 101 handle 101 flower + tc filter del dev $h1 ingress protocol ip pref 102 handle 102 flower + + rm -f $tmpfile $tmpfile1 + log_test "mirred_egress_to_ingress_tcp ($tcflags)" +} + setup_prepare() { h1=${NETIFS[p1]} From 6894717a1ea363c5a27010ba604f957c309d282d Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 1 Nov 2024 14:44:10 +0300 Subject: [PATCH 389/404] Bluetooth: fix use-after-free in device_for_each_child() commit 27aabf27fd014ae037cc179c61b0bee7cff55b3d upstream. Syzbot has reported the following KASAN splat: BUG: KASAN: slab-use-after-free in device_for_each_child+0x18f/0x1a0 Read of size 8 at addr ffff88801f605308 by task kbnepd bnep0/4980 CPU: 0 UID: 0 PID: 4980 Comm: kbnepd bnep0 Not tainted 6.12.0-rc4-00161-gae90f6a6170d #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-2.fc40 04/01/2014 Call Trace: dump_stack_lvl+0x100/0x190 ? device_for_each_child+0x18f/0x1a0 print_report+0x13a/0x4cb ? __virt_addr_valid+0x5e/0x590 ? __phys_addr+0xc6/0x150 ? device_for_each_child+0x18f/0x1a0 kasan_report+0xda/0x110 ? device_for_each_child+0x18f/0x1a0 ? __pfx_dev_memalloc_noio+0x10/0x10 device_for_each_child+0x18f/0x1a0 ? __pfx_device_for_each_child+0x10/0x10 pm_runtime_set_memalloc_noio+0xf2/0x180 netdev_unregister_kobject+0x1ed/0x270 unregister_netdevice_many_notify+0x123c/0x1d80 ? __mutex_trylock_common+0xde/0x250 ? __pfx_unregister_netdevice_many_notify+0x10/0x10 ? trace_contention_end+0xe6/0x140 ? __mutex_lock+0x4e7/0x8f0 ? __pfx_lock_acquire.part.0+0x10/0x10 ? rcu_is_watching+0x12/0xc0 ? unregister_netdev+0x12/0x30 unregister_netdevice_queue+0x30d/0x3f0 ? __pfx_unregister_netdevice_queue+0x10/0x10 ? __pfx_down_write+0x10/0x10 unregister_netdev+0x1c/0x30 bnep_session+0x1fb3/0x2ab0 ? __pfx_bnep_session+0x10/0x10 ? __pfx_lock_release+0x10/0x10 ? __pfx_woken_wake_function+0x10/0x10 ? __kthread_parkme+0x132/0x200 ? __pfx_bnep_session+0x10/0x10 ? kthread+0x13a/0x370 ? __pfx_bnep_session+0x10/0x10 kthread+0x2b7/0x370 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x48/0x80 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 Allocated by task 4974: kasan_save_stack+0x30/0x50 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_noprof+0x1d1/0x440 hci_alloc_dev_priv+0x1d/0x2820 __vhci_create_device+0xef/0x7d0 vhci_write+0x2c7/0x480 vfs_write+0x6a0/0xfc0 ksys_write+0x12f/0x260 do_syscall_64+0xc7/0x250 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 4979: kasan_save_stack+0x30/0x50 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x4f/0x70 kfree+0x141/0x490 hci_release_dev+0x4d9/0x600 bt_host_release+0x6a/0xb0 device_release+0xa4/0x240 kobject_put+0x1ec/0x5a0 put_device+0x1f/0x30 vhci_release+0x81/0xf0 __fput+0x3f6/0xb30 task_work_run+0x151/0x250 do_exit+0xa79/0x2c30 do_group_exit+0xd5/0x2a0 get_signal+0x1fcd/0x2210 arch_do_signal_or_restart+0x93/0x780 syscall_exit_to_user_mode+0x140/0x290 do_syscall_64+0xd4/0x250 entry_SYSCALL_64_after_hwframe+0x77/0x7f In 'hci_conn_del_sysfs()', 'device_unregister()' may be called when an underlying (kobject) reference counter is greater than 1. This means that reparenting (happened when the device is actually freed) is delayed and, during that delay, parent controller device (hciX) may be deleted. Since the latter may create a dangling pointer to freed parent, avoid that scenario by reparenting to NULL explicitly. Reported-by: syzbot+6cf5652d3df49fae2e3f@syzkaller.appspotmail.com Tested-by: syzbot+6cf5652d3df49fae2e3f@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=6cf5652d3df49fae2e3f Fixes: a85fb91e3d72 ("Bluetooth: Fix double free in hci_conn_cleanup") Signed-off-by: Dmitry Antipov Signed-off-by: Luiz Augusto von Dentz [ chanho: Backported from v5.10.y to v5.4.y. device_find_any_child() is not supported in v5.4.y, so changed to use device_find_child() with __match_any ] Signed-off-by: Chanho Min Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/hci_sysfs.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 266112c960ee..f8e7b0ba2d27 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -19,14 +19,9 @@ static const struct device_type bt_link = { .release = bt_link_release, }; -/* - * The rfcomm tty device will possibly retain even when conn - * is down, and sysfs doesn't support move zombie device, - * so we should move the device before conn device is destroyed. - */ -static int __match_tty(struct device *dev, void *data) +static int __match_any(struct device *dev, void *unused) { - return !strncmp(dev_name(dev), "rfcomm", 6); + return 1; } void hci_conn_init_sysfs(struct hci_conn *conn) @@ -71,10 +66,12 @@ void hci_conn_del_sysfs(struct hci_conn *conn) return; } + /* If there are devices using the connection as parent reset it to NULL + * before unregistering the device. + */ while (1) { struct device *dev; - - dev = device_find_child(&conn->dev, NULL, __match_tty); + dev = device_find_child(&conn->dev, NULL, __match_any); if (!dev) break; device_move(dev, NULL, DPM_ORDER_DEV_LAST); From fe87e2d0e6265859c659a3ef1e2559a83c5e8e68 Mon Sep 17 00:00:00 2001 From: Zhang Xiaoxu Date: Tue, 19 Sep 2023 13:38:04 -0500 Subject: [PATCH 390/404] cifs: Fix UAF in cifs_demultiplex_thread() commit d527f51331cace562393a8038d870b3e9916686f upstream. There is a UAF when xfstests on cifs: BUG: KASAN: use-after-free in smb2_is_network_name_deleted+0x27/0x160 Read of size 4 at addr ffff88810103fc08 by task cifsd/923 CPU: 1 PID: 923 Comm: cifsd Not tainted 6.1.0-rc4+ #45 ... Call Trace: dump_stack_lvl+0x34/0x44 print_report+0x171/0x472 kasan_report+0xad/0x130 kasan_check_range+0x145/0x1a0 smb2_is_network_name_deleted+0x27/0x160 cifs_demultiplex_thread.cold+0x172/0x5a4 kthread+0x165/0x1a0 ret_from_fork+0x1f/0x30 Allocated by task 923: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 __kasan_slab_alloc+0x54/0x60 kmem_cache_alloc+0x147/0x320 mempool_alloc+0xe1/0x260 cifs_small_buf_get+0x24/0x60 allocate_buffers+0xa1/0x1c0 cifs_demultiplex_thread+0x199/0x10d0 kthread+0x165/0x1a0 ret_from_fork+0x1f/0x30 Freed by task 921: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 kasan_save_free_info+0x2a/0x40 ____kasan_slab_free+0x143/0x1b0 kmem_cache_free+0xe3/0x4d0 cifs_small_buf_release+0x29/0x90 SMB2_negotiate+0x8b7/0x1c60 smb2_negotiate+0x51/0x70 cifs_negotiate_protocol+0xf0/0x160 cifs_get_smb_ses+0x5fa/0x13c0 mount_get_conns+0x7a/0x750 cifs_mount+0x103/0xd00 cifs_smb3_do_mount+0x1dd/0xcb0 smb3_get_tree+0x1d5/0x300 vfs_get_tree+0x41/0xf0 path_mount+0x9b3/0xdd0 __x64_sys_mount+0x190/0x1d0 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 The UAF is because: mount(pid: 921) | cifsd(pid: 923) -------------------------------|------------------------------- | cifs_demultiplex_thread SMB2_negotiate | cifs_send_recv | compound_send_recv | smb_send_rqst | wait_for_response | wait_event_state [1] | | standard_receive3 | cifs_handle_standard | handle_mid | mid->resp_buf = buf; [2] | dequeue_mid [3] KILL the process [4] | resp_iov[i].iov_base = buf | free_rsp_buf [5] | | is_network_name_deleted [6] | callback 1. After send request to server, wait the response until mid->mid_state != SUBMITTED; 2. Receive response from server, and set it to mid; 3. Set the mid state to RECEIVED; 4. Kill the process, the mid state already RECEIVED, get 0; 5. Handle and release the negotiate response; 6. UAF. It can be easily reproduce with add some delay in [3] - [6]. Only sync call has the problem since async call's callback is executed in cifsd process. Add an extra state to mark the mid state to READY before wakeup the waitter, then it can get the resp safely. Fixes: ec637e3ffb6b ("[CIFS] Avoid extra large buffer allocation (and memcpy) in cifs_readpages") Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Zhang Xiaoxu Signed-off-by: Steve French [fs/cifs was moved to fs/smb/client since 38c8a9a52082 ("smb: move client and server files to common directory fs/smb"). We apply the patch to fs/cifs with some minor context changes.] Signed-off-by: He Zhe Signed-off-by: Xiangyu Chen [ chanho: Backported to v5.4.y ] Signed-off-by: Chanho Min Signed-off-by: Greg Kroah-Hartman --- fs/cifs/cifsglob.h | 1 + fs/cifs/transport.c | 34 +++++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 253321adc266..76003dbd43ec 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1722,6 +1722,7 @@ static inline bool is_retryable_error(int error) #define MID_RETRY_NEEDED 8 /* session closed while this request out */ #define MID_RESPONSE_MALFORMED 0x10 #define MID_SHUTDOWN 0x20 +#define MID_RESPONSE_READY 0x40 /* ready for other process handle the rsp */ /* Flags */ #define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 60141a7468b0..37d08c1daf29 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -47,6 +47,8 @@ void cifs_wake_up_task(struct mid_q_entry *mid) { + if (mid->mid_state == MID_RESPONSE_RECEIVED) + mid->mid_state = MID_RESPONSE_READY; wake_up_process(mid->callback_data); } @@ -99,7 +101,8 @@ static void _cifs_mid_q_entry_release(struct kref *refcount) struct TCP_Server_Info *server = midEntry->server; if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && - midEntry->mid_state == MID_RESPONSE_RECEIVED && + (midEntry->mid_state == MID_RESPONSE_RECEIVED || + midEntry->mid_state == MID_RESPONSE_READY) && server->ops->handle_cancelled_mid) server->ops->handle_cancelled_mid(midEntry->resp_buf, server); @@ -737,7 +740,8 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ) int error; error = wait_event_freezekillable_unsafe(server->response_q, - midQ->mid_state != MID_REQUEST_SUBMITTED); + midQ->mid_state != MID_REQUEST_SUBMITTED && + midQ->mid_state != MID_RESPONSE_RECEIVED); if (error < 0) return -ERESTARTSYS; @@ -889,7 +893,7 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) spin_lock(&GlobalMid_Lock); switch (mid->mid_state) { - case MID_RESPONSE_RECEIVED: + case MID_RESPONSE_READY: spin_unlock(&GlobalMid_Lock); return rc; case MID_RETRY_NEEDED: @@ -987,6 +991,9 @@ cifs_compound_callback(struct mid_q_entry *mid) credits.instance = server->reconnect_instance; add_credits(server, &credits, mid->optype); + + if (mid->mid_state == MID_RESPONSE_RECEIVED) + mid->mid_state = MID_RESPONSE_READY; } static void @@ -1150,7 +1157,8 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, send_cancel(server, &rqst[i], midQ[i]); spin_lock(&GlobalMid_Lock); midQ[i]->mid_flags |= MID_WAIT_CANCELLED; - if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) { + if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED || + midQ[i]->mid_state == MID_RESPONSE_RECEIVED) { midQ[i]->callback = cifs_cancelled_callback; cancelled_mid[i] = true; credits[i].value = 0; @@ -1171,7 +1179,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, } if (!midQ[i]->resp_buf || - midQ[i]->mid_state != MID_RESPONSE_RECEIVED) { + midQ[i]->mid_state != MID_RESPONSE_READY) { rc = -EIO; cifs_dbg(FYI, "Bad MID state?\n"); goto out; @@ -1348,7 +1356,8 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, if (rc != 0) { send_cancel(server, &rqst, midQ); spin_lock(&GlobalMid_Lock); - if (midQ->mid_state == MID_REQUEST_SUBMITTED) { + if (midQ->mid_state == MID_REQUEST_SUBMITTED || + midQ->mid_state == MID_RESPONSE_RECEIVED) { /* no longer considered to be "in-flight" */ midQ->callback = DeleteMidQEntry; spin_unlock(&GlobalMid_Lock); @@ -1365,7 +1374,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, } if (!midQ->resp_buf || !out_buf || - midQ->mid_state != MID_RESPONSE_RECEIVED) { + midQ->mid_state != MID_RESPONSE_READY) { rc = -EIO; cifs_server_dbg(VFS, "Bad MID state?\n"); goto out; @@ -1485,13 +1494,15 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, /* Wait for a reply - allow signals to interrupt. */ rc = wait_event_interruptible(server->response_q, - (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) || + (!(midQ->mid_state == MID_REQUEST_SUBMITTED || + midQ->mid_state == MID_RESPONSE_RECEIVED)) || ((server->tcpStatus != CifsGood) && (server->tcpStatus != CifsNew))); /* Were we interrupted by a signal ? */ if ((rc == -ERESTARTSYS) && - (midQ->mid_state == MID_REQUEST_SUBMITTED) && + (midQ->mid_state == MID_REQUEST_SUBMITTED || + midQ->mid_state == MID_RESPONSE_RECEIVED) && ((server->tcpStatus == CifsGood) || (server->tcpStatus == CifsNew))) { @@ -1521,7 +1532,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, if (rc) { send_cancel(server, &rqst, midQ); spin_lock(&GlobalMid_Lock); - if (midQ->mid_state == MID_REQUEST_SUBMITTED) { + if (midQ->mid_state == MID_REQUEST_SUBMITTED || + midQ->mid_state == MID_RESPONSE_RECEIVED) { /* no longer considered to be "in-flight" */ midQ->callback = DeleteMidQEntry; spin_unlock(&GlobalMid_Lock); @@ -1539,7 +1551,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, return rc; /* rcvd frame is ok */ - if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) { + if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_READY) { rc = -EIO; cifs_tcon_dbg(VFS, "Bad MID state?\n"); goto out; From ee389fca75e4a4807b37f9619e008542b685729f Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 4 Oct 2021 15:37:42 -0400 Subject: [PATCH 391/404] NFS: Fix up commit deadlocks commit 133a48abf6ecc535d7eddc6da1c3e4c972445882 upstream. If O_DIRECT bumps the commit_info rpcs_out field, then that could lead to fsync() hangs. The fix is to ensure that O_DIRECT calls nfs_commit_end(). Fixes: 723c921e7dfc ("sched/wait, fs/nfs: Convert wait_on_atomic_t() usage to the new wait_var_event() API") Signed-off-by: Trond Myklebust Signed-off-by: Chanho Min Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/nfs/direct.c | 2 +- fs/nfs/write.c | 9 ++++++--- include/linux/nfs_fs.h | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 0682037f972b..32dc176ea1ab 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -700,7 +700,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) nfs_unlock_and_release_request(req); } - if (atomic_dec_and_test(&cinfo.mds->rpcs_out)) + if (nfs_commit_end(cinfo.mds)) nfs_direct_write_complete(dreq); } diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 10ce264a6456..c9895316fc07 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1658,10 +1658,13 @@ static void nfs_commit_begin(struct nfs_mds_commit_info *cinfo) atomic_inc(&cinfo->rpcs_out); } -static void nfs_commit_end(struct nfs_mds_commit_info *cinfo) +bool nfs_commit_end(struct nfs_mds_commit_info *cinfo) { - if (atomic_dec_and_test(&cinfo->rpcs_out)) + if (atomic_dec_and_test(&cinfo->rpcs_out)) { wake_up_var(&cinfo->rpcs_out); + return true; + } + return false; } void nfs_commitdata_release(struct nfs_commit_data *data) @@ -1756,6 +1759,7 @@ void nfs_init_commit(struct nfs_commit_data *data, data->res.fattr = &data->fattr; data->res.verf = &data->verf; nfs_fattr_init(&data->fattr); + nfs_commit_begin(cinfo->mds); } EXPORT_SYMBOL_GPL(nfs_init_commit); @@ -1801,7 +1805,6 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how, /* Set up the argument struct */ nfs_init_commit(data, head, NULL, cinfo); - atomic_inc(&cinfo->mds->rpcs_out); return nfs_initiate_commit(NFS_CLIENT(inode), data, NFS_PROTO(inode), data->mds_ops, how, 0); } diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 49cf5c855cbe..a96b116cc922 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -549,6 +549,7 @@ extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); extern int nfs_commit_inode(struct inode *, int); extern struct nfs_commit_data *nfs_commitdata_alloc(bool never_fail); extern void nfs_commit_free(struct nfs_commit_data *data); +bool nfs_commit_end(struct nfs_mds_commit_info *cinfo); static inline int nfs_have_writebacks(struct inode *inode) From 6cd3f13aaa62970b5169d990e936b2e96943bc6a Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 1 Mar 2024 11:49:57 -0500 Subject: [PATCH 392/404] nfs: fix UAF in direct writes commit 17f46b803d4f23c66cacce81db35fef3adb8f2af upstream. In production we have been hitting the following warning consistently ------------[ cut here ]------------ refcount_t: underflow; use-after-free. WARNING: CPU: 17 PID: 1800359 at lib/refcount.c:28 refcount_warn_saturate+0x9c/0xe0 Workqueue: nfsiod nfs_direct_write_schedule_work [nfs] RIP: 0010:refcount_warn_saturate+0x9c/0xe0 PKRU: 55555554 Call Trace: ? __warn+0x9f/0x130 ? refcount_warn_saturate+0x9c/0xe0 ? report_bug+0xcc/0x150 ? handle_bug+0x3d/0x70 ? exc_invalid_op+0x16/0x40 ? asm_exc_invalid_op+0x16/0x20 ? refcount_warn_saturate+0x9c/0xe0 nfs_direct_write_schedule_work+0x237/0x250 [nfs] process_one_work+0x12f/0x4a0 worker_thread+0x14e/0x3b0 ? ZSTD_getCParams_internal+0x220/0x220 kthread+0xdc/0x120 ? __btf_name_valid+0xa0/0xa0 ret_from_fork+0x1f/0x30 This is because we're completing the nfs_direct_request twice in a row. The source of this is when we have our commit requests to submit, we process them and send them off, and then in the completion path for the commit requests we have if (nfs_commit_end(cinfo.mds)) nfs_direct_write_complete(dreq); However since we're submitting asynchronous requests we sometimes have one that completes before we submit the next one, so we end up calling complete on the nfs_direct_request twice. The only other place we use nfs_generic_commit_list() is in __nfs_commit_inode, which wraps this call in a nfs_commit_begin(); nfs_commit_end(); Which is a common pattern for this style of completion handling, one that is also repeated in the direct code with get_dreq()/put_dreq() calls around where we process events as well as in the completion paths. Fix this by using the same pattern for the commit requests. Before with my 200 node rocksdb stress running this warning would pop every 10ish minutes. With my patch the stress test has been running for several hours without popping. Signed-off-by: Josef Bacik Cc: stable@vger.kernel.org Signed-off-by: Trond Myklebust [ chanho : Backports v5.4.y, commit 133a48abf6ec (NFS: Fix up commit deadlocks) is needed to use nfs_commit_end ] Signed-off-by: Chanho Min Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/nfs/direct.c | 11 +++++++++-- fs/nfs/write.c | 2 +- include/linux/nfs_fs.h | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 32dc176ea1ab..982f0eeac3df 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -727,10 +727,17 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) LIST_HEAD(mds_list); nfs_init_cinfo_from_dreq(&cinfo, dreq); + nfs_commit_begin(cinfo.mds); nfs_scan_commit(dreq->inode, &mds_list, &cinfo); res = nfs_generic_commit_list(dreq->inode, &mds_list, 0, &cinfo); - if (res < 0) /* res == -ENOMEM */ - nfs_direct_write_reschedule(dreq); + if (res < 0) { /* res == -ENOMEM */ + spin_lock(&dreq->lock); + if (dreq->flags == 0) + dreq->flags = NFS_ODIRECT_RESCHED_WRITES; + spin_unlock(&dreq->lock); + } + if (nfs_commit_end(cinfo.mds)) + nfs_direct_write_complete(dreq); } static void nfs_direct_write_schedule_work(struct work_struct *work) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index c9895316fc07..f3c672b11c4f 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1653,7 +1653,7 @@ static int wait_on_commit(struct nfs_mds_commit_info *cinfo) !atomic_read(&cinfo->rpcs_out)); } -static void nfs_commit_begin(struct nfs_mds_commit_info *cinfo) +void nfs_commit_begin(struct nfs_mds_commit_info *cinfo) { atomic_inc(&cinfo->rpcs_out); } diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index a96b116cc922..b2b441f3572b 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -549,6 +549,7 @@ extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); extern int nfs_commit_inode(struct inode *, int); extern struct nfs_commit_data *nfs_commitdata_alloc(bool never_fail); extern void nfs_commit_free(struct nfs_commit_data *data); +void nfs_commit_begin(struct nfs_mds_commit_info *cinfo); bool nfs_commit_end(struct nfs_mds_commit_info *cinfo); static inline int From ef49d17eac0071480115e99890192081cb5d8cbe Mon Sep 17 00:00:00 2001 From: Weitao Wang Date: Tue, 19 Aug 2025 15:58:43 +0300 Subject: [PATCH 393/404] usb: xhci: Fix slot_id resource race conflict commit 2eb03376151bb8585caa23ed2673583107bb5193 upstream. xHC controller may immediately reuse a slot_id after it's disabled, giving it to a new enumerating device before the xhci driver freed all resources related to the disabled device. In such a scenario, device-A with slot_id equal to 1 is disconnecting while device-B is enumerating, device-B will fail to enumerate in the follow sequence. 1.[device-A] send disable slot command 2.[device-B] send enable slot command 3.[device-A] disable slot command completed and wakeup waiting thread 4.[device-B] enable slot command completed with slot_id equal to 1 and wakeup waiting thread 5.[device-B] driver checks that slot_id is still in use (by device-A) in xhci_alloc_virt_device, and fail to enumerate due to this conflict 6.[device-A] xhci->devs[slot_id] set to NULL in xhci_free_virt_device To fix driver's slot_id resources conflict, clear xhci->devs[slot_id] and xhci->dcbba->dev_context_ptrs[slot_id] pointers in the interrupt context when disable slot command completes successfully. Simultaneously, adjust function xhci_free_virt_device to accurately handle device release. [minor smatch warning and commit message fix -Mathias] Cc: stable@vger.kernel.org Fixes: 7faac1953ed1 ("xhci: avoid race between disable slot command and host runtime suspend") Signed-off-by: Weitao Wang Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20250819125844.2042452-2-mathias.nyman@linux.intel.com Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-hub.c | 3 +-- drivers/usb/host/xhci-mem.c | 22 +++++++++++----------- drivers/usb/host/xhci-ring.c | 9 +++++++-- drivers/usb/host/xhci.c | 18 +++++++++++++----- drivers/usb/host/xhci.h | 3 ++- 5 files changed, 34 insertions(+), 21 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 66cb9f08bff1..2c9015f2a7d3 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -628,8 +628,7 @@ static int xhci_enter_test_mode(struct xhci_hcd *xhci, if (!xhci->devs[i]) continue; - retval = xhci_disable_slot(xhci, i); - xhci_free_virt_device(xhci, i); + retval = xhci_disable_and_free_slot(xhci, i); if (retval) xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n", i, retval); diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 6dddd5414fe9..8eb764b6050d 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -879,21 +879,20 @@ free_tts: * will be manipulated by the configure endpoint, allocate device, or update * hub functions while this function is removing the TT entries from the list. */ -void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) +void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, + int slot_id) { - struct xhci_virt_device *dev; int i; int old_active_eps = 0; /* Slot ID 0 is reserved */ - if (slot_id == 0 || !xhci->devs[slot_id]) + if (slot_id == 0 || !dev) return; - dev = xhci->devs[slot_id]; - - xhci->dcbaa->dev_context_ptrs[slot_id] = 0; - if (!dev) - return; + /* If device ctx array still points to _this_ device, clear it */ + if (dev->out_ctx && + xhci->dcbaa->dev_context_ptrs[slot_id] == cpu_to_le64(dev->out_ctx->dma)) + xhci->dcbaa->dev_context_ptrs[slot_id] = 0; trace_xhci_free_virt_device(dev); @@ -932,8 +931,9 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) if (dev->udev && dev->udev->slot_id) dev->udev->slot_id = 0; - kfree(xhci->devs[slot_id]); - xhci->devs[slot_id] = NULL; + if (xhci->devs[slot_id] == dev) + xhci->devs[slot_id] = NULL; + kfree(dev); } /* @@ -975,7 +975,7 @@ static void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_i out: /* we are now at a leaf device */ xhci_debugfs_remove_slot(xhci, slot_id); - xhci_free_virt_device(xhci, slot_id); + xhci_free_virt_device(xhci, vdev, slot_id); } int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 47326fb8b1fc..ac9464eddc83 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1258,7 +1258,8 @@ static void xhci_handle_cmd_enable_slot(struct xhci_hcd *xhci, int slot_id, command->slot_id = 0; } -static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id) +static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id, + u32 cmd_comp_code) { struct xhci_virt_device *virt_dev; struct xhci_slot_ctx *slot_ctx; @@ -1273,6 +1274,10 @@ static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id) if (xhci->quirks & XHCI_EP_LIMIT_QUIRK) /* Delete default control endpoint resources */ xhci_free_device_endpoint_resources(xhci, virt_dev, true); + if (cmd_comp_code == COMP_SUCCESS) { + xhci->dcbaa->dev_context_ptrs[slot_id] = 0; + xhci->devs[slot_id] = NULL; + } } static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id, @@ -1512,7 +1517,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, xhci_handle_cmd_enable_slot(xhci, slot_id, cmd, cmd_comp_code); break; case TRB_DISABLE_SLOT: - xhci_handle_cmd_disable_slot(xhci, slot_id); + xhci_handle_cmd_disable_slot(xhci, slot_id, cmd_comp_code); break; case TRB_CONFIG_EP: if (!cmd->completion) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index dcda4d7c2b75..c98789ea1934 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3947,7 +3947,7 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) xhci_disable_slot(xhci, udev->slot_id); spin_lock_irqsave(&xhci->lock, flags); - xhci_free_virt_device(xhci, udev->slot_id); + xhci_free_virt_device(xhci, virt_dev, udev->slot_id); spin_unlock_irqrestore(&xhci->lock, flags); } @@ -3996,6 +3996,16 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) return ret; } +int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id) +{ + struct xhci_virt_device *vdev = xhci->devs[slot_id]; + int ret; + + ret = xhci_disable_slot(xhci, slot_id); + xhci_free_virt_device(xhci, vdev, slot_id); + return ret; +} + /* * Checks if we have enough host controller resources for the default control * endpoint. @@ -4101,8 +4111,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) return 1; disable_slot: - xhci_disable_slot(xhci, udev->slot_id); - xhci_free_virt_device(xhci, udev->slot_id); + xhci_disable_and_free_slot(xhci, udev->slot_id); return 0; } @@ -4238,8 +4247,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, dev_warn(&udev->dev, "Device not responding to setup %s.\n", act); mutex_unlock(&xhci->mutex); - ret = xhci_disable_slot(xhci, udev->slot_id); - xhci_free_virt_device(xhci, udev->slot_id); + ret = xhci_disable_and_free_slot(xhci, udev->slot_id); if (!ret) { if (xhci_alloc_dev(hcd, udev) == 1) xhci_setup_addressable_virt_dev(xhci, udev); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index d27b08d43e39..d6fa03b21349 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1997,7 +1997,7 @@ void xhci_dbg_trace(struct xhci_hcd *xhci, void (*trace)(struct va_format *), /* xHCI memory management */ void xhci_mem_cleanup(struct xhci_hcd *xhci); int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags); -void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id); +void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, int slot_id); int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags); int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev); void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci, @@ -2087,6 +2087,7 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, struct usb_tt *tt, gfp_t mem_flags); int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); +int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id); int xhci_ext_cap_init(struct xhci_hcd *xhci); int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup); From d0225f41ee70611ca88ccb22c8542ecdfa7faea8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 Aug 2025 08:49:08 +0300 Subject: [PATCH 394/404] scsi: qla4xxx: Prevent a potential error pointer dereference [ Upstream commit 9dcf111dd3e7ed5fce82bb108e3a3fc001c07225 ] The qla4xxx_get_ep_fwdb() function is supposed to return NULL on error, but qla4xxx_ep_connect() returns error pointers. Propagating the error pointers will lead to an Oops in the caller, so change the error pointers to NULL. Fixes: 13483730a13b ("[SCSI] qla4xxx: fix flash/ddb support") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/aJwnVKS9tHsw1tEu@stanley.mountain Reviewed-by: Chris Leech Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/qla4xxx/ql4_os.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index af1c45dd2f38..4957e50b7b5d 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -6593,6 +6593,8 @@ static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha, ep = qla4xxx_ep_connect(ha->host, (struct sockaddr *)dst_addr, 0); vfree(dst_addr); + if (IS_ERR(ep)) + return NULL; return ep; } From 6cd6e75cf9cf19efedd8835de52dbfb6e47a8cfe Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 18 Aug 2025 12:59:45 +0300 Subject: [PATCH 395/404] ALSA: usb-audio: Fix size validation in convert_chmap_v3() [ Upstream commit 89f0addeee3cb2dc49837599330ed9c4612f05b0 ] The "p" pointer is void so sizeof(*p) is 1. The intent was to check sizeof(*cs_desc), which is 3, instead. Fixes: ecfd41166b72 ("ALSA: usb-audio: Validate UAC3 cluster segment descriptors") Signed-off-by: Dan Carpenter Link: https://patch.msgid.link/aKL5kftC1qGt6lpv@stanley.mountain Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/usb/stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 47cfaf29fdd7..bb919f1d4043 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -350,7 +350,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor u16 cs_len; u8 cs_type; - if (len < sizeof(*p)) + if (len < sizeof(*cs_desc)) break; cs_len = le16_to_cpu(cs_desc->wLength); if (len < cs_len) From 89dfc9280e828265832ab8c8f9cf0f15e1ce2603 Mon Sep 17 00:00:00 2001 From: Minhong He Date: Fri, 15 Aug 2025 14:38:45 +0800 Subject: [PATCH 396/404] ipv6: sr: validate HMAC algorithm ID in seg6_hmac_info_add [ Upstream commit 84967deee9d9870b15bc4c3acb50f1d401807902 ] The seg6_genl_sethmac() directly uses the algorithm ID provided by the userspace without verifying whether it is an HMAC algorithm supported by the system. If an unsupported HMAC algorithm ID is configured, packets using SRv6 HMAC will be dropped during encapsulation or decapsulation. Fixes: 4f4853dc1c9c ("ipv6: sr: implement API to control SR HMAC structure") Signed-off-by: Minhong He Reviewed-by: Kuniyuki Iwashima Link: https://patch.msgid.link/20250815063845.85426-1-heminhong@kylinos.cn Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/ipv6/seg6_hmac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c index b3b2aa92e60d..292a36576115 100644 --- a/net/ipv6/seg6_hmac.c +++ b/net/ipv6/seg6_hmac.c @@ -295,6 +295,9 @@ int seg6_hmac_info_add(struct net *net, u32 key, struct seg6_hmac_info *hinfo) struct seg6_pernet_data *sdata = seg6_pernet(net); int err; + if (!__hmac_get_algo(hinfo->alg_id)) + return -EINVAL; + err = rhashtable_lookup_insert_fast(&sdata->hmac_infos, &hinfo->node, rht_params); From c4f464cfc04edb1c90c2f4d47e6009efd9cfa133 Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Tue, 19 Aug 2025 15:19:57 -0700 Subject: [PATCH 397/404] ixgbe: xsk: resolve the negative overflow of budget in ixgbe_xmit_zc [ Upstream commit 4d4d9ef9dfee877d494e5418f68a1016ef08cad6 ] Resolve the budget negative overflow which leads to returning true in ixgbe_xmit_zc even when the budget of descs are thoroughly consumed. Before this patch, when the budget is decreased to zero and finishes sending the last allowed desc in ixgbe_xmit_zc, it will always turn back and enter into the while() statement to see if it should keep processing packets, but in the meantime it unexpectedly decreases the value again to 'unsigned int (0--)', namely, UINT_MAX. Finally, the ixgbe_xmit_zc returns true, showing 'we complete cleaning the budget'. That also means 'clean_complete = true' in ixgbe_poll. The true theory behind this is if that budget number of descs are consumed, it implies that we might have more descs to be done. So we should return false in ixgbe_xmit_zc to tell napi poll to find another chance to start polling to handle the rest of descs. On the contrary, returning true here means job done and we know we finish all the possible descs this time and we don't intend to start a new napi poll. It is apparently against our expectations. Please also see how ixgbe_clean_tx_irq() handles the problem: it uses do..while() statement to make sure the budget can be decreased to zero at most and the negative overflow never happens. The patch adds 'likely' because we rarely would not hit the loop condition since the standard budget is 256. Fixes: 8221c5eba8c1 ("ixgbe: add AF_XDP zero-copy Tx support") Signed-off-by: Jason Xing Reviewed-by: Larysa Zaremba Reviewed-by: Paul Menzel Reviewed-by: Aleksandr Loktionov Tested-by: Priya Singh Signed-off-by: Tony Nguyen Link: https://patch.msgid.link/20250819222000.3504873-4-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c index 921a2ddb497e..c68eb5dddf5b 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c @@ -582,7 +582,7 @@ static bool ixgbe_xmit_zc(struct ixgbe_ring *xdp_ring, unsigned int budget) dma_addr_t dma; u32 cmd_type; - while (budget-- > 0) { + while (likely(budget)) { if (unlikely(!ixgbe_desc_unused(xdp_ring))) { work_done = false; break; @@ -619,6 +619,8 @@ static bool ixgbe_xmit_zc(struct ixgbe_ring *xdp_ring, unsigned int budget) xdp_ring->next_to_use++; if (xdp_ring->next_to_use == xdp_ring->count) xdp_ring->next_to_use = 0; + + budget--; } if (tx_desc) { From 7689ab22de36f8db19095f6bdf11f28cfde92f5c Mon Sep 17 00:00:00 2001 From: William Liu Date: Tue, 19 Aug 2025 03:36:28 +0000 Subject: [PATCH 398/404] net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 15de71d06a400f7fdc15bf377a2552b0ec437cf5 ] The following setup can trigger a WARNING in htb_activate due to the condition: !cl->leaf.q->q.qlen tc qdisc del dev lo root tc qdisc add dev lo root handle 1: htb default 1 tc class add dev lo parent 1: classid 1:1 \ htb rate 64bit tc qdisc add dev lo parent 1:1 handle f: \ cake memlimit 1b ping -I lo -f -c1 -s64 -W0.001 127.0.0.1 This is because the low memlimit leads to a low buffer_limit, which causes packet dropping. However, cake_enqueue still returns NET_XMIT_SUCCESS, causing htb_enqueue to call htb_activate with an empty child qdisc. We should return NET_XMIT_CN when packets are dropped from the same tin and flow. I do not believe return value of NET_XMIT_CN is necessary for packet drops in the case of ack filtering, as that is meant to optimize performance, not to signal congestion. Fixes: 046f6fd5daef ("sched: Add Common Applications Kept Enhanced (cake) qdisc") Signed-off-by: William Liu Reviewed-by: Savino Dicanosa Acked-by: Toke Høiland-Jørgensen Reviewed-by: Jamal Hadi Salim Link: https://patch.msgid.link/20250819033601.579821-1-will@willsroot.io Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_cake.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c index fc96ec46e6f6..738691b5697b 100644 --- a/net/sched/sch_cake.c +++ b/net/sched/sch_cake.c @@ -1725,7 +1725,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, ktime_t now = ktime_get(); struct cake_tin_data *b; struct cake_flow *flow; - u32 idx; + u32 idx, tin; /* choose flow to insert into */ idx = cake_classify(sch, &b, skb, q->flow_mode, &ret); @@ -1735,6 +1735,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, __qdisc_drop(skb, to_free); return ret; } + tin = (u32)(b - q->tins); idx--; flow = &b->flows[idx]; @@ -1904,13 +1905,22 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, q->buffer_max_used = q->buffer_used; if (q->buffer_used > q->buffer_limit) { + bool same_flow = false; u32 dropped = 0; + u32 drop_id; while (q->buffer_used > q->buffer_limit) { dropped++; - cake_drop(sch, to_free); + drop_id = cake_drop(sch, to_free); + + if ((drop_id >> 16) == tin && + (drop_id & 0xFFFF) == idx) + same_flow = true; } b->drop_overlimit += dropped; + + if (same_flow) + return NET_XMIT_CN; } return NET_XMIT_SUCCESS; } From 1fb7c8400dffce6f180722893f1cc2c539d69451 Mon Sep 17 00:00:00 2001 From: William Liu Date: Tue, 19 Aug 2025 03:36:59 +0000 Subject: [PATCH 399/404] net/sched: Remove unnecessary WARNING condition for empty child qdisc in htb_activate [ Upstream commit 2c2192e5f9c7c2892fe2363244d1387f62710d83 ] The WARN_ON trigger based on !cl->leaf.q->q.qlen is unnecessary in htb_activate. htb_dequeue_tree already accounts for that scenario. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: William Liu Reviewed-by: Savino Dicanosa Link: https://patch.msgid.link/20250819033632.579854-1-will@willsroot.io Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/sched/sch_htb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 2562219ccca4..dd5088f7bffb 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -558,7 +558,7 @@ htb_change_class_mode(struct htb_sched *q, struct htb_class *cl, s64 *diff) */ static inline void htb_activate(struct htb_sched *q, struct htb_class *cl) { - WARN_ON(cl->level || !cl->leaf.q || !cl->leaf.q->q.qlen); + WARN_ON(cl->level || !cl->leaf.q); if (!cl->prio_activity) { cl->prio_activity = 1 << cl->prio; From de987b46c4175abca884bf1f7eba6b9fdba0ff73 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Aug 2025 17:08:34 +0200 Subject: [PATCH 400/404] ALSA: usb-audio: Use correct sub-type for UAC3 feature unit validation [ Upstream commit 8410fe81093ff231e964891e215b624dabb734b0 ] The entry of the validators table for UAC3 feature unit is defined with a wrong sub-type UAC_FEATURE (= 0x06) while it should have been UAC3_FEATURE (= 0x07). This patch corrects the entry value. Fixes: 57f8770620e9 ("ALSA: usb-audio: More validations of descriptor units") Link: https://patch.msgid.link/20250821150835.8894-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/usb/validate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/validate.c b/sound/usb/validate.c index 4ee2a328cb5b..46cf36ab0acd 100644 --- a/sound/usb/validate.c +++ b/sound/usb/validate.c @@ -285,7 +285,7 @@ static const struct usb_desc_validator audio_validators[] = { /* UAC_VERSION_3, UAC3_EXTENDED_TERMINAL: not implemented yet */ FUNC(UAC_VERSION_3, UAC3_MIXER_UNIT, validate_mixer_unit), FUNC(UAC_VERSION_3, UAC3_SELECTOR_UNIT, validate_selector_unit), - FUNC(UAC_VERSION_3, UAC_FEATURE_UNIT, validate_uac3_feature_unit), + FUNC(UAC_VERSION_3, UAC3_FEATURE_UNIT, validate_uac3_feature_unit), /* UAC_VERSION_3, UAC3_EFFECT_UNIT: not implemented yet */ FUNC(UAC_VERSION_3, UAC3_PROCESSING_UNIT, validate_processing_unit), FUNC(UAC_VERSION_3, UAC3_EXTENSION_UNIT, validate_processing_unit), From bb79734b8ba6ba90c7922fff0c82c35b6005511f Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Thu, 21 Aug 2025 14:35:40 +0200 Subject: [PATCH 401/404] s390/hypfs: Avoid unnecessary ioctl registration in debugfs [ Upstream commit fec7bdfe7f8694a0c39e6c3ec026ff61ca1058b9 ] Currently, hypfs registers ioctl callbacks for all debugfs files, despite only one file requiring them. This leads to unintended exposure of unused interfaces to user space and can trigger side effects such as restricted access when kernel lockdown is enabled. Restrict ioctl registration to only those files that implement ioctl functionality to avoid interface clutter and unnecessary access restrictions. Tested-by: Mete Durlu Reviewed-by: Vasily Gorbik Fixes: 5496197f9b08 ("debugfs: Restrict debugfs when the kernel is locked down") Signed-off-by: Peter Oberparleiter Signed-off-by: Alexander Gordeev Signed-off-by: Sasha Levin --- arch/s390/hypfs/hypfs_dbfs.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index f4c7dbfaf8ee..c5f53dc3dbbc 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c @@ -64,24 +64,28 @@ static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) long rc; mutex_lock(&df->lock); - if (df->unlocked_ioctl) - rc = df->unlocked_ioctl(file, cmd, arg); - else - rc = -ENOTTY; + rc = df->unlocked_ioctl(file, cmd, arg); mutex_unlock(&df->lock); return rc; } -static const struct file_operations dbfs_ops = { +static const struct file_operations dbfs_ops_ioctl = { .read = dbfs_read, .llseek = no_llseek, .unlocked_ioctl = dbfs_ioctl, }; +static const struct file_operations dbfs_ops = { + .read = dbfs_read, +}; + void hypfs_dbfs_create_file(struct hypfs_dbfs_file *df) { - df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df, - &dbfs_ops); + const struct file_operations *fops = &dbfs_ops; + + if (df->unlocked_ioctl) + fops = &dbfs_ops_ioctl; + df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df, fops); mutex_init(&df->lock); } From 7a0208c5b4e19ae62dc30c8825bd08bbc93a5e01 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Thu, 21 Aug 2025 15:12:37 +0200 Subject: [PATCH 402/404] s390/hypfs: Enable limited access during lockdown [ Upstream commit 3868f910440c47cd5d158776be4ba4e2186beda7 ] When kernel lockdown is active, debugfs_locked_down() blocks access to hypfs files that register ioctl callbacks, even if the ioctl interface is not required for a function. This unnecessarily breaks userspace tools that only rely on read operations. Resolve this by registering a minimal set of file operations during lockdown, avoiding ioctl registration and preserving access for affected tooling. Note that this change restores hypfs functionality when lockdown is active from early boot (e.g. via lockdown=integrity kernel parameter), but does not apply to scenarios where lockdown is enabled dynamically while Linux is running. Tested-by: Mete Durlu Reviewed-by: Vasily Gorbik Fixes: 5496197f9b08 ("debugfs: Restrict debugfs when the kernel is locked down") Signed-off-by: Peter Oberparleiter Signed-off-by: Alexander Gordeev Signed-off-by: Sasha Levin --- arch/s390/hypfs/hypfs_dbfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index c5f53dc3dbbc..5848f2e374a6 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c @@ -6,6 +6,7 @@ * Author(s): Michael Holzheu */ +#include #include #include "hypfs.h" @@ -83,7 +84,7 @@ void hypfs_dbfs_create_file(struct hypfs_dbfs_file *df) { const struct file_operations *fops = &dbfs_ops; - if (df->unlocked_ioctl) + if (df->unlocked_ioctl && !security_locked_down(LOCKDOWN_DEBUGFS)) fops = &dbfs_ops_ioctl; df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df, fops); mutex_init(&df->lock); From fa728ded21be39e371ef2f130cd64b9f1e8ea17e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 26 Aug 2025 17:27:47 -0400 Subject: [PATCH 403/404] alloc_fdtable(): change calling conventions. [ Upstream commit 1d3b4bec3ce55e0c46cdce7d0402dbd6b4af3a3d ] First of all, tell it how many slots do we want, not which slot is wanted. It makes one caller (dup_fd()) more straightforward and doesn't harm another (expand_fdtable()). Furthermore, make it return ERR_PTR() on failure rather than returning NULL. Simplifies the callers. Simplify the size calculation, while we are at it - note that we always have slots_wanted greater than BITS_PER_LONG. What the rules boil down to is * use the smallest power of two large enough to give us that many slots * on 32bit skip 64 and 128 - the minimal capacity we want there is 256 slots (i.e. 1Kb fd array). * on 64bit don't skip anything, the minimal capacity is 128 - and we'll never be asked for 64 or less. 128 slots means 1Kb fd array, again. * on 128bit, if that ever happens, don't skip anything - we'll never be asked for 128 or less, so the fd array allocation will be at least 2Kb. Reviewed-by: Christian Brauner Signed-off-by: Al Viro Signed-off-by: Sasha Levin --- fs/file.c | 66 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/fs/file.c b/fs/file.c index 9574a9116468..95f6af59df80 100644 --- a/fs/file.c +++ b/fs/file.c @@ -78,9 +78,17 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *ofdt) copy_fd_bitmaps(nfdt, ofdt, fdt_words(ofdt)); } -static struct fdtable * alloc_fdtable(unsigned int nr) +/* + * Note how the fdtable bitmap allocations very much have to be a multiple of + * BITS_PER_LONG. This is not only because we walk those things in chunks of + * 'unsigned long' in some places, but simply because that is how the Linux + * kernel bitmaps are defined to work: they are not "bits in an array of bytes", + * they are very much "bits in an array of unsigned long". + */ +static struct fdtable *alloc_fdtable(unsigned int slots_wanted) { struct fdtable *fdt; + unsigned int nr; void *data; /* @@ -88,21 +96,32 @@ static struct fdtable * alloc_fdtable(unsigned int nr) * Allocation steps are keyed to the size of the fdarray, since it * grows far faster than any of the other dynamic data. We try to fit * the fdarray into comfortable page-tuned chunks: starting at 1024B - * and growing in powers of two from there on. + * and growing in powers of two from there on. Since we called only + * with slots_wanted > BITS_PER_LONG (embedded instance in files->fdtab + * already gives BITS_PER_LONG slots), the above boils down to + * 1. use the smallest power of two large enough to give us that many + * slots. + * 2. on 32bit skip 64 and 128 - the minimal capacity we want there is + * 256 slots (i.e. 1Kb fd array). + * 3. on 64bit don't skip anything, 1Kb fd array means 128 slots there + * and we are never going to be asked for 64 or less. */ - nr /= (1024 / sizeof(struct file *)); - nr = roundup_pow_of_two(nr + 1); - nr *= (1024 / sizeof(struct file *)); + if (IS_ENABLED(CONFIG_32BIT) && slots_wanted < 256) + nr = 256; + else + nr = roundup_pow_of_two(slots_wanted); /* * Note that this can drive nr *below* what we had passed if sysctl_nr_open - * had been set lower between the check in expand_files() and here. Deal - * with that in caller, it's cheaper that way. + * had been set lower between the check in expand_files() and here. * * We make sure that nr remains a multiple of BITS_PER_LONG - otherwise * bitmaps handling below becomes unpleasant, to put it mildly... */ - if (unlikely(nr > sysctl_nr_open)) - nr = ((sysctl_nr_open - 1) | (BITS_PER_LONG - 1)) + 1; + if (unlikely(nr > sysctl_nr_open)) { + nr = round_down(sysctl_nr_open, BITS_PER_LONG); + if (nr < slots_wanted) + return ERR_PTR(-EMFILE); + } /* * Check if the allocation size would exceed INT_MAX. kvmalloc_array() @@ -146,7 +165,7 @@ out_arr: out_fdt: kfree(fdt); out: - return NULL; + return ERR_PTR(-ENOMEM); } /* @@ -163,7 +182,7 @@ static int expand_fdtable(struct files_struct *files, unsigned int nr) struct fdtable *new_fdt, *cur_fdt; spin_unlock(&files->file_lock); - new_fdt = alloc_fdtable(nr); + new_fdt = alloc_fdtable(nr + 1); /* make sure all __fd_install() have seen resize_in_progress * or have finished their rcu_read_lock_sched() section. @@ -172,16 +191,8 @@ static int expand_fdtable(struct files_struct *files, unsigned int nr) synchronize_rcu(); spin_lock(&files->file_lock); - if (!new_fdt) - return -ENOMEM; - /* - * extremely unlikely race - sysctl_nr_open decreased between the check in - * caller and alloc_fdtable(). Cheaper to catch it here... - */ - if (unlikely(new_fdt->max_fds <= nr)) { - __free_fdtable(new_fdt); - return -EMFILE; - } + if (IS_ERR(new_fdt)) + return PTR_ERR(new_fdt); cur_fdt = files_fdtable(files); BUG_ON(nr < cur_fdt->max_fds); copy_fdtable(new_fdt, cur_fdt); @@ -318,16 +329,9 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) if (new_fdt != &newf->fdtab) __free_fdtable(new_fdt); - new_fdt = alloc_fdtable(open_files - 1); - if (!new_fdt) { - *errorp = -ENOMEM; - goto out_release; - } - - /* beyond sysctl_nr_open; nothing to do */ - if (unlikely(new_fdt->max_fds < open_files)) { - __free_fdtable(new_fdt); - *errorp = -EMFILE; + new_fdt = alloc_fdtable(open_files); + if (IS_ERR(new_fdt)) { + *errorp = PTR_ERR(new_fdt); goto out_release; } From c25f780e491e4734eb27d65aa58e0909fd78ad9f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 28 Aug 2025 16:21:37 +0200 Subject: [PATCH 404/404] Linux 5.4.297 Link: https://lore.kernel.org/r/20250826110905.607690791@linuxfoundation.org Link: https://lore.kernel.org/r/20250827073826.377382421@linuxfoundation.org Tested-by: Jon Hunter Tested-by: Linux Kernel Functional Testing Tested-by: Alok Tiwari Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 16a23aaaa547..3a6324569093 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 4 -SUBLEVEL = 296 +SUBLEVEL = 297 EXTRAVERSION = NAME = Kleptomaniac Octopus