From 39f9bd880abac6068bedb24a4e16e7bd26bf92da Mon Sep 17 00:00:00 2001 From: Jisoo Jang Date: Thu, 9 Mar 2023 19:44:57 +0900 Subject: [PATCH 001/190] wifi: brcmfmac: slab-out-of-bounds read in brcmf_get_assoc_ies() commit 0da40e018fd034d87c9460123fa7f897b69fdee7 upstream. Fix a slab-out-of-bounds read that occurs in kmemdup() called from brcmf_get_assoc_ies(). The bug could occur when assoc_info->req_len, data from a URB provided by a USB device, is bigger than the size of buffer which is defined as WL_EXTRA_BUF_MAX. Add the size check for req_len/resp_len of assoc_info. Found by a modified version of syzkaller. [ 46.592467][ T7] ================================================================== [ 46.594687][ T7] BUG: KASAN: slab-out-of-bounds in kmemdup+0x3e/0x50 [ 46.596572][ T7] Read of size 3014656 at addr ffff888019442000 by task kworker/0:1/7 [ 46.598575][ T7] [ 46.599157][ T7] CPU: 0 PID: 7 Comm: kworker/0:1 Tainted: G O 5.14.0+ #145 [ 46.601333][ T7] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 [ 46.604360][ T7] Workqueue: events brcmf_fweh_event_worker [ 46.605943][ T7] Call Trace: [ 46.606584][ T7] dump_stack_lvl+0x8e/0xd1 [ 46.607446][ T7] print_address_description.constprop.0.cold+0x93/0x334 [ 46.608610][ T7] ? kmemdup+0x3e/0x50 [ 46.609341][ T7] kasan_report.cold+0x79/0xd5 [ 46.610151][ T7] ? kmemdup+0x3e/0x50 [ 46.610796][ T7] kasan_check_range+0x14e/0x1b0 [ 46.611691][ T7] memcpy+0x20/0x60 [ 46.612323][ T7] kmemdup+0x3e/0x50 [ 46.612987][ T7] brcmf_get_assoc_ies+0x967/0xf60 [ 46.613904][ T7] ? brcmf_notify_vif_event+0x3d0/0x3d0 [ 46.614831][ T7] ? lock_chain_count+0x20/0x20 [ 46.615683][ T7] ? mark_lock.part.0+0xfc/0x2770 [ 46.616552][ T7] ? lock_chain_count+0x20/0x20 [ 46.617409][ T7] ? mark_lock.part.0+0xfc/0x2770 [ 46.618244][ T7] ? lock_chain_count+0x20/0x20 [ 46.619024][ T7] brcmf_bss_connect_done.constprop.0+0x241/0x2e0 [ 46.620019][ T7] ? brcmf_parse_configure_security.isra.0+0x2a0/0x2a0 [ 46.620818][ T7] ? __lock_acquire+0x181f/0x5790 [ 46.621462][ T7] brcmf_notify_connect_status+0x448/0x1950 [ 46.622134][ T7] ? rcu_read_lock_bh_held+0xb0/0xb0 [ 46.622736][ T7] ? brcmf_cfg80211_join_ibss+0x7b0/0x7b0 [ 46.623390][ T7] ? find_held_lock+0x2d/0x110 [ 46.623962][ T7] ? brcmf_fweh_event_worker+0x19f/0xc60 [ 46.624603][ T7] ? mark_held_locks+0x9f/0xe0 [ 46.625145][ T7] ? lockdep_hardirqs_on_prepare+0x3e0/0x3e0 [ 46.625871][ T7] ? brcmf_cfg80211_join_ibss+0x7b0/0x7b0 [ 46.626545][ T7] brcmf_fweh_call_event_handler.isra.0+0x90/0x100 [ 46.627338][ T7] brcmf_fweh_event_worker+0x557/0xc60 [ 46.627962][ T7] ? brcmf_fweh_call_event_handler.isra.0+0x100/0x100 [ 46.628736][ T7] ? rcu_read_lock_sched_held+0xa1/0xd0 [ 46.629396][ T7] ? rcu_read_lock_bh_held+0xb0/0xb0 [ 46.629970][ T7] ? lockdep_hardirqs_on_prepare+0x273/0x3e0 [ 46.630649][ T7] process_one_work+0x92b/0x1460 [ 46.631205][ T7] ? pwq_dec_nr_in_flight+0x330/0x330 [ 46.631821][ T7] ? rwlock_bug.part.0+0x90/0x90 [ 46.632347][ T7] worker_thread+0x95/0xe00 [ 46.632832][ T7] ? __kthread_parkme+0x115/0x1e0 [ 46.633393][ T7] ? process_one_work+0x1460/0x1460 [ 46.633957][ T7] kthread+0x3a1/0x480 [ 46.634369][ T7] ? set_kthread_struct+0x120/0x120 [ 46.634933][ T7] ret_from_fork+0x1f/0x30 [ 46.635431][ T7] [ 46.635687][ T7] Allocated by task 7: [ 46.636151][ T7] kasan_save_stack+0x1b/0x40 [ 46.636628][ T7] __kasan_kmalloc+0x7c/0x90 [ 46.637108][ T7] kmem_cache_alloc_trace+0x19e/0x330 [ 46.637696][ T7] brcmf_cfg80211_attach+0x4a0/0x4040 [ 46.638275][ T7] brcmf_attach+0x389/0xd40 [ 46.638739][ T7] brcmf_usb_probe+0x12de/0x1690 [ 46.639279][ T7] usb_probe_interface+0x2aa/0x760 [ 46.639820][ T7] really_probe+0x205/0xb70 [ 46.640342][ T7] __driver_probe_device+0x311/0x4b0 [ 46.640876][ T7] driver_probe_device+0x4e/0x150 [ 46.641445][ T7] __device_attach_driver+0x1cc/0x2a0 [ 46.642000][ T7] bus_for_each_drv+0x156/0x1d0 [ 46.642543][ T7] __device_attach+0x23f/0x3a0 [ 46.643065][ T7] bus_probe_device+0x1da/0x290 [ 46.643644][ T7] device_add+0xb7b/0x1eb0 [ 46.644130][ T7] usb_set_configuration+0xf59/0x16f0 [ 46.644720][ T7] usb_generic_driver_probe+0x82/0xa0 [ 46.645295][ T7] usb_probe_device+0xbb/0x250 [ 46.645786][ T7] really_probe+0x205/0xb70 [ 46.646258][ T7] __driver_probe_device+0x311/0x4b0 [ 46.646804][ T7] driver_probe_device+0x4e/0x150 [ 46.647387][ T7] __device_attach_driver+0x1cc/0x2a0 [ 46.647926][ T7] bus_for_each_drv+0x156/0x1d0 [ 46.648454][ T7] __device_attach+0x23f/0x3a0 [ 46.648939][ T7] bus_probe_device+0x1da/0x290 [ 46.649478][ T7] device_add+0xb7b/0x1eb0 [ 46.649936][ T7] usb_new_device.cold+0x49c/0x1029 [ 46.650526][ T7] hub_event+0x1c98/0x3950 [ 46.650975][ T7] process_one_work+0x92b/0x1460 [ 46.651535][ T7] worker_thread+0x95/0xe00 [ 46.651991][ T7] kthread+0x3a1/0x480 [ 46.652413][ T7] ret_from_fork+0x1f/0x30 [ 46.652885][ T7] [ 46.653131][ T7] The buggy address belongs to the object at ffff888019442000 [ 46.653131][ T7] which belongs to the cache kmalloc-2k of size 2048 [ 46.654669][ T7] The buggy address is located 0 bytes inside of [ 46.654669][ T7] 2048-byte region [ffff888019442000, ffff888019442800) [ 46.656137][ T7] The buggy address belongs to the page: [ 46.656720][ T7] page:ffffea0000651000 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x19440 [ 46.657792][ T7] head:ffffea0000651000 order:3 compound_mapcount:0 compound_pincount:0 [ 46.658673][ T7] flags: 0x100000000010200(slab|head|node=0|zone=1) [ 46.659422][ T7] raw: 0100000000010200 0000000000000000 dead000000000122 ffff888100042000 [ 46.660363][ T7] raw: 0000000000000000 0000000000080008 00000001ffffffff 0000000000000000 [ 46.661236][ T7] page dumped because: kasan: bad access detected [ 46.661956][ T7] page_owner tracks the page as allocated [ 46.662588][ T7] page last allocated via order 3, migratetype Unmovable, gfp_mask 0x52a20(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP), pid 7, ts 31136961085, free_ts 0 [ 46.664271][ T7] prep_new_page+0x1aa/0x240 [ 46.664763][ T7] get_page_from_freelist+0x159a/0x27c0 [ 46.665340][ T7] __alloc_pages+0x2da/0x6a0 [ 46.665847][ T7] alloc_pages+0xec/0x1e0 [ 46.666308][ T7] allocate_slab+0x380/0x4e0 [ 46.666770][ T7] ___slab_alloc+0x5bc/0x940 [ 46.667264][ T7] __slab_alloc+0x6d/0x80 [ 46.667712][ T7] kmem_cache_alloc_trace+0x30a/0x330 [ 46.668299][ T7] brcmf_usbdev_qinit.constprop.0+0x50/0x470 [ 46.668885][ T7] brcmf_usb_probe+0xc97/0x1690 [ 46.669438][ T7] usb_probe_interface+0x2aa/0x760 [ 46.669988][ T7] really_probe+0x205/0xb70 [ 46.670487][ T7] __driver_probe_device+0x311/0x4b0 [ 46.671031][ T7] driver_probe_device+0x4e/0x150 [ 46.671604][ T7] __device_attach_driver+0x1cc/0x2a0 [ 46.672192][ T7] bus_for_each_drv+0x156/0x1d0 [ 46.672739][ T7] page_owner free stack trace missing [ 46.673335][ T7] [ 46.673620][ T7] Memory state around the buggy address: [ 46.674213][ T7] ffff888019442700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 46.675083][ T7] ffff888019442780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 46.675994][ T7] >ffff888019442800: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 46.676875][ T7] ^ [ 46.677323][ T7] ffff888019442880: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 46.678190][ T7] ffff888019442900: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 46.679052][ T7] ================================================================== [ 46.679945][ T7] Disabling lock debugging due to kernel taint [ 46.680725][ T7] Kernel panic - not syncing: Reviewed-by: Arend van Spriel Signed-off-by: Jisoo Jang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230309104457.22628-1-jisoo.jang@yonsei.ac.kr Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 75790b13c962..d77c1dbb5e19 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -5362,6 +5362,11 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg, (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf; req_len = le32_to_cpu(assoc_info->req_len); resp_len = le32_to_cpu(assoc_info->resp_len); + if (req_len > WL_EXTRA_BUF_MAX || resp_len > WL_EXTRA_BUF_MAX) { + brcmf_err("invalid lengths in assoc info: req %u resp %u\n", + req_len, resp_len); + return -EINVAL; + } if (req_len) { err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies", cfg->extra_buf, From 8d59548bae309000442c297bff3e54ab535f0ab7 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Sun, 16 Apr 2023 16:14:04 +0800 Subject: [PATCH 002/190] bluetooth: Perform careful capability checks in hci_sock_ioctl() commit 25c150ac103a4ebeed0319994c742a90634ddf18 upstream. Previously, capability was checked using capable(), which verified that the caller of the ioctl system call had the required capability. In addition, the result of the check would be stored in the HCI_SOCK_TRUSTED flag, making it persistent for the socket. However, malicious programs can abuse this approach by deliberately sharing an HCI socket with a privileged task. The HCI socket will be marked as trusted when the privileged task occasionally makes an ioctl call. This problem can be solved by using sk_capable() to check capability, which ensures that not only the current task but also the socket opener has the specified capability, thus reducing the risk of privilege escalation through the previously identified vulnerability. Cc: stable@vger.kernel.org Fixes: f81f5b2db869 ("Bluetooth: Send control open and close messages for HCI raw sockets") Signed-off-by: Ruihan Li Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Greg Kroah-Hartman --- net/bluetooth/hci_sock.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 6908817a5a70..908a57578794 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -989,7 +989,14 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, if (hci_sock_gen_cookie(sk)) { struct sk_buff *skb; - if (capable(CAP_NET_ADMIN)) + /* Perform careful checks before setting the HCI_SOCK_TRUSTED + * flag. Make sure that not only the current task but also + * the socket opener has the required capability, since + * privileged programs can be tricked into making ioctl calls + * on HCI sockets, and the socket should not be marked as + * trusted simply because the ioctl caller is privileged. + */ + if (sk_capable(sk, CAP_NET_ADMIN)) hci_sock_set_flag(sk, HCI_SOCK_TRUSTED); /* Send event to monitor */ From 433e33de1636a364f65284d9aa30020c8d9a39f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= Date: Mon, 17 Apr 2023 18:20:03 +0300 Subject: [PATCH 003/190] USB: serial: option: add UNISOC vendor and TOZED LT70C product MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a095edfc15f0832e046ae23964e249ef5c95af87 upstream. Add UNISOC vendor ID and TOZED LT70-C modem which is based from UNISOC SL8563. The modem supports the NCM mode. Interface 0 is used for running the AT commands. Interface 12 is the ADB interface. T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 6 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1782 ProdID=4055 Rev=04.04 S: Manufacturer=Unisoc Phone S: Product=Unisoc Phone S: SerialNumber= C: #Ifs=14 Cfg#= 1 Atr=c0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0d Prot=00 Driver=cdc_ncm E: Ad=82(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#=10 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#=11 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=08(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#=12 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=09(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#=13 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0d Prot=00 Driver=cdc_ncm E: Ad=84(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 3 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 4 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0d Prot=00 Driver=cdc_ncm E: Ad=86(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 5 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 6 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0d Prot=00 Driver=cdc_ncm E: Ad=88(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 7 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 8 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8a(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Arınç ÜNAL Link: https://lore.kernel.org/r/20230417152003.243248-1-arinc.unal@arinc9.com Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 8dd94ce7245e..06c5f46ff0f9 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -595,6 +595,11 @@ static void option_instat_callback(struct urb *urb); #define SIERRA_VENDOR_ID 0x1199 #define SIERRA_PRODUCT_EM9191 0x90d3 +/* UNISOC (Spreadtrum) products */ +#define UNISOC_VENDOR_ID 0x1782 +/* TOZED LT70-C based on UNISOC SL8563 uses UNISOC's vendor ID */ +#define TOZED_PRODUCT_LT70C 0x4055 + /* Device flags */ /* Highest interface number which can be used with NCTRL() and RSVD() */ @@ -2225,6 +2230,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); From b31d0d357d8f8c4fcfca4571ee3fada3dc946968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Dahlstr=C3=B6m?= Date: Mon, 13 Mar 2023 21:50:29 +0100 Subject: [PATCH 004/190] iio: adc: palmas_gpadc: fix NULL dereference on rmmod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 49f76c499d38bf67803438eee88c8300d0f6ce09 ] Calling dev_to_iio_dev() on a platform device pointer is undefined and will make adc NULL. Signed-off-by: Patrik Dahlström Link: https://lore.kernel.org/r/20230313205029.1881745-1-risca@dalakolonin.se Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin --- drivers/iio/adc/palmas_gpadc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c index 7dcd4213d38a..6b76622b4fbf 100644 --- a/drivers/iio/adc/palmas_gpadc.c +++ b/drivers/iio/adc/palmas_gpadc.c @@ -633,7 +633,7 @@ out: static int palmas_gpadc_remove(struct platform_device *pdev) { - struct iio_dev *indio_dev = dev_to_iio_dev(&pdev->dev); + struct iio_dev *indio_dev = dev_get_drvdata(&pdev->dev); struct palmas_gpadc *adc = iio_priv(indio_dev); if (adc->wakeup1_enable || adc->wakeup2_enable) From c574cb62e05684f6c15157009089d9eb3a98c007 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 22 Mar 2023 15:53:32 +0100 Subject: [PATCH 005/190] ASoC: Intel: bytcr_rt5640: Add quirk for the Acer Iconia One 7 B1-750 [ Upstream commit e38c5e80c3d293a883c6f1d553f2146ec0bda35e ] The Acer Iconia One 7 B1-750 tablet mostly works fine with the defaults for an Bay Trail CR tablet. Except for the internal mic, instead of an analog mic on IN3 a digital mic on DMIC1 is uses. Add a quirk with these settings for this tablet. Acked-by: Pierre-Louis Bossart Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20230322145332.131525-1-hdegoede@redhat.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/boards/bytcr_rt5640.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 2001bc774c64..d27dd170beda 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -400,6 +400,18 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream, /* Please keep this list alphabetically sorted */ static const struct dmi_system_id byt_rt5640_quirk_table[] = { + { /* Acer Iconia One 7 B1-750 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "VESPA2"), + }, + .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | + BYT_RT5640_JD_SRC_JD1_IN4P | + BYT_RT5640_OVCD_TH_1500UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { /* Acer Iconia Tab 8 W1-810 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), From a3f85de6f4db59ed446ca57f2d7ab12eb15ca046 Mon Sep 17 00:00:00 2001 From: Jiping Ma Date: Tue, 7 Jan 2020 14:34:00 +0800 Subject: [PATCH 006/190] stmmac: debugfs entry name is not be changed when udev rename device name. commit 481a7d154cbbd5ca355cc01cc8969876b240eded upstream. Add one notifier for udev changes net device name. Fixes: b6601323ef9e ("net: stmmac: debugfs entry name is not be changed when udev rename") Signed-off-by: Jiping Ma Signed-off-by: David S. Miller Signed-off-by: Gou Hao Signed-off-by: Greg Kroah-Hartman --- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 0a4d093adfc9..3e35cdf0d2b7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -114,6 +114,7 @@ MODULE_PARM_DESC(chain_mode, "To use chain instead of ring mode"); static irqreturn_t stmmac_interrupt(int irq, void *dev_id); #ifdef CONFIG_DEBUG_FS +static const struct net_device_ops stmmac_netdev_ops; static int stmmac_init_fs(struct net_device *dev); static void stmmac_exit_fs(struct net_device *dev); #endif @@ -4034,6 +4035,34 @@ static const struct file_operations stmmac_dma_cap_fops = { .release = single_release, }; +/* Use network device events to rename debugfs file entries. + */ +static int stmmac_device_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct stmmac_priv *priv = netdev_priv(dev); + + if (dev->netdev_ops != &stmmac_netdev_ops) + goto done; + + switch (event) { + case NETDEV_CHANGENAME: + if (priv->dbgfs_dir) + priv->dbgfs_dir = debugfs_rename(stmmac_fs_dir, + priv->dbgfs_dir, + stmmac_fs_dir, + dev->name); + break; + } +done: + return NOTIFY_DONE; +} + +static struct notifier_block stmmac_notifier = { + .notifier_call = stmmac_device_event, +}; + static int stmmac_init_fs(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); @@ -4072,6 +4101,8 @@ static int stmmac_init_fs(struct net_device *dev) return -ENOMEM; } + register_netdevice_notifier(&stmmac_notifier); + return 0; } @@ -4079,6 +4110,7 @@ static void stmmac_exit_fs(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); + unregister_netdevice_notifier(&stmmac_notifier); debugfs_remove_recursive(priv->dbgfs_dir); } #endif /* CONFIG_DEBUG_FS */ From dbe0fc9202a0406d9a88c38da32d0d852e14d166 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 4 Apr 2023 09:25:15 +0200 Subject: [PATCH 007/190] USB: dwc3: fix runtime pm imbalance on unbind commit 44d257e9012ee8040e41d224d0e5bfb5ef5427ea upstream. Make sure to balance the runtime PM usage count on driver unbind by adding back the pm_runtime_allow() call that had been erroneously removed. Fixes: 266d0493900a ("usb: dwc3: core: don't trigger runtime pm when remove driver") Cc: stable@vger.kernel.org # 5.9 Cc: Li Jun Acked-by: Thinh Nguyen Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20230404072524.19014-3-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 65caee589e67..81a5ca15b9c7 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1563,6 +1563,7 @@ static int dwc3_remove(struct platform_device *pdev) dwc3_core_exit(dwc); dwc3_ulpi_exit(dwc); + pm_runtime_allow(&pdev->dev); pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); From 1433de982aec5cada15aa152ab2a26895a79cd8c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 14 Jul 2021 13:06:38 -0300 Subject: [PATCH 008/190] perf sched: Cast PTHREAD_STACK_MIN to int as it may turn into sysconf(__SC_THREAD_STACK_MIN_VALUE) commit d08c84e01afa7a7eee6badab25d5420fa847f783 upstream. In fedora rawhide the PTHREAD_STACK_MIN define may end up expanded to a sysconf() call, and that will return 'long int', breaking the build: 45 fedora:rawhide : FAIL gcc version 11.1.1 20210623 (Red Hat 11.1.1-6) (GCC) builtin-sched.c: In function 'create_tasks': /git/perf-5.14.0-rc1/tools/include/linux/kernel.h:43:24: error: comparison of distinct pointer types lacks a cast [-Werror] 43 | (void) (&_max1 == &_max2); \ | ^~ builtin-sched.c:673:34: note: in expansion of macro 'max' 673 | (size_t) max(16 * 1024, PTHREAD_STACK_MIN)); | ^~~ cc1: all warnings being treated as errors $ grep __sysconf /usr/include/*/*.h /usr/include/bits/pthread_stack_min-dynamic.h:extern long int __sysconf (int __name) __THROW; /usr/include/bits/pthread_stack_min-dynamic.h:# define PTHREAD_STACK_MIN __sysconf (__SC_THREAD_STACK_MIN_VALUE) /usr/include/bits/time.h:extern long int __sysconf (int); /usr/include/bits/time.h:# define CLK_TCK ((__clock_t) __sysconf (2)) /* 2 is _SC_CLK_TCK */ $ So cast it to int to cope with that. Signed-off-by: Arnaldo Carvalho de Melo Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- tools/perf/builtin-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index cbf39dab19c1..4562e3b2f4d3 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -659,7 +659,7 @@ static void create_tasks(struct perf_sched *sched) err = pthread_attr_init(&attr); BUG_ON(err); err = pthread_attr_setstacksize(&attr, - (size_t) max(16 * 1024, PTHREAD_STACK_MIN)); + (size_t) max(16 * 1024, (int)PTHREAD_STACK_MIN)); BUG_ON(err); err = pthread_mutex_lock(&sched->start_work_mutex); BUG_ON(err); From 8b3a7f0071a42d0b48ef4921f892b7e774c826aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nuno=20S=C3=A1?= Date: Mon, 27 Mar 2023 16:54:14 +0200 Subject: [PATCH 009/190] staging: iio: resolver: ads1210: fix config mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 16313403d873ff17a587818b61f84c8cb4971cef upstream. As stated in the device datasheet [1], bits a0 and a1 have to be set to 1 for the configuration mode. [1]: https://www.analog.com/media/en/technical-documentation/data-sheets/ad2s1210.pdf Fixes: b19e9ad5e2cb9 ("staging:iio:resolver:ad2s1210 general driver cleanup") Cc: stable Signed-off-by: Nuno Sá Link: https://lore.kernel.org/r/20230327145414.1505537-1-nuno.sa@analog.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/resolver/ad2s1210.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index aca983f34f5e..f41ee9243801 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -85,7 +85,7 @@ struct ad2s1210_state { static const int ad2s1210_mode_vals[4][2] = { [MOD_POS] = { 0, 0 }, [MOD_VEL] = { 0, 1 }, - [MOD_CONFIG] = { 1, 0 }, + [MOD_CONFIG] = { 1, 1 }, }; static inline void ad2s1210_set_mode(enum ad2s1210_mode mode, From 2a352e42ac5432552b8bd6cbc202039bf9189308 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 11 Feb 2020 19:18:55 +0100 Subject: [PATCH 010/190] debugfs: regset32: Add Runtime PM support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 30332eeefec8f83afcea00c360f99ef64b87f220 upstream. Hardware registers of devices under control of power management cannot be accessed at all times. If such a device is suspended, register accesses may lead to undefined behavior, like reading bogus values, or causing exceptions or system lock-ups. Extend struct debugfs_regset32 with an optional field to let device drivers specify the device the registers in the set belong to. This allows debugfs_show_regset32() to make sure the device is resumed while its registers are being read. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Reviewed-by: Greg Kroah-Hartman Acked-by: Rafael J. Wysocki Signed-off-by: Herbert Xu Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/file.c | 8 ++++++++ include/linux/debugfs.h | 1 + 2 files changed, 9 insertions(+) diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index a57d080d2ba5..acdc802bfe9a 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "internal.h" @@ -1084,7 +1085,14 @@ static int debugfs_show_regset32(struct seq_file *s, void *data) { struct debugfs_regset32 *regset = s->private; + if (regset->dev) + pm_runtime_get_sync(regset->dev); + debugfs_print_regs32(s, regset->regs, regset->nregs, regset->base, ""); + + if (regset->dev) + pm_runtime_put(regset->dev); + return 0; } diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 6ebc269e48ac..0624c9a1f01e 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -35,6 +35,7 @@ struct debugfs_regset32 { const struct debugfs_reg32 *regs; int nregs; void __iomem *base; + struct device *dev; /* Optional device for Runtime PM */ }; extern struct dentry *arch_debugfs_dir; From 6744044115bc815b95e8d8cd3ceb4165f74fc965 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 5 Apr 2023 11:03:42 +0200 Subject: [PATCH 011/190] xhci: fix debugfs register accesses while suspended commit 735baf1b23458f71a8b15cb924af22c9ff9cd125 upstream. Wire up the debugfs regset device pointer so that the controller is resumed before accessing registers to avoid crashing or locking up if it happens to be runtime suspended. Fixes: 02b6fdc2a153 ("usb: xhci: Add debugfs interface for xHCI driver") Cc: stable@vger.kernel.org # 4.15: 30332eeefec8: debugfs: regset32: Add Runtime PM support Cc: stable@vger.kernel.org # 4.15 Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20230405090342.7363-1-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-debugfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c index 448d7b11dec4..608104cdcf33 100644 --- a/drivers/usb/host/xhci-debugfs.c +++ b/drivers/usb/host/xhci-debugfs.c @@ -132,6 +132,7 @@ static void xhci_debugfs_regset(struct xhci_hcd *xhci, u32 base, regset->regs = regs; regset->nregs = nregs; regset->base = hcd->regs + base; + regset->dev = hcd->self.controller; debugfs_create_regset32((const char *)rgs->name, 0444, parent, regset); } From 830181ddced5a05a711dc9da8043203b1f33a77e Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Tue, 11 Apr 2023 12:14:26 +0100 Subject: [PATCH 012/190] MIPS: fw: Allow firmware to pass a empty env commit ee1809ed7bc456a72dc8410b475b73021a3a68d5 upstream. fw_getenv will use env entry to determine style of env, however it is legal for firmware to just pass a empty list. Check if first entry exist before running strchr to avoid null pointer dereference. Cc: stable@vger.kernel.org Link: https://github.com/clbr/n64bootloader/issues/5 Signed-off-by: Jiaxun Yang Signed-off-by: Thomas Bogendoerfer Signed-off-by: Greg Kroah-Hartman --- arch/mips/fw/lib/cmdline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/fw/lib/cmdline.c b/arch/mips/fw/lib/cmdline.c index 6ecda64ad184..ed88abc40513 100644 --- a/arch/mips/fw/lib/cmdline.c +++ b/arch/mips/fw/lib/cmdline.c @@ -51,7 +51,7 @@ char *fw_getenv(char *envname) { char *result = NULL; - if (_fw_envp != NULL) { + if (_fw_envp != NULL && fw_envp(0) != NULL) { /* * Return a pointer to the given environment variable. * YAMON uses "name", "value" pairs, while U-Boot uses From f7ba53a9d768192950b35629d4d900569a8c9cf2 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sun, 9 Apr 2023 17:15:52 +0200 Subject: [PATCH 013/190] pwm: meson: Fix axg ao mux parents commit eb411c0cf59ae6344b34bc6f0d298a22b300627e upstream. This fix is basically the same as 9bce02ef0dfa ("pwm: meson: Fix the G12A AO clock parents order"). Vendor driver referenced there has xtal as first parent also for axg ao. In addition fix the name of the aoclk81 clock. Apparently name aoclk81 as used by the vendor driver was changed when mainlining the axg clock driver. Fixes: bccaa3f917c9 ("pwm: meson: Add clock source configuration for Meson-AXG") Cc: stable@vger.kernel.org Signed-off-by: Heiner Kallweit Reviewed-by: Martin Blumenstingl Signed-off-by: Thierry Reding Signed-off-by: Greg Kroah-Hartman --- drivers/pwm/pwm-meson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c index e247ab632530..90aba3091b23 100644 --- a/drivers/pwm/pwm-meson.c +++ b/drivers/pwm/pwm-meson.c @@ -425,7 +425,7 @@ static const struct meson_pwm_data pwm_axg_ee_data = { }; static const char * const pwm_axg_ao_parent_names[] = { - "aoclk81", "xtal", "fclk_div4", "fclk_div5" + "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5" }; static const struct meson_pwm_data pwm_axg_ao_data = { From 2702b67f59d455072a08dc40312f9b090d4dec04 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 27 Apr 2023 17:59:20 +0200 Subject: [PATCH 014/190] ring-buffer: Sync IRQ works before buffer destruction commit 675751bb20634f981498c7d66161584080cc061e upstream. If something was written to the buffer just before destruction, it may be possible (maybe not in a real system, but it did happen in ARCH=um with time-travel) to destroy the ringbuffer before the IRQ work ran, leading this KASAN report (or a crash without KASAN): BUG: KASAN: slab-use-after-free in irq_work_run_list+0x11a/0x13a Read of size 8 at addr 000000006d640a48 by task swapper/0 CPU: 0 PID: 0 Comm: swapper Tainted: G W O 6.3.0-rc1 #7 Stack: 60c4f20f 0c203d48 41b58ab3 60f224fc 600477fa 60f35687 60c4f20f 601273dd 00000008 6101eb00 6101eab0 615be548 Call Trace: [<60047a58>] show_stack+0x25e/0x282 [<60c609e0>] dump_stack_lvl+0x96/0xfd [<60c50d4c>] print_report+0x1a7/0x5a8 [<603078d3>] kasan_report+0xc1/0xe9 [<60308950>] __asan_report_load8_noabort+0x1b/0x1d [<60232844>] irq_work_run_list+0x11a/0x13a [<602328b4>] irq_work_tick+0x24/0x34 [<6017f9dc>] update_process_times+0x162/0x196 [<6019f335>] tick_sched_handle+0x1a4/0x1c3 [<6019fd9e>] tick_sched_timer+0x79/0x10c [<601812b9>] __hrtimer_run_queues.constprop.0+0x425/0x695 [<60182913>] hrtimer_interrupt+0x16c/0x2c4 [<600486a3>] um_timer+0x164/0x183 [...] Allocated by task 411: save_stack_trace+0x99/0xb5 stack_trace_save+0x81/0x9b kasan_save_stack+0x2d/0x54 kasan_set_track+0x34/0x3e kasan_save_alloc_info+0x25/0x28 ____kasan_kmalloc+0x8b/0x97 __kasan_kmalloc+0x10/0x12 __kmalloc+0xb2/0xe8 load_elf_phdrs+0xee/0x182 [...] The buggy address belongs to the object at 000000006d640800 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 584 bytes inside of freed 1024-byte region [000000006d640800, 000000006d640c00) Add the appropriate irq_work_sync() so the work finishes before the buffers are destroyed. Prior to the commit in the Fixes tag below, there was only a single global IRQ work, so this issue didn't exist. Link: https://lore.kernel.org/linux-trace-kernel/20230427175920.a76159263122.I8295e405c44362a86c995e9c2c37e3e03810aa56@changeid Cc: stable@vger.kernel.org Cc: Masami Hiramatsu Fixes: 15693458c4bc ("tracing/ring-buffer: Move poll wake ups into ring buffer code") Signed-off-by: Johannes Berg Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/ring_buffer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 37fade5101ee..ba8b72f9cdc0 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1326,6 +1326,8 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer) struct list_head *head = cpu_buffer->pages; struct buffer_page *bpage, *tmp; + irq_work_sync(&cpu_buffer->irq_work.work); + free_buffer_page(cpu_buffer->reader_page); if (head) { @@ -1431,6 +1433,8 @@ ring_buffer_free(struct ring_buffer *buffer) cpuhp_state_remove_instance(CPUHP_TRACE_RB_PREPARE, &buffer->node); + irq_work_sync(&buffer->irq_work.work); + for_each_buffer_cpu(buffer, cpu) rb_free_cpu_buffer(buffer->buffers[cpu]); From a4ae9bfe519ca60f01fc2d4610c397261f3ad920 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Fri, 31 Mar 2023 14:32:18 +0200 Subject: [PATCH 015/190] reiserfs: Add security prefix to xattr name in reiserfs_security_write() commit d82dcd9e21b77d338dc4875f3d4111f0db314a7c upstream. Reiserfs sets a security xattr at inode creation time in two stages: first, it calls reiserfs_security_init() to obtain the xattr from active LSMs; then, it calls reiserfs_security_write() to actually write that xattr. Unfortunately, it seems there is a wrong expectation that LSMs provide the full xattr name in the form 'security.'. However, LSMs always provided just the suffix, causing reiserfs to not write the xattr at all (if the suffix is shorter than the prefix), or to write an xattr with the wrong name. Add a temporary buffer in reiserfs_security_write(), and write to it the full xattr name, before passing it to reiserfs_xattr_set_handle(). Also replace the name length check with a check that the full xattr name is not larger than XATTR_NAME_MAX. Cc: stable@vger.kernel.org # v2.6.x Fixes: 57fe60df6241 ("reiserfs: add atomic addition of selinux attributes during inode creation") Signed-off-by: Roberto Sassu Signed-off-by: Paul Moore Signed-off-by: Greg Kroah-Hartman --- fs/reiserfs/xattr_security.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c index 59d87f9f72fb..159af6c26f4b 100644 --- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c @@ -81,11 +81,15 @@ int reiserfs_security_write(struct reiserfs_transaction_handle *th, struct inode *inode, struct reiserfs_security_handle *sec) { + char xattr_name[XATTR_NAME_MAX + 1] = XATTR_SECURITY_PREFIX; int error; - if (strlen(sec->name) < sizeof(XATTR_SECURITY_PREFIX)) + + if (XATTR_SECURITY_PREFIX_LEN + strlen(sec->name) > XATTR_NAME_MAX) return -EINVAL; - error = reiserfs_xattr_set_handle(th, inode, sec->name, sec->value, + strlcat(xattr_name, sec->name, sizeof(xattr_name)); + + error = reiserfs_xattr_set_handle(th, inode, xattr_name, sec->value, sec->length, XATTR_CREATE); if (error == -ENODATA || error == -EOPNOTSUPP) error = 0; From dfde805e02a182d8185be465000443a31a16c05a Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 4 Apr 2023 17:23:59 -0700 Subject: [PATCH 016/190] KVM: nVMX: Emulate NOPs in L2, and PAUSE if it's not intercepted commit 4984563823f0034d3533854c1b50e729f5191089 upstream. Extend VMX's nested intercept logic for emulated instructions to handle "pause" interception, in quotes because KVM's emulator doesn't filter out NOPs when checking for nested intercepts. Failure to allow emulation of NOPs results in KVM injecting a #UD into L2 on any NOP that collides with the emulator's definition of PAUSE, i.e. on all single-byte NOPs. For PAUSE itself, honor L1's PAUSE-exiting control, but ignore PLE to avoid unnecessarily injecting a #UD into L2. Per the SDM, the first execution of PAUSE after VM-Entry is treated as the beginning of a new loop, i.e. will never trigger a PLE VM-Exit, and so L1 can't expect any given execution of PAUSE to deterministically exit. ... the processor considers this execution to be the first execution of PAUSE in a loop. (It also does so for the first execution of PAUSE at CPL 0 after VM entry.) All that said, the PLE side of things is currently a moot point, as KVM doesn't expose PLE to L1. Note, vmx_check_intercept() is still wildly broken when L1 wants to intercept an instruction, as KVM injects a #UD instead of synthesizing a nested VM-Exit. That issue extends far beyond NOP/PAUSE and needs far more effort to fix, i.e. is a problem for the future. Fixes: 07721feee46b ("KVM: nVMX: Don't emulate instructions in guest mode") Cc: Mathias Krause Cc: stable@vger.kernel.org Reviewed-by: Paolo Bonzini Link: https://lore.kernel.org/r/20230405002359.418138-1-seanjc@google.com Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman --- arch/x86/kvm/vmx/vmx.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 265e70b0eb79..55e52064c4ec 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -13878,6 +13878,21 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu, /* FIXME: produce nested vmexit and return X86EMUL_INTERCEPTED. */ break; + case x86_intercept_pause: + /* + * PAUSE is a single-byte NOP with a REPE prefix, i.e. collides + * with vanilla NOPs in the emulator. Apply the interception + * check only to actual PAUSE instructions. Don't check + * PAUSE-loop-exiting, software can't expect a given PAUSE to + * exit, i.e. KVM is within its rights to allow L2 to execute + * the PAUSE. + */ + if ((info->rep_prefix != REPE_PREFIX) || + !nested_cpu_has2(vmcs12, CPU_BASED_PAUSE_EXITING)) + return X86EMUL_CONTINUE; + + break; + /* TODO: check more intercepts... */ default: break; From b539fb4eac054a2d0105a6b8edff4ad5ab54312a Mon Sep 17 00:00:00 2001 From: Reid Tonking Date: Wed, 26 Apr 2023 14:49:56 -0500 Subject: [PATCH 017/190] i2c: omap: Fix standard mode false ACK readings commit c770657bd2611b077ec1e7b1fe6aa92f249399bd upstream. Using standard mode, rare false ACK responses were appearing with i2cdetect tool. This was happening due to NACK interrupt triggering ISR thread before register access interrupt was ready. Removing the NACK interrupt's ability to trigger ISR thread lets register access ready interrupt do this instead. Cc: # v3.7+ Fixes: 3b2f8f82dad7 ("i2c: omap: switch to threaded IRQ support") Signed-off-by: Reid Tonking Acked-by: Vignesh Raghavendra Reviewed-by: Tony Lindgren Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index cd9c65f3d404..11321ad482a3 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1027,7 +1027,7 @@ omap_i2c_isr(int irq, void *dev_id) u16 stat; stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG); - mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG); + mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG) & ~OMAP_I2C_STAT_NACK; if (stat & mask) ret = IRQ_WAKE_THREAD; From 951ed2e634b53ad0fb0ec02b3f7f21bbd3523c0c Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Wed, 1 Mar 2023 20:29:18 +0800 Subject: [PATCH 018/190] Revert "ubifs: dirty_cow_znode: Fix memleak in error handling path" commit 7d01cb27f6aebc54efbe28d8961a973b8f795b13 upstream. This reverts commit 122deabfe1428 (ubifs: dirty_cow_znode: Fix memleak in error handling path). After commit 122deabfe1428 applied, if insert_old_idx() failed, old index neither exists in TNC nor in old-index tree. Which means that old index node could be overwritten in layout_leb_in_gaps(), then ubifs image will be corrupted in power-cut. Fixes: 122deabfe1428 (ubifs: dirty_cow_znode: Fix memleak ... path) Cc: stable@vger.kernel.org Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- fs/ubifs/tnc.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 4665c4d7d76a..2073aa706c83 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -279,18 +279,11 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c, if (zbr->len) { err = insert_old_idx(c, zbr->lnum, zbr->offs); if (unlikely(err)) - /* - * Obsolete znodes will be freed by tnc_destroy_cnext() - * or free_obsolete_znodes(), copied up znodes should - * be added back to tnc and freed by - * ubifs_destroy_tnc_subtree(). - */ - goto out; + return ERR_PTR(err); err = add_idx_dirt(c, zbr->lnum, zbr->len); } else err = 0; -out: zbr->znode = zn; zbr->lnum = 0; zbr->offs = 0; From cc29c7216d7f057eb0613b97dc38c7e1962a88d2 Mon Sep 17 00:00:00 2001 From: Zhihao Cheng Date: Wed, 1 Mar 2023 20:29:19 +0800 Subject: [PATCH 019/190] ubifs: Fix memleak when insert_old_idx() failed commit b5fda08ef213352ac2df7447611eb4d383cce929 upstream. Following process will cause a memleak for copied up znode: dirty_cow_znode zn = copy_znode(c, znode); err = insert_old_idx(c, zbr->lnum, zbr->offs); if (unlikely(err)) return ERR_PTR(err); // No one refers to zn. Fetch a reproducer in [Link]. Function copy_znode() is split into 2 parts: resource allocation and znode replacement, insert_old_idx() is split in similar way, so resource cleanup could be done in error handling path without corrupting metadata(mem & disk). It's okay that old index inserting is put behind of add_idx_dirt(), old index is used in layout_leb_in_gaps(), so the two processes do not depend on each other. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216705 Fixes: 1e51764a3c2a ("UBIFS: add new flash file system") Cc: stable@vger.kernel.org Signed-off-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- fs/ubifs/tnc.c | 137 +++++++++++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 50 deletions(-) diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 2073aa706c83..08ed942b7627 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -56,6 +56,33 @@ enum { NOT_ON_MEDIA = 3, }; +static void do_insert_old_idx(struct ubifs_info *c, + struct ubifs_old_idx *old_idx) +{ + struct ubifs_old_idx *o; + struct rb_node **p, *parent = NULL; + + p = &c->old_idx.rb_node; + while (*p) { + parent = *p; + o = rb_entry(parent, struct ubifs_old_idx, rb); + if (old_idx->lnum < o->lnum) + p = &(*p)->rb_left; + else if (old_idx->lnum > o->lnum) + p = &(*p)->rb_right; + else if (old_idx->offs < o->offs) + p = &(*p)->rb_left; + else if (old_idx->offs > o->offs) + p = &(*p)->rb_right; + else { + ubifs_err(c, "old idx added twice!"); + kfree(old_idx); + } + } + rb_link_node(&old_idx->rb, parent, p); + rb_insert_color(&old_idx->rb, &c->old_idx); +} + /** * insert_old_idx - record an index node obsoleted since the last commit start. * @c: UBIFS file-system description object @@ -81,35 +108,15 @@ enum { */ static int insert_old_idx(struct ubifs_info *c, int lnum, int offs) { - struct ubifs_old_idx *old_idx, *o; - struct rb_node **p, *parent = NULL; + struct ubifs_old_idx *old_idx; old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS); if (unlikely(!old_idx)) return -ENOMEM; old_idx->lnum = lnum; old_idx->offs = offs; + do_insert_old_idx(c, old_idx); - p = &c->old_idx.rb_node; - while (*p) { - parent = *p; - o = rb_entry(parent, struct ubifs_old_idx, rb); - if (lnum < o->lnum) - p = &(*p)->rb_left; - else if (lnum > o->lnum) - p = &(*p)->rb_right; - else if (offs < o->offs) - p = &(*p)->rb_left; - else if (offs > o->offs) - p = &(*p)->rb_right; - else { - ubifs_err(c, "old idx added twice!"); - kfree(old_idx); - return 0; - } - } - rb_link_node(&old_idx->rb, parent, p); - rb_insert_color(&old_idx->rb, &c->old_idx); return 0; } @@ -211,23 +218,6 @@ static struct ubifs_znode *copy_znode(struct ubifs_info *c, __set_bit(DIRTY_ZNODE, &zn->flags); __clear_bit(COW_ZNODE, &zn->flags); - ubifs_assert(c, !ubifs_zn_obsolete(znode)); - __set_bit(OBSOLETE_ZNODE, &znode->flags); - - if (znode->level != 0) { - int i; - const int n = zn->child_cnt; - - /* The children now have new parent */ - for (i = 0; i < n; i++) { - struct ubifs_zbranch *zbr = &zn->zbranch[i]; - - if (zbr->znode) - zbr->znode->parent = zn; - } - } - - atomic_long_inc(&c->dirty_zn_cnt); return zn; } @@ -245,6 +235,42 @@ static int add_idx_dirt(struct ubifs_info *c, int lnum, int dirt) return ubifs_add_dirt(c, lnum, dirt); } +/** + * replace_znode - replace old znode with new znode. + * @c: UBIFS file-system description object + * @new_zn: new znode + * @old_zn: old znode + * @zbr: the branch of parent znode + * + * Replace old znode with new znode in TNC. + */ +static void replace_znode(struct ubifs_info *c, struct ubifs_znode *new_zn, + struct ubifs_znode *old_zn, struct ubifs_zbranch *zbr) +{ + ubifs_assert(c, !ubifs_zn_obsolete(old_zn)); + __set_bit(OBSOLETE_ZNODE, &old_zn->flags); + + if (old_zn->level != 0) { + int i; + const int n = new_zn->child_cnt; + + /* The children now have new parent */ + for (i = 0; i < n; i++) { + struct ubifs_zbranch *child = &new_zn->zbranch[i]; + + if (child->znode) + child->znode->parent = new_zn; + } + } + + zbr->znode = new_zn; + zbr->lnum = 0; + zbr->offs = 0; + zbr->len = 0; + + atomic_long_inc(&c->dirty_zn_cnt); +} + /** * dirty_cow_znode - ensure a znode is not being committed. * @c: UBIFS file-system description object @@ -277,21 +303,32 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c, return zn; if (zbr->len) { - err = insert_old_idx(c, zbr->lnum, zbr->offs); - if (unlikely(err)) - return ERR_PTR(err); + struct ubifs_old_idx *old_idx; + + old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS); + if (unlikely(!old_idx)) { + err = -ENOMEM; + goto out; + } + old_idx->lnum = zbr->lnum; + old_idx->offs = zbr->offs; + err = add_idx_dirt(c, zbr->lnum, zbr->len); - } else - err = 0; + if (err) { + kfree(old_idx); + goto out; + } - zbr->znode = zn; - zbr->lnum = 0; - zbr->offs = 0; - zbr->len = 0; + do_insert_old_idx(c, old_idx); + } + + replace_znode(c, zn, znode, zbr); - if (unlikely(err)) - return ERR_PTR(err); return zn; + +out: + kfree(zn); + return ERR_PTR(err); } /** From 7bc3be867a15b1308b6ea20b8025337cbcf25781 Mon Sep 17 00:00:00 2001 From: Wang YanQing Date: Tue, 28 Mar 2023 23:35:34 +0800 Subject: [PATCH 020/190] ubi: Fix return value overwrite issue in try_write_vid_and_data() commit 31a149d5c13c4cbcf97de3435817263a2d8c9d6e upstream. The commit 2d78aee426d8 ("UBI: simplify LEB write and atomic LEB change code") adds helper function, try_write_vid_and_data(), to simplify the code, but this helper function has bug, it will return 0 (success) when ubi_io_write_vid_hdr() or the ubi_io_write_data() return error number (-EIO, etc), because the return value of ubi_wl_put_peb() will overwrite the original return value. This issue will cause unexpected data loss issue, because the caller of this function and UBIFS willn't know the data is lost. Fixes: 2d78aee426d8 ("UBI: simplify LEB write and atomic LEB change code") Cc: stable@vger.kernel.org Signed-off-by: Wang YanQing Reviewed-by: Zhihao Cheng Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/ubi/eba.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index b98481b69314..3e25421f22a2 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -960,7 +960,7 @@ static int try_write_vid_and_data(struct ubi_volume *vol, int lnum, int offset, int len) { struct ubi_device *ubi = vol->ubi; - int pnum, opnum, err, vol_id = vol->vol_id; + int pnum, opnum, err, err2, vol_id = vol->vol_id; pnum = ubi_wl_get_peb(ubi); if (pnum < 0) { @@ -995,10 +995,19 @@ static int try_write_vid_and_data(struct ubi_volume *vol, int lnum, out_put: up_read(&ubi->fm_eba_sem); - if (err && pnum >= 0) - err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); - else if (!err && opnum >= 0) - err = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0); + if (err && pnum >= 0) { + err2 = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); + if (err2) { + ubi_warn(ubi, "failed to return physical eraseblock %d, error %d", + pnum, err2); + } + } else if (!err && opnum >= 0) { + err2 = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0); + if (err2) { + ubi_warn(ubi, "failed to return physical eraseblock %d, error %d", + opnum, err2); + } + } return err; } From 107d481642c356a5668058066360fc473911e628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Lindahl?= Date: Thu, 30 Mar 2023 11:32:14 +0200 Subject: [PATCH 021/190] ubifs: Free memory for tmpfile name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 1fb815b38bb31d6af9bd0540b8652a0d6fe6cfd3 upstream. When opening a ubifs tmpfile on an encrypted directory, function fscrypt_setup_filename allocates memory for the name that is to be stored in the directory entry, but after the name has been copied to the directory entry inode, the memory is not freed. When running kmemleak on it we see that it is registered as a leak. The report below is triggered by a simple program 'tmpfile' just opening a tmpfile: unreferenced object 0xffff88810178f380 (size 32): comm "tmpfile", pid 509, jiffies 4294934744 (age 1524.742s) backtrace: __kmem_cache_alloc_node __kmalloc fscrypt_setup_filename ubifs_tmpfile vfs_tmpfile path_openat Free this memory after it has been copied to the inode. Signed-off-by: Mårten Lindahl Reviewed-by: Zhihao Cheng Cc: stable@vger.kernel.org Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- fs/ubifs/dir.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 3b93b14e0041..cb52aa9ea276 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -445,6 +445,7 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry, mutex_unlock(&dir_ui->ui_mutex); ubifs_release_budget(c, &req); + fscrypt_free_filename(&nm); return 0; From 8a3f6a71abc15e06385336896c16dec3110beb2e Mon Sep 17 00:00:00 2001 From: Ondrej Mosnacek Date: Wed, 12 Apr 2023 15:59:19 +0200 Subject: [PATCH 022/190] selinux: fix Makefile dependencies of flask.h [ Upstream commit bcab1adeaad4b39a1e04cb98979a367d08253f03 ] Make the flask.h target depend on the genheaders binary instead of classmap.h to ensure that it is rebuilt if any of the dependencies of genheaders are changed. Notably this fixes flask.h not being rebuilt when initial_sid_to_string.h is modified. Fixes: 8753f6bec352 ("selinux: generate flask headers during kernel build") Signed-off-by: Ondrej Mosnacek Acked-by: Stephen Smalley Signed-off-by: Paul Moore Signed-off-by: Sasha Levin --- security/selinux/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/selinux/Makefile b/security/selinux/Makefile index c7161f8792b2..3efb0dda95b5 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -19,8 +19,8 @@ ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include $(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h - cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h + cmd_flask = $< $(obj)/flask.h $(obj)/av_permissions.h targets += flask.h av_permissions.h -$(obj)/flask.h: $(src)/include/classmap.h FORCE +$(obj)/flask.h: scripts/selinux/genheaders/genheaders FORCE $(call if_changed,flask) From 1b18998c27503e68a5f4894e6799a840c9d3b5da Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Wed, 12 Apr 2023 13:29:11 -0400 Subject: [PATCH 023/190] selinux: ensure av_permissions.h is built when needed [ Upstream commit 4ce1f694eb5d8ca607fed8542d32a33b4f1217a5 ] The Makefile rule responsible for building flask.h and av_permissions.h only lists flask.h as a target which means that av_permissions.h is only generated when flask.h needs to be generated. This patch fixes this by adding av_permissions.h as a target to the rule. Fixes: 8753f6bec352 ("selinux: generate flask headers during kernel build") Signed-off-by: Paul Moore Signed-off-by: Sasha Levin --- security/selinux/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/selinux/Makefile b/security/selinux/Makefile index 3efb0dda95b5..08ba8ca81d40 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -22,5 +22,5 @@ quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h cmd_flask = $< $(obj)/flask.h $(obj)/av_permissions.h targets += flask.h av_permissions.h -$(obj)/flask.h: scripts/selinux/genheaders/genheaders FORCE +$(obj)/flask.h $(obj)/av_permissions.h &: scripts/selinux/genheaders/genheaders FORCE $(call if_changed,flask) From e8d8052c4467cb22aafb0bf658087a9c14fdc4d4 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 19 Jan 2023 15:17:34 -0800 Subject: [PATCH 024/190] drm/rockchip: Drop unbalanced obj unref [ Upstream commit 8ee3b0e85f6ccd9e6c527bc50eaba774c3bb18d0 ] In the error path, rockchip_drm_gem_object_mmap() is dropping an obj reference that it doesn't own. Fixes: 41315b793e13 ("drm/rockchip: use drm_gem_mmap helpers") Signed-off-by: Rob Clark Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20230119231734.2884543-1-robdclark@gmail.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index a8db758d523e..94242fa9e25d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -270,9 +270,6 @@ static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj, else ret = rockchip_drm_gem_object_mmap_dma(obj, vma); - if (ret) - drm_gem_vm_close(vma); - return ret; } From be984c64a2583fae630bc51ae4bca94bff28e255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ADra=20Canal?= Date: Thu, 2 Feb 2023 09:55:17 -0300 Subject: [PATCH 025/190] drm/vgem: add missing mutex_destroy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 7c18189b14b33c1fbf76480b1bd217877c086e67 ] vgem_fence_open() instantiates a mutex for a particular fence instance, but never destroys it by calling mutex_destroy() in vgem_fence_close(). So, add the missing mutex_destroy() to guarantee proper resource destruction. Fixes: 407779848445 ("drm/vgem: Attach sw fences to exported vGEM dma-buf (ioctl)") Signed-off-by: Maíra Canal Reviewed-by: Stanislaw Gruszka Signed-off-by: Maíra Canal Link: https://patchwork.freedesktop.org/patch/msgid/20230202125517.427976-1-mcanal@igalia.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/vgem/vgem_fence.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c index b28876c222b4..04527d8f3623 100644 --- a/drivers/gpu/drm/vgem/vgem_fence.c +++ b/drivers/gpu/drm/vgem/vgem_fence.c @@ -280,4 +280,5 @@ void vgem_fence_close(struct vgem_file *vfile) { idr_for_each(&vfile->fence_idr, __vgem_fence_idr_fini, vfile); idr_destroy(&vfile->fence_idr); + mutex_destroy(&vfile->fence_mutex); } From cb6ee86575385b10db8ef61d24818d6b4ff64020 Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Fri, 27 Jan 2023 16:40:52 +0100 Subject: [PATCH 026/190] drm/probe-helper: Cancel previous job before starting new one [ Upstream commit a8e47884f1906cd7440fafa056adc8817568e73e ] Currently we schedule a call to output_poll_execute from drm_kms_helper_poll_enable for 10s in future. Later we try to replace that in drm_helper_probe_single_connector_modes with a 0s schedule with delayed_event set. But as there is already a job in the queue this fails, and the immediate job we wanted with delayed_event set doesn't occur until 10s later. And that call acts as if connector state has changed, reprobing modes. This has a side effect of waking up a display that has been blanked. Make sure we cancel the old job before submitting the immediate one. Fixes: 162b6a57ac50 ("drm/probe-helper: don't lose hotplug event") Acked-by: Daniel Vetter Signed-off-by: Dom Cobley [Maxime: Switched to mod_delayed_work] Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20230127154052.452524-1-maxime@cerno.tech Signed-off-by: Sasha Levin --- drivers/gpu/drm/drm_probe_helper.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index c0b26135dbd5..f9e0594ee702 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -459,8 +459,9 @@ retry: */ dev->mode_config.delayed_event = true; if (dev->mode_config.poll_enabled) - schedule_delayed_work(&dev->mode_config.output_poll_work, - 0); + mod_delayed_work(system_wq, + &dev->mode_config.output_poll_work, + 0); } /* Re-enable polling in case the global poll config changed. */ From 0a5be4ea8199b91efc3d5000e564a58a9cc62175 Mon Sep 17 00:00:00 2001 From: Qiuxu Zhuo Date: Fri, 16 Nov 2018 15:34:44 +0800 Subject: [PATCH 027/190] EDAC, skx: Move debugfs node under EDAC's hierarchy [ Upstream commit 85b9c8bfee67ed151c44861c71adc816fc1b46a9 ] The debugfs node is /sys/kernel/debug/skx_edac_test. Rename it and move under EDAC debugfs root directory. Remove the unused 'skx_fake_addr' and remove the 'skx_test' on error. Co-developed-by: Tony Luck Signed-off-by: Qiuxu Zhuo Signed-off-by: Borislav Petkov CC: Mauro Carvalho Chehab CC: arozansk@redhat.com CC: linux-edac Link: http://lkml.kernel.org/r/1542353684-13496-1-git-send-email-qiuxu.zhuo@intel.com Stable-dep-of: 71b1e3ba3fed ("EDAC/skx: Fix overflows on the DRAM row address mapping arrays") Signed-off-by: Sasha Levin --- drivers/edac/skx_edac.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/edac/skx_edac.c b/drivers/edac/skx_edac.c index dd209e0dd9ab..b97803580d70 100644 --- a/drivers/edac/skx_edac.c +++ b/drivers/edac/skx_edac.c @@ -896,12 +896,11 @@ static bool skx_decode(struct decoded_addr *res) #ifdef CONFIG_EDAC_DEBUG /* - * Debug feature. Make /sys/kernel/debug/skx_edac_test/addr. - * Write an address to this file to exercise the address decode - * logic in this driver. + * Debug feature. + * Exercise the address decode logic by writing an address to + * /sys/kernel/debug/edac/skx_test/addr. */ static struct dentry *skx_test; -static u64 skx_fake_addr; static int debugfs_u64_set(void *data, u64 val) { @@ -912,19 +911,19 @@ static int debugfs_u64_set(void *data, u64 val) return 0; } - DEFINE_SIMPLE_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n"); -static struct dentry *mydebugfs_create(const char *name, umode_t mode, - struct dentry *parent, u64 *value) -{ - return debugfs_create_file(name, mode, parent, value, &fops_u64_wo); -} - static void setup_skx_debug(void) { - skx_test = debugfs_create_dir("skx_edac_test", NULL); - mydebugfs_create("addr", S_IWUSR, skx_test, &skx_fake_addr); + skx_test = edac_debugfs_create_dir("skx_test"); + if (!skx_test) + return; + + if (!edac_debugfs_create_file("addr", 0200, skx_test, + NULL, &fops_u64_wo)) { + debugfs_remove(skx_test); + skx_test = NULL; + } } static void teardown_skx_debug(void) From 6b0eb6b21d459e243ff0253d6f46a11a3f980841 Mon Sep 17 00:00:00 2001 From: Qiuxu Zhuo Date: Sat, 11 Feb 2023 09:17:28 +0800 Subject: [PATCH 028/190] EDAC/skx: Fix overflows on the DRAM row address mapping arrays [ Upstream commit 71b1e3ba3fed5a34c5fac6d3a15c2634b04c1eb7 ] The current DRAM row address mapping arrays skx_{open,close}_row[] only support ranks with sizes up to 16G. Decoding a rank address to a DRAM row address for a 32G rank by using either one of the above arrays by the skx_edac driver, will result in an overflow on the array. For a 32G rank, the most significant DRAM row address bit (the bit17) is mapped from the bit34 of the rank address. Add this new mapping item to both arrays to fix the overflow issue. Fixes: 4ec656bdf43a ("EDAC, skx_edac: Add EDAC driver for Skylake") Reported-by: Feng Xu Tested-by: Feng Xu Signed-off-by: Qiuxu Zhuo Signed-off-by: Tony Luck Link: https://lore.kernel.org/all/20230211011728.71764-1-qiuxu.zhuo@intel.com Signed-off-by: Sasha Levin --- drivers/edac/skx_edac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/edac/skx_edac.c b/drivers/edac/skx_edac.c index b97803580d70..38a82a3f4516 100644 --- a/drivers/edac/skx_edac.c +++ b/drivers/edac/skx_edac.c @@ -825,13 +825,13 @@ rir_found: } static u8 skx_close_row[] = { - 15, 16, 17, 18, 20, 21, 22, 28, 10, 11, 12, 13, 29, 30, 31, 32, 33 + 15, 16, 17, 18, 20, 21, 22, 28, 10, 11, 12, 13, 29, 30, 31, 32, 33, 34 }; static u8 skx_close_column[] = { 3, 4, 5, 14, 19, 23, 24, 25, 26, 27 }; static u8 skx_open_row[] = { - 14, 15, 16, 20, 28, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33 + 14, 15, 16, 20, 28, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34 }; static u8 skx_open_column[] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 From cf73c672eab6c0af875b7167a507bddd1b0e130e Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Tue, 28 Feb 2023 22:17:51 +0530 Subject: [PATCH 029/190] ARM: dts: qcom: ipq4019: Fix the PCI I/O port range [ Upstream commit 2540279e9a9e74fc880d1e4c83754ecfcbe290a0 ] For 1MiB of the I/O region, the I/O ports of the legacy PCI devices are located in the range of 0x0 to 0x100000. Hence, fix the bogus PCI address (0x40200000) specified in the ranges property for I/O region. While at it, let's use the missing 0x prefix for the addresses. Fixes: 187519403273 ("ARM: dts: ipq4019: Add a few peripheral nodes") Reported-by: Arnd Bergmann Link: https://lore.kernel.org/linux-arm-msm/7c5dfa87-41df-4ba7-b0e4-72c8386402a8@app.fastmail.com/ Signed-off-by: Manivannan Sadhasivam Reviewed-by: Arnd Bergmann Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230228164752.55682-16-manivannan.sadhasivam@linaro.org Signed-off-by: Sasha Levin --- arch/arm/boot/dts/qcom-ipq4019.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi index 59527bb1225a..cb90e7645d08 100644 --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi @@ -387,8 +387,8 @@ #address-cells = <3>; #size-cells = <2>; - ranges = <0x81000000 0 0x40200000 0x40200000 0 0x00100000>, - <0x82000000 0 0x40300000 0x40300000 0 0x00d00000>; + ranges = <0x81000000 0x0 0x00000000 0x40200000 0x0 0x00100000>, + <0x82000000 0x0 0x40300000 0x40300000 0x0 0x00d00000>; interrupts = ; interrupt-names = "msi"; From 2bfbe3ad371ac5349302833198df14e442622cbc Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Wed, 8 Feb 2023 08:14:42 +0100 Subject: [PATCH 030/190] media: bdisp: Add missing check for create_workqueue [ Upstream commit 2371adeab717d8fe32144a84f3491a03c5838cfb ] Add the check for the return value of the create_workqueue in order to avoid NULL pointer dereference. Fixes: 28ffeebbb7bd ("[media] bdisp: 2D blitter driver using v4l2 mem2mem framework") Signed-off-by: Jiasheng Jiang Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 00f6e3f06dac..7a7271f9d875 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -1312,6 +1312,8 @@ static int bdisp_probe(struct platform_device *pdev) init_waitqueue_head(&bdisp->irq_queue); INIT_DELAYED_WORK(&bdisp->timeout_work, bdisp_irq_timeout); bdisp->work_queue = create_workqueue(BDISP_NAME); + if (!bdisp->work_queue) + return -ENOMEM; spin_lock_init(&bdisp->slock); mutex_init(&bdisp->lock); From e179516d012f1de239b4833afebbf14f453bc386 Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Fri, 30 Oct 2020 14:46:08 +0100 Subject: [PATCH 031/190] media: uapi: add MEDIA_BUS_FMT_METADATA_FIXED media bus format. [ Upstream commit 6ad253cc3436269fc6bcff03d704c672f368da0a ] MEDIA_BUS_FMT_METADATA_FIXED should be used when the same driver handles both sides of the link and the bus format is a fixed metadata format that is not configurable from userspace. The width and height will be set to 0 for this format. Signed-off-by: Dafna Hirschfeld Acked-by: Helen Koike Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Stable-dep-of: eed9496a0501 ("media: av7110: prevent underflow in write_ts_to_decoder()") Signed-off-by: Sasha Levin --- .../media/uapi/v4l/subdev-formats.rst | 27 +++++++++++++++++++ include/uapi/linux/media-bus-format.h | 8 ++++++ 2 files changed, 35 insertions(+) diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst index 8e73fcfc6900..cc2ad8af51ea 100644 --- a/Documentation/media/uapi/v4l/subdev-formats.rst +++ b/Documentation/media/uapi/v4l/subdev-formats.rst @@ -7565,3 +7565,30 @@ formats. - 0x5001 - Interleaved raw UYVY and JPEG image format with embedded meta-data used by Samsung S3C73MX camera sensors. + +.. _v4l2-mbus-metadata-fmts: + +Metadata Formats +^^^^^^^^^^^^^^^^ + +This section lists all metadata formats. + +The following table lists the existing metadata formats. + +.. tabularcolumns:: |p{8.0cm}|p{1.4cm}|p{7.7cm}| + +.. flat-table:: Metadata formats + :header-rows: 1 + :stub-columns: 0 + + * - Identifier + - Code + - Comments + * .. _MEDIA-BUS-FMT-METADATA-FIXED: + + - MEDIA_BUS_FMT_METADATA_FIXED + - 0x7001 + - This format should be used when the same driver handles + both sides of the link and the bus format is a fixed + metadata format that is not configurable from userspace. + Width and height will be set to 0 for this format. diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h index d6a5a3bfe6c4..be53a8c1a2df 100644 --- a/include/uapi/linux/media-bus-format.h +++ b/include/uapi/linux/media-bus-format.h @@ -153,4 +153,12 @@ /* HSV - next is 0x6002 */ #define MEDIA_BUS_FMT_AHSV8888_1X32 0x6001 +/* + * This format should be used when the same driver handles + * both sides of the link and the bus format is a fixed + * metadata format that is not configurable from userspace. + * Width and height will be set to 0 for this format. + */ +#define MEDIA_BUS_FMT_METADATA_FIXED 0x7001 + #endif /* __LINUX_MEDIA_BUS_FORMAT_H */ From 6606e2404ee9e20a3ae5b42fc3660d41b739ed3e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 7 Mar 2023 11:00:23 +0100 Subject: [PATCH 032/190] media: av7110: prevent underflow in write_ts_to_decoder() [ Upstream commit eed9496a0501357aa326ddd6b71408189ed872eb ] The buf[4] value comes from the user via ts_play(). It is a value in the u8 range. The final length we pass to av7110_ipack_instant_repack() is "len - (buf[4] + 1) - 4" so add a check to ensure that the length is not negative. It's not clear that passing a negative len value does anything bad necessarily, but it's not best practice. With the new bounds checking the "if (!len)" condition is no longer possible or required so remove that. Fixes: fd46d16d602a ("V4L/DVB (11759): dvb-ttpci: Add TS replay capability") Signed-off-by: Dan Carpenter Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/pci/ttpci/av7110_av.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/pci/ttpci/av7110_av.c b/drivers/media/pci/ttpci/av7110_av.c index ef1bc17cdc4d..03d1d1fba8bc 100644 --- a/drivers/media/pci/ttpci/av7110_av.c +++ b/drivers/media/pci/ttpci/av7110_av.c @@ -836,10 +836,10 @@ static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, s av7110_ipack_flush(ipack); if (buf[3] & ADAPT_FIELD) { + if (buf[4] > len - 1 - 4) + return 0; len -= buf[4] + 1; buf += buf[4] + 1; - if (!len) - return 0; } av7110_ipack_instant_repack(buf + 4, len - 4, ipack); From 944b50c208010d75856d834f31d30ee5335ee164 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Thu, 16 Mar 2023 20:44:26 +0530 Subject: [PATCH 033/190] firmware: qcom_scm: Clear download bit during reboot [ Upstream commit 781d32d1c9709fd25655c4e3e3e15370ae4ae4db ] During normal restart of a system download bit should be cleared irrespective of whether download mode is set or not. Fixes: 8c1b7dc9ba22 ("firmware: qcom: scm: Expose download-mode control") Signed-off-by: Mukesh Ojha Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/1678979666-551-1-git-send-email-quic_mojha@quicinc.com Signed-off-by: Sasha Levin --- drivers/firmware/qcom_scm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 513908a0c262..e795bd9c8038 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -586,8 +586,7 @@ static int qcom_scm_probe(struct platform_device *pdev) static void qcom_scm_shutdown(struct platform_device *pdev) { /* Clean shutdown, disable download mode to allow normal restart */ - if (download_mode) - qcom_scm_set_download_mode(false); + qcom_scm_set_download_mode(false); } static const struct of_device_id qcom_scm_dt_match[] = { From 812e0192a19769623472f0629f338d486e5a92d2 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 13 Jun 2022 11:20:30 -0700 Subject: [PATCH 034/190] drm/msm/adreno: Defer enabling runpm until hw_init() [ Upstream commit 4b18299b33655fa9672b774b6df774dc03d6aee8 ] To avoid preventing the display from coming up before the rootfs is mounted, without resorting to packing fw in the initrd, the GPU has this limbo state where the device is probed, but we aren't ready to start sending commands to it. This is particularly problematic for a6xx, since the GMU (which requires fw to be loaded) is the one that is controlling the power/clk/icc votes. So defer enabling runpm until we are ready to call gpu->hw_init(), as that is a point where we know we have all the needed fw and are ready to start sending commands to the coproc's. Signed-off-by: Rob Clark Patchwork: https://patchwork.freedesktop.org/patch/489337/ Link: https://lore.kernel.org/r/20220613182036.2567963-1-robdclark@gmail.com Stable-dep-of: db7662d076c9 ("drm/msm/adreno: drop bogus pm_runtime_set_active()") Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/adreno_device.c | 6 ++++++ drivers/gpu/drm/msm/adreno/adreno_gpu.c | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 7d3e9a129ac7..0275be7e13b1 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -190,6 +190,12 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) if (ret) return NULL; + /* + * Now that we have firmware loaded, and are ready to begin + * booting the gpu, go ahead and enable runpm: + */ + pm_runtime_enable(&pdev->dev); + /* Make sure pm runtime is active and reset any previous errors */ pm_runtime_set_active(&pdev->dev); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index c9f831604558..6da144c39409 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -725,7 +725,6 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, pm_runtime_set_autosuspend_delay(&pdev->dev, adreno_gpu->info->inactive_period); pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_enable(&pdev->dev); return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, adreno_gpu->info->name, &adreno_gpu_config); From 0b94849431687bada834cbdaf4be2c3be45ba724 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 3 Mar 2023 17:48:06 +0100 Subject: [PATCH 035/190] drm/msm/adreno: drop bogus pm_runtime_set_active() [ Upstream commit db7662d076c973072d788bd0e8130e04430307a1 ] The runtime PM status can only be updated while runtime PM is disabled. Drop the bogus pm_runtime_set_active() call that was made after enabling runtime PM and which (incidentally but correctly) left the runtime PM status set to 'suspended'. Fixes: 2c087a336676 ("drm/msm/adreno: Load the firmware before bringing up the hardware") Signed-off-by: Johan Hovold Patchwork: https://patchwork.freedesktop.org/patch/524972/ Link: https://lore.kernel.org/r/20230303164807.13124-4-johan+linaro@kernel.org Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/adreno_device.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 0275be7e13b1..7acb53a907e5 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -196,9 +196,6 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) */ pm_runtime_enable(&pdev->dev); - /* Make sure pm runtime is active and reset any previous errors */ - pm_runtime_set_active(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) { dev_err(dev->dev, "Couldn't power up the GPU: %d\n", ret); From b940919d8a6fce65e0de1c9303843b08e3768f6e Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 27 Feb 2023 17:09:17 +0100 Subject: [PATCH 036/190] x86/apic: Fix atomic update of offset in reserve_eilvt_offset() [ Upstream commit f96fb2df3eb31ede1b34b0521560967310267750 ] The detection of atomic update failure in reserve_eilvt_offset() is not correct. The value returned by atomic_cmpxchg() should be compared to the old value from the location to be updated. If these two are the same, then atomic update succeeded and "eilvt_offsets[offset]" location is updated to "new" in an atomic way. Otherwise, the atomic update failed and it should be retried with the value from "eilvt_offsets[offset]" - exactly what atomic_try_cmpxchg() does in a correct and more optimal way. Fixes: a68c439b1966c ("apic, x86: Check if EILVT APIC registers are available (AMD only)") Signed-off-by: Uros Bizjak Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20230227160917.107820-1-ubizjak@gmail.com Signed-off-by: Sasha Levin --- arch/x86/kernel/apic/apic.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 926939978c1c..9318fe7d850e 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -403,10 +403,9 @@ static unsigned int reserve_eilvt_offset(int offset, unsigned int new) if (vector && !eilvt_entry_is_changeable(vector, new)) /* may not change if vectors are different */ return rsvd; - rsvd = atomic_cmpxchg(&eilvt_offsets[offset], rsvd, new); - } while (rsvd != new); + } while (!atomic_try_cmpxchg(&eilvt_offsets[offset], &rsvd, new)); - rsvd &= ~APIC_EILVT_MASKED; + rsvd = new & ~APIC_EILVT_MASKED; if (rsvd && rsvd != vector) pr_info("LVT offset %d assigned for vector 0x%02x\n", offset, rsvd); From 722c156c6eab40a6e7dda98dfa66724f9d5aeceb Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Sat, 18 Mar 2023 16:15:06 +0800 Subject: [PATCH 037/190] media: dm1105: Fix use after free bug in dm1105_remove due to race condition [ Upstream commit 5abda7a16698d4d1f47af1168d8fa2c640116b4a ] In dm1105_probe, it called dm1105_ir_init and bound &dm1105->ir.work with dm1105_emit_key. When it handles IRQ request with dm1105_irq, it may call schedule_work to start the work. When we call dm1105_remove to remove the driver, there may be a sequence as follows: Fix it by finishing the work before cleanup in dm1105_remove CPU0 CPU1 |dm1105_emit_key dm1105_remove | dm1105_ir_exit | rc_unregister_device | rc_free_device | rc_dev_release | kfree(dev); | | | rc_keydown | //use Fixes: 34d2f9bf189c ("V4L/DVB: dm1105: use dm1105_dev & dev instead of dm1105dvb") Signed-off-by: Zheng Wang Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin --- drivers/media/pci/dm1105/dm1105.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c index 1ddb0576fb7b..dc3fc69e4480 100644 --- a/drivers/media/pci/dm1105/dm1105.c +++ b/drivers/media/pci/dm1105/dm1105.c @@ -1188,6 +1188,7 @@ static void dm1105_remove(struct pci_dev *pdev) struct dvb_demux *dvbdemux = &dev->demux; struct dmx_demux *dmx = &dvbdemux->dmx; + cancel_work_sync(&dev->ir.work); dm1105_ir_exit(dev); dmx->close(dmx); dvb_net_release(&dev->dvbnet); From 95e684340470a95ff4957cb9a536ec7a0461c75b Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Sat, 18 Mar 2023 16:50:23 +0800 Subject: [PATCH 038/190] media: saa7134: fix use after free bug in saa7134_finidev due to race condition [ Upstream commit 30cf57da176cca80f11df0d9b7f71581fe601389 ] In saa7134_initdev, it will call saa7134_hwinit1. There are three function invoking here: saa7134_video_init1, saa7134_ts_init1 and saa7134_vbi_init1. All of them will init a timer with same function. Take saa7134_video_init1 as an example. It'll bound &dev->video_q.timeout with saa7134_buffer_timeout. In buffer_activate, the timer funtcion is started. If we remove the module or device which will call saa7134_finidev to make cleanup, there may be a unfinished work. The possible sequence is as follows, which will cause a typical UAF bug. Fix it by canceling the timer works accordingly before cleanup in saa7134_finidev. CPU0 CPU1 |saa7134_buffer_timeout saa7134_finidev | kfree(dev); | | | saa7134_buffer_next | //use dev Fixes: 1e7126b4a86a ("media: saa7134: Convert timers to use timer_setup()") Signed-off-by: Zheng Wang Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin --- drivers/media/pci/saa7134/saa7134-ts.c | 1 + drivers/media/pci/saa7134/saa7134-vbi.c | 1 + drivers/media/pci/saa7134/saa7134-video.c | 1 + 3 files changed, 3 insertions(+) diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c index 2be703617e29..e7adcd4f9962 100644 --- a/drivers/media/pci/saa7134/saa7134-ts.c +++ b/drivers/media/pci/saa7134/saa7134-ts.c @@ -309,6 +309,7 @@ int saa7134_ts_start(struct saa7134_dev *dev) int saa7134_ts_fini(struct saa7134_dev *dev) { + del_timer_sync(&dev->ts_q.timeout); saa7134_pgtable_free(dev->pci, &dev->ts_q.pt); return 0; } diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c index 57bea543c39b..559db500b19c 100644 --- a/drivers/media/pci/saa7134/saa7134-vbi.c +++ b/drivers/media/pci/saa7134/saa7134-vbi.c @@ -194,6 +194,7 @@ int saa7134_vbi_init1(struct saa7134_dev *dev) int saa7134_vbi_fini(struct saa7134_dev *dev) { /* nothing */ + del_timer_sync(&dev->vbi_q.timeout); return 0; } diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 079219288af7..90255ecb08ca 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -2213,6 +2213,7 @@ int saa7134_video_init1(struct saa7134_dev *dev) void saa7134_video_fini(struct saa7134_dev *dev) { + del_timer_sync(&dev->video_q.timeout); /* free stuff */ vb2_queue_release(&dev->video_vbq); saa7134_pgtable_free(dev->pci, &dev->video_q.pt); From e7caf2c93e30c80f46cbc2e8506d0352cf474467 Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Thu, 21 Oct 2021 05:09:38 +0200 Subject: [PATCH 039/190] media: rcar_fdp1: Fix the correct variable assignments [ Upstream commit af88c2adbb72a09ab1bb5c37ba388c98fecca69b ] In the function fdp1_probe(), when get irq failed, the function platform_get_irq() log an error message, so remove redundant message here. And the variable type of "ret" is int, the "fdp1->irq" is unsigned int, when irq failed, this place maybe wrong, thus fix it. Signed-off-by: Tang Bin Reviewed-by: Geert Uytterhoeven Reviewed-by: Kieran Bingham Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Stable-dep-of: c766c90faf93 ("media: rcar_fdp1: Fix refcount leak in probe and remove function") Signed-off-by: Sasha Levin --- drivers/media/platform/rcar_fdp1.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index 2bd5898a6204..e1c8701d44ad 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -2287,11 +2287,10 @@ static int fdp1_probe(struct platform_device *pdev) return PTR_ERR(fdp1->regs); /* Interrupt service routine registration */ - fdp1->irq = ret = platform_get_irq(pdev, 0); - if (ret < 0) { - dev_err(&pdev->dev, "cannot find IRQ\n"); + ret = platform_get_irq(pdev, 0); + if (ret < 0) return ret; - } + fdp1->irq = ret; ret = devm_request_irq(&pdev->dev, fdp1->irq, fdp1_irq_handler, 0, dev_name(&pdev->dev), fdp1); From 418a8f3140e07f33bbd5a81625d0ef46c0732cef Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Fri, 6 Jan 2023 11:58:09 +0400 Subject: [PATCH 040/190] media: rcar_fdp1: Fix refcount leak in probe and remove function [ Upstream commit c766c90faf93897b77c9c5daa603cffab85ba907 ] rcar_fcp_get() take reference, which should be balanced with rcar_fcp_put(). Add missing rcar_fcp_put() in fdp1_remove and the error paths of fdp1_probe() to fix this. Fixes: 4710b752e029 ("[media] v4l: Add Renesas R-Car FDP1 Driver") Signed-off-by: Miaoqian Lin Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart [hverkuil: resolve merge conflict, remove() is now void] Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin --- drivers/media/platform/rcar_fdp1.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index e1c8701d44ad..605d8188ac8c 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -2313,8 +2313,10 @@ static int fdp1_probe(struct platform_device *pdev) /* Determine our clock rate */ clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) - return PTR_ERR(clk); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto put_dev; + } fdp1->clk_rate = clk_get_rate(clk); clk_put(clk); @@ -2323,7 +2325,7 @@ static int fdp1_probe(struct platform_device *pdev) ret = v4l2_device_register(&pdev->dev, &fdp1->v4l2_dev); if (ret) { v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n"); - return ret; + goto put_dev; } /* M2M registration */ @@ -2388,6 +2390,8 @@ release_m2m: unreg_dev: v4l2_device_unregister(&fdp1->v4l2_dev); +put_dev: + rcar_fcp_put(fdp1->fcp); return ret; } @@ -2399,6 +2403,7 @@ static int fdp1_remove(struct platform_device *pdev) video_unregister_device(&fdp1->vfd); v4l2_device_unregister(&fdp1->v4l2_dev); pm_runtime_disable(&pdev->dev); + rcar_fcp_put(fdp1->fcp); return 0; } From d69de993237b8f106b408313d01b67a6e5d13f1f Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 24 Mar 2023 13:38:33 -0700 Subject: [PATCH 041/190] media: rc: gpio-ir-recv: Fix support for wake-up [ Upstream commit 9c592f8ab114875fdb3b2040f01818e53de44991 ] The driver was intended from the start to be a wake-up source for the system, however due to the absence of a suitable call to device_set_wakeup_capable(), the device_may_wakeup() call used to decide whether to enable the GPIO interrupt as a wake-up source would never happen. Lookup the DT standard "wakeup-source" property and call device_init_wakeup() to ensure the device is flagged as being wakeup capable. Reported-by: Matthew Lear Fixes: fd0f6851eb46 ("[media] rc: Add support for GPIO based IR Receiver driver") Signed-off-by: Florian Fainelli Signed-off-by: Sean Young Signed-off-by: Hans Verkuil Signed-off-by: Sasha Levin --- drivers/media/rc/gpio-ir-recv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 3d99b51384ac..ed5cfde4d9e7 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -91,6 +91,8 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) rcdev->map_name = RC_MAP_EMPTY; gpio_dev->rcdev = rcdev; + if (of_property_read_bool(np, "wakeup-source")) + device_init_wakeup(dev, true); rc = devm_rc_register_device(dev, rcdev); if (rc < 0) { From 189be0d8b1c6559ef98ed5fd180771dcbe6ef4c6 Mon Sep 17 00:00:00 2001 From: Saurabh Sengar Date: Tue, 28 Mar 2023 00:30:04 -0700 Subject: [PATCH 042/190] x86/ioapic: Don't return 0 from arch_dynirq_lower_bound() [ Upstream commit 5af507bef93c09a94fb8f058213b489178f4cbe5 ] arch_dynirq_lower_bound() is invoked by the core interrupt code to retrieve the lowest possible Linux interrupt number for dynamically allocated interrupts like MSI. The x86 implementation uses this to exclude the IO/APIC GSI space. This works correctly as long as there is an IO/APIC registered, but returns 0 if not. This has been observed in VMs where the BIOS does not advertise an IO/APIC. 0 is an invalid interrupt number except for the legacy timer interrupt on x86. The return value is unchecked in the core code, so it ends up to allocate interrupt number 0 which is subsequently considered to be invalid by the caller, e.g. the MSI allocation code. The function has already a check for 0 in the case that an IO/APIC is registered, as ioapic_dynirq_base is 0 in case of device tree setups. Consolidate this and zero check for both ioapic_dynirq_base and gsi_top, which is used in the case that no IO/APIC is registered. Fixes: 3e5bedc2c258 ("x86/apic: Fix arch_dynirq_lower_bound() bug for DT enabled machines") Signed-off-by: Saurabh Sengar Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/1679988604-20308-1-git-send-email-ssengar@linux.microsoft.com Signed-off-by: Sasha Levin --- arch/x86/kernel/apic/io_apic.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 677508baf95a..af59aa9c5523 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2449,17 +2449,21 @@ static int io_apic_get_redir_entries(int ioapic) unsigned int arch_dynirq_lower_bound(unsigned int from) { + unsigned int ret; + /* * dmar_alloc_hwirq() may be called before setup_IO_APIC(), so use * gsi_top if ioapic_dynirq_base hasn't been initialized yet. */ - if (!ioapic_initialized) - return gsi_top; + ret = ioapic_dynirq_base ? : gsi_top; + /* - * For DT enabled machines ioapic_dynirq_base is irrelevant and not - * updated. So simply return @from if ioapic_dynirq_base == 0. + * For DT enabled machines ioapic_dynirq_base is irrelevant and + * always 0. gsi_top can be 0 if there is no IO/APIC registered. + * 0 is an invalid interrupt number for dynamic allocations. Return + * @from instead. */ - return ioapic_dynirq_base ? : from; + return ret ? : from; } #ifdef CONFIG_X86_32 From e74f7c87b669803fa3d0823281bc7f03a12847fe Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 2 Feb 2023 13:01:48 +0530 Subject: [PATCH 043/190] arm64: kgdb: Set PSTATE.SS to 1 to re-enable single-step [ Upstream commit af6c0bd59f4f3ad5daad2f7b777954b1954551d5 ] Currently only the first attempt to single-step has any effect. After that all further stepping remains "stuck" at the same program counter value. Refer to the ARM Architecture Reference Manual (ARM DDI 0487E.a) D2.12, PSTATE.SS=1 should be set at each step before transferring the PE to the 'Active-not-pending' state. The problem here is PSTATE.SS=1 is not set since the second single-step. After the first single-step, the PE transferes to the 'Inactive' state, with PSTATE.SS=0 and MDSCR.SS=1, thus PSTATE.SS won't be set to 1 due to kernel_active_single_step()=true. Then the PE transferes to the 'Active-pending' state when ERET and returns to the debugger by step exception. Before this patch: ================== Entering kdb (current=0xffff3376039f0000, pid 1) on processor 0 due to Keyboard Entry [0]kdb> [0]kdb> [0]kdb> bp write_sysrq_trigger Instruction(i) BP #0 at 0xffffa45c13d09290 (write_sysrq_trigger) is enabled addr at ffffa45c13d09290, hardtype=0 installed=0 [0]kdb> go $ echo h > /proc/sysrq-trigger Entering kdb (current=0xffff4f7e453f8000, pid 175) on processor 1 due to Breakpoint @ 0xffffad651a309290 [1]kdb> ss Entering kdb (current=0xffff4f7e453f8000, pid 175) on processor 1 due to SS trap @ 0xffffad651a309294 [1]kdb> ss Entering kdb (current=0xffff4f7e453f8000, pid 175) on processor 1 due to SS trap @ 0xffffad651a309294 [1]kdb> After this patch: ================= Entering kdb (current=0xffff6851c39f0000, pid 1) on processor 0 due to Keyboard Entry [0]kdb> bp write_sysrq_trigger Instruction(i) BP #0 at 0xffffc02d2dd09290 (write_sysrq_trigger) is enabled addr at ffffc02d2dd09290, hardtype=0 installed=0 [0]kdb> go $ echo h > /proc/sysrq-trigger Entering kdb (current=0xffff6851c53c1840, pid 174) on processor 1 due to Breakpoint @ 0xffffc02d2dd09290 [1]kdb> ss Entering kdb (current=0xffff6851c53c1840, pid 174) on processor 1 due to SS trap @ 0xffffc02d2dd09294 [1]kdb> ss Entering kdb (current=0xffff6851c53c1840, pid 174) on processor 1 due to SS trap @ 0xffffc02d2dd09298 [1]kdb> ss Entering kdb (current=0xffff6851c53c1840, pid 174) on processor 1 due to SS trap @ 0xffffc02d2dd0929c [1]kdb> Fixes: 44679a4f142b ("arm64: KGDB: Add step debugging support") Co-developed-by: Wei Li Signed-off-by: Wei Li Signed-off-by: Sumit Garg Tested-by: Douglas Anderson Acked-by: Daniel Thompson Tested-by: Daniel Thompson Link: https://lore.kernel.org/r/20230202073148.657746-3-sumit.garg@linaro.org Signed-off-by: Will Deacon Signed-off-by: Sasha Levin --- arch/arm64/include/asm/debug-monitors.h | 1 + arch/arm64/kernel/debug-monitors.c | 5 +++++ arch/arm64/kernel/kgdb.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h index 41b065f1be88..13630e8078ff 100644 --- a/arch/arm64/include/asm/debug-monitors.h +++ b/arch/arm64/include/asm/debug-monitors.h @@ -125,6 +125,7 @@ void user_regs_reset_single_step(struct user_pt_regs *regs, void kernel_enable_single_step(struct pt_regs *regs); void kernel_disable_single_step(void); int kernel_active_single_step(void); +void kernel_rewind_single_step(struct pt_regs *regs); #ifdef CONFIG_HAVE_HW_BREAKPOINT int reinstall_suspended_bps(struct pt_regs *regs); diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index 501e835c6500..f5837937cd93 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -437,6 +437,11 @@ int kernel_active_single_step(void) } NOKPROBE_SYMBOL(kernel_active_single_step); +void kernel_rewind_single_step(struct pt_regs *regs) +{ + set_regs_spsr_ss(regs); +} + /* ptrace API */ void user_enable_single_step(struct task_struct *task) { diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c index 8815b5457dd0..d7847ef10e9d 100644 --- a/arch/arm64/kernel/kgdb.c +++ b/arch/arm64/kernel/kgdb.c @@ -234,6 +234,8 @@ int kgdb_arch_handle_exception(int exception_vector, int signo, */ if (!kernel_active_single_step()) kernel_enable_single_step(linux_regs); + else + kernel_rewind_single_step(linux_regs); err = 0; break; default: From 0c6fcf1425157f1c2b58aadc0be0c3199b4e0913 Mon Sep 17 00:00:00 2001 From: Waiman Long Date: Mon, 20 May 2019 10:14:46 -0400 Subject: [PATCH 044/190] debugobjects: Add percpu free pools [ Upstream commit d86998b17a01050c0232231fa481e65ef8171ca6 ] When a multi-threaded workload does a lot of small memory object allocations and deallocations, it may cause the allocation and freeing of many debug objects. This will make the global pool_lock a bottleneck in the performance of the workload. Since interrupts are disabled when acquiring the pool_lock, it may even cause hard lockups to happen. To reduce contention of the global pool_lock, add a percpu debug object free pool that can be used to buffer some of the debug object allocation and freeing requests without acquiring the pool_lock. Each CPU will now have a percpu free pool that can hold up to a maximum of 64 debug objects. Allocation and freeing requests will go to the percpu free pool first. If that fails, the pool_lock will be taken and the global free pool will be used. The presence or absence of obj_cache is used as a marker to see if the percpu cache should be used. Signed-off-by: Waiman Long Signed-off-by: Thomas Gleixner Cc: Andrew Morton Cc: Yang Shi Cc: "Joel Fernandes (Google)" Cc: Qian Cai Cc: Zhong Jiang Link: https://lkml.kernel.org/r/20190520141450.7575-2-longman@redhat.com Stable-dep-of: 63a759694eed ("debugobject: Prevent init race with static objects") Signed-off-by: Sasha Levin --- lib/debugobjects.c | 115 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 24 deletions(-) diff --git a/lib/debugobjects.c b/lib/debugobjects.c index 14afeeb7d6ef..6e2baf9e9eb2 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -25,6 +25,7 @@ #define ODEBUG_POOL_SIZE 1024 #define ODEBUG_POOL_MIN_LEVEL 256 +#define ODEBUG_POOL_PERCPU_SIZE 64 #define ODEBUG_CHUNK_SHIFT PAGE_SHIFT #define ODEBUG_CHUNK_SIZE (1 << ODEBUG_CHUNK_SHIFT) @@ -35,6 +36,17 @@ struct debug_bucket { raw_spinlock_t lock; }; +/* + * Debug object percpu free list + * Access is protected by disabling irq + */ +struct debug_percpu_free { + struct hlist_head free_objs; + int obj_free; +}; + +static DEFINE_PER_CPU(struct debug_percpu_free, percpu_obj_pool); + static struct debug_bucket obj_hash[ODEBUG_HASH_SIZE]; static struct debug_obj obj_static_pool[ODEBUG_POOL_SIZE] __initdata; @@ -44,13 +56,19 @@ static DEFINE_RAW_SPINLOCK(pool_lock); static HLIST_HEAD(obj_pool); static HLIST_HEAD(obj_to_free); +/* + * Because of the presence of percpu free pools, obj_pool_free will + * under-count those in the percpu free pools. Similarly, obj_pool_used + * will over-count those in the percpu free pools. Adjustments will be + * made at debug_stats_show(). Both obj_pool_min_free and obj_pool_max_used + * can be off. + */ static int obj_pool_min_free = ODEBUG_POOL_SIZE; static int obj_pool_free = ODEBUG_POOL_SIZE; static int obj_pool_used; static int obj_pool_max_used; /* The number of objs on the global free list */ static int obj_nr_tofree; -static struct kmem_cache *obj_cache; static int debug_objects_maxchain __read_mostly; static int __maybe_unused debug_objects_maxchecked __read_mostly; @@ -63,6 +81,7 @@ static int debug_objects_pool_size __read_mostly static int debug_objects_pool_min_level __read_mostly = ODEBUG_POOL_MIN_LEVEL; static struct debug_obj_descr *descr_test __read_mostly; +static struct kmem_cache *obj_cache __read_mostly; /* * Track numbers of kmem_cache_alloc()/free() calls done. @@ -162,6 +181,21 @@ static struct debug_obj *lookup_object(void *addr, struct debug_bucket *b) return NULL; } +/* + * Allocate a new object from the hlist + */ +static struct debug_obj *__alloc_object(struct hlist_head *list) +{ + struct debug_obj *obj = NULL; + + if (list->first) { + obj = hlist_entry(list->first, typeof(*obj), node); + hlist_del(&obj->node); + } + + return obj; +} + /* * Allocate a new object. If the pool is empty, switch off the debugger. * Must be called with interrupts disabled. @@ -169,20 +203,21 @@ static struct debug_obj *lookup_object(void *addr, struct debug_bucket *b) static struct debug_obj * alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr) { - struct debug_obj *obj = NULL; + struct debug_percpu_free *percpu_pool; + struct debug_obj *obj; + + if (likely(obj_cache)) { + percpu_pool = this_cpu_ptr(&percpu_obj_pool); + obj = __alloc_object(&percpu_pool->free_objs); + if (obj) { + percpu_pool->obj_free--; + goto init_obj; + } + } raw_spin_lock(&pool_lock); - if (obj_pool.first) { - obj = hlist_entry(obj_pool.first, typeof(*obj), node); - - obj->object = addr; - obj->descr = descr; - obj->state = ODEBUG_STATE_NONE; - obj->astate = 0; - hlist_del(&obj->node); - - hlist_add_head(&obj->node, &b->list); - + obj = __alloc_object(&obj_pool); + if (obj) { obj_pool_used++; if (obj_pool_used > obj_pool_max_used) obj_pool_max_used = obj_pool_used; @@ -193,6 +228,14 @@ alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr) } raw_spin_unlock(&pool_lock); +init_obj: + if (obj) { + obj->object = addr; + obj->descr = descr; + obj->state = ODEBUG_STATE_NONE; + obj->astate = 0; + hlist_add_head(&obj->node, &b->list); + } return obj; } @@ -247,8 +290,21 @@ static bool __free_object(struct debug_obj *obj) { unsigned long flags; bool work; + struct debug_percpu_free *percpu_pool; - raw_spin_lock_irqsave(&pool_lock, flags); + local_irq_save(flags); + /* + * Try to free it into the percpu pool first. + */ + percpu_pool = this_cpu_ptr(&percpu_obj_pool); + if (obj_cache && percpu_pool->obj_free < ODEBUG_POOL_PERCPU_SIZE) { + hlist_add_head(&obj->node, &percpu_pool->free_objs); + percpu_pool->obj_free++; + local_irq_restore(flags); + return false; + } + + raw_spin_lock(&pool_lock); work = (obj_pool_free > debug_objects_pool_size) && obj_cache; obj_pool_used--; @@ -259,7 +315,8 @@ static bool __free_object(struct debug_obj *obj) obj_pool_free++; hlist_add_head(&obj->node, &obj_pool); } - raw_spin_unlock_irqrestore(&pool_lock, flags); + raw_spin_unlock(&pool_lock); + local_irq_restore(flags); return work; } @@ -822,13 +879,19 @@ void debug_check_no_obj_freed(const void *address, unsigned long size) static int debug_stats_show(struct seq_file *m, void *v) { + int cpu, obj_percpu_free = 0; + + for_each_possible_cpu(cpu) + obj_percpu_free += per_cpu(percpu_obj_pool.obj_free, cpu); + seq_printf(m, "max_chain :%d\n", debug_objects_maxchain); seq_printf(m, "max_checked :%d\n", debug_objects_maxchecked); seq_printf(m, "warnings :%d\n", debug_objects_warnings); seq_printf(m, "fixups :%d\n", debug_objects_fixups); - seq_printf(m, "pool_free :%d\n", obj_pool_free); + seq_printf(m, "pool_free :%d\n", obj_pool_free + obj_percpu_free); + seq_printf(m, "pool_pcp_free :%d\n", obj_percpu_free); seq_printf(m, "pool_min_free :%d\n", obj_pool_min_free); - seq_printf(m, "pool_used :%d\n", obj_pool_used); + seq_printf(m, "pool_used :%d\n", obj_pool_used - obj_percpu_free); seq_printf(m, "pool_max_used :%d\n", obj_pool_max_used); seq_printf(m, "on_free_list :%d\n", obj_nr_tofree); seq_printf(m, "objs_allocated:%d\n", debug_objects_allocated); @@ -1177,9 +1240,20 @@ free: */ void __init debug_objects_mem_init(void) { + int cpu; + if (!debug_objects_enabled) return; + /* + * Initialize the percpu object pools + * + * Initialization is not strictly necessary, but was done for + * completeness. + */ + for_each_possible_cpu(cpu) + INIT_HLIST_HEAD(&per_cpu(percpu_obj_pool.free_objs, cpu)); + obj_cache = kmem_cache_create("debug_objects_cache", sizeof (struct debug_obj), 0, SLAB_DEBUG_OBJECTS | SLAB_NOLEAKTRACE, @@ -1191,11 +1265,4 @@ void __init debug_objects_mem_init(void) pr_warn("out of memory.\n"); } else debug_objects_selftest(); - - /* - * Increase the thresholds for allocating and freeing objects - * according to the number of possible CPUs available in the system. - */ - debug_objects_pool_size += num_possible_cpus() * 32; - debug_objects_pool_min_level += num_possible_cpus() * 4; } From c1b1944cfb81f295af8a8cf41db47c96d6e7fe7b Mon Sep 17 00:00:00 2001 From: Waiman Long Date: Mon, 20 May 2019 10:14:50 -0400 Subject: [PATCH 045/190] debugobjects: Move printk out of db->lock critical sections [ Upstream commit d5f34153e526903abe71869dbbc898bfc0f69373 ] The db->lock is a raw spinlock and so the lock hold time is supposed to be short. This will not be the case when printk() is being involved in some of the critical sections. In order to avoid the long hold time, in case some messages need to be printed, the debug_object_is_on_stack() and debug_print_object() calls are now moved out of those critical sections. Signed-off-by: Waiman Long Signed-off-by: Thomas Gleixner Cc: Andrew Morton Cc: Yang Shi Cc: "Joel Fernandes (Google)" Cc: Qian Cai Cc: Zhong Jiang Link: https://lkml.kernel.org/r/20190520141450.7575-6-longman@redhat.com Stable-dep-of: 63a759694eed ("debugobject: Prevent init race with static objects") Signed-off-by: Sasha Levin --- lib/debugobjects.c | 58 +++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/lib/debugobjects.c b/lib/debugobjects.c index 6e2baf9e9eb2..6909a6e51de8 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -429,6 +429,7 @@ static void __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) { enum debug_obj_state state; + bool check_stack = false; struct debug_bucket *db; struct debug_obj *obj; unsigned long flags; @@ -448,7 +449,7 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) debug_objects_oom(); return; } - debug_object_is_on_stack(addr, onstack); + check_stack = true; } switch (obj->state) { @@ -459,20 +460,23 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) break; case ODEBUG_STATE_ACTIVE: - debug_print_object(obj, "init"); state = obj->state; raw_spin_unlock_irqrestore(&db->lock, flags); + debug_print_object(obj, "init"); debug_object_fixup(descr->fixup_init, addr, state); return; case ODEBUG_STATE_DESTROYED: + raw_spin_unlock_irqrestore(&db->lock, flags); debug_print_object(obj, "init"); - break; + return; default: break; } raw_spin_unlock_irqrestore(&db->lock, flags); + if (check_stack) + debug_object_is_on_stack(addr, onstack); } /** @@ -530,6 +534,8 @@ int debug_object_activate(void *addr, struct debug_obj_descr *descr) obj = lookup_object(addr, db); if (obj) { + bool print_object = false; + switch (obj->state) { case ODEBUG_STATE_INIT: case ODEBUG_STATE_INACTIVE: @@ -538,14 +544,14 @@ int debug_object_activate(void *addr, struct debug_obj_descr *descr) break; case ODEBUG_STATE_ACTIVE: - debug_print_object(obj, "activate"); state = obj->state; raw_spin_unlock_irqrestore(&db->lock, flags); + debug_print_object(obj, "activate"); ret = debug_object_fixup(descr->fixup_activate, addr, state); return ret ? 0 : -EINVAL; case ODEBUG_STATE_DESTROYED: - debug_print_object(obj, "activate"); + print_object = true; ret = -EINVAL; break; default: @@ -553,10 +559,13 @@ int debug_object_activate(void *addr, struct debug_obj_descr *descr) break; } raw_spin_unlock_irqrestore(&db->lock, flags); + if (print_object) + debug_print_object(obj, "activate"); return ret; } raw_spin_unlock_irqrestore(&db->lock, flags); + /* * We are here when a static object is activated. We * let the type specific code confirm whether this is @@ -588,6 +597,7 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr) struct debug_bucket *db; struct debug_obj *obj; unsigned long flags; + bool print_object = false; if (!debug_objects_enabled) return; @@ -605,24 +615,27 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr) if (!obj->astate) obj->state = ODEBUG_STATE_INACTIVE; else - debug_print_object(obj, "deactivate"); + print_object = true; break; case ODEBUG_STATE_DESTROYED: - debug_print_object(obj, "deactivate"); + print_object = true; break; default: break; } - } else { + } + + raw_spin_unlock_irqrestore(&db->lock, flags); + if (!obj) { struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr }; debug_print_object(&o, "deactivate"); + } else if (print_object) { + debug_print_object(obj, "deactivate"); } - - raw_spin_unlock_irqrestore(&db->lock, flags); } EXPORT_SYMBOL_GPL(debug_object_deactivate); @@ -637,6 +650,7 @@ void debug_object_destroy(void *addr, struct debug_obj_descr *descr) struct debug_bucket *db; struct debug_obj *obj; unsigned long flags; + bool print_object = false; if (!debug_objects_enabled) return; @@ -656,20 +670,22 @@ void debug_object_destroy(void *addr, struct debug_obj_descr *descr) obj->state = ODEBUG_STATE_DESTROYED; break; case ODEBUG_STATE_ACTIVE: - debug_print_object(obj, "destroy"); state = obj->state; raw_spin_unlock_irqrestore(&db->lock, flags); + debug_print_object(obj, "destroy"); debug_object_fixup(descr->fixup_destroy, addr, state); return; case ODEBUG_STATE_DESTROYED: - debug_print_object(obj, "destroy"); + print_object = true; break; default: break; } out_unlock: raw_spin_unlock_irqrestore(&db->lock, flags); + if (print_object) + debug_print_object(obj, "destroy"); } EXPORT_SYMBOL_GPL(debug_object_destroy); @@ -698,9 +714,9 @@ void debug_object_free(void *addr, struct debug_obj_descr *descr) switch (obj->state) { case ODEBUG_STATE_ACTIVE: - debug_print_object(obj, "free"); state = obj->state; raw_spin_unlock_irqrestore(&db->lock, flags); + debug_print_object(obj, "free"); debug_object_fixup(descr->fixup_free, addr, state); return; default: @@ -773,6 +789,7 @@ debug_object_active_state(void *addr, struct debug_obj_descr *descr, struct debug_bucket *db; struct debug_obj *obj; unsigned long flags; + bool print_object = false; if (!debug_objects_enabled) return; @@ -788,22 +805,25 @@ debug_object_active_state(void *addr, struct debug_obj_descr *descr, if (obj->astate == expect) obj->astate = next; else - debug_print_object(obj, "active_state"); + print_object = true; break; default: - debug_print_object(obj, "active_state"); + print_object = true; break; } - } else { + } + + raw_spin_unlock_irqrestore(&db->lock, flags); + if (!obj) { struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr }; debug_print_object(&o, "active_state"); + } else if (print_object) { + debug_print_object(obj, "active_state"); } - - raw_spin_unlock_irqrestore(&db->lock, flags); } EXPORT_SYMBOL_GPL(debug_object_active_state); @@ -839,10 +859,10 @@ repeat: switch (obj->state) { case ODEBUG_STATE_ACTIVE: - debug_print_object(obj, "free"); descr = obj->descr; state = obj->state; raw_spin_unlock_irqrestore(&db->lock, flags); + debug_print_object(obj, "free"); debug_object_fixup(descr->fixup_free, (void *) oaddr, state); goto repeat; From 970cc638917029d750c93c1b3728dd6c508b868d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 12 Apr 2023 09:54:39 +0200 Subject: [PATCH 046/190] debugobject: Prevent init race with static objects [ Upstream commit 63a759694eed61025713b3e14dd827c8548daadc ] Statically initialized objects are usually not initialized via the init() function of the subsystem. They are special cased and the subsystem provides a function to validate whether an object which is not yet tracked by debugobjects is statically initialized. This means the object is started to be tracked on first use, e.g. activation. This works perfectly fine, unless there are two concurrent operations on that object. Schspa decoded the problem: T0 T1 debug_object_assert_init(addr) lock_hash_bucket() obj = lookup_object(addr); if (!obj) { unlock_hash_bucket(); - > preemption lock_subsytem_object(addr); activate_object(addr) lock_hash_bucket(); obj = lookup_object(addr); if (!obj) { unlock_hash_bucket(); if (is_static_object(addr)) init_and_track(addr); lock_hash_bucket(); obj = lookup_object(addr); obj->state = ACTIVATED; unlock_hash_bucket(); subsys function modifies content of addr, so static object detection does not longer work. unlock_subsytem_object(addr); if (is_static_object(addr)) <- Fails debugobject emits a warning and invokes the fixup function which reinitializes the already active object in the worst case. This race exists forever, but was never observed until mod_timer() got a debug_object_assert_init() added which is outside of the timer base lock held section right at the beginning of the function to cover the lockless early exit points too. Rework the code so that the lookup, the static object check and the tracking object association happens atomically under the hash bucket lock. This prevents the issue completely as all callers are serialized on the hash bucket lock and therefore cannot observe inconsistent state. Fixes: 3ac7fe5a4aab ("infrastructure to debug (dynamic) objects") Reported-by: syzbot+5093ba19745994288b53@syzkaller.appspotmail.com Debugged-by: Schspa Shi Signed-off-by: Thomas Gleixner Reviewed-by: Stephen Boyd Link: https://syzkaller.appspot.com/bug?id=22c8a5938eab640d1c6bcc0e3dc7be519d878462 Link: https://lore.kernel.org/lkml/20230303161906.831686-1-schspa@gmail.com Link: https://lore.kernel.org/r/87zg7dzgao.ffs@tglx Signed-off-by: Sasha Levin --- lib/debugobjects.c | 125 ++++++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 59 deletions(-) diff --git a/lib/debugobjects.c b/lib/debugobjects.c index 6909a6e51de8..2315a75c45c3 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -196,10 +196,6 @@ static struct debug_obj *__alloc_object(struct hlist_head *list) return obj; } -/* - * Allocate a new object. If the pool is empty, switch off the debugger. - * Must be called with interrupts disabled. - */ static struct debug_obj * alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr) { @@ -425,11 +421,49 @@ static void debug_object_is_on_stack(void *addr, int onstack) WARN_ON(1); } +static struct debug_obj *lookup_object_or_alloc(void *addr, struct debug_bucket *b, + struct debug_obj_descr *descr, + bool onstack, bool alloc_ifstatic) +{ + struct debug_obj *obj = lookup_object(addr, b); + enum debug_obj_state state = ODEBUG_STATE_NONE; + + if (likely(obj)) + return obj; + + /* + * debug_object_init() unconditionally allocates untracked + * objects. It does not matter whether it is a static object or + * not. + * + * debug_object_assert_init() and debug_object_activate() allow + * allocation only if the descriptor callback confirms that the + * object is static and considered initialized. For non-static + * objects the allocation needs to be done from the fixup callback. + */ + if (unlikely(alloc_ifstatic)) { + if (!descr->is_static_object || !descr->is_static_object(addr)) + return ERR_PTR(-ENOENT); + /* Statically allocated objects are considered initialized */ + state = ODEBUG_STATE_INIT; + } + + obj = alloc_object(addr, b, descr); + if (likely(obj)) { + obj->state = state; + debug_object_is_on_stack(addr, onstack); + return obj; + } + + /* Out of memory. Do the cleanup outside of the locked region */ + debug_objects_enabled = 0; + return NULL; +} + static void __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) { enum debug_obj_state state; - bool check_stack = false; struct debug_bucket *db; struct debug_obj *obj; unsigned long flags; @@ -440,16 +474,11 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) raw_spin_lock_irqsave(&db->lock, flags); - obj = lookup_object(addr, db); - if (!obj) { - obj = alloc_object(addr, db, descr); - if (!obj) { - debug_objects_enabled = 0; - raw_spin_unlock_irqrestore(&db->lock, flags); - debug_objects_oom(); - return; - } - check_stack = true; + obj = lookup_object_or_alloc(addr, db, descr, onstack, false); + if (unlikely(!obj)) { + raw_spin_unlock_irqrestore(&db->lock, flags); + debug_objects_oom(); + return; } switch (obj->state) { @@ -475,8 +504,6 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) } raw_spin_unlock_irqrestore(&db->lock, flags); - if (check_stack) - debug_object_is_on_stack(addr, onstack); } /** @@ -516,14 +543,12 @@ EXPORT_SYMBOL_GPL(debug_object_init_on_stack); */ int debug_object_activate(void *addr, struct debug_obj_descr *descr) { + struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr }; enum debug_obj_state state; struct debug_bucket *db; struct debug_obj *obj; unsigned long flags; int ret; - struct debug_obj o = { .object = addr, - .state = ODEBUG_STATE_NOTAVAILABLE, - .descr = descr }; if (!debug_objects_enabled) return 0; @@ -532,8 +557,8 @@ int debug_object_activate(void *addr, struct debug_obj_descr *descr) raw_spin_lock_irqsave(&db->lock, flags); - obj = lookup_object(addr, db); - if (obj) { + obj = lookup_object_or_alloc(addr, db, descr, false, true); + if (likely(!IS_ERR_OR_NULL(obj))) { bool print_object = false; switch (obj->state) { @@ -566,24 +591,16 @@ int debug_object_activate(void *addr, struct debug_obj_descr *descr) raw_spin_unlock_irqrestore(&db->lock, flags); - /* - * We are here when a static object is activated. We - * let the type specific code confirm whether this is - * true or not. if true, we just make sure that the - * static object is tracked in the object tracker. If - * not, this must be a bug, so we try to fix it up. - */ - if (descr->is_static_object && descr->is_static_object(addr)) { - /* track this static object */ - debug_object_init(addr, descr); - debug_object_activate(addr, descr); - } else { - debug_print_object(&o, "activate"); - ret = debug_object_fixup(descr->fixup_activate, addr, - ODEBUG_STATE_NOTAVAILABLE); - return ret ? 0 : -EINVAL; + /* If NULL the allocation has hit OOM */ + if (!obj) { + debug_objects_oom(); + return 0; } - return 0; + + /* Object is neither static nor tracked. It's not initialized */ + debug_print_object(&o, "activate"); + ret = debug_object_fixup(descr->fixup_activate, addr, ODEBUG_STATE_NOTAVAILABLE); + return ret ? 0 : -EINVAL; } EXPORT_SYMBOL_GPL(debug_object_activate); @@ -737,6 +754,7 @@ EXPORT_SYMBOL_GPL(debug_object_free); */ void debug_object_assert_init(void *addr, struct debug_obj_descr *descr) { + struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr }; struct debug_bucket *db; struct debug_obj *obj; unsigned long flags; @@ -747,31 +765,20 @@ void debug_object_assert_init(void *addr, struct debug_obj_descr *descr) db = get_bucket((unsigned long) addr); raw_spin_lock_irqsave(&db->lock, flags); + obj = lookup_object_or_alloc(addr, db, descr, false, true); + raw_spin_unlock_irqrestore(&db->lock, flags); + if (likely(!IS_ERR_OR_NULL(obj))) + return; - obj = lookup_object(addr, db); + /* If NULL the allocation has hit OOM */ if (!obj) { - struct debug_obj o = { .object = addr, - .state = ODEBUG_STATE_NOTAVAILABLE, - .descr = descr }; - - raw_spin_unlock_irqrestore(&db->lock, flags); - /* - * Maybe the object is static, and we let the type specific - * code confirm. Track this static object if true, else invoke - * fixup. - */ - if (descr->is_static_object && descr->is_static_object(addr)) { - /* Track this static object */ - debug_object_init(addr, descr); - } else { - debug_print_object(&o, "assert_init"); - debug_object_fixup(descr->fixup_assert_init, addr, - ODEBUG_STATE_NOTAVAILABLE); - } + debug_objects_oom(); return; } - raw_spin_unlock_irqrestore(&db->lock, flags); + /* Object is neither tracked nor static. It's not initialized. */ + debug_print_object(&o, "assert_init"); + debug_object_fixup(descr->fixup_assert_init, addr, ODEBUG_STATE_NOTAVAILABLE); } EXPORT_SYMBOL_GPL(debug_object_assert_init); From 630e06968029edf274b03fc85ce295ad6246a9d2 Mon Sep 17 00:00:00 2001 From: "Alexey V. Vissarionov" Date: Wed, 15 Feb 2023 20:31:37 +0200 Subject: [PATCH 047/190] wifi: ath6kl: minor fix for allocation size [ Upstream commit 778f83f889e7fca37780d9640fcbd0229ae38eaa ] Although the "param" pointer occupies more or equal space compared to "*param", the allocation size should use the size of variable itself. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: bdcd81707973cf8a ("Add ath6kl cleaned up driver") Signed-off-by: Alexey V. Vissarionov Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230117110414.GC12547@altlinux.org Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath6kl/bmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c index bde5a10d470c..af98e871199d 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/drivers/net/wireless/ath/ath6kl/bmi.c @@ -246,7 +246,7 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param) return -EACCES; } - size = sizeof(cid) + sizeof(addr) + sizeof(param); + size = sizeof(cid) + sizeof(addr) + sizeof(*param); if (size > ar->bmi.max_cmd_size) { WARN_ON(1); return -EINVAL; From 6719e3797ec52cd144c8a5ba8aaab36674800585 Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Thu, 16 Feb 2023 22:23:01 +0300 Subject: [PATCH 048/190] wifi: ath9k: hif_usb: fix memory leak of remain_skbs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 7654cc03eb699297130b693ec34e25f77b17c947 ] hif_dev->remain_skb is allocated and used exclusively in ath9k_hif_usb_rx_stream(). It is implied that an allocated remain_skb is processed and subsequently freed (in error paths) only during the next call of ath9k_hif_usb_rx_stream(). So, if the urbs are deallocated between those two calls due to the device deinitialization or suspend, it is possible that ath9k_hif_usb_rx_stream() is not called next time and the allocated remain_skb is leaked. Our local Syzkaller instance was able to trigger that. remain_skb makes sense when receiving two consecutive urbs which are logically linked together, i.e. a specific data field from the first skb indicates a cached skb to be allocated, memcpy'd with some data and subsequently processed in the next call to ath9k_hif_usb_rx_stream(). Urbs deallocation supposedly makes that link irrelevant so we need to free the cached skb in those cases. Fix the leak by introducing a function to explicitly free remain_skb (if it is not NULL) when the rx urbs have been deallocated. remain_skb is NULL when it has not been allocated at all (hif_dev struct is kzalloced) or when it has been processed in next call to ath9k_hif_usb_rx_stream(). Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.") Signed-off-by: Fedor Pchelkin Signed-off-by: Alexey Khoroshilov Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230216192301.171225-1-pchelkin@ispras.ru Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath9k/hif_usb.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index e23d58f83dd6..3aa915d21554 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -534,6 +534,24 @@ static struct ath9k_htc_hif hif_usb = { .send = hif_usb_send, }; +/* Need to free remain_skb allocated in ath9k_hif_usb_rx_stream + * in case ath9k_hif_usb_rx_stream wasn't called next time to + * process the buffer and subsequently free it. + */ +static void ath9k_hif_usb_free_rx_remain_skb(struct hif_device_usb *hif_dev) +{ + unsigned long flags; + + spin_lock_irqsave(&hif_dev->rx_lock, flags); + if (hif_dev->remain_skb) { + dev_kfree_skb_any(hif_dev->remain_skb); + hif_dev->remain_skb = NULL; + hif_dev->rx_remain_len = 0; + RX_STAT_INC(hif_dev, skb_dropped); + } + spin_unlock_irqrestore(&hif_dev->rx_lock, flags); +} + static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, struct sk_buff *skb) { @@ -868,6 +886,7 @@ err: static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev) { usb_kill_anchored_urbs(&hif_dev->rx_submitted); + ath9k_hif_usb_free_rx_remain_skb(hif_dev); } static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) From dbb0157978eaa4ede28afe3cb848113911bc46d4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 6 Feb 2023 16:15:48 +0300 Subject: [PATCH 049/190] wifi: ath5k: fix an off by one check in ath5k_eeprom_read_freq_list() [ Upstream commit 4c856ee12df85aabd437c3836ed9f68d94268358 ] This loop checks that i < max at the start of loop but then it does i++ which could put it past the end of the array. It's harmless to check again and prevent a potential out of bounds. Fixes: 1048643ea94d ("ath5k: Clean up eeprom parsing and add missing calibration data") Signed-off-by: Dan Carpenter Reviewed-by: Luis Chamberlain Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/Y+D9hPQrHfWBJhXz@kili Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath5k/eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 01163b333945..92f5c8e83090 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -529,7 +529,7 @@ ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, ee->ee_n_piers[mode]++; freq2 = (val >> 8) & 0xff; - if (!freq2) + if (!freq2 || i >= max) break; pc[i++].freq = ath5k_eeprom_bin2freq(ee, From e7865f84adaf75cee1a4bbf79680329eca92b4e1 Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Fri, 24 Feb 2023 12:28:05 +0200 Subject: [PATCH 050/190] wifi: ath6kl: reduce WARN to dev_dbg() in callback [ Upstream commit 75c4a8154cb6c7239fb55d5550f481f6765fb83c ] The warn is triggered on a known race condition, documented in the code above the test, that is correctly handled. Using WARN() hinders automated testing. Reducing severity. Fixes: de2070fc4aa7 ("ath6kl: Fix kernel panic on continuous driver load/unload") Reported-and-tested-by: syzbot+555908813b2ea35dae9a@syzkaller.appspotmail.com Signed-off-by: Oliver Neukum Signed-off-by: Fedor Pchelkin Signed-off-by: Alexey Khoroshilov Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230126182431.867984-1-pchelkin@ispras.ru Signed-off-by: Sasha Levin --- drivers/net/wireless/ath/ath6kl/htc_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c index 434b66829646..73bf4af1f3c7 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c @@ -963,8 +963,8 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb, * Thus the possibility of ar->htc_target being NULL * via ath6kl_recv_complete -> ath6kl_usb_io_comp_work. */ - if (WARN_ON_ONCE(!target)) { - ath6kl_err("Target not yet initialized\n"); + if (!target) { + ath6kl_dbg(ATH6KL_DBG_HTC, "Target not yet initialized\n"); status = -EINVAL; goto free_skb; } From 0674dc8ef90b0180b89e81b90c201aad0ecb46d7 Mon Sep 17 00:00:00 2001 From: Luis Gerhorst Date: Mon, 27 Feb 2023 16:08:54 +0100 Subject: [PATCH 051/190] tools: bpftool: Remove invalid \' json escape [ Upstream commit c679bbd611c08b0559ffae079330bc4e5574696a ] RFC8259 ("The JavaScript Object Notation (JSON) Data Interchange Format") only specifies \", \\, \/, \b, \f, \n, \r, and \r as valid two-character escape sequences. This does not include \', which is not required in JSON because it exclusively uses double quotes as string separators. Solidus (/) may be escaped, but does not have to. Only reverse solidus (\), double quotes ("), and the control characters have to be escaped. Therefore, with this fix, bpftool correctly supports all valid two-character escape sequences (but still does not support characters that require multi-character escape sequences). Witout this fix, attempting to load a JSON file generated by bpftool using Python 3.10.6's default json.load() may fail with the error "Invalid \escape" if the file contains the invalid escaped single quote (\'). Fixes: b66e907cfee2 ("tools: bpftool: copy JSON writer from iproute2 repository") Signed-off-by: Luis Gerhorst Signed-off-by: Andrii Nakryiko Reviewed-by: Quentin Monnet Link: https://lore.kernel.org/bpf/20230227150853.16863-1-gerhorst@cs.fau.de Signed-off-by: Sasha Levin --- tools/bpf/bpftool/json_writer.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/bpf/bpftool/json_writer.c b/tools/bpf/bpftool/json_writer.c index c6eef76322ae..0c38c41269be 100644 --- a/tools/bpf/bpftool/json_writer.c +++ b/tools/bpf/bpftool/json_writer.c @@ -84,9 +84,6 @@ static void jsonw_puts(json_writer_t *self, const char *str) case '"': fputs("\\\"", self->out); break; - case '\'': - fputs("\\\'", self->out); - break; default: putc(*str, self->out); } From 39470f8de0868e58092883d06ee85da6577e2167 Mon Sep 17 00:00:00 2001 From: Alexander Mikhalitsyn Date: Mon, 13 Mar 2023 12:32:11 +0100 Subject: [PATCH 052/190] scm: fix MSG_CTRUNC setting condition for SO_PASSSEC [ Upstream commit a02d83f9947d8f71904eda4de046630c3eb6802c ] Currently, kernel would set MSG_CTRUNC flag if msg_control buffer wasn't provided and SO_PASSCRED was set or if there was pending SCM_RIGHTS. For some reason we have no corresponding check for SO_PASSSEC. In the recvmsg(2) doc we have: MSG_CTRUNC indicates that some control data was discarded due to lack of space in the buffer for ancillary data. So, we need to set MSG_CTRUNC flag for all types of SCM. This change can break applications those don't check MSG_CTRUNC flag. Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Leon Romanovsky Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Alexander Mikhalitsyn v2: - commit message was rewritten according to Eric's suggestion Acked-by: Paul Moore Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/net/scm.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/include/net/scm.h b/include/net/scm.h index 1ce365f4c256..585adc1346bd 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -105,16 +105,27 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc } } } + +static inline bool scm_has_secdata(struct socket *sock) +{ + return test_bit(SOCK_PASSSEC, &sock->flags); +} #else static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { } + +static inline bool scm_has_secdata(struct socket *sock) +{ + return false; +} #endif /* CONFIG_SECURITY_NETWORK */ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm, int flags) { if (!msg->msg_control) { - if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp) + if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp || + scm_has_secdata(sock)) msg->msg_flags |= MSG_CTRUNC; scm_destroy(scm); return; From e0fc29181d49784ed6fd2a559d5e6acadd3659d2 Mon Sep 17 00:00:00 2001 From: Vadim Fedorenko Date: Wed, 15 Mar 2023 08:33:02 -0700 Subject: [PATCH 053/190] vlan: partially enable SIOCSHWTSTAMP in container [ Upstream commit 731b73dba359e3ff00517c13aa0daa82b34ff466 ] Setting timestamp filter was explicitly disabled on vlan devices in containers because it might affect other processes on the host. But it's absolutely legit in case when real device is in the same namespace. Fixes: 873017af7784 ("vlan: disable SIOCSHWTSTAMP in container") Signed-off-by: Vadim Fedorenko Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/8021q/vlan_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 84ef83772114..c80add6edf59 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -369,7 +369,7 @@ static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch (cmd) { case SIOCSHWTSTAMP: - if (!net_eq(dev_net(dev), &init_net)) + if (!net_eq(dev_net(dev), dev_net(real_dev))) break; case SIOCGMIIPHY: case SIOCGMIIREG: From 36a320c3e2fe960eb5eb56ee31c2a07f55d4000a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 16 Mar 2023 01:10:07 +0000 Subject: [PATCH 054/190] net/packet: convert po->origdev to an atomic flag [ Upstream commit ee5675ecdf7a4e713ed21d98a70c2871d6ebed01 ] syzbot/KCAN reported that po->origdev can be read while another thread is changing its value. We can avoid this splat by converting this field to an actual bit. Following patches will convert remaining 1bit fields. Fixes: 80feaacb8a64 ("[AF_PACKET]: Add option to return orig_dev to userspace.") Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/packet/af_packet.c | 10 ++++------ net/packet/diag.c | 2 +- net/packet/internal.h | 22 +++++++++++++++++++++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 6fa0a9a453a8..91c35d45e43c 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2105,7 +2105,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, sll = &PACKET_SKB_CB(skb)->sa.ll; sll->sll_hatype = dev->type; sll->sll_pkttype = skb->pkt_type; - if (unlikely(po->origdev)) + if (unlikely(packet_sock_flag(po, PACKET_SOCK_ORIGDEV))) sll->sll_ifindex = orig_dev->ifindex; else sll->sll_ifindex = dev->ifindex; @@ -2371,7 +2371,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, sll->sll_hatype = dev->type; sll->sll_protocol = skb->protocol; sll->sll_pkttype = skb->pkt_type; - if (unlikely(po->origdev)) + if (unlikely(packet_sock_flag(po, PACKET_SOCK_ORIGDEV))) sll->sll_ifindex = orig_dev->ifindex; else sll->sll_ifindex = dev->ifindex; @@ -3841,9 +3841,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv if (copy_from_user(&val, optval, sizeof(val))) return -EFAULT; - lock_sock(sk); - po->origdev = !!val; - release_sock(sk); + packet_sock_flag_set(po, PACKET_SOCK_ORIGDEV, val); return 0; } case PACKET_VNET_HDR: @@ -3976,7 +3974,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, val = po->auxdata; break; case PACKET_ORIGDEV: - val = po->origdev; + val = packet_sock_flag(po, PACKET_SOCK_ORIGDEV); break; case PACKET_VNET_HDR: val = po->has_vnet_hdr; diff --git a/net/packet/diag.c b/net/packet/diag.c index 7ef1c881ae74..bf5928e5df03 100644 --- a/net/packet/diag.c +++ b/net/packet/diag.c @@ -24,7 +24,7 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb) pinfo.pdi_flags |= PDI_RUNNING; if (po->auxdata) pinfo.pdi_flags |= PDI_AUXDATA; - if (po->origdev) + if (packet_sock_flag(po, PACKET_SOCK_ORIGDEV)) pinfo.pdi_flags |= PDI_ORIGDEV; if (po->has_vnet_hdr) pinfo.pdi_flags |= PDI_VNETHDR; diff --git a/net/packet/internal.h b/net/packet/internal.h index f10294800aaf..f39dcc7608bc 100644 --- a/net/packet/internal.h +++ b/net/packet/internal.h @@ -115,9 +115,9 @@ struct packet_sock { int copy_thresh; spinlock_t bind_lock; struct mutex pg_vec_lock; + unsigned long flags; unsigned int running; /* bind_lock must be held */ unsigned int auxdata:1, /* writer must hold sock lock */ - origdev:1, has_vnet_hdr:1, tp_loss:1, tp_tx_has_off:1; @@ -142,4 +142,24 @@ static struct packet_sock *pkt_sk(struct sock *sk) return (struct packet_sock *)sk; } +enum packet_sock_flags { + PACKET_SOCK_ORIGDEV, +}; + +static inline void packet_sock_flag_set(struct packet_sock *po, + enum packet_sock_flags flag, + bool val) +{ + if (val) + set_bit(flag, &po->flags); + else + clear_bit(flag, &po->flags); +} + +static inline bool packet_sock_flag(const struct packet_sock *po, + enum packet_sock_flags flag) +{ + return test_bit(flag, &po->flags); +} + #endif From e70e38104e5ecd6717f46f054592ba2683c5c7c3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 16 Mar 2023 01:10:08 +0000 Subject: [PATCH 055/190] net/packet: convert po->auxdata to an atomic flag [ Upstream commit fd53c297aa7b077ae98a3d3d2d3aa278a1686ba6 ] po->auxdata can be read while another thread is changing its value, potentially raising KCSAN splat. Convert it to PACKET_SOCK_AUXDATA flag. Fixes: 8dc419447415 ("[PACKET]: Add optional checksum computation for recvmsg") Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/packet/af_packet.c | 8 +++----- net/packet/diag.c | 2 +- net/packet/internal.h | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 91c35d45e43c..60986c209311 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -3444,7 +3444,7 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, copy_len); } - if (pkt_sk(sk)->auxdata) { + if (packet_sock_flag(pkt_sk(sk), PACKET_SOCK_AUXDATA)) { struct tpacket_auxdata aux; aux.tp_status = TP_STATUS_USER; @@ -3827,9 +3827,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv if (copy_from_user(&val, optval, sizeof(val))) return -EFAULT; - lock_sock(sk); - po->auxdata = !!val; - release_sock(sk); + packet_sock_flag_set(po, PACKET_SOCK_AUXDATA, val); return 0; } case PACKET_ORIGDEV: @@ -3971,7 +3969,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, break; case PACKET_AUXDATA: - val = po->auxdata; + val = packet_sock_flag(po, PACKET_SOCK_AUXDATA); break; case PACKET_ORIGDEV: val = packet_sock_flag(po, PACKET_SOCK_ORIGDEV); diff --git a/net/packet/diag.c b/net/packet/diag.c index bf5928e5df03..d9f912ad23df 100644 --- a/net/packet/diag.c +++ b/net/packet/diag.c @@ -22,7 +22,7 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb) pinfo.pdi_flags = 0; if (po->running) pinfo.pdi_flags |= PDI_RUNNING; - if (po->auxdata) + if (packet_sock_flag(po, PACKET_SOCK_AUXDATA)) pinfo.pdi_flags |= PDI_AUXDATA; if (packet_sock_flag(po, PACKET_SOCK_ORIGDEV)) pinfo.pdi_flags |= PDI_ORIGDEV; diff --git a/net/packet/internal.h b/net/packet/internal.h index f39dcc7608bc..3d871cae85b8 100644 --- a/net/packet/internal.h +++ b/net/packet/internal.h @@ -117,8 +117,7 @@ struct packet_sock { struct mutex pg_vec_lock; unsigned long flags; unsigned int running; /* bind_lock must be held */ - unsigned int auxdata:1, /* writer must hold sock lock */ - has_vnet_hdr:1, + unsigned int has_vnet_hdr:1, /* writer must hold sock lock */ tp_loss:1, tp_tx_has_off:1; int pressure; @@ -144,6 +143,7 @@ static struct packet_sock *pkt_sk(struct sock *sk) enum packet_sock_flags { PACKET_SOCK_ORIGDEV, + PACKET_SOCK_AUXDATA, }; static inline void packet_sock_flag_set(struct packet_sock *po, From d62b7d1cb403d0e482ee7626958852dbba909899 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 18 Mar 2023 20:56:19 -0500 Subject: [PATCH 056/190] scsi: target: iscsit: Fix TAS handling during conn cleanup [ Upstream commit cc79da306ebb2edb700c3816b90219223182ac3c ] Fix a bug added in commit f36199355c64 ("scsi: target: iscsi: Fix cmd abort fabric stop race"). If CMD_T_TAS is set on the se_cmd we must call iscsit_free_cmd() to do the last put on the cmd and free it, because the connection is down and we will not up sending the response and doing the put from the normal I/O path. Add a check for CMD_T_TAS in iscsit_release_commands_from_conn() so we now detect this case and run iscsit_free_cmd(). Fixes: f36199355c64 ("scsi: target: iscsi: Fix cmd abort fabric stop race") Signed-off-by: Mike Christie Link: https://lore.kernel.org/r/20230319015620.96006-9-michael.christie@oracle.com Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/target/iscsi/iscsi_target.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 58ccded1be85..7738e249c4a2 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -4056,9 +4056,12 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) { struct se_cmd *se_cmd = &cmd->se_cmd; - if (se_cmd->se_tfo != NULL) { - spin_lock_irq(&se_cmd->t_state_lock); - if (se_cmd->transport_state & CMD_T_ABORTED) { + if (!se_cmd->se_tfo) + continue; + + spin_lock_irq(&se_cmd->t_state_lock); + if (se_cmd->transport_state & CMD_T_ABORTED) { + if (!(se_cmd->transport_state & CMD_T_TAS)) /* * LIO's abort path owns the cleanup for this, * so put it back on the list and let @@ -4066,11 +4069,10 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) */ list_move_tail(&cmd->i_conn_node, &conn->conn_cmd_list); - } else { - se_cmd->transport_state |= CMD_T_FABRIC_STOP; - } - spin_unlock_irq(&se_cmd->t_state_lock); + } else { + se_cmd->transport_state |= CMD_T_FABRIC_STOP; } + spin_unlock_irq(&se_cmd->t_state_lock); } spin_unlock_bh(&conn->cmd_lock); From ce8c40a493937db8f358ec02cc54227eb1e02a67 Mon Sep 17 00:00:00 2001 From: Danila Chernetsov Date: Fri, 17 Mar 2023 17:51:09 +0000 Subject: [PATCH 057/190] scsi: megaraid: Fix mega_cmd_done() CMDID_INT_CMDS [ Upstream commit 75cb113cd43f06aaf4f1bda0069cfd5b98e909eb ] When cmdid == CMDID_INT_CMDS, the 'cmds' pointer is NULL but is dereferenced below. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 0f2bb84d2a68 ("[SCSI] megaraid: simplify internal command handling") Signed-off-by: Danila Chernetsov Link: https://lore.kernel.org/r/20230317175109.18585-1-listdansp@mail.ru Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/megaraid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 7352d46ebb09..44d648baabd8 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -1444,6 +1444,7 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status) */ if (cmdid == CMDID_INT_CMDS) { scb = &adapter->int_scb; + cmd = scb->cmd; list_del_init(&scb->list); scb->state = SCB_FREE; From c19fe3816ea3de9dcf1b702dbb2684d8ea47b21a Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 26 Aug 2019 17:03:44 -0500 Subject: [PATCH 058/190] rtlwifi: rtl_pci: Fix memory leak when hardware init fails [ Upstream commit 8cc782cd997dc4eb3ac183228d563727884ba874 ] If the call to hw_init() fails for any of the drivers, the driver will leak memory that was allocated in BT coexistence setup. Technically, each of the drivers should have done this free; however placing it in rtl_pci fixes all the drivers with only a single patch. Signed-off-by: Larry Finger Signed-off-by: Kalle Valo Stable-dep-of: 905a9241e4e8 ("wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_rfreg()") Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtlwifi/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c index 83749578fa8b..8bda1104bda8 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.c +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -1817,6 +1817,8 @@ static int rtl_pci_start(struct ieee80211_hw *hw) if (err) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Failed to config hardware!\n"); + kfree(rtlpriv->btcoexist.btc_context); + kfree(rtlpriv->btcoexist.wifi_only_context); return err; } rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, From bea9dde0b19844199d3be95c9d6d266f5782db1c Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 23 Jul 2020 15:42:30 -0500 Subject: [PATCH 059/190] rtlwifi: Start changing RT_TRACE into rtl_dbg [ Upstream commit 78a7245d84300cd616dbce26e6fc42a039a62279 ] The macro name RT_TRACE makes it seem that it is used for tracing, when is actually used for debugging. Change the name to RT_DEBUG. This step creates the new macro while keeping the old RT_TRACE to allow building. It will be removed at the end of the patch series. Signed-off-by: Larry Finger Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200723204244.24457-2-Larry.Finger@lwfinger.net Stable-dep-of: 905a9241e4e8 ("wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_rfreg()") Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtlwifi/debug.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.h b/drivers/net/wireless/realtek/rtlwifi/debug.h index ad6834af618b..14f822afc89a 100644 --- a/drivers/net/wireless/realtek/rtlwifi/debug.h +++ b/drivers/net/wireless/realtek/rtlwifi/debug.h @@ -181,6 +181,10 @@ void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level, const char *titlestring, const void *hexdata, int hexdatalen); +#define rtl_dbg(rtlpriv, comp, level, fmt, ...) \ + _rtl_dbg_trace(rtlpriv, comp, level, \ + fmt, ##__VA_ARGS__) + #define RT_TRACE(rtlpriv, comp, level, fmt, ...) \ _rtl_dbg_trace(rtlpriv, comp, level, \ fmt, ##__VA_ARGS__) @@ -197,6 +201,13 @@ void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level, struct rtl_priv; +__printf(4, 5) +static inline void rtl_dbg(struct rtl_priv *rtlpriv, + u64 comp, int level, + const char *fmt, ...) +{ +} + __printf(4, 5) static inline void RT_TRACE(struct rtl_priv *rtlpriv, u64 comp, int level, From f5331b69602bf72a2b12874cb9f3172cf98f83c5 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 23 Jul 2020 15:42:31 -0500 Subject: [PATCH 060/190] rtlwifi: Replace RT_TRACE with rtl_dbg [ Upstream commit f108a420e50a62e0bc5cdcd7d4a2440986b526e3 ] The macro name RT_TRACE makes it seem that it is used for tracing, when is actually used for debugging. Change the name to rtl_dbg. Any Sparse errors exposed by this change were also fixed. Signed-off-by: Larry Finger Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20200723204244.24457-3-Larry.Finger@lwfinger.net Stable-dep-of: 905a9241e4e8 ("wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_rfreg()") Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtlwifi/base.c | 144 +++++----- drivers/net/wireless/realtek/rtlwifi/cam.c | 82 +++--- drivers/net/wireless/realtek/rtlwifi/core.c | 259 ++++++++--------- drivers/net/wireless/realtek/rtlwifi/debug.c | 4 +- drivers/net/wireless/realtek/rtlwifi/efuse.c | 72 ++--- drivers/net/wireless/realtek/rtlwifi/pci.c | 282 +++++++++---------- drivers/net/wireless/realtek/rtlwifi/ps.c | 98 +++---- drivers/net/wireless/realtek/rtlwifi/regd.c | 18 +- drivers/net/wireless/realtek/rtlwifi/usb.c | 18 +- 9 files changed, 488 insertions(+), 489 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index 6d1b6a4a8150..7644d7cbcb5a 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -217,8 +217,8 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, } else { if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "1T2R or 2T2R\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "1T2R or 2T2R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0xFF; ht_cap->mcs.rx_mask[4] = 0x01; @@ -226,7 +226,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); } else if (get_rf_type(rtlphy) == RF_1T1R) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0x00; @@ -1344,7 +1344,7 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) rtlpriv->cfg->ops->chk_switch_dmdp(hw); } if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); mac->link_state = MAC80211_LINKING; /* Dul mac */ @@ -1405,7 +1405,7 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) if (mac->act_scanning) return false; - RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, "%s ACT_ADDBAREQ From :%pM\n", is_tx ? "Tx" : "Rx", hdr->addr2); RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "req\n", @@ -1420,8 +1420,8 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) rcu_read_lock(); sta = rtl_find_sta(hw, hdr->addr3); if (sta == NULL) { - RT_TRACE(rtlpriv, COMP_SEND | COMP_RECV, - DBG_DMESG, "sta is NULL\n"); + rtl_dbg(rtlpriv, COMP_SEND | COMP_RECV, + DBG_DMESG, "sta is NULL\n"); rcu_read_unlock(); return true; } @@ -1448,13 +1448,13 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) } break; case ACT_ADDBARSP: - RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - "%s ACT_ADDBARSP From :%pM\n", - is_tx ? "Tx" : "Rx", hdr->addr2); + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + "%s ACT_ADDBARSP From :%pM\n", + is_tx ? "Tx" : "Rx", hdr->addr2); break; case ACT_DELBA: - RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - "ACT_ADDBADEL From :%pM\n", hdr->addr2); + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + "ACT_ADDBADEL From :%pM\n", hdr->addr2); break; } break; @@ -1539,9 +1539,9 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx, /* 68 : UDP BOOTP client * 67 : UDP BOOTP server */ - RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), - DBG_DMESG, "dhcp %s !!\n", - (is_tx) ? "Tx" : "Rx"); + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), + DBG_DMESG, "dhcp %s !!\n", + (is_tx) ? "Tx" : "Rx"); if (is_tx) setup_special_tx(rtlpriv, ppsc, @@ -1560,8 +1560,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx, rtlpriv->btcoexist.btc_info.in_4way = true; rtlpriv->btcoexist.btc_info.in_4way_ts = jiffies; - RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - "802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"); + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + "802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"); if (is_tx) { rtlpriv->ra.is_special_data = true; @@ -1603,12 +1603,12 @@ static void rtl_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, info = IEEE80211_SKB_CB(skb); ieee80211_tx_info_clear_status(info); if (ack) { - RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_LOUD, - "tx report: ack\n"); + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_LOUD, + "tx report: ack\n"); info->flags |= IEEE80211_TX_STAT_ACK; } else { - RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_LOUD, - "tx report: not ack\n"); + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_LOUD, + "tx report: not ack\n"); info->flags &= ~IEEE80211_TX_STAT_ACK; } ieee80211_tx_status_irqsafe(hw, skb); @@ -1646,8 +1646,8 @@ static u16 rtl_get_tx_report_sn(struct ieee80211_hw *hw, tx_report->last_sent_time = jiffies; tx_info->sn = sn; tx_info->send_time = tx_report->last_sent_time; - RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_DMESG, - "Send TX-Report sn=0x%X\n", sn); + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_DMESG, + "Send TX-Report sn=0x%X\n", sn); return sn; } @@ -1694,9 +1694,9 @@ void rtl_tx_report_handler(struct ieee80211_hw *hw, u8 *tmp_buf, u8 c2h_cmd_len) break; } } - RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_DMESG, - "Recv TX-Report st=0x%02X sn=0x%X retry=0x%X\n", - st, sn, retry); + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_DMESG, + "Recv TX-Report st=0x%02X sn=0x%X retry=0x%X\n", + st, sn, retry); } EXPORT_SYMBOL_GPL(rtl_tx_report_handler); @@ -1709,9 +1709,9 @@ bool rtl_check_tx_report_acked(struct ieee80211_hw *hw) return true; if (time_before(tx_report->last_sent_time + 3 * HZ, jiffies)) { - RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_WARNING, - "Check TX-Report timeout!! s_sn=0x%X r_sn=0x%X\n", - tx_report->last_sent_sn, tx_report->last_recv_sn); + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_WARNING, + "Check TX-Report timeout!! s_sn=0x%X r_sn=0x%X\n", + tx_report->last_sent_sn, tx_report->last_recv_sn); return true; /* 3 sec. (timeout) seen as acked */ } @@ -1727,8 +1727,8 @@ void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms) if (rtl_check_tx_report_acked(hw)) break; usleep_range(1000, 2000); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "Wait 1ms (%d/%d) to disable key.\n", i, wait_ms); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "Wait 1ms (%d/%d) to disable key.\n", i, wait_ms); } } @@ -1790,9 +1790,9 @@ int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return -ENXIO; tid_data = &sta_entry->tids[tid]; - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - "on ra = %pM tid = %d seq:%d\n", sta->addr, tid, - *ssn); + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, + "on ra = %pM tid = %d seq:%d\n", sta->addr, tid, + *ssn); tid_data->agg.agg_state = RTL_AGG_START; @@ -1809,8 +1809,8 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (sta == NULL) return -EINVAL; - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - "on ra = %pM tid = %d\n", sta->addr, tid); + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, + "on ra = %pM tid = %d\n", sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1849,8 +1849,8 @@ int rtl_rx_agg_start(struct ieee80211_hw *hw, return -ENXIO; tid_data = &sta_entry->tids[tid]; - RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG, - "on ra = %pM tid = %d\n", sta->addr, tid); + rtl_dbg(rtlpriv, COMP_RECV, DBG_DMESG, + "on ra = %pM tid = %d\n", sta->addr, tid); tid_data->agg.rx_agg_state = RTL_RX_AGG_START; return 0; @@ -1865,8 +1865,8 @@ int rtl_rx_agg_stop(struct ieee80211_hw *hw, if (sta == NULL) return -EINVAL; - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - "on ra = %pM tid = %d\n", sta->addr, tid); + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, + "on ra = %pM tid = %d\n", sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1885,8 +1885,8 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw, if (sta == NULL) return -EINVAL; - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - "on ra = %pM tid = %d\n", sta->addr, tid); + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, + "on ra = %pM tid = %d\n", sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1906,9 +1906,9 @@ void rtl_rx_ampdu_apply(struct rtl_priv *rtlpriv) btc_ops->btc_get_ampdu_cfg(rtlpriv, &reject_agg, &ctrl_agg_size, &agg_size); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Set RX AMPDU: coex - reject=%d, ctrl_agg_size=%d, size=%d", - reject_agg, ctrl_agg_size, agg_size); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Set RX AMPDU: coex - reject=%d, ctrl_agg_size=%d, size=%d", + reject_agg, ctrl_agg_size, agg_size); rtlpriv->hw->max_rx_aggregation_subframes = (ctrl_agg_size ? agg_size : IEEE80211_MAX_AMPDU_BUF_HT); @@ -1996,9 +1996,9 @@ void rtl_scan_list_expire(struct ieee80211_hw *hw) list_del(&entry->list); rtlpriv->scan_list.num--; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - "BSSID=%pM is expire in scan list (total=%d)\n", - entry->bssid, rtlpriv->scan_list.num); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "BSSID=%pM is expire in scan list (total=%d)\n", + entry->bssid, rtlpriv->scan_list.num); kfree(entry); } @@ -2032,9 +2032,9 @@ void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb) if (memcmp(entry->bssid, hdr->addr3, ETH_ALEN) == 0) { list_del_init(&entry->list); entry_found = true; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - "Update BSSID=%pM to scan list (total=%d)\n", - hdr->addr3, rtlpriv->scan_list.num); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Update BSSID=%pM to scan list (total=%d)\n", + hdr->addr3, rtlpriv->scan_list.num); break; } } @@ -2048,9 +2048,9 @@ void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb) memcpy(entry->bssid, hdr->addr3, ETH_ALEN); rtlpriv->scan_list.num++; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - "Add BSSID=%pM to scan list (total=%d)\n", - hdr->addr3, rtlpriv->scan_list.num); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Add BSSID=%pM to scan list (total=%d)\n", + hdr->addr3, rtlpriv->scan_list.num); } entry->age = jiffies; @@ -2213,8 +2213,8 @@ label_lps_done: if ((rtlpriv->link_info.bcn_rx_inperiod + rtlpriv->link_info.num_rx_inperiod) == 0) { rtlpriv->link_info.roam_times++; - RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, - "AP off for %d s\n", + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "AP off for %d s\n", (rtlpriv->link_info.roam_times * 2)); /* if we can't recv beacon for 10s, @@ -2325,11 +2325,11 @@ static void rtl_c2h_content_parsing(struct ieee80211_hw *hw, switch (cmd_id) { case C2H_DBG: - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "[C2H], C2H_DBG!!\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "[C2H], C2H_DBG!!\n"); break; case C2H_TXBF: - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "[C2H], C2H_TXBF!!\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_TXBF!!\n"); break; case C2H_TX_REPORT: rtl_tx_report_handler(hw, cmd_buf, cmd_len); @@ -2339,20 +2339,20 @@ static void rtl_c2h_content_parsing(struct ieee80211_hw *hw, hal_ops->c2h_ra_report_handler(hw, cmd_buf, cmd_len); break; case C2H_BT_INFO: - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "[C2H], C2H_BT_INFO!!\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_BT_INFO!!\n"); if (rtlpriv->cfg->ops->get_btc_status()) btc_ops->btc_btinfo_notify(rtlpriv, cmd_buf, cmd_len); break; case C2H_BT_MP: - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "[C2H], C2H_BT_MP!!\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_BT_MP!!\n"); if (rtlpriv->cfg->ops->get_btc_status()) btc_ops->btc_btmpinfo_notify(rtlpriv, cmd_buf, cmd_len); break; default: - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "[C2H], Unknown packet!! cmd_id(%#X)!\n", cmd_id); + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], Unknown packet!! cmd_id(%#X)!\n", cmd_id); break; } } @@ -2376,8 +2376,8 @@ void rtl_c2hcmd_launcher(struct ieee80211_hw *hw, int exec) if (!skb) break; - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "C2H rx_desc_shift=%d\n", - *((u8 *)skb->cb)); + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, "C2H rx_desc_shift=%d\n", + *((u8 *)skb->cb)); RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_DMESG, "C2H data: ", skb->data, skb->len); @@ -2721,29 +2721,29 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len) (memcmp(mac->bssid, ap5_6, 3) == 0) || vendor == PEER_ATH) { vendor = PEER_ATH; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ath find\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ath find\n"); } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) || (memcmp(mac->bssid, ap4_5, 3) == 0) || (memcmp(mac->bssid, ap4_1, 3) == 0) || (memcmp(mac->bssid, ap4_2, 3) == 0) || (memcmp(mac->bssid, ap4_3, 3) == 0) || vendor == PEER_RAL) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ral find\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ral find\n"); vendor = PEER_RAL; } else if (memcmp(mac->bssid, ap6_1, 3) == 0 || vendor == PEER_CISCO) { vendor = PEER_CISCO; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>cisco find\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>cisco find\n"); } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) || (memcmp(mac->bssid, ap3_2, 3) == 0) || (memcmp(mac->bssid, ap3_3, 3) == 0) || vendor == PEER_BROAD) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>broad find\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>broad find\n"); vendor = PEER_BROAD; } else if (memcmp(mac->bssid, ap7_1, 3) == 0 || vendor == PEER_MARV) { vendor = PEER_MARV; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>marv find\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>marv find\n"); } mac->vendor = vendor; diff --git a/drivers/net/wireless/realtek/rtlwifi/cam.c b/drivers/net/wireless/realtek/rtlwifi/cam.c index f7a7dcbf945e..c63129525875 100644 --- a/drivers/net/wireless/realtek/rtlwifi/cam.c +++ b/drivers/net/wireless/realtek/rtlwifi/cam.c @@ -64,14 +64,14 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "WRITE %x: %x\n", - rtlpriv->cfg->maps[WCAMI], target_content); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "The Key ID is %d\n", entry_no); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "WRITE %x: %x\n", - rtlpriv->cfg->maps[RWCAM], target_command); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE %x: %x\n", + rtlpriv->cfg->maps[WCAMI], target_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "The Key ID is %d\n", entry_no); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE %x: %x\n", + rtlpriv->cfg->maps[RWCAM], target_command); } else if (entry_i == 1) { @@ -85,10 +85,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "WRITE A4: %x\n", target_content); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "WRITE A0: %x\n", target_command); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE A4: %x\n", target_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE A0: %x\n", target_command); } else { @@ -104,15 +104,15 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "WRITE A4: %x\n", target_content); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "WRITE A0: %x\n", target_command); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE A4: %x\n", target_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE A0: %x\n", target_command); } } - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "after set key, usconfig:%x\n", us_config); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "after set key, usconfig:%x\n", us_config); } u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, @@ -122,14 +122,14 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, u32 us_config; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n", - ul_entry_idx, ul_key_id, ul_enc_alg, - ul_default_key, mac_addr); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n", + ul_entry_idx, ul_key_id, ul_enc_alg, + ul_default_key, mac_addr); if (ul_key_id == TOTAL_CAM_ENTRY) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "ulKeyId exceed!\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "ulKeyId exceed!\n"); return 0; } @@ -141,7 +141,7 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, rtl_cam_program_entry(hw, ul_entry_idx, mac_addr, (u8 *)key_content, us_config); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "end\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "end\n"); return 1; @@ -154,7 +154,7 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u32 ul_command; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id); ul_command = ul_key_id * CAM_CONTENT_COUNT; ul_command = ul_command | BIT(31) | BIT(16); @@ -162,10 +162,10 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], 0); rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s: WRITE A4: %x\n", __func__, 0); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s: WRITE A0: %x\n", __func__, ul_command); return 0; @@ -216,10 +216,10 @@ void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index) rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content); rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s: WRITE A4: %x\n", __func__, ul_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s: WRITE A0: %x\n", __func__, ul_command); } EXPORT_SYMBOL(rtl_cam_mark_invalid); @@ -266,12 +266,10 @@ void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index) rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content); rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "rtl_cam_empty_entry(): WRITE A4: %x\n", - ul_content); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "rtl_cam_empty_entry(): WRITE A0: %x\n", - ul_command); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "%s: WRITE A4: %x\n", __func__, ul_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "%s: WRITE A0: %x\n", __func__, ul_command); } } @@ -334,8 +332,8 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) /* Remove from HW Security CAM */ eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]); rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "&&&&&&&&&del entry %d\n", i); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "&&&&&&&&&del entry %d\n", i); } } return; diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c index 4bf7967590ca..0ad4e0f099f9 100644 --- a/drivers/net/wireless/realtek/rtlwifi/core.c +++ b/drivers/net/wireless/realtek/rtlwifi/core.c @@ -98,8 +98,8 @@ static void rtl_fw_do_work(const struct firmware *firmware, void *context, struct rtl_priv *rtlpriv = rtl_priv(hw); int err; - RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, - "Firmware callback routine entered!\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); complete(&rtlpriv->firmware_loading_complete); if (!firmware) { if (rtlpriv->cfg->alt_fw_name) { @@ -235,8 +235,8 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, u8 retry_limit = 0x30; if (mac->vif) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "vif has been set!! mac->vif = 0x%p\n", mac->vif); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "vif has been set!! mac->vif = 0x%p\n", mac->vif); return -EOPNOTSUPP; } @@ -251,16 +251,16 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, /*fall through*/ case NL80211_IFTYPE_STATION: if (mac->beacon_enabled == 1) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "NL80211_IFTYPE_STATION\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "NL80211_IFTYPE_STATION\n"); mac->beacon_enabled = 0; rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]); } break; case NL80211_IFTYPE_ADHOC: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "NL80211_IFTYPE_ADHOC\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "NL80211_IFTYPE_ADHOC\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -277,8 +277,8 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, mac->p2p = P2P_ROLE_GO; /*fall through*/ case NL80211_IFTYPE_AP: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "NL80211_IFTYPE_AP\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "NL80211_IFTYPE_AP\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -292,8 +292,8 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, retry_limit = 0x07; break; case NL80211_IFTYPE_MESH_POINT: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "NL80211_IFTYPE_MESH_POINT\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "NL80211_IFTYPE_MESH_POINT\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -314,8 +314,8 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, } if (mac->p2p) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "p2p role %x\n", vif->type); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "p2p role %x\n", vif->type); mac->basic_rates = 0xff0;/*disable cck rate for p2p*/ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, (u8 *)(&mac->basic_rates)); @@ -379,8 +379,8 @@ static int rtl_op_change_interface(struct ieee80211_hw *hw, vif->type = new_type; vif->p2p = p2p; ret = rtl_op_add_interface(hw, vif); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "p2p %x\n", p2p); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "p2p %x\n", p2p); return ret; } @@ -454,8 +454,8 @@ static void _rtl_add_wowlan_patterns(struct ieee80211_hw *hw, memset(mask, 0, MAX_WOL_BIT_MASK_SIZE); if (patterns[i].pattern_len < 0 || patterns[i].pattern_len > MAX_WOL_PATTERN_SIZE) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_WARNING, - "Pattern[%d] is too long\n", i); + rtl_dbg(rtlpriv, COMP_POWER, DBG_WARNING, + "Pattern[%d] is too long\n", i); continue; } pattern_os = patterns[i].pattern; @@ -534,8 +534,8 @@ static void _rtl_add_wowlan_patterns(struct ieee80211_hw *hw, "pattern to hw\n", content, len); /* 3. calculate crc */ rtl_pattern.crc = _calculate_wol_pattern_crc(content, len); - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - "CRC_Remainder = 0x%x\n", rtl_pattern.crc); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "CRC_Remainder = 0x%x\n", rtl_pattern.crc); /* 4. write crc & mask_for_hw to hw */ rtlpriv->cfg->ops->add_wowlan_pattern(hw, &rtl_pattern, i); @@ -550,7 +550,7 @@ static int rtl_op_suspend(struct ieee80211_hw *hw, struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); if (WARN_ON(!wow)) return -EINVAL; @@ -576,7 +576,7 @@ static int rtl_op_resume(struct ieee80211_hw *hw) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); time64_t now; - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); rtlhal->driver_is_goingto_unload = false; rtlhal->enter_pnp_sleep = false; rtlhal->wake_from_pnp_sleep = true; @@ -607,8 +607,8 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&rtlpriv->locks.conf_mutex); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /* BIT(2)*/ - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"); } /*For IPS */ @@ -651,9 +651,9 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) } if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", - hw->conf.long_frame_max_tx_count); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", + hw->conf.long_frame_max_tx_count); /* brought up everything changes (changed == ~0) indicates first * open, so use our default value instead of that of wiphy. */ @@ -828,13 +828,13 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, if (*new_flags & FIF_ALLMULTI) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] | rtlpriv->cfg->maps[MAC_RCR_AB]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Enable receive multicast frame\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Enable receive multicast frame\n"); } else { mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] | rtlpriv->cfg->maps[MAC_RCR_AB]); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Disable receive multicast frame\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Disable receive multicast frame\n"); } update_rcr = true; } @@ -842,12 +842,12 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, if (changed_flags & FIF_FCSFAIL) { if (*new_flags & FIF_FCSFAIL) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Enable receive FCS error frame\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Enable receive FCS error frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Disable receive FCS error frame\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Disable receive FCS error frame\n"); } if (!update_rcr) update_rcr = true; @@ -874,12 +874,12 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, if (*new_flags & FIF_CONTROL) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Enable receive control frame.\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Enable receive control frame.\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Disable receive control frame.\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Disable receive control frame.\n"); } if (!update_rcr) update_rcr = true; @@ -888,12 +888,12 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, if (changed_flags & FIF_OTHER_BSS) { if (*new_flags & FIF_OTHER_BSS) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Enable receive other BSS's frame.\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Enable receive other BSS's frame.\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Disable receive other BSS's frame.\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Disable receive other BSS's frame.\n"); } if (!update_rcr) update_rcr = true; @@ -941,7 +941,7 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw, sta->supp_rates[0] &= 0xfffffff0; memcpy(sta_entry->mac_addr, sta->addr, ETH_ALEN); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, "Add sta addr is %pM\n", sta->addr); rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0, true); } @@ -956,8 +956,8 @@ static int rtl_op_sta_remove(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_sta_info *sta_entry; if (sta) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "Remove sta addr is %pM\n", sta->addr); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "Remove sta addr is %pM\n", sta->addr); sta_entry = (struct rtl_sta_info *)sta->drv_priv; sta_entry->wireless_mode = 0; sta_entry->ratr_index = 0; @@ -1004,8 +1004,8 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw, int aci; if (queue >= AC_MAX) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "queue number %d is incorrect!\n", queue); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "queue number %d is incorrect!\n", queue); return -EINVAL; } @@ -1050,8 +1050,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, (changed & BSS_CHANGED_BEACON_ENABLED && bss_conf->enable_beacon)) { if (mac->beacon_enabled == 0) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "BSS_CHANGED_BEACON_ENABLED\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "BSS_CHANGED_BEACON_ENABLED\n"); /*start hw beacon interrupt. */ /*rtlpriv->cfg->ops->set_bcn_reg(hw); */ @@ -1068,8 +1068,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if ((changed & BSS_CHANGED_BEACON_ENABLED && !bss_conf->enable_beacon)) { if (mac->beacon_enabled == 1) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "ADHOC DISABLE BEACON\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "ADHOC DISABLE BEACON\n"); mac->beacon_enabled = 0; rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, @@ -1078,8 +1078,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, } } if (changed & BSS_CHANGED_BEACON_INT) { - RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE, - "BSS_CHANGED_BEACON_INT\n"); + rtl_dbg(rtlpriv, COMP_BEACON, DBG_TRACE, + "BSS_CHANGED_BEACON_INT\n"); mac->beacon_interval = bss_conf->beacon_int; rtlpriv->cfg->ops->set_bcn_intv(hw); } @@ -1117,8 +1117,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rcu_read_unlock(); goto out; } - RT_TRACE(rtlpriv, COMP_EASY_CONCURRENT, DBG_LOUD, - "send PS STATIC frame\n"); + rtl_dbg(rtlpriv, COMP_EASY_CONCURRENT, DBG_LOUD, + "send PS STATIC frame\n"); if (rtlpriv->dm.supp_phymode_switch) { if (sta->ht_cap.ht_supported) rtl_send_smps_action(hw, sta, @@ -1158,8 +1158,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, HW_VAR_KEEP_ALIVE, (u8 *)(&keep_alive)); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "BSS_CHANGED_ASSOC\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "BSS_CHANGED_ASSOC\n"); } else { struct cfg80211_bss *bss = NULL; @@ -1176,14 +1176,14 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_OFF); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "bssid = %pMF\n", mac->bssid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "bssid = %pMF\n", mac->bssid); if (bss) { cfg80211_unlink_bss(hw->wiphy, bss); cfg80211_put_bss(hw->wiphy, bss); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "cfg80211_unlink !!\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "cfg80211_unlink !!\n"); } eth_zero_addr(mac->bssid); @@ -1194,8 +1194,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (rtlpriv->cfg->ops->chk_switch_dmdp) rtlpriv->cfg->ops->chk_switch_dmdp(hw); } - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "BSS_CHANGED_UN_ASSOC\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "BSS_CHANGED_UN_ASSOC\n"); } rtlpriv->cfg->ops->set_network_type(hw, vif->type); /* For FW LPS: @@ -1213,14 +1213,14 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ERP_CTS_PROT) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "BSS_CHANGED_ERP_CTS_PROT\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "BSS_CHANGED_ERP_CTS_PROT\n"); mac->use_cts_protect = bss_conf->use_cts_prot; } if (changed & BSS_CHANGED_ERP_PREAMBLE) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", bss_conf->use_short_preamble); mac->short_preamble = bss_conf->use_short_preamble; @@ -1229,8 +1229,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ERP_SLOT) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "BSS_CHANGED_ERP_SLOT\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "BSS_CHANGED_ERP_SLOT\n"); if (bss_conf->use_short_slot) mac->slot_time = RTL_SLOT_TIME_9; @@ -1244,8 +1244,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_HT) { struct ieee80211_sta *sta = NULL; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "BSS_CHANGED_HT\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "BSS_CHANGED_HT\n"); rcu_read_lock(); sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid); @@ -1276,8 +1276,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, (u8 *)bss_conf->bssid); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "bssid: %pM\n", bss_conf->bssid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "bssid: %pM\n", bss_conf->bssid); mac->vendor = PEER_UNKNOWN; memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN); @@ -1407,27 +1407,27 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw, switch (action) { case IEEE80211_AMPDU_TX_START: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "IEEE80211_AMPDU_TX_START: TID:%d\n", tid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_TX_START: TID:%d\n", tid); return rtl_tx_agg_start(hw, vif, sta, tid, ssn); case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid); return rtl_tx_agg_stop(hw, vif, sta, tid); case IEEE80211_AMPDU_TX_OPERATIONAL: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid); rtl_tx_agg_oper(hw, sta, tid); break; case IEEE80211_AMPDU_RX_START: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "IEEE80211_AMPDU_RX_START:TID:%d\n", tid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_RX_START:TID:%d\n", tid); return rtl_rx_agg_start(hw, sta, tid); case IEEE80211_AMPDU_RX_STOP: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid); return rtl_rx_agg_stop(hw, sta, tid); default: pr_err("IEEE80211_AMPDU_ERR!!!!:\n"); @@ -1443,7 +1443,7 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); mac->act_scanning = true; if (rtlpriv->link_info.higher_busytraffic) { mac->skip_scan = true; @@ -1481,7 +1481,7 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); mac->act_scanning = false; mac->skip_scan = false; @@ -1531,8 +1531,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, rtlpriv->btcoexist.btc_info.in_4way = false; if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "not open hw encryption\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "not open hw encryption\n"); return -ENOSPC; /*User disabled HW-crypto */ } /* To support IBSS, use sw-crypto for GTK */ @@ -1540,10 +1540,10 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, vif->type == NL80211_IFTYPE_MESH_POINT) && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) return -ENOSPC; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "%s hardware based encryption for keyidx: %d, mac: %pM\n", - cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, - sta ? sta->addr : bcast_addr); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s hardware based encryption for keyidx: %d, mac: %pM\n", + cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, + sta ? sta->addr : bcast_addr); rtlpriv->sec.being_setkey = true; rtl_ips_nic_on(hw); mutex_lock(&rtlpriv->locks.conf_mutex); @@ -1552,28 +1552,28 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: key_type = WEP40_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n"); break; case WLAN_CIPHER_SUITE_WEP104: - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n"); key_type = WEP104_ENCRYPTION; break; case WLAN_CIPHER_SUITE_TKIP: key_type = TKIP_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n"); break; case WLAN_CIPHER_SUITE_CCMP: key_type = AESCCMP_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n"); break; case WLAN_CIPHER_SUITE_AES_CMAC: /* HW don't support CMAC encryption, * use software CMAC encryption */ key_type = AESCMAC_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CMAC\n"); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "HW don't support CMAC encryption, use software CMAC encryption\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CMAC\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "HW don't support CMAC encryption, use software CMAC encryption\n"); err = -EOPNOTSUPP; goto out_unlock; default: @@ -1619,9 +1619,9 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, key_type == WEP104_ENCRYPTION)) wep_only = true; rtlpriv->sec.pairwise_enc_algorithm = key_type; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n", - key_type); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n", + key_type); rtlpriv->cfg->ops->enable_hw_sec(hw); } } @@ -1629,8 +1629,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (cmd) { case SET_KEY: if (wep_only) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set WEP(group/pairwise) key\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set WEP(group/pairwise) key\n"); /* Pairwise key with an assigned MAC address. */ rtlpriv->sec.pairwise_enc_algorithm = key_type; rtlpriv->sec.group_enc_algorithm = key_type; @@ -1640,8 +1640,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, rtlpriv->sec.key_len[key_idx] = key->keylen; eth_zero_addr(mac_addr); } else if (group_key) { /* group key */ - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set group key\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); /* group key */ rtlpriv->sec.group_enc_algorithm = key_type; /*set local buf about group key. */ @@ -1650,8 +1650,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, rtlpriv->sec.key_len[key_idx] = key->keylen; memcpy(mac_addr, bcast_addr, ETH_ALEN); } else { /* pairwise key */ - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set pairwise key\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set pairwise key\n"); if (!sta) { WARN_ONCE(true, "rtlwifi: pairwise key without mac_addr\n"); @@ -1683,8 +1683,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; break; case DISABLE_KEY: - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "disable key delete one entry\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "disable key delete one entry\n"); /*set local buf about wep key. */ if (vif->type == NL80211_IFTYPE_AP || vif->type == NL80211_IFTYPE_MESH_POINT) { @@ -1732,9 +1732,9 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) { rtlpriv->rfkill.rfkill_state = radio_state; - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "wireless radio switch turned %s\n", - radio_state ? "on" : "off"); + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "wireless radio switch turned %s\n", + radio_state ? "on" : "off"); blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; wiphy_rfkill_set_hw_state(hw->wiphy, blocked); @@ -1779,26 +1779,27 @@ bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, do { cfg_cmd = pwrcfgcmd[ary_idx]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), famsk(%#x), interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n", - GET_PWR_CFG_OFFSET(cfg_cmd), - GET_PWR_CFG_CUT_MASK(cfg_cmd), - GET_PWR_CFG_FAB_MASK(cfg_cmd), - GET_PWR_CFG_INTF_MASK(cfg_cmd), - GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd), - GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd)); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "%s: offset(%#x),cut_msk(%#x), famsk(%#x), interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n", + __func__, + GET_PWR_CFG_OFFSET(cfg_cmd), + GET_PWR_CFG_CUT_MASK(cfg_cmd), + GET_PWR_CFG_FAB_MASK(cfg_cmd), + GET_PWR_CFG_INTF_MASK(cfg_cmd), + GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd), + GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd)); if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) && (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) && (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) { switch (GET_PWR_CFG_CMD(cfg_cmd)) { case PWR_CMD_READ: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n"); break; case PWR_CMD_WRITE: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "%s(): PWR_CMD_WRITE\n", __func__); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "%s(): PWR_CMD_WRITE\n", __func__); offset = GET_PWR_CFG_OFFSET(cfg_cmd); /*Read the value from system register*/ @@ -1811,7 +1812,7 @@ bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, rtl_write_byte(rtlpriv, offset, value); break; case PWR_CMD_POLLING: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n"); polling_bit = false; offset = GET_PWR_CFG_OFFSET(cfg_cmd); @@ -1832,8 +1833,8 @@ bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, } while (!polling_bit); break; case PWR_CMD_DELAY: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "%s: PWR_CMD_DELAY\n", __func__); if (GET_PWR_CFG_VALUE(cfg_cmd) == PWRSEQ_DELAY_US) udelay(GET_PWR_CFG_OFFSET(cfg_cmd)); @@ -1841,8 +1842,8 @@ bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, mdelay(GET_PWR_CFG_OFFSET(cfg_cmd)); break; case PWR_CMD_END: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "%s: PWR_CMD_END\n", __func__); return true; default: WARN_ONCE(true, diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c index 474439fc2da1..cead66f7eb9f 100644 --- a/drivers/net/wireless/realtek/rtlwifi/debug.c +++ b/drivers/net/wireless/realtek/rtlwifi/debug.c @@ -425,8 +425,8 @@ static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp, &path, &addr, &bitmask, &data); if (num != 4) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, - "Format is \n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "Format is \n"); return count; } diff --git a/drivers/net/wireless/realtek/rtlwifi/efuse.c b/drivers/net/wireless/realtek/rtlwifi/efuse.c index 9729e51fce38..5d8995097ee7 100644 --- a/drivers/net/wireless/realtek/rtlwifi/efuse.c +++ b/drivers/net/wireless/realtek/rtlwifi/efuse.c @@ -160,8 +160,8 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value) const u32 efuse_len = rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n", - address, value); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n", + address, value); if (address < efuse_len) { rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value); @@ -251,9 +251,9 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) u8 efuse_usage; if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) { - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - "read_efuse(): Invalid offset(%#x) with read bytes(%#x)!!\n", - _offset, _size_byte); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "%s: Invalid offset(%#x) with read bytes(%#x)!!\n", + __func__, _offset, _size_byte); return; } @@ -416,9 +416,9 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw) (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) result = false; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - "efuse_shadow_update_chk(): totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", - totalbytes, hdr_num, words_need, efuse_used); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "%s: totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", + __func__, totalbytes, hdr_num, words_need, efuse_used); return result; } @@ -456,7 +456,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) u8 word_en = 0x0F; u8 first_pg = false; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n"); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n"); if (!efuse_shadow_update_chk(hw)) { efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); @@ -464,8 +464,8 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - "efuse out of capacity!!\n"); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "efuse out of capacity!!\n"); return false; } efuse_power_switch(hw, true, true); @@ -503,8 +503,8 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) if (!efuse_pg_packet_write(hw, (u8) offset, word_en, tmpdata)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "PG section(%#x) fail!!\n", offset); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "PG section(%#x) fail!!\n", offset); break; } } @@ -518,7 +518,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n"); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n"); return true; } @@ -656,8 +656,8 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) struct rtl_priv *rtlpriv = rtl_priv(hw); u8 tmpidx = 0; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - "Addr = %x Data=%x\n", addr, data); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "Addr = %x Data=%x\n", addr, data); rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff)); @@ -1036,8 +1036,8 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, if (efuse_addr >= (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) { - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - "efuse_addr(%#x) Out of size!!\n", efuse_addr); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "efuse_addr(%#x) Out of size!!\n", efuse_addr); } return true; @@ -1077,8 +1077,8 @@ static u8 enable_efuse_data_write(struct ieee80211_hw *hw, u8 tmpdata[8]; memset(tmpdata, 0xff, PGPKT_DATA_SIZE); - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - "word_en = %x efuse_addr=%x\n", word_en, efuse_addr); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "word_en = %x efuse_addr=%x\n", word_en, efuse_addr); if (!(word_en & BIT(0))) { tmpaddr = start_addr; @@ -1281,11 +1281,11 @@ int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv, eeprom_id = *((u16 *)&hwinfo[0]); if (eeprom_id != params[0]) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "EEPROM ID(%#x) is invalid!!\n", eeprom_id); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } @@ -1296,30 +1296,30 @@ int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv, rtlefuse->eeprom_did = *(u16 *)&hwinfo[params[2]]; rtlefuse->eeprom_svid = *(u16 *)&hwinfo[params[3]]; rtlefuse->eeprom_smid = *(u16 *)&hwinfo[params[4]]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROMId = 0x%4x\n", eeprom_id); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROMId = 0x%4x\n", eeprom_id); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); for (i = 0; i < 6; i += 2) { usvalue = *(u16 *)&hwinfo[params[5] + i]; *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); rtlefuse->eeprom_channelplan = *&hwinfo[params[6]]; rtlefuse->eeprom_version = *(u16 *)&hwinfo[params[7]]; rtlefuse->txpwr_fromeprom = true; rtlefuse->eeprom_oemid = *&hwinfo[params[8]]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); /* set channel plan to world wide 13 */ rtlefuse->channel_plan = params[9]; diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c index 8bda1104bda8..0d22bd300f04 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.c +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -226,8 +226,8 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) return; if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - "PCI(Bridge) UNKNOWN\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "PCI(Bridge) UNKNOWN\n"); return; } @@ -276,8 +276,8 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) return; if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - "PCI(Bridge) UNKNOWN\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "PCI(Bridge) UNKNOWN\n"); return; } @@ -293,10 +293,10 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) pci_write_config_byte(rtlpci->pdev, (num4bytes << 2), u_pcibridge_aspmsetting); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "PlatformEnableASPM(): Write reg[%x] = %x\n", - (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), - u_pcibridge_aspmsetting); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "PlatformEnableASPM(): Write reg[%x] = %x\n", + (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), + u_pcibridge_aspmsetting); udelay(50); @@ -353,11 +353,11 @@ static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, list_for_each_entry(tpriv, &rtlpriv->glb_var->glb_priv_list, list) { tpcipriv = (struct rtl_pci_priv *)tpriv->priv; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "pcipriv->ndis_adapter.funcnumber %x\n", + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "pcipriv->ndis_adapter.funcnumber %x\n", pcipriv->ndis_adapter.funcnumber); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "tpcipriv->ndis_adapter.funcnumber %x\n", + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "tpcipriv->ndis_adapter.funcnumber %x\n", tpcipriv->ndis_adapter.funcnumber); if (pcipriv->ndis_adapter.busnumber == @@ -372,8 +372,8 @@ static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, } } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "find_buddy_priv %d\n", find_buddy_priv); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "find_buddy_priv %d\n", find_buddy_priv); if (find_buddy_priv) *buddy_priv = tpriv; @@ -410,8 +410,8 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev, pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &linkctrl_reg); pcipriv->ndis_adapter.linkctrl_reg = (u8)linkctrl_reg; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n", - pcipriv->ndis_adapter.linkctrl_reg); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n", + pcipriv->ndis_adapter.linkctrl_reg); pci_read_config_byte(pdev, 0x98, &tmp); tmp |= BIT(4); @@ -579,11 +579,11 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) if (rtlpriv->rtlhal.earlymode_enable) skb_pull(skb, EM_HDR_LEN); - RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, - "new ring->idx:%d, free: skb_queue_len:%d, free: seq:%x\n", - ring->idx, - skb_queue_len(&ring->queue), - *(u16 *)(skb->data + 22)); + rtl_dbg(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, + "new ring->idx:%d, free: skb_queue_len:%d, free: seq:%x\n", + ring->idx, + skb_queue_len(&ring->queue), + *(u16 *)(skb->data + 22)); if (prio == TXCMD_QUEUE) { dev_kfree_skb(skb); @@ -630,10 +630,10 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) } if ((ring->entries - skb_queue_len(&ring->queue)) <= 4) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, - "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n", - prio, ring->idx, - skb_queue_len(&ring->queue)); + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n", + prio, ring->idx, + skb_queue_len(&ring->queue)); ieee80211_wake_queue(hw, skb_get_queue_mapping(skb)); } @@ -823,9 +823,9 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) skb_reserve(skb, stats.rx_drvinfo_size + stats.rx_bufshift); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "skb->end - skb->tail = %d, len is %d\n", - skb->end - skb->tail, len); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "skb->end - skb->tail = %d, len is %d\n", + skb->end - skb->tail, len); dev_kfree_skb_any(skb); goto new_trx_end; } @@ -946,67 +946,67 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) /*<1> beacon related */ if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "beacon ok interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "beacon ok interrupt!\n"); if (unlikely(intvec.inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "beacon err interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "beacon err interrupt!\n"); if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n"); if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BCNINT]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "prepare beacon for interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "prepare beacon for interrupt!\n"); tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet); } /*<2> Tx related */ if (unlikely(intvec.intb & rtlpriv->cfg->maps[RTL_IMR_TXFOVW])) - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "IMR_TXFOVW!\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, "IMR_TXFOVW!\n"); if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "Manage ok interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "Manage ok interrupt!\n"); _rtl_pci_tx_isr(hw, MGNT_QUEUE); } if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "HIGH_QUEUE ok interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "HIGH_QUEUE ok interrupt!\n"); _rtl_pci_tx_isr(hw, HIGH_QUEUE); } if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BKDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "BK Tx OK interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "BK Tx OK interrupt!\n"); _rtl_pci_tx_isr(hw, BK_QUEUE); } if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BEDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "BE TX OK interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "BE TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, BE_QUEUE); } if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_VIDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "VI TX OK interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "VI TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, VI_QUEUE); } if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_VODOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "Vo TX OK interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "Vo TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, VO_QUEUE); } @@ -1014,8 +1014,8 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) if (intvec.intd & rtlpriv->cfg->maps[RTL_IMR_H2CDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "H2C TX OK interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "H2C TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, H2C_QUEUE); } } @@ -1024,34 +1024,34 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "CMD TX OK interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "CMD TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, TXCMD_QUEUE); } } /*<3> Rx related */ if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n"); _rtl_pci_rx_interrupt(hw); } if (unlikely(intvec.inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "rx descriptor unavailable!\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "rx descriptor unavailable!\n"); _rtl_pci_rx_interrupt(hw); } if (unlikely(intvec.intb & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "rx overflow !\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, "rx overflow !\n"); _rtl_pci_rx_interrupt(hw); } /*<4> fw related*/ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723AE) { if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_C2HCMD]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "firmware interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "firmware interrupt!\n"); queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.fwevt_wq, 0); } @@ -1067,8 +1067,8 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) { if (unlikely(intvec.inta & rtlpriv->cfg->maps[RTL_IMR_HSISR_IND])) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "hsisr interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "hsisr interrupt!\n"); _rtl_pci_hs_interrupt(hw); } } @@ -1272,8 +1272,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, rtlpci->tx_ring[prio].entries = entries; skb_queue_head_init(&rtlpci->tx_ring[prio].queue); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "queue:%d, ring_addr:%p\n", - prio, desc); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "queue:%d, ring_addr:%p\n", + prio, desc); /* init every desc in this ring */ if (!rtlpriv->use_new_trx_flow) { @@ -1670,10 +1670,10 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, true, HW_DESC_OWN); if (own == 1 && hw_queue != BEACON_QUEUE) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", - hw_queue, ring->idx, idx, - skb_queue_len(&ring->queue)); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue)); spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); @@ -1683,8 +1683,8 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, if (rtlpriv->cfg->ops->get_available_desc && rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "get_available_desc fail\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "get_available_desc fail\n"); spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); return skb->len; } @@ -1707,8 +1707,8 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && hw_queue != BEACON_QUEUE) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, - "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", hw_queue, ring->idx, idx, skb_queue_len(&ring->queue)); @@ -1815,8 +1815,8 @@ static int rtl_pci_start(struct ieee80211_hw *hw) err = rtlpriv->cfg->ops->hw_init(hw); if (err) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "Failed to config hardware!\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Failed to config hardware!\n"); kfree(rtlpriv->btcoexist.btc_context); kfree(rtlpriv->btcoexist.wifi_only_context); return err; @@ -1825,7 +1825,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw) &rtlmac->retry_long); rtlpriv->cfg->ops->enable_interrupt(hw); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n"); rtl_init_rx_config(hw); @@ -1836,7 +1836,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw) rtlpci->up_first_time = false; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%s OK\n", __func__); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%s OK\n", __func__); return 0; } @@ -1930,71 +1930,71 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, deviceid == RTL_PCI_8171_DID) { switch (revisionid) { case RTL_PCI_REVISION_ID_8192PCIE: - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8192 PCI-E is found - vid/did=%x/%x\n", - venderid, deviceid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8192 PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; return false; case RTL_PCI_REVISION_ID_8192SE: - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8192SE is found - vid/did=%x/%x\n", - venderid, deviceid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8192SE is found - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Err: Unknown device - vid/did=%x/%x\n", - venderid, deviceid); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Err: Unknown device - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; } } else if (deviceid == RTL_PCI_8723AE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8723AE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8723AE PCI-E is found - vid/did=%x/%x\n", - venderid, deviceid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8723AE PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8192CET_DID || deviceid == RTL_PCI_8192CE_DID || deviceid == RTL_PCI_8191CE_DID || deviceid == RTL_PCI_8188CE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8192C PCI-E is found - vid/did=%x/%x\n", - venderid, deviceid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8192C PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8192DE_DID || deviceid == RTL_PCI_8192DE_DID2) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8192D PCI-E is found - vid/did=%x/%x\n", - venderid, deviceid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8192D PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8188EE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8188EE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find adapter, Hardware type is 8188EE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8188EE\n"); } else if (deviceid == RTL_PCI_8723BE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8723BE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find adapter, Hardware type is 8723BE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8723BE\n"); } else if (deviceid == RTL_PCI_8192EE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192EE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find adapter, Hardware type is 8192EE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8192EE\n"); } else if (deviceid == RTL_PCI_8821AE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8821AE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find adapter, Hardware type is 8821AE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8821AE\n"); } else if (deviceid == RTL_PCI_8812AE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8812AE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find adapter, Hardware type is 8812AE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8812AE\n"); } else if (deviceid == RTL_PCI_8822BE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8822BE; rtlhal->bandset = BAND_ON_BOTH; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find adapter, Hardware type is 8822BE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8822BE\n"); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Err: Unknown device - vid/did=%x/%x\n", + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Err: Unknown device - vid/did=%x/%x\n", venderid, deviceid); rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE; @@ -2003,17 +2003,17 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) { if (revisionid == 0 || revisionid == 1) { if (revisionid == 0) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find 92DE MAC0\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find 92DE MAC0\n"); rtlhal->interfaceindex = 0; } else if (revisionid == 1) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find 92DE MAC1\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find 92DE MAC1\n"); rtlhal->interfaceindex = 1; } } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n", + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n", venderid, deviceid, revisionid); rtlhal->interfaceindex = 0; } @@ -2047,9 +2047,9 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { pcipriv->ndis_adapter.pcibridge_vendor = tmp; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "Pci Bridge Vendor is found index: %d\n", - tmp); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Pci Bridge Vendor is found index: %d\n", + tmp); break; } } @@ -2077,22 +2077,22 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, } } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n", - pcipriv->ndis_adapter.busnumber, - pcipriv->ndis_adapter.devnumber, - pcipriv->ndis_adapter.funcnumber, - pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n", + pcipriv->ndis_adapter.busnumber, + pcipriv->ndis_adapter.devnumber, + pcipriv->ndis_adapter.funcnumber, + pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", - pcipriv->ndis_adapter.pcibridge_busnum, - pcipriv->ndis_adapter.pcibridge_devnum, - pcipriv->ndis_adapter.pcibridge_funcnum, - pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], - pcipriv->ndis_adapter.pcibridge_pciehdr_offset, - pcipriv->ndis_adapter.pcibridge_linkctrlreg, - pcipriv->ndis_adapter.amd_l1_patch); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", + pcipriv->ndis_adapter.pcibridge_busnum, + pcipriv->ndis_adapter.pcibridge_devnum, + pcipriv->ndis_adapter.pcibridge_funcnum, + pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], + pcipriv->ndis_adapter.pcibridge_pciehdr_offset, + pcipriv->ndis_adapter.pcibridge_linkctrlreg, + pcipriv->ndis_adapter.amd_l1_patch); rtl_pci_parse_configuration(pdev, hw); list_add_tail(&rtlpriv->list, &rtlpriv->glb_var->glb_priv_list); @@ -2120,8 +2120,8 @@ static int rtl_pci_intr_mode_msi(struct ieee80211_hw *hw) rtlpci->using_msi = true; - RT_TRACE(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG, - "MSI Interrupt Mode!\n"); + rtl_dbg(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG, + "MSI Interrupt Mode!\n"); return 0; } @@ -2138,8 +2138,8 @@ static int rtl_pci_intr_mode_legacy(struct ieee80211_hw *hw) return ret; rtlpci->using_msi = false; - RT_TRACE(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG, - "Pin-based Interrupt Mode!\n"); + rtl_dbg(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG, + "Pin-based Interrupt Mode!\n"); return 0; } @@ -2266,10 +2266,10 @@ int rtl_pci_probe(struct pci_dev *pdev, goto fail2; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n", - pmem_start, pmem_len, pmem_flags, - rtlpriv->io.pci_mem_start); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n", + pmem_start, pmem_len, pmem_flags, + rtlpriv->io.pci_mem_start); /* Disable Clk Request */ pci_write_config_byte(pdev, 0x81, 0); @@ -2331,9 +2331,9 @@ int rtl_pci_probe(struct pci_dev *pdev, rtlpci = rtl_pcidev(pcipriv); err = rtl_pci_intr_mode_decide(hw); if (err) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "%s: failed to register IRQ handler\n", - wiphy_name(hw->wiphy)); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "%s: failed to register IRQ handler\n", + wiphy_name(hw->wiphy)); goto fail3; } rtlpci->irq_alloc = 1; diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c b/drivers/net/wireless/realtek/rtlwifi/ps.c index 5f998ea2d5a6..102f0d0e1cd0 100644 --- a/drivers/net/wireless/realtek/rtlwifi/ps.c +++ b/drivers/net/wireless/realtek/rtlwifi/ps.c @@ -41,8 +41,8 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) rtlpriv->intf_ops->reset_trx_ring(hw); if (is_hal_stop(rtlhal)) - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Driver is already down!\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Driver is already down!\n"); /*<2> Enable Adapter */ if (rtlpriv->cfg->ops->hw_init(hw)) @@ -103,9 +103,9 @@ static bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, if (ppsc->rfchange_inprogress) { spin_unlock(&rtlpriv->locks.rf_ps_lock); - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "RF Change in progress! Wait to set..state_toset(%d).\n", - state_toset); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "RF Change in progress! Wait to set..state_toset(%d).\n", + state_toset); /* Set RF after the previous action is done. */ while (ppsc->rfchange_inprogress) { @@ -217,8 +217,8 @@ void rtl_ips_nic_off_wq_callback(void *data) enum rf_pwrstate rtstate; if (mac->opmode != NL80211_IFTYPE_STATION) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "not station return\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "not station return\n"); return; } @@ -254,8 +254,8 @@ void rtl_ips_nic_off_wq_callback(void *data) !ppsc->swrf_processing && (mac->link_state == MAC80211_NOLINK) && !mac->act_scanning) { - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "IPSEnter(): Turn off RF\n"); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "IPSEnter(): Turn off RF\n"); ppsc->inactive_pwrstate = ERFOFF; ppsc->in_powersavemode = true; @@ -333,8 +333,8 @@ static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw) ppsc->last_delaylps_stamp_jiffies); if (ps_timediff < 2000) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n"); return false; } @@ -379,9 +379,9 @@ void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) if ((ppsc->fwctrl_lps) && ppsc->report_linked) { if (ppsc->dot11_psmode == EACTIVE) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "FW LPS leave ps_mode:%x\n", - FW_PS_ACTIVE_MODE); + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "FW LPS leave ps_mode:%x\n", + FW_PS_ACTIVE_MODE); enter_fwlps = false; ppsc->pwr_mode = FW_PS_ACTIVE_MODE; ppsc->smart_ps = 0; @@ -394,9 +394,9 @@ void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); } else { if (rtl_get_fwlps_doze(hw)) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "FW LPS enter ps_mode:%x\n", - ppsc->fwctrl_psmode); + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "FW LPS enter ps_mode:%x\n", + ppsc->fwctrl_psmode); if (rtlpriv->cfg->ops->get_btc_status()) rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); enter_fwlps = true; @@ -446,8 +446,8 @@ static void rtl_lps_enter_core(struct ieee80211_hw *hw) * bt_ccoexist may ask to enter lps. * In normal case, this constraint move to rtl_lps_set_psmode(). */ - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Enter 802.11 power save mode...\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Enter 802.11 power save mode...\n"); rtl_lps_set_psmode(hw, EAUTOPS); mutex_unlock(&rtlpriv->locks.lps_mutex); @@ -475,8 +475,8 @@ static void rtl_lps_leave_core(struct ieee80211_hw *hw) RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); } - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Busy Traffic,Leave 802.11 power save..\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Busy Traffic,Leave 802.11 power save..\n"); rtl_lps_set_psmode(hw, EACTIVE); } @@ -560,8 +560,8 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_work, MSECS(5)); } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); } } EXPORT_SYMBOL_GPL(rtl_swlps_beacon); @@ -656,9 +656,9 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) /* this print should always be dtim_conter = 0 & * sleep = dtim_period, that meaons, we should * awake before every dtim */ - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - "dtim_counter:%x will sleep :%d beacon_intv\n", - rtlpriv->psc.dtim_counter, sleep_intv); + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "dtim_counter:%x will sleep :%d beacon_intv\n", + rtlpriv->psc.dtim_counter, sleep_intv); /* we tested that 40ms is enough for sw & hw sw delay */ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq, @@ -769,9 +769,9 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, if (ie[0] == 12) { find_p2p_ps_ie = true; if ((noa_len - 2) % 13 != 0) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "P2P notice of absence: invalid length.%d\n", - noa_len); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "P2P notice of absence: invalid length.%d\n", + noa_len); return; } else { noa_num = (noa_len - 2) / 13; @@ -782,8 +782,8 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, noa_index = ie[3]; if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == P2P_PS_NONE || noa_index != p2pinfo->noa_index) { - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, - "update NOA ie.\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "update NOA ie.\n"); p2pinfo->noa_index = noa_index; p2pinfo->opp_ps = (ie[4] >> 7); p2pinfo->ctwindow = ie[4] & 0x7F; @@ -854,7 +854,7 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, if (ie == NULL) return; - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "action frame find P2P IE.\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "action frame find P2P IE.\n"); /*to find noa ie*/ while (ie + 1 < end) { noa_len = READEF2BYTE((__le16 *)&ie[1]); @@ -862,13 +862,13 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, return; if (ie[0] == 12) { - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "find NOA IE.\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "find NOA IE.\n"); RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_LOUD, "noa ie ", ie, noa_len); if ((noa_len - 2) % 13 != 0) { - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, - "P2P notice of absence: invalid length.%d\n", - noa_len); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "P2P notice of absence: invalid length.%d\n", + noa_len); return; } else { noa_num = (noa_len - 2) / 13; @@ -926,7 +926,7 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw , u8 p2p_ps_state) struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, " p2p state %x\n" , p2p_ps_state); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, " p2p state %x\n", p2p_ps_state); switch (p2p_ps_state) { case P2P_PS_DISABLE: p2pinfo->p2p_ps_state = p2p_ps_state; @@ -978,18 +978,18 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw , u8 p2p_ps_state) default: break; } - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, - "ctwindow %x oppps %x\n", - p2pinfo->ctwindow , p2pinfo->opp_ps); - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, - "count %x duration %x index %x interval %x start time %x noa num %x\n", - p2pinfo->noa_count_type[0], - p2pinfo->noa_duration[0], - p2pinfo->noa_index, - p2pinfo->noa_interval[0], - p2pinfo->noa_start_time[0], - p2pinfo->noa_num); - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "end\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "ctwindow %x oppps %x\n", + p2pinfo->ctwindow, p2pinfo->opp_ps); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "count %x duration %x index %x interval %x start time %x noa num %x\n", + p2pinfo->noa_count_type[0], + p2pinfo->noa_duration[0], + p2pinfo->noa_index, + p2pinfo->noa_interval[0], + p2pinfo->noa_start_time[0], + p2pinfo->noa_num); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "end\n"); } void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len) diff --git a/drivers/net/wireless/realtek/rtlwifi/regd.c b/drivers/net/wireless/realtek/rtlwifi/regd.c index 72ca370331fb..f89f60ddfebe 100644 --- a/drivers/net/wireless/realtek/rtlwifi/regd.c +++ b/drivers/net/wireless/realtek/rtlwifi/regd.c @@ -434,13 +434,13 @@ int rtl_regd_init(struct ieee80211_hw *hw, rtlpriv->regd.country_code = channel_plan_to_country_code(rtlpriv->efuse.channel_plan); - RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, - "rtl: EEPROM regdomain: 0x%0x country code: %d\n", - rtlpriv->efuse.channel_plan, rtlpriv->regd.country_code); + rtl_dbg(rtlpriv, COMP_REGD, DBG_DMESG, + "rtl: EEPROM regdomain: 0x%0x country code: %d\n", + rtlpriv->efuse.channel_plan, rtlpriv->regd.country_code); if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { - RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, - "rtl: EEPROM indicates invalid country code, world wide 13 should be used\n"); + rtl_dbg(rtlpriv, COMP_REGD, DBG_DMESG, + "rtl: EEPROM indicates invalid country code, world wide 13 should be used\n"); rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; } @@ -455,9 +455,9 @@ int rtl_regd_init(struct ieee80211_hw *hw, rtlpriv->regd.alpha2[1] = '0'; } - RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, - "rtl: Country alpha2 being used: %c%c\n", - rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); + rtl_dbg(rtlpriv, COMP_REGD, DBG_TRACE, + "rtl: Country alpha2 being used: %c%c\n", + rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); @@ -469,7 +469,7 @@ void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); + rtl_dbg(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); } diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c index 395671383ca9..35ebbd8ca9ca 100644 --- a/drivers/net/wireless/realtek/rtlwifi/usb.c +++ b/drivers/net/wireless/realtek/rtlwifi/usb.c @@ -282,14 +282,14 @@ static int _rtl_usb_init_tx(struct ieee80211_hw *hw) ? USB_HIGH_SPEED_BULK_SIZE : USB_FULL_SPEED_BULK_SIZE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "USB Max Bulk-out Size=%d\n", - rtlusb->max_bulk_out_size); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "USB Max Bulk-out Size=%d\n", + rtlusb->max_bulk_out_size); for (i = 0; i < __RTL_TXQ_NUM; i++) { u32 ep_num = rtlusb->ep_map.ep_mapping[i]; if (!ep_num) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "Invalid endpoint map setting!\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Invalid endpoint map setting!\n"); return -EINVAL; } } @@ -358,10 +358,10 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) else if (usb_endpoint_dir_out(pep_desc)) rtlusb->out_ep_nums++; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "USB EP(0x%02x), MaxPacketSize=%d, Interval=%d\n", - pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, - pep_desc->bInterval); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "USB EP(0x%02x), MaxPacketSize=%d, Interval=%d\n", + pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, + pep_desc->bInterval); } if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) { pr_err("Too few input end points found\n"); @@ -960,7 +960,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); } if (rtlpriv->psc.sw_ps_enabled) { From 8b9af7b6aadc36b524bcff0a95965e01216a229a Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Sun, 26 Mar 2023 05:31:38 +0000 Subject: [PATCH 061/190] wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_rfreg() [ Upstream commit 905a9241e4e8c15d2c084fee916280514848fe35 ] If there is a failure during copy_from_user or user-provided data buffer is invalid, rtl_debugfs_set_write_rfreg should return negative error code instead of a positive value count. Fix this bug by returning correct error code. Moreover, the check of buffer against null is removed since it will be handled by copy_from_user. Fixes: 610247f46feb ("rtlwifi: Improve debugging by using debugfs") Signed-off-by: Wei Chen Reviewed-by: Simon Horman Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230326053138.91338-1-harperchen1110@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtlwifi/debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c index cead66f7eb9f..deacc7a28d3a 100644 --- a/drivers/net/wireless/realtek/rtlwifi/debug.c +++ b/drivers/net/wireless/realtek/rtlwifi/debug.c @@ -416,8 +416,8 @@ static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp, tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); - if (!buffer || copy_from_user(tmp, buffer, tmp_len)) - return count; + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT; tmp[tmp_len] = '\0'; @@ -427,7 +427,7 @@ static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp, if (num != 4) { rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, "Format is \n"); - return count; + return -EINVAL; } rtl_set_rfreg(hw, path, addr, bitmask, data); From fdd067ce935a17e5c3276754284fb966f758b8fa Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Sun, 26 Mar 2023 05:42:17 +0000 Subject: [PATCH 062/190] wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_reg() [ Upstream commit 5dbe1f8eb8c5ac69394400a5b86fd81775e96c43 ] If there is a failure during copy_from_user or user-provided data buffer is invalid, rtl_debugfs_set_write_reg should return negative error code instead of a positive value count. Fix this bug by returning correct error code. Moreover, the check of buffer against null is removed since it will be handled by copy_from_user. Fixes: 610247f46feb ("rtlwifi: Improve debugging by using debugfs") Signed-off-by: Wei Chen Reviewed-by: Simon Horman Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230326054217.93492-1-harperchen1110@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/realtek/rtlwifi/debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c index deacc7a28d3a..6a0dfc6d4905 100644 --- a/drivers/net/wireless/realtek/rtlwifi/debug.c +++ b/drivers/net/wireless/realtek/rtlwifi/debug.c @@ -319,8 +319,8 @@ static ssize_t rtl_debugfs_set_write_reg(struct file *filp, tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); - if (!buffer || copy_from_user(tmp, buffer, tmp_len)) - return count; + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT; tmp[tmp_len] = '\0'; @@ -328,7 +328,7 @@ static ssize_t rtl_debugfs_set_write_reg(struct file *filp, num = sscanf(tmp, "%x %x %x", &addr, &val, &len); if (num != 3) - return count; + return -EINVAL; switch (len) { case 1: From 1ad26fcb66b32a762f7ac57f4c780a216c37901b Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Wed, 5 Apr 2023 14:21:15 +0100 Subject: [PATCH 063/190] bpftool: Fix bug for long instructions in program CFG dumps [ Upstream commit 67cf52cdb6c8fa6365d29106555dacf95c9fd374 ] When dumping the control flow graphs for programs using the 16-byte long load instruction, we need to skip the second part of this instruction when looking for the next instruction to process. Otherwise, we end up printing "BUG_ld_00" from the kernel disassembler in the CFG. Fixes: efcef17a6d65 ("tools: bpftool: generate .dot graph from CFG information") Signed-off-by: Quentin Monnet Link: https://lore.kernel.org/r/20230405132120.59886-3-quentin@isovalent.com Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- tools/bpf/bpftool/xlated_dumper.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c index 3284759df98a..7f49347bf5aa 100644 --- a/tools/bpf/bpftool/xlated_dumper.c +++ b/tools/bpf/bpftool/xlated_dumper.c @@ -336,8 +336,15 @@ void dump_xlated_for_graph(struct dump_data *dd, void *buf_start, void *buf_end, struct bpf_insn *insn_start = buf_start; struct bpf_insn *insn_end = buf_end; struct bpf_insn *cur = insn_start; + bool double_insn = false; for (; cur <= insn_end; cur++) { + if (double_insn) { + double_insn = false; + continue; + } + double_insn = cur->code == (BPF_LD | BPF_IMM | BPF_DW); + printf("% 4d: ", (int)(cur - insn_start + start_idx)); print_bpf_insn(&cbs, cur, true); if (cur != insn_end) From f1943e5703861f89f4376596e3d28d0dd52c5ead Mon Sep 17 00:00:00 2001 From: Nicolai Stange Date: Mon, 15 Nov 2021 15:18:08 +0100 Subject: [PATCH 064/190] crypto: drbg - make drbg_prepare_hrng() handle jent instantiation errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 559edd47cce4cc407d606b4d7f376822816fd4b8 ] Now that drbg_prepare_hrng() doesn't do anything but to instantiate a jitterentropy crypto_rng instance, it looks a little odd to have the related error handling at its only caller, drbg_instantiate(). Move the handling of jitterentropy allocation failures from drbg_instantiate() close to the allocation itself in drbg_prepare_hrng(). There is no change in behaviour. Signed-off-by: Nicolai Stange Reviewed-by: Stephan Müller Signed-off-by: Herbert Xu Stable-dep-of: 686cd976b6dd ("crypto: drbg - Only fail when jent is unavailable in FIPS mode") Signed-off-by: Sasha Levin --- crypto/drbg.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crypto/drbg.c b/crypto/drbg.c index c8c56763dfde..8b80fd3690ff 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -1512,6 +1512,14 @@ static int drbg_prepare_hrng(struct drbg_state *drbg) return 0; drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0); + if (IS_ERR(drbg->jent)) { + const int err = PTR_ERR(drbg->jent); + + drbg->jent = NULL; + if (fips_enabled || err != -ENOENT) + return err; + pr_info("DRBG: Continuing without Jitter RNG\n"); + } return 0; } @@ -1567,14 +1575,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers, if (ret) goto free_everything; - if (IS_ERR(drbg->jent)) { - ret = PTR_ERR(drbg->jent); - drbg->jent = NULL; - if (fips_enabled || ret != -ENOENT) - goto free_everything; - pr_info("DRBG: Continuing without Jitter RNG\n"); - } - reseed = false; } From 1fd247c1ded58f9bc1130fe4b26fb187fa1af55d Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 28 Mar 2023 11:35:23 +0800 Subject: [PATCH 065/190] crypto: drbg - Only fail when jent is unavailable in FIPS mode [ Upstream commit 686cd976b6ddedeeb1a1fb09ba53a891d3cc9a03 ] When jent initialisation fails for any reason other than ENOENT, the entire drbg fails to initialise, even when we're not in FIPS mode. This is wrong because we can still use the kernel RNG when we're not in FIPS mode. Change it so that it only fails when we are in FIPS mode. Fixes: 57225e679788 ("crypto: drbg - Use callback API for random readiness") Signed-off-by: Herbert Xu Reviewed-by: Stephan Mueller Signed-off-by: Herbert Xu Signed-off-by: Sasha Levin --- crypto/drbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/drbg.c b/crypto/drbg.c index 8b80fd3690ff..0df8cc9bb563 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -1516,7 +1516,7 @@ static int drbg_prepare_hrng(struct drbg_state *drbg) const int err = PTR_ERR(drbg->jent); drbg->jent = NULL; - if (fips_enabled || err != -ENOENT) + if (fips_enabled) return err; pr_info("DRBG: Continuing without Jitter RNG\n"); } From 1d2c6c6e37fe5de11fd01a82badf03390e12df7a Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Fri, 10 Mar 2023 15:38:53 +0800 Subject: [PATCH 066/190] md/raid10: fix leak of 'r10bio->remaining' for recovery [ Upstream commit 26208a7cffd0c7cbf14237ccd20c7270b3ffeb7e ] raid10_sync_request() will add 'r10bio->remaining' for both rdev and replacement rdev. However, if the read io fails, recovery_request_write() returns without issuing the write io, in this case, end_sync_request() is only called once and 'remaining' is leaked, cause an io hang. Fix the problem by decreasing 'remaining' according to if 'bio' and 'repl_bio' is valid. Fixes: 24afd80d99f8 ("md/raid10: handle recovery of replacement devices.") Signed-off-by: Yu Kuai Signed-off-by: Song Liu Link: https://lore.kernel.org/r/20230310073855.1337560-5-yukuai1@huaweicloud.com Signed-off-by: Sasha Levin --- drivers/md/raid10.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 9f9cd2fadc1e..8181d9a375f0 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2266,11 +2266,22 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio) { struct r10conf *conf = mddev->private; int d; - struct bio *wbio, *wbio2; + struct bio *wbio = r10_bio->devs[1].bio; + struct bio *wbio2 = r10_bio->devs[1].repl_bio; + + /* Need to test wbio2->bi_end_io before we call + * generic_make_request as if the former is NULL, + * the latter is free to free wbio2. + */ + if (wbio2 && !wbio2->bi_end_io) + wbio2 = NULL; if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) { fix_recovery_read_error(r10_bio); - end_sync_request(r10_bio); + if (wbio->bi_end_io) + end_sync_request(r10_bio); + if (wbio2) + end_sync_request(r10_bio); return; } @@ -2279,14 +2290,6 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio) * and submit the write request */ d = r10_bio->devs[1].devnum; - wbio = r10_bio->devs[1].bio; - wbio2 = r10_bio->devs[1].repl_bio; - /* Need to test wbio2->bi_end_io before we call - * generic_make_request as if the former is NULL, - * the latter is free to free wbio2. - */ - if (wbio2 && !wbio2->bi_end_io) - wbio2 = NULL; if (wbio->bi_end_io) { atomic_inc(&conf->mirrors[d].rdev->nr_pending); md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio)); From 133008af833b4f2e021d2c294c29c70364a3f0ba Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Fri, 10 Mar 2023 15:38:54 +0800 Subject: [PATCH 067/190] md/raid10: fix memleak for 'conf->bio_split' [ Upstream commit c9ac2acde53f5385de185bccf6aaa91cf9ac1541 ] In the error path of raid10_run(), 'conf' need be freed, however, 'conf->bio_split' is missed and memory will be leaked. Since there are 3 places to free 'conf', factor out a helper to fix the problem. Fixes: fc9977dd069e ("md/raid10: simplify the splitting of requests.") Signed-off-by: Yu Kuai Signed-off-by: Song Liu Link: https://lore.kernel.org/r/20230310073855.1337560-6-yukuai1@huaweicloud.com Signed-off-by: Sasha Levin --- drivers/md/raid10.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 8181d9a375f0..fca95eb3cb1f 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3671,6 +3671,20 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new) return nc*fc; } +static void raid10_free_conf(struct r10conf *conf) +{ + if (!conf) + return; + + mempool_exit(&conf->r10bio_pool); + kfree(conf->mirrors); + kfree(conf->mirrors_old); + kfree(conf->mirrors_new); + safe_put_page(conf->tmppage); + bioset_exit(&conf->bio_split); + kfree(conf); +} + static struct r10conf *setup_conf(struct mddev *mddev) { struct r10conf *conf = NULL; @@ -3753,13 +3767,7 @@ static struct r10conf *setup_conf(struct mddev *mddev) return conf; out: - if (conf) { - mempool_exit(&conf->r10bio_pool); - kfree(conf->mirrors); - safe_put_page(conf->tmppage); - bioset_exit(&conf->bio_split); - kfree(conf); - } + raid10_free_conf(conf); return ERR_PTR(err); } @@ -3973,10 +3981,7 @@ static int raid10_run(struct mddev *mddev) out_free_conf: md_unregister_thread(&mddev->thread); - mempool_exit(&conf->r10bio_pool); - safe_put_page(conf->tmppage); - kfree(conf->mirrors); - kfree(conf); + raid10_free_conf(conf); mddev->private = NULL; out: return -EIO; @@ -3984,15 +3989,7 @@ out: static void raid10_free(struct mddev *mddev, void *priv) { - struct r10conf *conf = priv; - - mempool_exit(&conf->r10bio_pool); - safe_put_page(conf->tmppage); - kfree(conf->mirrors); - kfree(conf->mirrors_old); - kfree(conf->mirrors_new); - bioset_exit(&conf->bio_split); - kfree(conf); + raid10_free_conf(priv); } static void raid10_quiesce(struct mddev *mddev, int quiesce) From 49de75fc7ca979c6eadbd35d3ed263ed53973d8f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 24 Sep 2020 08:51:33 +0200 Subject: [PATCH 068/190] md: update the optimal I/O size on reshape [ Upstream commit 16ef510139315a2147ee7525796f8dbd4e4b7864 ] The raid5 and raid10 drivers currently update the read-ahead size, but not the optimal I/O size on reshape. To prepare for deriving the read-ahead size from the optimal I/O size make sure it is updated as well. Signed-off-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Reviewed-by: Martin K. Petersen Acked-by: Song Liu Signed-off-by: Jens Axboe Stable-dep-of: f0ddb83da3cb ("md/raid10: fix memleak of md thread") Signed-off-by: Sasha Levin --- drivers/md/raid10.c | 22 ++++++++++++++-------- drivers/md/raid5.c | 10 ++++++++-- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index fca95eb3cb1f..2a7f9df5b82c 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3771,10 +3771,20 @@ static struct r10conf *setup_conf(struct mddev *mddev) return ERR_PTR(err); } +static void raid10_set_io_opt(struct r10conf *conf) +{ + int raid_disks = conf->geo.raid_disks; + + if (!(conf->geo.raid_disks % conf->geo.near_copies)) + raid_disks /= conf->geo.near_copies; + blk_queue_io_opt(conf->mddev->queue, (conf->mddev->chunk_sectors << 9) * + raid_disks); +} + static int raid10_run(struct mddev *mddev) { struct r10conf *conf; - int i, disk_idx, chunk_size; + int i, disk_idx; struct raid10_info *disk; struct md_rdev *rdev; sector_t size; @@ -3810,18 +3820,13 @@ static int raid10_run(struct mddev *mddev) mddev->thread = conf->thread; conf->thread = NULL; - chunk_size = mddev->chunk_sectors << 9; if (mddev->queue) { blk_queue_max_discard_sectors(mddev->queue, mddev->chunk_sectors); blk_queue_max_write_same_sectors(mddev->queue, 0); blk_queue_max_write_zeroes_sectors(mddev->queue, 0); - blk_queue_io_min(mddev->queue, chunk_size); - if (conf->geo.raid_disks % conf->geo.near_copies) - blk_queue_io_opt(mddev->queue, chunk_size * conf->geo.raid_disks); - else - blk_queue_io_opt(mddev->queue, chunk_size * - (conf->geo.raid_disks / conf->geo.near_copies)); + blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9); + raid10_set_io_opt(conf); } rdev_for_each(rdev, mddev) { @@ -4724,6 +4729,7 @@ static void end_reshape(struct r10conf *conf) stripe /= conf->geo.near_copies; if (conf->mddev->queue->backing_dev_info->ra_pages < 2 * stripe) conf->mddev->queue->backing_dev_info->ra_pages = 2 * stripe; + raid10_set_io_opt(conf); } conf->fullsync = 0; } diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 7fe0619c487a..7eeae0301ccc 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -7153,6 +7153,12 @@ static int only_parity(int raid_disk, int algo, int raid_disks, int max_degraded return 0; } +static void raid5_set_io_opt(struct r5conf *conf) +{ + blk_queue_io_opt(conf->mddev->queue, (conf->chunk_sectors << 9) * + (conf->raid_disks - conf->max_degraded)); +} + static int raid5_run(struct mddev *mddev) { struct r5conf *conf; @@ -7442,8 +7448,7 @@ static int raid5_run(struct mddev *mddev) chunk_size = mddev->chunk_sectors << 9; blk_queue_io_min(mddev->queue, chunk_size); - blk_queue_io_opt(mddev->queue, chunk_size * - (conf->raid_disks - conf->max_degraded)); + raid5_set_io_opt(conf); mddev->queue->limits.raid_partial_stripes_expensive = 1; /* * We can only discard a whole stripe. It doesn't make sense to @@ -8037,6 +8042,7 @@ static void end_reshape(struct r5conf *conf) / PAGE_SIZE); if (conf->mddev->queue->backing_dev_info->ra_pages < 2 * stripe) conf->mddev->queue->backing_dev_info->ra_pages = 2 * stripe; + raid5_set_io_opt(conf); } } } From abf4d67060c8f63caff096e5fca1564bfef1e5d4 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Fri, 10 Mar 2023 15:38:55 +0800 Subject: [PATCH 069/190] md/raid10: fix memleak of md thread [ Upstream commit f0ddb83da3cbbf8a1f9087a642c448ff52ee9abd ] In raid10_run(), if setup_conf() succeed and raid10_run() failed before setting 'mddev->thread', then in the error path 'conf->thread' is not freed. Fix the problem by setting 'mddev->thread' right after setup_conf(). Fixes: 43a521238aca ("md-cluster: choose correct label when clustered layout is not supported") Signed-off-by: Yu Kuai Signed-off-by: Song Liu Link: https://lore.kernel.org/r/20230310073855.1337560-7-yukuai1@huaweicloud.com Signed-off-by: Sasha Levin --- drivers/md/raid10.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 2a7f9df5b82c..dc625f9cfa9d 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3805,6 +3805,9 @@ static int raid10_run(struct mddev *mddev) if (!conf) goto out; + mddev->thread = conf->thread; + conf->thread = NULL; + if (mddev_is_clustered(conf->mddev)) { int fc, fo; @@ -3817,9 +3820,6 @@ static int raid10_run(struct mddev *mddev) } } - mddev->thread = conf->thread; - conf->thread = NULL; - if (mddev->queue) { blk_queue_max_discard_sectors(mddev->queue, mddev->chunk_sectors); From c2cd1a9a23d3fdbe88b2ebef187d57cde5f3b644 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 16 Apr 2023 15:47:38 +0300 Subject: [PATCH 070/190] wifi: iwlwifi: make the loop for card preparation effective [ Upstream commit 28965ec0b5d9112585f725660e2ff13218505ace ] Since we didn't reset t to 0, only the first iteration of the loop did checked the ready bit several times. From the second iteration and on, we just tested the bit once and continued to the next iteration. Reported-and-tested-by: Lorenzo Zolfanelli Link: https://bugzilla.kernel.org/show_bug.cgi?id=216452 Fixes: 289e5501c314 ("iwlwifi: fix the preparation of the card") Signed-off-by: Emmanuel Grumbach Signed-off-by: Gregory Greenman Link: https://lore.kernel.org/r/20230416154301.615b683ab9c8.Ic52c3229d3345b0064fa34263293db095d88daf8@changeid Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 2d2afc175830..c69c13e762bb 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -666,7 +666,6 @@ static int iwl_pcie_set_hw_ready(struct iwl_trans *trans) int iwl_pcie_prepare_card_hw(struct iwl_trans *trans) { int ret; - int t = 0; int iter; IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); @@ -681,6 +680,8 @@ int iwl_pcie_prepare_card_hw(struct iwl_trans *trans) usleep_range(1000, 2000); for (iter = 0; iter < 10; iter++) { + int t = 0; + /* If HW is not ready, prepare the conditions to check again */ iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE); From 38f32fbc658afa58608f6a6e9f2f987cf211b422 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 17 Apr 2023 11:41:33 +0300 Subject: [PATCH 071/190] wifi: iwlwifi: mvm: check firmware response size [ Upstream commit 13513cec93ac9902d0b896976d8bab3758a9881c ] Check the firmware response size for responses to the memory read/write command in debugfs before using it. Fixes: 2b55f43f8e47 ("iwlwifi: mvm: Add mem debugfs entry") Signed-off-by: Johannes Berg Signed-off-by: Gregory Greenman Link: https://lore.kernel.org/r/20230417113648.0d56fcaf68ee.I70e9571f3ed7263929b04f8fabad23c9b999e4ea@changeid Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 05b77419953c..9540c874fc38 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1835,6 +1835,11 @@ static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf, if (ret < 0) return ret; + if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) { + ret = -EIO; + goto out; + } + rsp = (void *)hcmd.resp_pkt->data; if (le32_to_cpu(rsp->status) != DEBUG_MEM_STATUS_SUCCESS) { ret = -ENXIO; @@ -1912,6 +1917,11 @@ static ssize_t iwl_dbgfs_mem_write(struct file *file, if (ret < 0) return ret; + if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) { + ret = -EIO; + goto out; + } + rsp = (void *)hcmd.resp_pkt->data; if (rsp->status != DEBUG_MEM_STATUS_SUCCESS) { ret = -ENXIO; From 503c3308972c622c1de801138f8a1ce0c1ffe28a Mon Sep 17 00:00:00 2001 From: Joe Damato Date: Sun, 16 Apr 2023 19:12:22 +0000 Subject: [PATCH 072/190] ixgbe: Allow flow hash to be set via ethtool [ Upstream commit 4f3ed1293feb9502dc254b05802faf1ad3317ac6 ] ixgbe currently returns `EINVAL` whenever the flowhash it set by ethtool because the ethtool code in the kernel passes a non-zero value for hfunc that ixgbe should allow. When ethtool is called with `ETHTOOL_SRXFHINDIR`, `ethtool_set_rxfh_indir` will call ixgbe's set_rxfh function with `ETH_RSS_HASH_NO_CHANGE`. This value should be accepted. When ethtool is called with `ETHTOOL_SRSSH`, `ethtool_set_rxfh` will call ixgbe's set_rxfh function with `rxfh.hfunc`, which appears to be hardcoded in ixgbe to always be `ETH_RSS_HASH_TOP`. This value should also be accepted. Before this patch: $ sudo ethtool -L eth1 combined 10 $ sudo ethtool -X eth1 default Cannot set RX flow hash configuration: Invalid argument After this patch: $ sudo ethtool -L eth1 combined 10 $ sudo ethtool -X eth1 default $ sudo ethtool -x eth1 RX flow hash indirection table for eth1 with 10 RX ring(s): 0: 0 1 2 3 4 5 6 7 8: 8 9 0 1 2 3 4 5 16: 6 7 8 9 0 1 2 3 24: 4 5 6 7 8 9 0 1 ... Fixes: 1c7cf0784e4d ("ixgbe: support for ethtool set_rxfh") Signed-off-by: Joe Damato Reviewed-by: Sridhar Samudrala Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 8829bd95d0d3..a852f9c92074 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -3005,8 +3005,8 @@ static int ixgbe_set_rxfh(struct net_device *netdev, const u32 *indir, int i; u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter); - if (hfunc) - return -EINVAL; + if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) + return -EOPNOTSUPP; /* Fill out the redirection table */ if (indir) { From d72cdce4997470768a4a52de91e46b3ec12c2738 Mon Sep 17 00:00:00 2001 From: Joe Damato Date: Sun, 16 Apr 2023 19:12:23 +0000 Subject: [PATCH 073/190] ixgbe: Enable setting RSS table to default values [ Upstream commit e85d3d55875f7a1079edfbc4e4e98d6f8aea9ac7 ] ethtool uses `ETHTOOL_GRXRINGS` to compute how many queues are supported by RSS. The driver should return the smaller of either: - The maximum number of RSS queues the device supports, OR - The number of RX queues configured Prior to this change, running `ethtool -X $iface default` fails if the number of queues configured is larger than the number supported by RSS, even though changing the queue count correctly resets the flowhash to use all supported queues. Other drivers (for example, i40e) will succeed but the flow hash will reset to support the maximum number of queues supported by RSS, even if that amount is smaller than the configured amount. Prior to this change: $ sudo ethtool -L eth1 combined 20 $ sudo ethtool -x eth1 RX flow hash indirection table for eth1 with 20 RX ring(s): 0: 0 1 2 3 4 5 6 7 8: 8 9 10 11 12 13 14 15 16: 0 1 2 3 4 5 6 7 24: 8 9 10 11 12 13 14 15 32: 0 1 2 3 4 5 6 7 ... You can see that the flowhash was correctly set to use the maximum number of queues supported by the driver (16). However, asking the NIC to reset to "default" fails: $ sudo ethtool -X eth1 default Cannot set RX flow hash configuration: Invalid argument After this change, the flowhash can be reset to default which will use all of the available RSS queues (16) or the configured queue count, whichever is smaller. Starting with eth1 which has 10 queues and a flowhash distributing to all 10 queues: $ sudo ethtool -x eth1 RX flow hash indirection table for eth1 with 10 RX ring(s): 0: 0 1 2 3 4 5 6 7 8: 8 9 0 1 2 3 4 5 16: 6 7 8 9 0 1 2 3 ... Increasing the queue count to 48 resets the flowhash to distribute to 16 queues, as it did before this patch: $ sudo ethtool -L eth1 combined 48 $ sudo ethtool -x eth1 RX flow hash indirection table for eth1 with 16 RX ring(s): 0: 0 1 2 3 4 5 6 7 8: 8 9 10 11 12 13 14 15 16: 0 1 2 3 4 5 6 7 ... Due to the other bugfix in this series, the flowhash can be set to use queues 0-5: $ sudo ethtool -X eth1 equal 5 $ sudo ethtool -x eth1 RX flow hash indirection table for eth1 with 16 RX ring(s): 0: 0 1 2 3 4 0 1 2 8: 3 4 0 1 2 3 4 0 16: 1 2 3 4 0 1 2 3 ... Due to this bugfix, the flowhash can be reset to default and use 16 queues: $ sudo ethtool -X eth1 default $ sudo ethtool -x eth1 RX flow hash indirection table for eth1 with 16 RX ring(s): 0: 0 1 2 3 4 5 6 7 8: 8 9 10 11 12 13 14 15 16: 0 1 2 3 4 5 6 7 ... Fixes: 91cd94bfe4f0 ("ixgbe: add basic support for setting and getting nfc controls") Signed-off-by: Joe Damato Reviewed-by: Sridhar Samudrala Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Signed-off-by: Sasha Levin --- .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index a852f9c92074..3d361557a63a 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -2539,6 +2539,14 @@ static int ixgbe_get_rss_hash_opts(struct ixgbe_adapter *adapter, return 0; } +static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter) +{ + if (adapter->hw.mac.type < ixgbe_mac_X550) + return 16; + else + return 64; +} + static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, u32 *rule_locs) { @@ -2547,7 +2555,8 @@ static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, switch (cmd->cmd) { case ETHTOOL_GRXRINGS: - cmd->data = adapter->num_rx_queues; + cmd->data = min_t(int, adapter->num_rx_queues, + ixgbe_rss_indir_tbl_max(adapter)); ret = 0; break; case ETHTOOL_GRXCLSRLCNT: @@ -2949,14 +2958,6 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) return ret; } -static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter) -{ - if (adapter->hw.mac.type < ixgbe_mac_X550) - return 16; - else - return 64; -} - static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev) { return IXGBE_RSS_KEY_SIZE; From 1f7641bc82fa1f839240cd8ce94f0fbb7cba9f9f Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Thu, 13 Apr 2023 17:13:19 +0200 Subject: [PATCH 074/190] netfilter: nf_tables: don't write table validation state without mutex [ Upstream commit 9a32e9850686599ed194ccdceb6cd3dd56b2d9b9 ] The ->cleanup callback needs to be removed, this doesn't work anymore as the transaction mutex is already released in the ->abort function. Just do it after a successful validation pass, this either happens from commit or abort phases where transaction mutex is held. Fixes: f102d66b335a ("netfilter: nf_tables: use dedicated mutex to guard transactions") Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso Signed-off-by: Sasha Levin --- include/linux/netfilter/nfnetlink.h | 1 - net/netfilter/nf_tables_api.c | 8 ++------ net/netfilter/nfnetlink.c | 2 -- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index e713476ff29d..a806803fbe37 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -32,7 +32,6 @@ struct nfnetlink_subsystem { struct module *owner; int (*commit)(struct net *net, struct sk_buff *skb); int (*abort)(struct net *net, struct sk_buff *skb); - void (*cleanup)(struct net *net); bool (*valid_genid)(struct net *net, u32 genid); }; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 079f76849693..d7a082d5cd70 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -6241,6 +6241,8 @@ static int nf_tables_validate(struct net *net) if (nft_table_validate(net, table) < 0) return -EAGAIN; } + + nft_validate_state_update(net, NFT_VALIDATE_SKIP); break; } @@ -6767,11 +6769,6 @@ static int __nf_tables_abort(struct net *net) return 0; } -static void nf_tables_cleanup(struct net *net) -{ - nft_validate_state_update(net, NFT_VALIDATE_SKIP); -} - static int nf_tables_abort(struct net *net, struct sk_buff *skb) { int ret = __nf_tables_abort(net); @@ -6802,7 +6799,6 @@ static const struct nfnetlink_subsystem nf_tables_subsys = { .cb = nf_tables_cb, .commit = nf_tables_commit, .abort = nf_tables_abort, - .cleanup = nf_tables_cleanup, .valid_genid = nf_tables_valid_genid, .owner = THIS_MODULE, }; diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 9bacddc761ba..39e369e18cb8 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -495,8 +495,6 @@ done: } else { ss->abort(net, oskb); } - if (ss->cleanup) - ss->cleanup(net); nfnl_err_deliver(&err_list, oskb); kfree_skb(skb); From 022ea4374c319690c804706bda9dc42946d1556d Mon Sep 17 00:00:00 2001 From: Ziyang Xuan Date: Thu, 20 Apr 2023 20:40:35 +0800 Subject: [PATCH 075/190] ipv4: Fix potential uninit variable access bug in __ip_make_skb() [ Upstream commit 99e5acae193e369b71217efe6f1dad42f3f18815 ] Like commit ea30388baebc ("ipv6: Fix an uninit variable access bug in __ip6_make_skb()"). icmphdr does not in skb linear region under the scenario of SOCK_RAW socket. Access icmp_hdr(skb)->type directly will trigger the uninit variable access bug. Use a local variable icmp_type to carry the correct value in different scenarios. Fixes: 96793b482540 ("[IPV4]: Add ICMPMsgStats MIB (RFC 4293)") Reviewed-by: Willem de Bruijn Signed-off-by: Ziyang Xuan Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv4/ip_output.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 06a981676356..92fa11e75a4d 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1443,9 +1443,19 @@ struct sk_buff *__ip_make_skb(struct sock *sk, cork->dst = NULL; skb_dst_set(skb, &rt->dst); - if (iph->protocol == IPPROTO_ICMP) - icmp_out_count(net, ((struct icmphdr *) - skb_transport_header(skb))->type); + if (iph->protocol == IPPROTO_ICMP) { + u8 icmp_type; + + /* For such sockets, transhdrlen is zero when do ip_append_data(), + * so icmphdr does not in skb linear region and can not get icmp_type + * by icmp_hdr(skb)->type. + */ + if (sk->sk_type == SOCK_RAW && !inet_sk(sk)->hdrincl) + icmp_type = fl4->fl4_icmp_type; + else + icmp_type = icmp_hdr(skb)->type; + icmp_out_count(net, icmp_type); + } ip_cork_release(cork); out: From 70a104588e3131415e559c06deb834ce259a285a Mon Sep 17 00:00:00 2001 From: Liu Jian Date: Fri, 14 Apr 2023 18:30:06 +0800 Subject: [PATCH 076/190] Revert "Bluetooth: btsdio: fix use after free bug in btsdio_remove due to unfinished work" [ Upstream commit db2bf510bd5d57f064d9e1db395ed86a08320c54 ] This reverts commit 1e9ac114c4428fdb7ff4635b45d4f46017e8916f. This patch introduces a possible null-ptr-def problem. Revert it. And the fixed bug by this patch have resolved by commit 73f7b171b7c0 ("Bluetooth: btsdio: fix use after free bug in btsdio_remove due to race condition"). Fixes: 1e9ac114c442 ("Bluetooth: btsdio: fix use after free bug in btsdio_remove due to unfinished work") Signed-off-by: Liu Jian Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Sasha Levin --- drivers/bluetooth/btsdio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c index bd55bf7a9914..20142bc77554 100644 --- a/drivers/bluetooth/btsdio.c +++ b/drivers/bluetooth/btsdio.c @@ -353,7 +353,6 @@ static void btsdio_remove(struct sdio_func *func) BT_DBG("func %p", func); - cancel_work_sync(&data->work); if (!data) return; From 9559f37375d7521141b299b06ac9b82f76355638 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Fri, 21 Apr 2023 11:52:55 -0700 Subject: [PATCH 077/190] netlink: Use copy_to_user() for optval in netlink_getsockopt(). [ Upstream commit d913d32cc2707e9cd24fe6fa6d7d470e9c728980 ] Brad Spencer provided a detailed report [0] that when calling getsockopt() for AF_NETLINK, some SOL_NETLINK options set only 1 byte even though such options require at least sizeof(int) as length. The options return a flag value that fits into 1 byte, but such behaviour confuses users who do not initialise the variable before calling getsockopt() and do not strictly check the returned value as char. Currently, netlink_getsockopt() uses put_user() to copy data to optlen and optval, but put_user() casts the data based on the pointer, char *optval. As a result, only 1 byte is set to optval. To avoid this behaviour, we need to use copy_to_user() or cast optval for put_user(). Note that this changes the behaviour on big-endian systems, but we document that the size of optval is int in the man page. $ man 7 netlink ... Socket options To set or get a netlink socket option, call getsockopt(2) to read or setsockopt(2) to write the option with the option level argument set to SOL_NETLINK. Unless otherwise noted, optval is a pointer to an int. Fixes: 9a4595bc7e67 ("[NETLINK]: Add set/getsockopt options to support more than 32 groups") Fixes: be0c22a46cfb ("netlink: add NETLINK_BROADCAST_ERROR socket option") Fixes: 38938bfe3489 ("netlink: add NETLINK_NO_ENOBUFS socket flag") Fixes: 0a6a3a23ea6e ("netlink: add NETLINK_CAP_ACK socket option") Fixes: 2d4bc93368f5 ("netlink: extended ACK reporting") Fixes: 89d35528d17d ("netlink: Add new socket option to enable strict checking on dumps") Reported-by: Brad Spencer Link: https://lore.kernel.org/netdev/ZD7VkNWFfp22kTDt@datsun.rim.net/ Signed-off-by: Kuniyuki Iwashima Reviewed-by: Johannes Berg Link: https://lore.kernel.org/r/20230421185255.94606-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- net/netlink/af_netlink.c | 67 +++++++++++++--------------------------- 1 file changed, 22 insertions(+), 45 deletions(-) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 6a49c0aa55bd..6867158656b8 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1738,7 +1738,8 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, { struct sock *sk = sock->sk; struct netlink_sock *nlk = nlk_sk(sk); - int len, val, err; + unsigned int flag; + int len, val; if (level != SOL_NETLINK) return -ENOPROTOOPT; @@ -1750,39 +1751,17 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, switch (optname) { case NETLINK_PKTINFO: - if (len < sizeof(int)) - return -EINVAL; - len = sizeof(int); - val = nlk->flags & NETLINK_F_RECV_PKTINFO ? 1 : 0; - if (put_user(len, optlen) || - put_user(val, optval)) - return -EFAULT; - err = 0; + flag = NETLINK_F_RECV_PKTINFO; break; case NETLINK_BROADCAST_ERROR: - if (len < sizeof(int)) - return -EINVAL; - len = sizeof(int); - val = nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR ? 1 : 0; - if (put_user(len, optlen) || - put_user(val, optval)) - return -EFAULT; - err = 0; + flag = NETLINK_F_BROADCAST_SEND_ERROR; break; case NETLINK_NO_ENOBUFS: - if (len < sizeof(int)) - return -EINVAL; - len = sizeof(int); - val = nlk->flags & NETLINK_F_RECV_NO_ENOBUFS ? 1 : 0; - if (put_user(len, optlen) || - put_user(val, optval)) - return -EFAULT; - err = 0; + flag = NETLINK_F_RECV_NO_ENOBUFS; break; case NETLINK_LIST_MEMBERSHIPS: { - int pos, idx, shift; + int pos, idx, shift, err = 0; - err = 0; netlink_lock_table(); for (pos = 0; pos * 8 < nlk->ngroups; pos += sizeof(u32)) { if (len - pos < sizeof(u32)) @@ -1799,31 +1778,29 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, if (put_user(ALIGN(nlk->ngroups / 8, sizeof(u32)), optlen)) err = -EFAULT; netlink_unlock_table(); - break; + return err; } case NETLINK_CAP_ACK: - if (len < sizeof(int)) - return -EINVAL; - len = sizeof(int); - val = nlk->flags & NETLINK_F_CAP_ACK ? 1 : 0; - if (put_user(len, optlen) || - put_user(val, optval)) - return -EFAULT; - err = 0; + flag = NETLINK_F_CAP_ACK; break; case NETLINK_EXT_ACK: - if (len < sizeof(int)) - return -EINVAL; - len = sizeof(int); - val = nlk->flags & NETLINK_F_EXT_ACK ? 1 : 0; - if (put_user(len, optlen) || put_user(val, optval)) - return -EFAULT; - err = 0; + flag = NETLINK_F_EXT_ACK; break; default: - err = -ENOPROTOOPT; + return -ENOPROTOOPT; } - return err; + + if (len < sizeof(int)) + return -EINVAL; + + len = sizeof(int); + val = nlk->flags & flag ? 1 : 0; + + if (put_user(len, optlen) || + copy_to_user(optval, &val, len)) + return -EFAULT; + + return 0; } static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb) From 5f17c166b40de3069ae5714a36fc94ca354decab Mon Sep 17 00:00:00 2001 From: Gencen Gan Date: Mon, 24 Apr 2023 23:28:01 +0800 Subject: [PATCH 078/190] net: amd: Fix link leak when verifying config failed [ Upstream commit d325c34d9e7e38d371c0a299d415e9b07f66a1fb ] After failing to verify configuration, it returns directly without releasing link, which may cause memory leak. Paolo Abeni thinks that the whole code of this driver is quite "suboptimal" and looks unmainatained since at least ~15y, so he suggests that we could simply remove the whole driver, please take it into consideration. Simon Horman suggests that the fix label should be set to "Linux-2.6.12-rc2" considering that the problem has existed since the driver was introduced and the commit above doesn't seem to exist in net/net-next. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Gan Gecen Reviewed-by: Dongliang Mu Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/amd/nmclan_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/amd/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c index 9c152d85840d..c9d2a6f15062 100644 --- a/drivers/net/ethernet/amd/nmclan_cs.c +++ b/drivers/net/ethernet/amd/nmclan_cs.c @@ -652,7 +652,7 @@ static int nmclan_config(struct pcmcia_device *link) } else { pr_notice("mace id not found: %x %x should be 0x40 0x?9\n", sig[0], sig[1]); - return -ENODEV; + goto failed; } } From 1f69c086b20e27763af28145981435423f088268 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 24 Apr 2023 15:20:22 -0700 Subject: [PATCH 079/190] tcp/udp: Fix memleaks of sk and zerocopy skbs with TX timestamp. [ Upstream commit 50749f2dd6854a41830996ad302aef2ffaf011d8 ] syzkaller reported [0] memory leaks of an UDP socket and ZEROCOPY skbs. We can reproduce the problem with these sequences: sk = socket(AF_INET, SOCK_DGRAM, 0) sk.setsockopt(SOL_SOCKET, SO_TIMESTAMPING, SOF_TIMESTAMPING_TX_SOFTWARE) sk.setsockopt(SOL_SOCKET, SO_ZEROCOPY, 1) sk.sendto(b'', MSG_ZEROCOPY, ('127.0.0.1', 53)) sk.close() sendmsg() calls msg_zerocopy_alloc(), which allocates a skb, sets skb->cb->ubuf.refcnt to 1, and calls sock_hold(). Here, struct ubuf_info_msgzc indirectly holds a refcnt of the socket. When the skb is sent, __skb_tstamp_tx() clones it and puts the clone into the socket's error queue with the TX timestamp. When the original skb is received locally, skb_copy_ubufs() calls skb_unclone(), and pskb_expand_head() increments skb->cb->ubuf.refcnt. This additional count is decremented while freeing the skb, but struct ubuf_info_msgzc still has a refcnt, so __msg_zerocopy_callback() is not called. The last refcnt is not released unless we retrieve the TX timestamped skb by recvmsg(). Since we clear the error queue in inet_sock_destruct() after the socket's refcnt reaches 0, there is a circular dependency. If we close() the socket holding such skbs, we never call sock_put() and leak the count, sk, and skb. TCP has the same problem, and commit e0c8bccd40fc ("net: stream: purge sk_error_queue in sk_stream_kill_queues()") tried to fix it by calling skb_queue_purge() during close(). However, there is a small chance that skb queued in a qdisc or device could be put into the error queue after the skb_queue_purge() call. In __skb_tstamp_tx(), the cloned skb should not have a reference to the ubuf to remove the circular dependency, but skb_clone() does not call skb_copy_ubufs() for zerocopy skb. So, we need to call skb_orphan_frags_rx() for the cloned skb to call skb_copy_ubufs(). [0]: BUG: memory leak unreferenced object 0xffff88800c6d2d00 (size 1152): comm "syz-executor392", pid 264, jiffies 4294785440 (age 13.044s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 cd af e8 81 00 00 00 00 ................ 02 00 07 40 00 00 00 00 00 00 00 00 00 00 00 00 ...@............ backtrace: [<0000000055636812>] sk_prot_alloc+0x64/0x2a0 net/core/sock.c:2024 [<0000000054d77b7a>] sk_alloc+0x3b/0x800 net/core/sock.c:2083 [<0000000066f3c7e0>] inet_create net/ipv4/af_inet.c:319 [inline] [<0000000066f3c7e0>] inet_create+0x31e/0xe40 net/ipv4/af_inet.c:245 [<000000009b83af97>] __sock_create+0x2ab/0x550 net/socket.c:1515 [<00000000b9b11231>] sock_create net/socket.c:1566 [inline] [<00000000b9b11231>] __sys_socket_create net/socket.c:1603 [inline] [<00000000b9b11231>] __sys_socket_create net/socket.c:1588 [inline] [<00000000b9b11231>] __sys_socket+0x138/0x250 net/socket.c:1636 [<000000004fb45142>] __do_sys_socket net/socket.c:1649 [inline] [<000000004fb45142>] __se_sys_socket net/socket.c:1647 [inline] [<000000004fb45142>] __x64_sys_socket+0x73/0xb0 net/socket.c:1647 [<0000000066999e0e>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] [<0000000066999e0e>] do_syscall_64+0x38/0x90 arch/x86/entry/common.c:80 [<0000000017f238c1>] entry_SYSCALL_64_after_hwframe+0x63/0xcd BUG: memory leak unreferenced object 0xffff888017633a00 (size 240): comm "syz-executor392", pid 264, jiffies 4294785440 (age 13.044s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 2d 6d 0c 80 88 ff ff .........-m..... backtrace: [<000000002b1c4368>] __alloc_skb+0x229/0x320 net/core/skbuff.c:497 [<00000000143579a6>] alloc_skb include/linux/skbuff.h:1265 [inline] [<00000000143579a6>] sock_omalloc+0xaa/0x190 net/core/sock.c:2596 [<00000000be626478>] msg_zerocopy_alloc net/core/skbuff.c:1294 [inline] [<00000000be626478>] msg_zerocopy_realloc+0x1ce/0x7f0 net/core/skbuff.c:1370 [<00000000cbfc9870>] __ip_append_data+0x2adf/0x3b30 net/ipv4/ip_output.c:1037 [<0000000089869146>] ip_make_skb+0x26c/0x2e0 net/ipv4/ip_output.c:1652 [<00000000098015c2>] udp_sendmsg+0x1bac/0x2390 net/ipv4/udp.c:1253 [<0000000045e0e95e>] inet_sendmsg+0x10a/0x150 net/ipv4/af_inet.c:819 [<000000008d31bfde>] sock_sendmsg_nosec net/socket.c:714 [inline] [<000000008d31bfde>] sock_sendmsg+0x141/0x190 net/socket.c:734 [<0000000021e21aa4>] __sys_sendto+0x243/0x360 net/socket.c:2117 [<00000000ac0af00c>] __do_sys_sendto net/socket.c:2129 [inline] [<00000000ac0af00c>] __se_sys_sendto net/socket.c:2125 [inline] [<00000000ac0af00c>] __x64_sys_sendto+0xe1/0x1c0 net/socket.c:2125 [<0000000066999e0e>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] [<0000000066999e0e>] do_syscall_64+0x38/0x90 arch/x86/entry/common.c:80 [<0000000017f238c1>] entry_SYSCALL_64_after_hwframe+0x63/0xcd Fixes: f214f915e7db ("tcp: enable MSG_ZEROCOPY") Fixes: b5947e5d1e71 ("udp: msg_zerocopy") Reported-by: syzbot Signed-off-by: Kuniyuki Iwashima Reviewed-by: Willem de Bruijn Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/core/skbuff.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 7f501dff4501..5ae62d743357 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4445,6 +4445,9 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, skb = alloc_skb(0, GFP_ATOMIC); } else { skb = skb_clone(orig_skb, GFP_ATOMIC); + + if (skb_orphan_frags_rx(skb, GFP_ATOMIC)) + return; } if (!skb) return; From ca379f42eef058d01eede4fc84db825398f0649f Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 8 Mar 2023 20:40:43 +0000 Subject: [PATCH 080/190] pstore: Revert pmsg_lock back to a normal mutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 5239a89b06d6b199f133bf0ffea421683187f257 ] This reverts commit 76d62f24db07f22ccf9bc18ca793c27d4ebef721. So while priority inversion on the pmsg_lock is an occasional problem that an rt_mutex would help with, in uses where logging is writing to pmsg heavily from multiple threads, the pmsg_lock can be heavily contended. After this change landed, it was reported that cases where the mutex locking overhead was commonly adding on the order of 10s of usecs delay had suddenly jumped to ~msec delay with rtmutex. It seems the slight differences in the locks under this level of contention causes the normal mutexes to utilize the spinning optimizations, while the rtmutexes end up in the sleeping slowpath (which allows additional threads to pile on trying to take the lock). In this case, it devolves to a worse case senerio where the lock acquisition and scheduling overhead dominates, and each thread is waiting on the order of ~ms to do ~us of work. Obviously, having tons of threads all contending on a single lock for logging is non-optimal, so the proper fix is probably reworking pstore pmsg to have per-cpu buffers so we don't have contention. Additionally, Steven Rostedt has provided some furhter optimizations for rtmutexes that improves the rtmutex spinning path, but at least in my testing, I still see the test tripping into the sleeping path on rtmutexes while utilizing the spinning path with mutexes. But in the short term, lets revert the change to the rt_mutex and go back to normal mutexes to avoid a potentially major performance regression. And we can work on optimizations to both rtmutexes and finer-grained locking for pstore pmsg in the future. Cc: Wei Wang Cc: Midas Chien Cc: "Chunhui Li (李春辉)" Cc: Steven Rostedt Cc: Kees Cook Cc: Anton Vorontsov Cc: "Guilherme G. Piccoli" Cc: Tony Luck Cc: kernel-team@android.com Fixes: 76d62f24db07 ("pstore: Switch pmsg_lock to an rt_mutex to avoid priority inversion") Reported-by: "Chunhui Li (李春辉)" Signed-off-by: John Stultz Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20230308204043.2061631-1-jstultz@google.com Signed-off-by: Sasha Levin --- fs/pstore/pmsg.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c index ffc13ea196d2..24db02de1787 100644 --- a/fs/pstore/pmsg.c +++ b/fs/pstore/pmsg.c @@ -15,10 +15,9 @@ #include #include #include -#include #include "internal.h" -static DEFINE_RT_MUTEX(pmsg_lock); +static DEFINE_MUTEX(pmsg_lock); static ssize_t write_pmsg(struct file *file, const char __user *buf, size_t count, loff_t *ppos) @@ -37,9 +36,9 @@ static ssize_t write_pmsg(struct file *file, const char __user *buf, if (!access_ok(VERIFY_READ, buf, count)) return -EFAULT; - rt_mutex_lock(&pmsg_lock); + mutex_lock(&pmsg_lock); ret = psinfo->write_user(&record, buf); - rt_mutex_unlock(&pmsg_lock); + mutex_unlock(&pmsg_lock); return ret ? ret : count; } From 7d33ce0f6cd7021e39c0eafeeccb26796c864ff8 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 7 Mar 2023 17:30:37 +0100 Subject: [PATCH 081/190] usb: host: xhci-rcar: remove leftover quirk handling [ Upstream commit 5d67f4861884762ebc2bddb5d667444e45f25782 ] Loading V3 firmware does not need a quirk anymore, remove the leftover code. Fixes: ed8603e11124 ("usb: host: xhci-rcar: Simplify getting the firmware name for R-Car Gen3") Reviewed-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20230307163041.3815-10-wsa+renesas@sang-engineering.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/host/xhci-rcar.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index 4ebbe2c23292..4353c1948e5c 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -74,7 +74,6 @@ MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V3); /* For soc_device_attribute */ #define RCAR_XHCI_FIRMWARE_V2 BIT(0) /* FIRMWARE V2 */ -#define RCAR_XHCI_FIRMWARE_V3 BIT(1) /* FIRMWARE V3 */ static const struct soc_device_attribute rcar_quirks_match[] = { { @@ -156,8 +155,6 @@ static int xhci_rcar_download_firmware(struct usb_hcd *hcd) if (quirks & RCAR_XHCI_FIRMWARE_V2) firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2; - else if (quirks & RCAR_XHCI_FIRMWARE_V3) - firmware_name = XHCI_RCAR_FIRMWARE_NAME_V3; else firmware_name = priv->firmware_name; From f0572d73af4f3862fdc70f46f0e35e7869355c62 Mon Sep 17 00:00:00 2001 From: Marco Pagani Date: Wed, 1 Mar 2023 15:03:08 +0100 Subject: [PATCH 082/190] fpga: bridge: fix kernel-doc parameter description [ Upstream commit 7ef1a2c1c9dffa177ecc3ea50b7f5ee63a621137 ] Fix the kernel-doc description for the "struct fpga_image_info *info" parameter of the fpga_bridge_get() function. Fixes: 060ac5c8fa7b ("fpga: bridge: kernel-doc fixes") Signed-off-by: Marco Pagani Reviewed-by: Tom Rix Acked-by: Xu Yilun Link: https://lore.kernel.org/r/20230301140309.512578-1-marpagan@redhat.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/fpga/fpga-bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c index c983dac97501..c7db12192fac 100644 --- a/drivers/fpga/fpga-bridge.c +++ b/drivers/fpga/fpga-bridge.c @@ -121,7 +121,7 @@ static int fpga_bridge_dev_match(struct device *dev, const void *data) /** * fpga_bridge_get - get an exclusive reference to a fpga bridge * @dev: parent device that fpga bridge was registered with - * @info: fpga manager info + * @info: fpga image specific information * * Given a device, get an exclusive reference to a fpga bridge. * From ad03fe033a71ed1fd2cb68a067198ae0e342f991 Mon Sep 17 00:00:00 2001 From: Zheng Wang Date: Mon, 20 Mar 2023 14:29:31 +0800 Subject: [PATCH 083/190] usb: gadget: udc: renesas_usb3: Fix use after free bug in renesas_usb3_remove due to race condition [ Upstream commit 2b947f8769be8b8181dc795fd292d3e7120f5204 ] In renesas_usb3_probe, role_work is bound with renesas_usb3_role_work. renesas_usb3_start will be called to start the work. If we remove the driver which will call usbhs_remove, there may be an unfinished work. The possible sequence is as follows: CPU0 CPU1 renesas_usb3_role_work renesas_usb3_remove usb_role_switch_unregister device_unregister kfree(sw) //free usb3->role_sw usb_role_switch_set_role //use usb3->role_sw The usb3->role_sw could be freed under such circumstance and then used in usb_role_switch_set_role. This bug was found by static analysis. And note that removing a driver is a root-only operation, and should never happen in normal case. But the root user may directly remove the device which will also trigger the remove function. Fix it by canceling the work before cleanup in the renesas_usb3_remove. Fixes: 39facfa01c9f ("usb: gadget: udc: renesas_usb3: Add register of usb role switch") Signed-off-by: Zheng Wang Reviewed-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20230320062931.505170-1-zyytlz.wz@163.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- 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 c17d7a71e29a..013db752d55d 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -2478,6 +2478,7 @@ static int renesas_usb3_remove(struct platform_device *pdev) debugfs_remove_recursive(usb3->dentry); device_remove_file(&pdev->dev, &dev_attr_role); + cancel_work_sync(&usb3->role_work); usb_role_switch_unregister(usb3->role_sw); usb_del_gadget_udc(&usb3->gadget); From 6a85270f619e6d36fbecf13f73176bc6759af554 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 28 Mar 2023 19:15:29 -0700 Subject: [PATCH 084/190] linux/vt_buffer.h: allow either builtin or modular for macros [ Upstream commit 2b76ffe81e32afd6d318dc4547e2ba8c46207b77 ] Fix build errors on ARCH=alpha when CONFIG_MDA_CONSOLE=m. This allows the ARCH macros to be the only ones defined. In file included from ../drivers/video/console/mdacon.c:37: ../arch/alpha/include/asm/vga.h:17:40: error: expected identifier or '(' before 'volatile' 17 | static inline void scr_writew(u16 val, volatile u16 *addr) | ^~~~~~~~ ../include/linux/vt_buffer.h:24:34: note: in definition of macro 'scr_writew' 24 | #define scr_writew(val, addr) (*(addr) = (val)) | ^~~~ ../include/linux/vt_buffer.h:24:40: error: expected ')' before '=' token 24 | #define scr_writew(val, addr) (*(addr) = (val)) | ^ ../arch/alpha/include/asm/vga.h:17:20: note: in expansion of macro 'scr_writew' 17 | static inline void scr_writew(u16 val, volatile u16 *addr) | ^~~~~~~~~~ ../arch/alpha/include/asm/vga.h:25:29: error: expected identifier or '(' before 'volatile' 25 | static inline u16 scr_readw(volatile const u16 *addr) | ^~~~~~~~ Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Randy Dunlap Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: dri-devel@lists.freedesktop.org Cc: linux-fbdev@vger.kernel.org Link: https://lore.kernel.org/r/20230329021529.16188-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- include/linux/vt_buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/vt_buffer.h b/include/linux/vt_buffer.h index 848db1b1569f..919d999a8c1d 100644 --- a/include/linux/vt_buffer.h +++ b/include/linux/vt_buffer.h @@ -16,7 +16,7 @@ #include -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE) +#if IS_ENABLED(CONFIG_VGA_CONSOLE) || IS_ENABLED(CONFIG_MDA_CONSOLE) #include #endif From 17751e425854acd8bcf93b2ca0f795960ee27a03 Mon Sep 17 00:00:00 2001 From: Wang Li Date: Fri, 9 Apr 2021 09:54:58 +0000 Subject: [PATCH 085/190] spi: qup: fix PM reference leak in spi_qup_remove() [ Upstream commit cec77e0a249892ceb10061bf17b63f9fb111d870 ] pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in reference leak here. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced. Reported-by: Hulk Robot Signed-off-by: Wang Li Reviewed-by: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20210409095458.29921-1-wangli74@huawei.com Signed-off-by: Mark Brown Stable-dep-of: 61f49171a43a ("spi: qup: Don't skip cleanup in remove's error path") Signed-off-by: Sasha Levin --- drivers/spi/spi-qup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index 1ca678bcb527..e8009f8c212c 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -1249,7 +1249,7 @@ static int spi_qup_remove(struct platform_device *pdev) struct spi_qup *controller = spi_master_get_devdata(master); int ret; - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) return ret; From fd53f41bd86daa39b454fd4637a908ff2123547f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 30 Mar 2023 23:03:40 +0200 Subject: [PATCH 086/190] spi: qup: Don't skip cleanup in remove's error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 61f49171a43ab1f80c73c5c88c508770c461e0f2 ] Returning early in a platform driver's remove callback is wrong. In this case the dma resources are not released in the error path. this is never retried later and so this is a permanent leak. To fix this, only skip hardware disabling if waking the device fails. Fixes: 64ff247a978f ("spi: Add Qualcomm QUP SPI controller support") Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20230330210341.2459548-2-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-qup.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index e8009f8c212c..defe959884da 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -1249,19 +1249,23 @@ static int spi_qup_remove(struct platform_device *pdev) struct spi_qup *controller = spi_master_get_devdata(master); int ret; - ret = pm_runtime_resume_and_get(&pdev->dev); - if (ret < 0) - return ret; + ret = pm_runtime_get_sync(&pdev->dev); - ret = spi_qup_set_state(controller, QUP_STATE_RESET); - if (ret) - return ret; + if (ret >= 0) { + ret = spi_qup_set_state(controller, QUP_STATE_RESET); + if (ret) + dev_warn(&pdev->dev, "failed to reset controller (%pe)\n", + ERR_PTR(ret)); + + clk_disable_unprepare(controller->cclk); + clk_disable_unprepare(controller->iclk); + } else { + dev_warn(&pdev->dev, "failed to resume, skip hw disable (%pe)\n", + ERR_PTR(ret)); + } spi_qup_release_dma(master); - clk_disable_unprepare(controller->cclk); - clk_disable_unprepare(controller->iclk); - pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); From 70bc8a7e0c330082906f926f897ddbee75ea8905 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Sat, 1 Apr 2023 19:59:46 +0200 Subject: [PATCH 087/190] spi: fsl-spi: Fix CPM/QE mode Litte Endian [ Upstream commit c20c57d9868d7f9fd1b2904c7801b07e128f6322 ] CPM has the same problem as QE so for CPM also use the fix added by commit 0398fb70940e ("spi/spi_mpc8xxx: Fix QE mode Litte Endian"): CPM mode uses Little Endian so words > 8 bits are byte swapped. Workaround this by always enforcing wordsize 8 for 16 and 32 bits words. Unfortunately this will not work for LSB transfers where wordsize is > 8 bits so disable these for now. Also limit the workaround to 16 and 32 bits words because it can only work for multiples of 8-bits. Signed-off-by: Christophe Leroy Cc: Joakim Tjernlund Fixes: 0398fb70940e ("spi/spi_mpc8xxx: Fix QE mode Litte Endian") Link: https://lore.kernel.org/r/1b7d3e84b1128f42c1887dd2fb9cdf390f541bc1.1680371809.git.christophe.leroy@csgroup.eu Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/spi/spi-fsl-spi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index cd784552de7f..479d10dc6cb8 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -205,8 +205,8 @@ static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs, struct spi_device *spi, int bits_per_word) { - /* QE uses Little Endian for words > 8 - * so transform all words > 8 into 8 bits + /* CPM/QE uses Little Endian for words > 8 + * so transform 16 and 32 bits words into 8 bits * Unfortnatly that doesn't work for LSB so * reject these for now */ /* Note: 32 bits word, LSB works iff @@ -214,9 +214,11 @@ static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs, if (spi->mode & SPI_LSB_FIRST && bits_per_word > 8) return -EINVAL; - if (bits_per_word > 8) + if (bits_per_word <= 8) + return bits_per_word; + if (bits_per_word == 16 || bits_per_word == 32) return 8; /* pretend its 8 bits */ - return bits_per_word; + return -EINVAL; } static int fsl_spi_setup_transfer(struct spi_device *spi, @@ -246,7 +248,7 @@ static int fsl_spi_setup_transfer(struct spi_device *spi, bits_per_word = mspi_apply_cpu_mode_quirks(cs, spi, mpc8xxx_spi, bits_per_word); - else if (mpc8xxx_spi->flags & SPI_QE) + else bits_per_word = mspi_apply_qe_mode_quirks(cs, spi, bits_per_word); From 2053e93ac15519ed1f1fe6eba79a33a4963be4a3 Mon Sep 17 00:00:00 2001 From: "Dae R. Jeong" Date: Mon, 27 Mar 2023 21:01:53 +0900 Subject: [PATCH 088/190] vmci_host: fix a race condition in vmci_host_poll() causing GPF [ Upstream commit ae13381da5ff0e8e084c0323c3cc0a945e43e9c7 ] During fuzzing, a general protection fault is observed in vmci_host_poll(). general protection fault, probably for non-canonical address 0xdffffc0000000019: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x00000000000000c8-0x00000000000000cf] RIP: 0010:__lock_acquire+0xf3/0x5e00 kernel/locking/lockdep.c:4926 <- omitting registers -> Call Trace: lock_acquire+0x1a4/0x4a0 kernel/locking/lockdep.c:5672 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0xb3/0x100 kernel/locking/spinlock.c:162 add_wait_queue+0x3d/0x260 kernel/sched/wait.c:22 poll_wait include/linux/poll.h:49 [inline] vmci_host_poll+0xf8/0x2b0 drivers/misc/vmw_vmci/vmci_host.c:174 vfs_poll include/linux/poll.h:88 [inline] do_pollfd fs/select.c:873 [inline] do_poll fs/select.c:921 [inline] do_sys_poll+0xc7c/0x1aa0 fs/select.c:1015 __do_sys_ppoll fs/select.c:1121 [inline] __se_sys_ppoll+0x2cc/0x330 fs/select.c:1101 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x4e/0xa0 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x46/0xb0 Example thread interleaving that causes the general protection fault is as follows: CPU1 (vmci_host_poll) CPU2 (vmci_host_do_init_context) ----- ----- // Read uninitialized context context = vmci_host_dev->context; // Initialize context vmci_host_dev->context = vmci_ctx_create(); vmci_host_dev->ct_type = VMCIOBJ_CONTEXT; if (vmci_host_dev->ct_type == VMCIOBJ_CONTEXT) { // Dereferencing the wrong pointer poll_wait(..., &context->host_context); } In this scenario, vmci_host_poll() reads vmci_host_dev->context first, and then reads vmci_host_dev->ct_type to check that vmci_host_dev->context is initialized. However, since these two reads are not atomically executed, there is a chance of a race condition as described above. To fix this race condition, read vmci_host_dev->context after checking the value of vmci_host_dev->ct_type so that vmci_host_poll() always reads an initialized context. Reported-by: Dae R. Jeong Fixes: 8bf503991f87 ("VMCI: host side driver implementation.") Signed-off-by: Dae R. Jeong Link: https://lore.kernel.org/r/ZCGFsdBAU4cYww5l@dragonet Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/misc/vmw_vmci/vmci_host.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c index 83e0c95d20a4..5acbf384ffa6 100644 --- a/drivers/misc/vmw_vmci/vmci_host.c +++ b/drivers/misc/vmw_vmci/vmci_host.c @@ -169,10 +169,16 @@ static int vmci_host_close(struct inode *inode, struct file *filp) static __poll_t vmci_host_poll(struct file *filp, poll_table *wait) { struct vmci_host_dev *vmci_host_dev = filp->private_data; - struct vmci_ctx *context = vmci_host_dev->context; + struct vmci_ctx *context; __poll_t mask = 0; if (vmci_host_dev->ct_type == VMCIOBJ_CONTEXT) { + /* + * Read context only if ct_type == VMCIOBJ_CONTEXT to make + * sure that context is initialized + */ + context = vmci_host_dev->context; + /* Check for VMCI calls to this VM context. */ if (wait) poll_wait(filp, &context->host_context.wait_queue, From d72e2dc104e65827798e116f9e4853b85488d3e8 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 4 Apr 2023 18:21:09 +0100 Subject: [PATCH 089/190] of: Fix modalias string generation [ Upstream commit b19a4266c52de78496fe40f0b37580a3b762e67d ] The helper generating an OF based modalias (of_device_get_modalias()) works fine, but due to the use of snprintf() internally it needs a buffer one byte longer than what should be needed just for the entire string (excluding the '\0'). Most users of this helper are sysfs hooks providing the modalias string to users. They all provide a PAGE_SIZE buffer which is way above the number of bytes required to fit the modalias string and hence do not suffer from this issue. There is another user though, of_device_request_module(), which is only called by drivers/usb/common/ulpi.c. This request module function is faulty, but maybe because in most cases there is an alternative, ULPI driver users have not noticed it. In this function, of_device_get_modalias() is called twice. The first time without buffer just to get the number of bytes required by the modalias string (excluding the null byte), and a second time, after buffer allocation, to fill the buffer. The allocation asks for an additional byte, in order to store the trailing '\0'. However, the buffer *length* provided to of_device_get_modalias() excludes this extra byte. The internal use of snprintf() with a length that is exactly the number of bytes to be written has the effect of using the last available byte to store a '\0', which then smashes the last character of the modalias string. Provide the actual size of the buffer to of_device_get_modalias() to fix this issue. Note: the "str[size - 1] = '\0';" line is not really needed as snprintf will anyway end the string with a null byte, but there is a possibility that this function might be called on a struct device_node without compatible, in this case snprintf() would not be executed. So we keep it just to avoid possible unbounded strings. Cc: Stephen Boyd Cc: Peter Chen Fixes: 9c829c097f2f ("of: device: Support loading a module with OF based modalias") Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230404172148.82422-2-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/of/device.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/of/device.c b/drivers/of/device.c index 258742830e36..566d8af05157 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -258,12 +258,15 @@ int of_device_request_module(struct device *dev) if (size < 0) return size; - str = kmalloc(size + 1, GFP_KERNEL); + /* Reserve an additional byte for the trailing '\0' */ + size++; + + str = kmalloc(size, GFP_KERNEL); if (!str) return -ENOMEM; of_device_get_modalias(dev, str, size); - str[size] = '\0'; + str[size - 1] = '\0'; ret = request_module(str); kfree(str); From 5de0fc84554ac09f6a800c3dbbef7351f685f8e0 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 22 Feb 2023 19:42:58 -0800 Subject: [PATCH 090/190] ia64: mm/contig: fix section mismatch warning/error [ Upstream commit 58deeb4ef3b054498747d0929d94ac53ab90981f ] alloc_per_cpu_data() is called by find_memory(), which is marked as __init. Therefore alloc_per_cpu_data() can also be marked as __init to remedy this modpost problem. WARNING: modpost: vmlinux.o: section mismatch in reference: alloc_per_cpu_data (section: .text) -> memblock_alloc_try_nid (section: .init.text) Link: https://lkml.kernel.org/r/20230223034258.12917-1-rdunlap@infradead.org Fixes: 4b9ddc7cf272 ("[IA64] Fix section mismatch in contig.c version of per_cpu_init()") Signed-off-by: Randy Dunlap Cc: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin --- arch/ia64/mm/contig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index e2e40bbd391c..18a2b105f7f3 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c @@ -82,7 +82,7 @@ skip: return __per_cpu_start + __per_cpu_offset[smp_processor_id()]; } -static inline void +static inline __init void alloc_per_cpu_data(void) { cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * num_possible_cpus(), From e5f7e4b2e2bd6bb28bd999ba29cee53dc7cb67d3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 22 Feb 2023 19:43:09 -0800 Subject: [PATCH 091/190] ia64: salinfo: placate defined-but-not-used warning [ Upstream commit 0de155752b152d6bcd96b5b5bf20af336abd183a ] When CONFIG_PROC_FS is not set, proc_salinfo_show() is not used. Mark the function as __maybe_unused to quieten the warning message. ../arch/ia64/kernel/salinfo.c:584:12: warning: 'proc_salinfo_show' defined but not used [-Wunused-function] 584 | static int proc_salinfo_show(struct seq_file *m, void *v) | ^~~~~~~~~~~~~~~~~ Link: https://lkml.kernel.org/r/20230223034309.13375-1-rdunlap@infradead.org Fixes: 3f3942aca6da ("proc: introduce proc_create_single{,_data}") Signed-off-by: Randy Dunlap Cc: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin --- arch/ia64/kernel/salinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index aba1f463a8dd..b889db4492c8 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c @@ -580,7 +580,7 @@ static int salinfo_cpu_pre_down(unsigned int cpu) * 'data' contains an integer that corresponds to the feature we're * testing */ -static int proc_salinfo_show(struct seq_file *m, void *v) +static int __maybe_unused proc_salinfo_show(struct seq_file *m, void *v) { unsigned long data = (unsigned long)v; seq_puts(m, (sal_platform_features & data) ? "1\n" : "0\n"); From 7cd88edc4803be118d84d6bec38127c8de66ffe2 Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Mon, 1 Jun 2020 12:34:37 +0530 Subject: [PATCH 092/190] mtd: spi-nor: cadence-quadspi: Make driver independent of flash geometry [ Upstream commit 834b4e8d344139ba64cda22099b2b2ef6c9a542d ] Drop configuration of Flash size, erase size and page size configuration. Flash size is needed only if using AHB decoder (BIT 23 of CONFIG_REG) which is not used by the driver. Erase size and page size are needed if IP is configured to send WREN automatically. But since SPI NOR layer takes care of sending WREN, there is no need to configure these fields either. Therefore drop these in preparation to move the driver to spi-mem framework where flash geometry is not visible to controller driver. Signed-off-by: Vignesh Raghavendra Reviewed-by: Tudor Ambarus Acked-by: Tudor Ambarus Link: https://lore.kernel.org/r/20200601070444.16923-2-vigneshr@ti.com Signed-off-by: Mark Brown Stable-dep-of: 2087e85bb66e ("spi: cadence-quadspi: fix suspend-resume implementations") Signed-off-by: Sasha Levin --- drivers/mtd/spi-nor/cadence-quadspi.c | 36 +-------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c index a92f531ad23a..cdebe6853e6c 100644 --- a/drivers/mtd/spi-nor/cadence-quadspi.c +++ b/drivers/mtd/spi-nor/cadence-quadspi.c @@ -80,9 +80,6 @@ struct cqspi_st { dma_addr_t mmap_phys_base; int current_cs; - int current_page_size; - int current_erase_size; - int current_addr_width; unsigned long master_ref_clk_hz; bool is_decoded_cs; u32 fifo_depth; @@ -734,32 +731,6 @@ static void cqspi_chipselect(struct spi_nor *nor) writel(reg, reg_base + CQSPI_REG_CONFIG); } -static void cqspi_configure_cs_and_sizes(struct spi_nor *nor) -{ - struct cqspi_flash_pdata *f_pdata = nor->priv; - struct cqspi_st *cqspi = f_pdata->cqspi; - void __iomem *iobase = cqspi->iobase; - unsigned int reg; - - /* configure page size and block size. */ - reg = readl(iobase + CQSPI_REG_SIZE); - reg &= ~(CQSPI_REG_SIZE_PAGE_MASK << CQSPI_REG_SIZE_PAGE_LSB); - reg &= ~(CQSPI_REG_SIZE_BLOCK_MASK << CQSPI_REG_SIZE_BLOCK_LSB); - reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; - reg |= (nor->page_size << CQSPI_REG_SIZE_PAGE_LSB); - reg |= (ilog2(nor->mtd.erasesize) << CQSPI_REG_SIZE_BLOCK_LSB); - reg |= (nor->addr_width - 1); - writel(reg, iobase + CQSPI_REG_SIZE); - - /* configure the chip select */ - cqspi_chipselect(nor); - - /* Store the new configuration of the controller */ - cqspi->current_page_size = nor->page_size; - cqspi->current_erase_size = nor->mtd.erasesize; - cqspi->current_addr_width = nor->addr_width; -} - static unsigned int calculate_ticks_for_ns(const unsigned int ref_clk_hz, const unsigned int ns_val) { @@ -865,18 +836,13 @@ static void cqspi_configure(struct spi_nor *nor) int switch_cs = (cqspi->current_cs != f_pdata->cs); int switch_ck = (cqspi->sclk != sclk); - if ((cqspi->current_page_size != nor->page_size) || - (cqspi->current_erase_size != nor->mtd.erasesize) || - (cqspi->current_addr_width != nor->addr_width)) - switch_cs = 1; - if (switch_cs || switch_ck) cqspi_controller_enable(cqspi, 0); /* Switch chip select. */ if (switch_cs) { cqspi->current_cs = f_pdata->cs; - cqspi_configure_cs_and_sizes(nor); + cqspi_chipselect(nor); } /* Setup baudrate divisor and delays */ From cf2ed090e4454ec19dc646e52f3bf626f598e283 Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Mon, 1 Jun 2020 12:34:39 +0530 Subject: [PATCH 093/190] mtd: spi-nor: cadence-quadspi: Don't initialize rx_dma_complete on failure [ Upstream commit 48aae57f0f9f57797772bd462b4d64902b1b4ae1 ] If driver fails to acquire DMA channel then don't initialize rx_dma_complete struct as it won't be used. Signed-off-by: Vignesh Raghavendra Reviewed-by: Tudor Ambarus Acked-by: Tudor Ambarus Link: https://lore.kernel.org/r/20200601070444.16923-4-vigneshr@ti.com Signed-off-by: Mark Brown Stable-dep-of: 2087e85bb66e ("spi: cadence-quadspi: fix suspend-resume implementations") Signed-off-by: Sasha Levin --- drivers/mtd/spi-nor/cadence-quadspi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c index cdebe6853e6c..bd62ed871031 100644 --- a/drivers/mtd/spi-nor/cadence-quadspi.c +++ b/drivers/mtd/spi-nor/cadence-quadspi.c @@ -1173,6 +1173,7 @@ static void cqspi_request_mmap_dma(struct cqspi_st *cqspi) if (IS_ERR(cqspi->rx_chan)) { dev_err(&cqspi->pdev->dev, "No Rx DMA available\n"); cqspi->rx_chan = NULL; + return; } init_completion(&cqspi->rx_dma_complete); } From 37e06a125236658289b651b191adf1d954737c06 Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Mon, 1 Jun 2020 12:34:41 +0530 Subject: [PATCH 094/190] mtd: spi-nor: cadence-quadspi: Handle probe deferral while requesting DMA channel [ Upstream commit 935da5e5100f57d843cac4781b21f1c235059aa0 ] dma_request_chan_by_mask() can throw EPROBE_DEFER if DMA provider is not yet probed. Currently driver just falls back to using PIO mode (which is less efficient) in this case. Instead return probe deferral error as is so that driver will be re probed once DMA provider is available. Signed-off-by: Vignesh Raghavendra Reviewed-by: Tudor Ambarus Acked-by: Tudor Ambarus Link: https://lore.kernel.org/r/20200601070444.16923-6-vigneshr@ti.com Signed-off-by: Mark Brown Stable-dep-of: 2087e85bb66e ("spi: cadence-quadspi: fix suspend-resume implementations") Signed-off-by: Sasha Levin --- drivers/mtd/spi-nor/cadence-quadspi.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c index bd62ed871031..16ac2e3c351d 100644 --- a/drivers/mtd/spi-nor/cadence-quadspi.c +++ b/drivers/mtd/spi-nor/cadence-quadspi.c @@ -1162,7 +1162,7 @@ static void cqspi_controller_init(struct cqspi_st *cqspi) cqspi_controller_enable(cqspi, 1); } -static void cqspi_request_mmap_dma(struct cqspi_st *cqspi) +static int cqspi_request_mmap_dma(struct cqspi_st *cqspi) { dma_cap_mask_t mask; @@ -1171,11 +1171,16 @@ static void cqspi_request_mmap_dma(struct cqspi_st *cqspi) cqspi->rx_chan = dma_request_chan_by_mask(&mask); if (IS_ERR(cqspi->rx_chan)) { - dev_err(&cqspi->pdev->dev, "No Rx DMA available\n"); + int ret = PTR_ERR(cqspi->rx_chan); + + if (ret != -EPROBE_DEFER) + dev_err(&cqspi->pdev->dev, "No Rx DMA available\n"); cqspi->rx_chan = NULL; - return; + return ret; } init_completion(&cqspi->rx_dma_complete); + + return 0; } static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np) @@ -1256,8 +1261,11 @@ static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np) dev_dbg(nor->dev, "using direct mode for %s\n", mtd->name); - if (!cqspi->rx_chan) - cqspi_request_mmap_dma(cqspi); + if (!cqspi->rx_chan) { + ret = cqspi_request_mmap_dma(cqspi); + if (ret == -EPROBE_DEFER) + goto err; + } } } From e3f9fc9a4f1499cc9e1bad4482d377494e367b3d Mon Sep 17 00:00:00 2001 From: Dhruva Gole Date: Mon, 17 Apr 2023 14:40:27 +0530 Subject: [PATCH 095/190] spi: cadence-quadspi: fix suspend-resume implementations [ Upstream commit 2087e85bb66ee3652dafe732bb9b9b896229eafc ] The cadence QSPI driver misbehaves after performing a full system suspend resume: ... spi-nor spi0.0: resume() failed ... This results in a flash connected via OSPI interface after system suspend- resume to be unusable. fix these suspend and resume functions. Fixes: 140623410536 ("mtd: spi-nor: Add driver for Cadence Quad SPI Flash Controller") Signed-off-by: Dhruva Gole Link: https://lore.kernel.org/r/20230417091027.966146-3-d-gole@ti.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- drivers/mtd/spi-nor/cadence-quadspi.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c index 16ac2e3c351d..d5c6b91fd113 100644 --- a/drivers/mtd/spi-nor/cadence-quadspi.c +++ b/drivers/mtd/spi-nor/cadence-quadspi.c @@ -1412,17 +1412,30 @@ static int cqspi_remove(struct platform_device *pdev) static int cqspi_suspend(struct device *dev) { struct cqspi_st *cqspi = dev_get_drvdata(dev); + struct spi_master *master = dev_get_drvdata(dev); + int ret; + ret = spi_master_suspend(master); cqspi_controller_enable(cqspi, 0); - return 0; + + clk_disable_unprepare(cqspi->clk); + + return ret; } static int cqspi_resume(struct device *dev) { struct cqspi_st *cqspi = dev_get_drvdata(dev); + struct spi_master *master = dev_get_drvdata(dev); - cqspi_controller_enable(cqspi, 1); - return 0; + clk_prepare_enable(cqspi->clk); + cqspi_wait_idle(cqspi); + cqspi_controller_init(cqspi); + + cqspi->current_cs = -1; + cqspi->sclk = 0; + + return spi_master_resume(master); } static const struct dev_pm_ops cqspi__dev_pm_ops = { From 8fabf09fb17e029420b8a171516febd8477bb6a1 Mon Sep 17 00:00:00 2001 From: Kevin Brodsky Date: Tue, 11 Apr 2023 10:27:47 +0100 Subject: [PATCH 096/190] uapi/linux/const.h: prefer ISO-friendly __typeof__ [ Upstream commit 31088f6f7906253ef4577f6a9b84e2d42447dba0 ] typeof is (still) a GNU extension, which means that it cannot be used when building ISO C (e.g. -std=c99). It should therefore be avoided in uapi headers in favour of the ISO-friendly __typeof__. Unfortunately this issue could not be detected by CONFIG_UAPI_HEADER_TEST=y as the __ALIGN_KERNEL() macro is not expanded in any uapi header. This matters from a userspace perspective, not a kernel one. uapi headers and their contents are expected to be usable in a variety of situations, and in particular when building ISO C applications (with -std=c99 or similar). This particular problem can be reproduced by trying to use the __ALIGN_KERNEL macro directly in application code, say: #include int align(int x, int a) { return __KERNEL_ALIGN(x, a); } and trying to build that with -std=c99. Link: https://lkml.kernel.org/r/20230411092747.3759032-1-kevin.brodsky@arm.com Fixes: a79ff731a1b2 ("netfilter: xtables: make XT_ALIGN() usable in exported headers by exporting __ALIGN_KERNEL()") Signed-off-by: Kevin Brodsky Reported-by: Ruben Ayrapetyan Tested-by: Ruben Ayrapetyan Reviewed-by: Petr Vorel Tested-by: Petr Vorel Reviewed-by: Masahiro Yamada Cc: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin --- include/uapi/linux/const.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/const.h b/include/uapi/linux/const.h index af2a44c08683..a429381e7ca5 100644 --- a/include/uapi/linux/const.h +++ b/include/uapi/linux/const.h @@ -28,7 +28,7 @@ #define _BITUL(x) (_UL(1) << (x)) #define _BITULL(x) (_ULL(1) << (x)) -#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) +#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (__typeof__(x))(a) - 1) #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) #define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) From fffc3079b802ed22289681e5ee1a444c2ba04ae2 Mon Sep 17 00:00:00 2001 From: John Paul Adrian Glaubitz Date: Wed, 19 Apr 2023 13:48:52 +0200 Subject: [PATCH 097/190] sh: sq: Fix incorrect element size for allocating bitmap buffer [ Upstream commit 80f746e2bd0e1da3fdb49a53570e54a1a225faac ] The Store Queue code allocates a bitmap buffer with the size of multiple of sizeof(long) in sq_api_init(). While the buffer size is calculated correctly, the code uses the wrong element size to allocate the buffer which results in the allocated bitmap buffer being too small. Fix this by allocating the buffer with kcalloc() with element size sizeof(long) instead of kzalloc() whose elements size defaults to sizeof(char). Fixes: d7c30c682a27 ("sh: Store Queue API rework.") Reviewed-by: Geert Uytterhoeven Signed-off-by: John Paul Adrian Glaubitz Link: https://lore.kernel.org/r/20230419114854.528677-1-glaubitz@physik.fu-berlin.de Signed-off-by: Sasha Levin --- arch/sh/kernel/cpu/sh4/sq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index 4ca78ed71ad2..c218bae8fe20 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -383,7 +383,7 @@ static int __init sq_api_init(void) if (unlikely(!sq_cache)) return ret; - sq_bitmap = kzalloc(size, GFP_KERNEL); + sq_bitmap = kcalloc(size, sizeof(long), GFP_KERNEL); if (unlikely(!sq_bitmap)) goto out; From 5a80589cb08ec292f8682f85d4902a9abc021f8e Mon Sep 17 00:00:00 2001 From: Yinhao Hu Date: Wed, 12 Apr 2023 13:58:52 +0800 Subject: [PATCH 098/190] usb: chipidea: fix missing goto in `ci_hdrc_probe` [ Upstream commit d6f712f53b79f5017cdcefafb7a5aea9ec52da5d ] From the comment of ci_usb_phy_init, it returns an error code if usb_phy_init has failed, and it should do some clean up, not just return directly. Fix this by goto the error handling. Fixes: 74475ede784d ("usb: chipidea: move PHY operation to core") Reviewed-by: Dongliang Mu Acked-by: Peter Chen Signed-off-by: Yinhao Hu Link: https://lore.kernel.org/r/20230412055852.971991-1-dddddd@hust.edu.cn Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/chipidea/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 3fd1073a345d..9f6a52ed038e 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -984,7 +984,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) ret = ci_usb_phy_init(ci); if (ret) { dev_err(dev, "unable to init phy: %d\n", ret); - return ret; + goto ulpi_exit; } ci->hw_bank.phys = res->start; From b25186b6529dcbed6944f25d2f5fb101394839fa Mon Sep 17 00:00:00 2001 From: Shenwei Wang Date: Mon, 10 Apr 2023 14:55:55 -0500 Subject: [PATCH 099/190] tty: serial: fsl_lpuart: adjust buffer length to the intended size [ Upstream commit f73fd750552524b06b5d77ebfdd106ccc8fcac61 ] Based on the fls function definition provided below, we should not subtract 1 to obtain the correct buffer length: fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. Fixes: 5887ad43ee02 ("tty: serial: fsl_lpuart: Use cyclic DMA for Rx") Signed-off-by: Shenwei Wang Link: https://lore.kernel.org/r/20230410195555.1003900-1-shenwei.wang@nxp.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/fsl_lpuart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 6ea1d23623e5..dbfec943071d 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -994,7 +994,7 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport) * 10ms at any baud rate. */ sport->rx_dma_rng_buf_len = (DMA_RX_TIMEOUT * baud / bits / 1000) * 2; - sport->rx_dma_rng_buf_len = (1 << (fls(sport->rx_dma_rng_buf_len) - 1)); + sport->rx_dma_rng_buf_len = (1 << fls(sport->rx_dma_rng_buf_len)); if (sport->rx_dma_rng_buf_len < 16) sport->rx_dma_rng_buf_len = 16; From 0bd49a043c7984c93c2a0af41222fb71c3986a4e Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 14 Apr 2023 10:02:39 -0700 Subject: [PATCH 100/190] serial: 8250: Add missing wakeup event reporting [ Upstream commit 0ba9e3a13c6adfa99e32b2576d20820ab10ad48a ] An 8250 UART configured as a wake-up source would not have reported itself through sysfs as being the source of wake-up, correct that. Fixes: b3b708fa2780 ("wake up from a serial port") Signed-off-by: Florian Fainelli Link: https://lore.kernel.org/r/20230414170241.2016255-1-f.fainelli@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/tty/serial/8250/8250_port.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index ce266e10a21e..81574efff3c1 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -1885,6 +1886,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) unsigned char status; unsigned long flags; struct uart_8250_port *up = up_to_u8250p(port); + struct tty_port *tport = &port->state->port; bool skip_rx = false; if (iir & UART_IIR_NO_INT) @@ -1908,6 +1910,8 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) skip_rx = true; if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { + if (irqd_is_wakeup_set(irq_get_irq_data(port->irq))) + pm_wakeup_event(tport->tty->dev, 0); if (!up->dma || handle_rx_dma(up, iir)) status = serial8250_rx_chars(up, status); } From 24eb9f773259580280e91a6ed677cc82e8416746 Mon Sep 17 00:00:00 2001 From: Philipp Hortmann Date: Tue, 18 Apr 2023 22:02:01 +0200 Subject: [PATCH 101/190] staging: rtl8192e: Fix W_DISABLE# does not work after stop/start [ Upstream commit 3fac2397f562eb669ddc2f45867a253f3fc26184 ] When loading the driver for rtl8192e, the W_DISABLE# switch is working as intended. But when the WLAN is turned off in software and then turned on again the W_DISABLE# does not work anymore. Reason for this is that in the function _rtl92e_dm_check_rf_ctrl_gpio() the bfirst_after_down is checked and returned when true. bfirst_after_down is set true when switching the WLAN off in software. But it is not set to false again when WLAN is turned on again. Add bfirst_after_down = false in _rtl92e_sta_up to reset bit and fix above described bug. Fixes: 94a799425eee ("From: wlanfae [PATCH 1/8] rtl8192e: Import new version of driver from realtek") Signed-off-by: Philipp Hortmann Link: https://lore.kernel.org/r/20230418200201.GA17398@matrix-ESPRIMO-P710 Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index da73998bc5f7..d5ef1986bde4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -778,6 +778,7 @@ static int _rtl92e_sta_up(struct net_device *dev, bool is_silent_reset) else netif_wake_queue(dev); + priv->bfirst_after_down = false; return 0; } From 699949219e35fe29fd42ccf8cd92c989c3d15109 Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Thu, 13 Apr 2023 15:38:34 -0700 Subject: [PATCH 102/190] spmi: Add a check for remove callback when removing a SPMI driver [ Upstream commit b56eef3e16d888883fefab47425036de80dd38fc ] When removing a SPMI driver, there can be a crash due to NULL pointer dereference if it does not have a remove callback defined. This is one such call trace observed when removing the QCOM SPMI PMIC driver: dump_backtrace.cfi_jt+0x0/0x8 dump_stack_lvl+0xd8/0x16c panic+0x188/0x498 __cfi_slowpath+0x0/0x214 __cfi_slowpath+0x1dc/0x214 spmi_drv_remove+0x16c/0x1e0 device_release_driver_internal+0x468/0x79c driver_detach+0x11c/0x1a0 bus_remove_driver+0xc4/0x124 driver_unregister+0x58/0x84 cleanup_module+0x1c/0xc24 [qcom_spmi_pmic] __do_sys_delete_module+0x3ec/0x53c __arm64_sys_delete_module+0x18/0x28 el0_svc_common+0xdc/0x294 el0_svc+0x38/0x9c el0_sync_handler+0x8c/0xf0 el0_sync+0x1b4/0x1c0 If a driver has all its resources allocated through devm_() APIs and does not need any other explicit cleanup, it would not require a remove callback to be defined. Hence, add a check for remove callback presence before calling it when removing a SPMI driver. Link: https://lore.kernel.org/r/1671601032-18397-2-git-send-email-quic_jprakash@quicinc.com Fixes: 6f00f8c8635f ("mfd: qcom-spmi-pmic: Use devm_of_platform_populate()") Fixes: 5a86bf343976 ("spmi: Linux driver framework for SPMI") Signed-off-by: Jishnu Prakash Signed-off-by: Stephen Boyd Link: https://lore.kernel.org/r/20230413223834.4084793-7-sboyd@kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/spmi/spmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index aa3edabc2b0f..55f1cad836ba 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -356,7 +356,8 @@ static int spmi_drv_remove(struct device *dev) const struct spmi_driver *sdrv = to_spmi_driver(dev->driver); pm_runtime_get_sync(dev); - sdrv->remove(to_spmi_device(dev)); + if (sdrv->remove) + sdrv->remove(to_spmi_device(dev)); pm_runtime_put_noidle(dev); pm_runtime_disable(dev); From 93e92236d447c8a1709bd53bf982d60885a70d47 Mon Sep 17 00:00:00 2001 From: Liang He Date: Thu, 30 Mar 2023 11:35:58 +0800 Subject: [PATCH 103/190] macintosh/windfarm_smu_sat: Add missing of_node_put() [ Upstream commit 631cf002826007ab7415258ee647dcaf8845ad5a ] We call of_node_get() in wf_sat_probe() after sat is created, so we need the of_node_put() before *kfree(sat)*. Fixes: ac171c46667c ("[PATCH] powerpc: Thermal control for dual core G5s") Signed-off-by: Liang He Signed-off-by: Michael Ellerman Link: https://msgid.link/20230330033558.2562778-1-windhl@126.com Signed-off-by: Sasha Levin --- drivers/macintosh/windfarm_smu_sat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index 51ef77de4174..3d4b8c33640a 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -172,6 +172,7 @@ static void wf_sat_release(struct kref *ref) if (sat->nr >= 0) sats[sat->nr] = NULL; + of_node_put(sat->node); kfree(sat); } From e58a712c4d49e21997091744a777b1dc0fd2047c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 22 Feb 2023 23:01:13 -0800 Subject: [PATCH 104/190] powerpc/mpc512x: fix resource printk format warning [ Upstream commit 7538c97e2b80ff6b7a8ea2ecf16a04355461b439 ] Use "%pa" format specifier for resource_size_t to avoid a compiler printk format warning. ../arch/powerpc/platforms/512x/clock-commonclk.c: In function 'mpc5121_clk_provide_backwards_compat': ../arch/powerpc/platforms/512x/clock-commonclk.c:989:44: error: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=] 989 | snprintf(devname, sizeof(devname), "%08x.%s", res.start, np->name); \ | ^~~~~~~~~ ~~~~~~~~~ | | | resource_size_t {aka long long unsigned int} Prevents 24 such warnings. Fixes: 01f25c371658 ("clk: mpc512x: add backwards compat to the CCF code") Signed-off-by: Randy Dunlap Signed-off-by: Michael Ellerman Link: https://msgid.link/20230223070116.660-2-rdunlap@infradead.org Signed-off-by: Sasha Levin --- arch/powerpc/platforms/512x/clock-commonclk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c index b3097fe6441b..1019d78e44bb 100644 --- a/arch/powerpc/platforms/512x/clock-commonclk.c +++ b/arch/powerpc/platforms/512x/clock-commonclk.c @@ -985,7 +985,7 @@ static void mpc5121_clk_provide_migration_support(void) #define NODE_PREP do { \ of_address_to_resource(np, 0, &res); \ - snprintf(devname, sizeof(devname), "%08x.%s", res.start, np->name); \ + snprintf(devname, sizeof(devname), "%pa.%s", &res.start, np->name); \ } while (0) #define NODE_CHK(clkname, clkitem, regnode, regflag) do { \ From cfa9715beb9b6c2abccf7350e1cf2ef67776865d Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 22 Feb 2023 23:01:14 -0800 Subject: [PATCH 105/190] powerpc/wii: fix resource printk format warnings [ Upstream commit 7b69600d4da0049244e9be2f5ef5a2f8e04fcd9a ] Use "%pa" format specifier for resource_size_t to avoid compiler printk format warnings. ../arch/powerpc/platforms/embedded6xx/flipper-pic.c: In function 'flipper_pic_init': ../include/linux/kern_levels.h:5:25: error: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=] ../arch/powerpc/platforms/embedded6xx/flipper-pic.c:148:9: note: in expansion of macro 'pr_info' 148 | pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base); | ^~~~~~~ ../arch/powerpc/platforms/embedded6xx/hlwd-pic.c: In function 'hlwd_pic_init': ../include/linux/kern_levels.h:5:25: error: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=] ../arch/powerpc/platforms/embedded6xx/hlwd-pic.c:174:9: note: in expansion of macro 'pr_info' 174 | pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base); | ^~~~~~~ ../arch/powerpc/platforms/embedded6xx/wii.c: In function 'wii_ioremap_hw_regs': ../include/linux/kern_levels.h:5:25: error: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=] ../arch/powerpc/platforms/embedded6xx/wii.c:77:17: note: in expansion of macro 'pr_info' 77 | pr_info("%s at 0x%08x mapped to 0x%p\n", name, | ^~~~~~~ Fixes: 028ee972f032 ("powerpc: gamecube/wii: flipper interrupt controller support") Fixes: 9c21025c7845 ("powerpc: wii: hollywood interrupt controller support") Fixes: 5a7ee3198dfa ("powerpc: wii: platform support") Signed-off-by: Randy Dunlap Signed-off-by: Michael Ellerman Link: https://msgid.link/20230223070116.660-3-rdunlap@infradead.org Signed-off-by: Sasha Levin --- arch/powerpc/platforms/embedded6xx/flipper-pic.c | 2 +- arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 2 +- arch/powerpc/platforms/embedded6xx/wii.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c index db0be007fd06..bfca4d42b00d 100644 --- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c @@ -149,7 +149,7 @@ static struct irq_domain * __init flipper_pic_init(struct device_node *np) } io_base = ioremap(res.start, resource_size(&res)); - pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base); + pr_info("controller at 0x%pa mapped to 0x%p\n", &res.start, io_base); __flipper_quiesce(io_base); diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c index 7b4edf1cb2c8..bdc7e1a80366 100644 --- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c @@ -178,7 +178,7 @@ static struct irq_domain *hlwd_pic_init(struct device_node *np) return NULL; } - pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base); + pr_info("controller at 0x%pa mapped to 0x%p\n", &res.start, io_base); __hlwd_quiesce(io_base); diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c index 343bffd20fca..768231005fb5 100644 --- a/arch/powerpc/platforms/embedded6xx/wii.c +++ b/arch/powerpc/platforms/embedded6xx/wii.c @@ -122,8 +122,8 @@ static void __iomem *wii_ioremap_hw_regs(char *name, char *compatible) hw_regs = ioremap(res.start, resource_size(&res)); if (hw_regs) { - pr_info("%s at 0x%08x mapped to 0x%p\n", name, - res.start, hw_regs); + pr_info("%s at 0x%pa mapped to 0x%p\n", name, + &res.start, hw_regs); } out_put: From b9f090f4394e51d995888bfa748875b16cbc8e89 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 22 Feb 2023 23:01:16 -0800 Subject: [PATCH 106/190] powerpc/sysdev/tsi108: fix resource printk format warnings [ Upstream commit 55d8bd02cc1b9f1063993b5c42c9cabf4af67dea ] Use "%pa" format specifier for resource_size_t to avoid a compiler printk format warning. arch/powerpc/sysdev/tsi108_pci.c: In function 'tsi108_setup_pci': include/linux/kern_levels.h:5:25: error: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'resource_size_t' Fixes: c4342ff92bed ("[POWERPC] Update mpc7448hpc2 board irq support using device tree") Fixes: 2b9d7467a6db ("[POWERPC] Add tsi108 pci and platform device data register function") Signed-off-by: Randy Dunlap [mpe: Use pr_info() and unsplit string] Signed-off-by: Michael Ellerman Link: https://msgid.link/20230223070116.660-5-rdunlap@infradead.org Signed-off-by: Sasha Levin --- arch/powerpc/sysdev/tsi108_pci.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 28ff1f53cefc..6bd50c690006 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c @@ -229,9 +229,8 @@ int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary) (hose)->ops = &tsi108_direct_pci_ops; - printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. " - "Firmware bus number: %d->%d\n", - rsrc.start, hose->first_busno, hose->last_busno); + pr_info("Found tsi108 PCI host bridge at 0x%pa. Firmware bus number: %d->%d\n", + &rsrc.start, hose->first_busno, hose->last_busno); /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ From 59cadf0c3f7a72668a7308a302659d29c58f1ecc Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 22 Feb 2023 17:42:41 -0800 Subject: [PATCH 107/190] macintosh: via-pmu-led: requires ATA to be set [ Upstream commit 05dce4ba125336875cd3eed3c1503fa81cd2f691 ] LEDS_TRIGGER_DISK depends on ATA, so selecting LEDS_TRIGGER_DISK when ATA is not set/enabled causes a Kconfig warning: WARNING: unmet direct dependencies detected for LEDS_TRIGGER_DISK Depends on [n]: NEW_LEDS [=y] && LEDS_TRIGGERS [=y] && ATA [=n] Selected by [y]: - ADB_PMU_LED_DISK [=y] && MACINTOSH_DRIVERS [=y] && ADB_PMU_LED [=y] && LEDS_CLASS [=y] Fix this by making ADB_PMU_LED_DISK depend on ATA. Seen on both PPC32 and PPC64. Fixes: 0e865a80c135 ("macintosh: Remove dependency on IDE_GD_ATA if ADB_PMU_LED_DISK is selected") Signed-off-by: Randy Dunlap Signed-off-by: Michael Ellerman Link: https://msgid.link/20230223014241.20878-1-rdunlap@infradead.org Signed-off-by: Sasha Levin --- drivers/macintosh/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index a316624742f6..c3d421c7b0cf 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -83,6 +83,7 @@ config ADB_PMU_LED config ADB_PMU_LED_DISK bool "Use front LED as DISK LED by default" + depends on ATA depends on ADB_PMU_LED depends on LEDS_CLASS select LEDS_TRIGGERS From c5a65267117c21a8e031306774c75085161e0f0b Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Mon, 6 Mar 2023 15:33:41 -0600 Subject: [PATCH 108/190] powerpc/rtas: use memmove for potentially overlapping buffer copy [ Upstream commit 271208ee5e335cb1ad280d22784940daf7ddf820 ] Using memcpy() isn't safe when buf is identical to rtas_err_buf, which can happen during boot before slab is up. Full context which may not be obvious from the diff: if (altbuf) { buf = altbuf; } else { buf = rtas_err_buf; if (slab_is_available()) buf = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC); } if (buf) memcpy(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX); This was found by inspection and I'm not aware of it causing problems in practice. It appears to have been introduced by commit 033ef338b6e0 ("powerpc: Merge rtas.c into arch/powerpc/kernel"); the old ppc64 version of this code did not have this problem. Use memmove() instead. Fixes: 033ef338b6e0 ("powerpc: Merge rtas.c into arch/powerpc/kernel") Signed-off-by: Nathan Lynch Reviewed-by: Andrew Donnellan Signed-off-by: Michael Ellerman Link: https://msgid.link/20230220-rtas-queue-for-6-4-v1-2-010e4416f13f@linux.ibm.com Signed-off-by: Sasha Levin --- arch/powerpc/kernel/rtas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 7c7648e6f1c2..2646dd54eb0b 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -401,7 +401,7 @@ static char *__fetch_rtas_last_error(char *altbuf) buf = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC); } if (buf) - memcpy(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX); + memmove(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX); } return buf; From 6805c1fcbe37989dd6fa4d545d04ccbea5e69d1f Mon Sep 17 00:00:00 2001 From: Yang Jihong Date: Mon, 27 Feb 2023 10:35:08 +0800 Subject: [PATCH 109/190] perf/core: Fix hardlockup failure caused by perf throttle [ Upstream commit 15def34e2635ab7e0e96f1bc32e1b69609f14942 ] commit e050e3f0a71bf ("perf: Fix broken interrupt rate throttling") introduces a change in throttling threshold judgment. Before this, compare hwc->interrupts and max_samples_per_tick, then increase hwc->interrupts by 1, but this commit reverses order of these two behaviors, causing the semantics of max_samples_per_tick to change. In literal sense of "max_samples_per_tick", if hwc->interrupts == max_samples_per_tick, it should not be throttled, therefore, the judgment condition should be changed to "hwc->interrupts > max_samples_per_tick". In fact, this may cause the hardlockup to fail, The minimum value of max_samples_per_tick may be 1, in this case, the return value of __perf_event_account_interrupt function is 1. As a result, nmi_watchdog gets throttled, which would stop PMU (Use x86 architecture as an example, see x86_pmu_handle_irq). Fixes: e050e3f0a71b ("perf: Fix broken interrupt rate throttling") Signed-off-by: Yang Jihong Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20230227023508.102230-1-yangjihong1@huawei.com Signed-off-by: Sasha Levin --- kernel/events/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 72ed3f3d078f..2bf4b6b109bf 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -7843,8 +7843,8 @@ __perf_event_account_interrupt(struct perf_event *event, int throttle) hwc->interrupts = 1; } else { hwc->interrupts++; - if (unlikely(throttle - && hwc->interrupts >= max_samples_per_tick)) { + if (unlikely(throttle && + hwc->interrupts > max_samples_per_tick)) { __this_cpu_inc(perf_throttled_count); tick_dep_set_cpu(smp_processor_id(), TICK_DEP_BIT_PERF_EVENTS); hwc->interrupts = MAX_INTERRUPTS; From 401794fa478652d0aa41f800f93f48b8de0e4af0 Mon Sep 17 00:00:00 2001 From: Natalia Petrova Date: Fri, 3 Mar 2023 15:44:08 +0300 Subject: [PATCH 110/190] RDMA/rdmavt: Delete unnecessary NULL check [ Upstream commit b73a0b80c69de77d8d4942abb37066531c0169b2 ] There is no need to check 'rdi->qp_dev' for NULL. The field 'qp_dev' is created in rvt_register_device() which will fail if the 'qp_dev' allocation fails in rvt_driver_qp_init(). Overwise this pointer doesn't changed and passed to rvt_qp_exit() by the next step. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 0acb0cc7ecc1 ("IB/rdmavt: Initialize and teardown of qpn table") Signed-off-by: Natalia Petrova Link: https://lore.kernel.org/r/20230303124408.16685-1-n.petrova@fintech.ru Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/sw/rdmavt/qp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c index fbc316775669..c12fc2eace16 100644 --- a/drivers/infiniband/sw/rdmavt/qp.c +++ b/drivers/infiniband/sw/rdmavt/qp.c @@ -321,8 +321,6 @@ void rvt_qp_exit(struct rvt_dev_info *rdi) if (qps_inuse) rvt_pr_err(rdi, "QP memory leak! %u still in use\n", qps_inuse); - if (!rdi->qp_dev) - return; kfree(rdi->qp_dev->qp_table); free_qpn_table(&rdi->qp_dev->qpn_table); From 3d5ae269c4bd392ec1edbfb3bd031b8f42d7feff Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 7 Mar 2023 12:51:27 +0300 Subject: [PATCH 111/190] RDMA/mlx4: Prevent shift wrapping in set_user_sq_size() [ Upstream commit d50b3c73f1ac20dabc53dc6e9d64ce9c79a331eb ] The ucmd->log_sq_bb_count variable is controlled by the user so this shift can wrap. Fix it by using check_shl_overflow() in the same way that it was done in commit 515f60004ed9 ("RDMA/hns: Prevent undefined behavior in hns_roce_set_user_sq_size()"). Fixes: 839041329fd3 ("IB/mlx4: Sanity check userspace send queue sizes") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/a8dfbd1d-c019-4556-930b-bab1ded73b10@kili.mountain Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/hw/mlx4/qp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 7209b8a9b0dd..87358b8c4558 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -436,9 +436,13 @@ static int set_user_sq_size(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, struct mlx4_ib_create_qp *ucmd) { + u32 cnt; + /* Sanity check SQ size before proceeding */ - if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes || - ucmd->log_sq_stride > + if (check_shl_overflow(1, ucmd->log_sq_bb_count, &cnt) || + cnt > dev->dev->caps.max_wqes) + return -EINVAL; + if (ucmd->log_sq_stride > ilog2(roundup_pow_of_two(dev->dev->caps.max_sq_desc_sz)) || ucmd->log_sq_stride < MLX4_IB_MIN_SQ_STRIDE) return -EINVAL; From 9551abd92e411f4302103d63ddbeeb3d9b818d4c Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Fri, 17 Mar 2023 23:56:57 +0100 Subject: [PATCH 112/190] power: supply: generic-adc-battery: fix unit scaling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 44263f50065969f2344808388bd589740f026167 ] power-supply properties are reported in µV, µA and µW. The IIO API provides mV, mA, mW, so the values need to be multiplied by 1000. Fixes: e60fea794e6e ("power: battery: Generic battery driver using IIO") Reviewed-by: Linus Walleij Reviewed-by: Matti Vaittinen Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/supply/generic-adc-battery.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/power/supply/generic-adc-battery.c b/drivers/power/supply/generic-adc-battery.c index 97b0e873e87d..c2d6378bb897 100644 --- a/drivers/power/supply/generic-adc-battery.c +++ b/drivers/power/supply/generic-adc-battery.c @@ -138,6 +138,9 @@ static int read_channel(struct gab *adc_bat, enum power_supply_property psp, result); if (ret < 0) pr_err("read channel error\n"); + else + *result *= 1000; + return ret; } From 281714e480ff7ca12169fbf6835187fc27f69fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= Date: Tue, 31 Jan 2023 09:32:27 +0100 Subject: [PATCH 113/190] clk: add missing of_node_put() in "assigned-clocks" property parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 27a6e1b09a782517fddac91259970ac466a3f7b6 ] When returning from of_parse_phandle_with_args(), the np member of the of_phandle_args structure should be put after usage. Add missing of_node_put() calls in both __set_clk_parents() and __set_clk_rates(). Fixes: 86be408bfbd8 ("clk: Support for clock parents and rates assigned from device tree") Signed-off-by: Clément Léger Link: https://lore.kernel.org/r/20230131083227.10990-1-clement.leger@bootlin.com Signed-off-by: Stephen Boyd Signed-off-by: Sasha Levin --- drivers/clk/clk-conf.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c index 49819b546134..5c6760e45a16 100644 --- a/drivers/clk/clk-conf.c +++ b/drivers/clk/clk-conf.c @@ -36,9 +36,12 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) else return rc; } - if (clkspec.np == node && !clk_supplier) + if (clkspec.np == node && !clk_supplier) { + of_node_put(clkspec.np); return 0; + } pclk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); if (IS_ERR(pclk)) { if (PTR_ERR(pclk) != -EPROBE_DEFER) pr_warn("clk: couldn't get parent clock %d for %pOF\n", @@ -51,10 +54,12 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) if (rc < 0) goto err; if (clkspec.np == node && !clk_supplier) { + of_node_put(clkspec.np); rc = 0; goto err; } clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); if (IS_ERR(clk)) { if (PTR_ERR(clk) != -EPROBE_DEFER) pr_warn("clk: couldn't get assigned clock %d for %pOF\n", @@ -96,10 +101,13 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier) else return rc; } - if (clkspec.np == node && !clk_supplier) + if (clkspec.np == node && !clk_supplier) { + of_node_put(clkspec.np); return 0; + } clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); if (IS_ERR(clk)) { if (PTR_ERR(clk) != -EPROBE_DEFER) pr_warn("clk: couldn't get clock %d for %pOF\n", From d3aa6c9453a8885b23bc436bf7c1842cc6568167 Mon Sep 17 00:00:00 2001 From: Patrick Kelsey Date: Fri, 7 Apr 2023 12:52:39 -0400 Subject: [PATCH 114/190] IB/hfi1: Fix SDMA mmu_rb_node not being evicted in LRU order [ Upstream commit 9fe8fec5e43d5a80f43cbf61aaada1b047a1eb61 ] hfi1_mmu_rb_remove_unless_exact() did not move mmu_rb_node objects in mmu_rb_handler->lru_list after getting a cache hit on an mmu_rb_node. As a result, hfi1_mmu_rb_evict() was not guaranteed to evict truly least-recently used nodes. This could be a performance issue for an application when that application: - Uses some long-lived buffers frequently. - Uses a large number of buffers once. - Hits the mmu_rb_handler cache size or pinned-page limits, forcing mmu_rb_handler cache entries to be evicted. In this case, the one-time use buffers cause the long-lived buffer entries to eventually filter to the end of the LRU list where hfi1_mmu_rb_evict() will consider evicting a frequently-used long-lived entry instead of evicting one of the one-time use entries. Fix this by inserting new mmu_rb_node at the tail of mmu_rb_handler->lru_list and move mmu_rb_ndoe to the tail of mmu_rb_handler->lru_list when the mmu_rb_node is a hit in hfi1_mmu_rb_remove_unless_exact(). Change hfi1_mmu_rb_evict() to evict from the head of mmu_rb_handler->lru_list instead of the tail. Fixes: 0636e9ab8355 ("IB/hfi1: Add cache evict LRU list") Signed-off-by: Brendan Cunningham Signed-off-by: Patrick Kelsey Signed-off-by: Dennis Dalessandro Link: https://lore.kernel.org/r/168088635931.3027109.10423156330761536044.stgit@252.162.96.66.static.eigbox.net Signed-off-by: Leon Romanovsky Signed-off-by: Sasha Levin --- drivers/infiniband/hw/hfi1/mmu_rb.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c index e1c7996c018e..513a297b4ff0 100644 --- a/drivers/infiniband/hw/hfi1/mmu_rb.c +++ b/drivers/infiniband/hw/hfi1/mmu_rb.c @@ -175,7 +175,7 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, goto unlock; } __mmu_int_rb_insert(mnode, &handler->root); - list_add(&mnode->list, &handler->lru_list); + list_add_tail(&mnode->list, &handler->lru_list); ret = handler->ops->insert(handler->ops_arg, mnode); if (ret) { @@ -222,8 +222,10 @@ bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler, spin_lock_irqsave(&handler->lock, flags); node = __mmu_rb_search(handler, addr, len); if (node) { - if (node->addr == addr && node->len == len) + if (node->addr == addr && node->len == len) { + list_move_tail(&node->list, &handler->lru_list); goto unlock; + } __mmu_int_rb_remove(node, &handler->root); list_del(&node->list); /* remove from LRU list */ ret = true; @@ -244,8 +246,7 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) INIT_LIST_HEAD(&del_list); spin_lock_irqsave(&handler->lock, flags); - list_for_each_entry_safe_reverse(rbnode, ptr, &handler->lru_list, - list) { + list_for_each_entry_safe(rbnode, ptr, &handler->lru_list, list) { if (handler->ops->evict(handler->ops_arg, rbnode, evict_arg, &stop)) { __mmu_int_rb_remove(rbnode, &handler->root); @@ -257,9 +258,7 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) } spin_unlock_irqrestore(&handler->lock, flags); - while (!list_empty(&del_list)) { - rbnode = list_first_entry(&del_list, struct mmu_rb_node, list); - list_del(&rbnode->list); + list_for_each_entry_safe(rbnode, ptr, &del_list, list) { handler->ops->remove(handler->ops_arg, rbnode); } } From c5e44eb6430d45995b4502fee3cdfe402ecd6693 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 13 Mar 2023 18:45:53 -0400 Subject: [PATCH 115/190] NFSv4.1: Always send a RECLAIM_COMPLETE after establishing lease [ Upstream commit 40882deb83c29d8df4470d4e5e7f137b6acf7ad1 ] The spec requires that we always at least send a RECLAIM_COMPLETE when we're done establishing the lease and recovering any state. Fixes: fce5c838e133 ("nfs41: RECLAIM_COMPLETE functionality") Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- fs/nfs/nfs4state.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index e5b4c6987c84..f0f0fb7499e3 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -66,6 +66,8 @@ #define OPENOWNER_POOL_SIZE 8 +static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp); + const nfs4_stateid zero_stateid = { { .data = { 0 } }, .type = NFS4_SPECIAL_STATEID_TYPE, @@ -338,6 +340,8 @@ do_confirm: status = nfs4_proc_create_session(clp, cred); if (status != 0) goto out; + if (!(clp->cl_exchange_flags & EXCHGID4_FLAG_CONFIRMED_R)) + nfs4_state_start_reclaim_reboot(clp); nfs41_finish_session_reset(clp); nfs_mark_client_ready(clp, NFS_CS_READY); out: From 9c88c82523e45eaf1de6d5afdcb7658e212ab599 Mon Sep 17 00:00:00 2001 From: Dai Ngo Date: Tue, 18 Apr 2023 13:19:02 -0700 Subject: [PATCH 116/190] SUNRPC: remove the maximum number of retries in call_bind_status [ Upstream commit 691d0b782066a6eeeecbfceb7910a8f6184e6105 ] Currently call_bind_status places a hard limit of 3 to the number of retries on EACCES error. This limit was done to prevent NLM unlock requests from being hang forever when the server keeps returning garbage. However this change causes problem for cases when NLM service takes longer than 9 seconds to register with the port mapper after a restart. This patch removes this hard coded limit and let the RPC handles the retry based on the standard hard/soft task semantics. Fixes: 0b760113a3a1 ("NLM: Don't hang forever on NLM unlock requests") Reported-by: Helen Chao Tested-by: Helen Chao Signed-off-by: Dai Ngo Reviewed-by: Jeff Layton Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- include/linux/sunrpc/sched.h | 3 +-- net/sunrpc/clnt.c | 3 --- net/sunrpc/sched.c | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index ad2e243f3f03..96837ae07822 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -88,8 +88,7 @@ struct rpc_task { #endif unsigned char tk_priority : 2,/* Task priority */ tk_garb_retry : 2, - tk_cred_retry : 2, - tk_rebind_retry : 2; + tk_cred_retry : 2; }; typedef void (*rpc_action)(struct rpc_task *); diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 1946bd13d5df..e5498253ad93 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1814,9 +1814,6 @@ call_bind_status(struct rpc_task *task) status = -EOPNOTSUPP; break; } - if (task->tk_rebind_retry == 0) - break; - task->tk_rebind_retry--; rpc_delay(task, 3*HZ); goto retry_timeout; case -ETIMEDOUT: diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index e36ae4d4b540..9af919364a00 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -709,7 +709,6 @@ rpc_init_task_statistics(struct rpc_task *task) /* Initialize retry counters */ task->tk_garb_retry = 2; task->tk_cred_retry = 2; - task->tk_rebind_retry = 2; /* starting timestamp */ task->tk_start = ktime_get(); From 9b710c80976cc43a369bab7278ea9baa926153a8 Mon Sep 17 00:00:00 2001 From: Mark Zhang Date: Thu, 20 Apr 2023 04:39:06 +0300 Subject: [PATCH 117/190] RDMA/mlx5: Use correct device num_ports when modify DC [ Upstream commit 746aa3c8cb1a650ff2583497ac646e505831b9b9 ] Just like other QP types, when modify DC, the port_num should be compared with dev->num_ports, instead of HCA_CAP.num_ports. Otherwise Multi-port vHCA on DC may not work. Fixes: 776a3906b692 ("IB/mlx5: Add support for DC target QP") Link: https://lore.kernel.org/r/20230420013906.1244185-1-markzhang@nvidia.com Signed-off-by: Mark Zhang Reviewed-by: Maor Gottlieb Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin --- drivers/infiniband/hw/mlx5/qp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 1520a3098f7d..0455abfba41c 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -3350,7 +3350,7 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr, return -EINVAL; if (attr->port_num == 0 || - attr->port_num > MLX5_CAP_GEN(dev->mdev, num_ports)) { + attr->port_num > dev->num_ports) { mlx5_ib_dbg(dev, "invalid port number %d. number of ports is %d\n", attr->port_num, dev->num_ports); return -EINVAL; From 1234be447d32cc8b086200bddb3a14bd29a8df3b Mon Sep 17 00:00:00 2001 From: Stafford Horne Date: Sat, 11 Feb 2023 19:14:06 +0900 Subject: [PATCH 118/190] openrisc: Properly store r31 to pt_regs on unhandled exceptions [ Upstream commit 812489ac4dd91144a74ce65ecf232252a2e406fb ] In commit 91993c8c2ed5 ("openrisc: use shadow registers to save regs on exception") the unhandled exception path was changed to do an early store of r30 instead of r31. The entry code was not updated and r31 is not getting stored to pt_regs. This patch updates the entry handler to store r31 instead of r30. We also remove some misleading commented out store r30 and r31 instructrions. I noticed this while working on adding floating point exception handling, This issue probably would never impact anything since we kill the process or Oops right away on unhandled exceptions. Fixes: 91993c8c2ed5 ("openrisc: use shadow registers to save regs on exception") Signed-off-by: Stafford Horne Signed-off-by: Sasha Levin --- arch/openrisc/kernel/entry.S | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S index c2c3ce8a0f84..7b408d67f11e 100644 --- a/arch/openrisc/kernel/entry.S +++ b/arch/openrisc/kernel/entry.S @@ -177,7 +177,6 @@ handler: ;\ l.sw PT_GPR28(r1),r28 ;\ l.sw PT_GPR29(r1),r29 ;\ /* r30 already save */ ;\ -/* l.sw PT_GPR30(r1),r30*/ ;\ l.sw PT_GPR31(r1),r31 ;\ TRACE_IRQS_OFF_ENTRY ;\ /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ @@ -215,9 +214,8 @@ handler: ;\ l.sw PT_GPR27(r1),r27 ;\ l.sw PT_GPR28(r1),r28 ;\ l.sw PT_GPR29(r1),r29 ;\ - /* r31 already saved */ ;\ - l.sw PT_GPR30(r1),r30 ;\ -/* l.sw PT_GPR31(r1),r31 */ ;\ + /* r30 already saved */ ;\ + l.sw PT_GPR31(r1),r31 ;\ /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ l.addi r30,r0,-1 ;\ l.sw PT_ORIG_GPR11(r1),r30 ;\ From 118f50ac48cb6851de211aaedabe7589c4dad293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 7 Jul 2021 18:28:27 +0200 Subject: [PATCH 119/190] pwm: mtk-disp: Don't check the return code of pwmchip_remove() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 9b7b5736ffd5da6f8f6329ebe5f1829cbcf8afae ] pwmchip_remove() returns always 0. Don't use the value to make it possible to eventually change the function to return void. Also the driver core ignores the return value of mtk_disp_pwm_remove(). Signed-off-by: Uwe Kleine-König Signed-off-by: Thierry Reding Stable-dep-of: 36dd7f530ae7 ("pwm: mtk-disp: Disable shadow registers before setting backlight values") Signed-off-by: Sasha Levin --- drivers/pwm/pwm-mtk-disp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c index 893940d45f0d..dd31a00d6326 100644 --- a/drivers/pwm/pwm-mtk-disp.c +++ b/drivers/pwm/pwm-mtk-disp.c @@ -248,13 +248,12 @@ disable_clk_main: static int mtk_disp_pwm_remove(struct platform_device *pdev) { struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev); - int ret; - ret = pwmchip_remove(&mdp->chip); + pwmchip_remove(&mdp->chip); clk_unprepare(mdp->clk_mm); clk_unprepare(mdp->clk_main); - return ret; + return 0; } static const struct mtk_pwm_data mt2701_pwm_data = { From a9c39726e86858953aceca9326b3df0d0827eae3 Mon Sep 17 00:00:00 2001 From: Jitao Shi Date: Sun, 8 Aug 2021 21:24:29 +0800 Subject: [PATCH 120/190] pwm: mtk-disp: Adjust the clocks to avoid them mismatch [ Upstream commit d7a4e582587d97a586b1f7709e3bddcf35928e96 ] The clks "main" and "mm" are prepared in .probe() (and unprepared in .remove()). This results in the clocks being on during suspend which results in unnecessarily increased power consumption. Remove the clock operations from .probe() and .remove(). Add the clk_prepare_enable() in .enable() and the clk_disable_unprepare() in .disable(). Signed-off-by: Jitao Shi [thierry.reding@gmail.com: squashed in fixup patch] Signed-off-by: Thierry Reding Stable-dep-of: 36dd7f530ae7 ("pwm: mtk-disp: Disable shadow registers before setting backlight values") Signed-off-by: Sasha Levin --- drivers/pwm/pwm-mtk-disp.c | 95 +++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 52 deletions(-) diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c index dd31a00d6326..6d0893886604 100644 --- a/drivers/pwm/pwm-mtk-disp.c +++ b/drivers/pwm/pwm-mtk-disp.c @@ -82,6 +82,19 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, u64 div, rate; int err; + err = clk_prepare_enable(mdp->clk_main); + if (err < 0) { + dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err)); + return err; + } + + err = clk_prepare_enable(mdp->clk_mm); + if (err < 0) { + dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err)); + clk_disable_unprepare(mdp->clk_main); + return err; + } + /* * Find period, high_width and clk_div to suit duty_ns and period_ns. * Calculate proper div value to keep period value in the bound. @@ -95,8 +108,11 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, rate = clk_get_rate(mdp->clk_main); clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >> PWM_PERIOD_BIT_WIDTH; - if (clk_div > PWM_CLKDIV_MAX) + if (clk_div > PWM_CLKDIV_MAX) { + clk_disable_unprepare(mdp->clk_mm); + clk_disable_unprepare(mdp->clk_main); return -EINVAL; + } div = NSEC_PER_SEC * (clk_div + 1); period = div64_u64(rate * period_ns, div); @@ -106,16 +122,6 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, high_width = div64_u64(rate * duty_ns, div); value = period | (high_width << PWM_HIGH_WIDTH_SHIFT); - err = clk_enable(mdp->clk_main); - if (err < 0) - return err; - - err = clk_enable(mdp->clk_mm); - if (err < 0) { - clk_disable(mdp->clk_main); - return err; - } - mtk_disp_pwm_update_bits(mdp, mdp->data->con0, PWM_CLKDIV_MASK, clk_div << PWM_CLKDIV_SHIFT); @@ -130,10 +136,21 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, mtk_disp_pwm_update_bits(mdp, mdp->data->commit, mdp->data->commit_mask, 0x0); + } else { + /* + * For MT2701, disable double buffer before writing register + * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH. + */ + mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug, + mdp->data->bls_debug_mask, + mdp->data->bls_debug_mask); + mtk_disp_pwm_update_bits(mdp, mdp->data->con0, + mdp->data->con0_sel, + mdp->data->con0_sel); } - clk_disable(mdp->clk_mm); - clk_disable(mdp->clk_main); + clk_disable_unprepare(mdp->clk_mm); + clk_disable_unprepare(mdp->clk_main); return 0; } @@ -143,13 +160,16 @@ static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip); int err; - err = clk_enable(mdp->clk_main); - if (err < 0) - return err; - - err = clk_enable(mdp->clk_mm); + err = clk_prepare_enable(mdp->clk_main); if (err < 0) { - clk_disable(mdp->clk_main); + dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err)); + return err; + } + + err = clk_prepare_enable(mdp->clk_mm); + if (err < 0) { + dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err)); + clk_disable_unprepare(mdp->clk_main); return err; } @@ -166,8 +186,8 @@ static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask, 0x0); - clk_disable(mdp->clk_mm); - clk_disable(mdp->clk_main); + clk_disable_unprepare(mdp->clk_mm); + clk_disable_unprepare(mdp->clk_main); } static const struct pwm_ops mtk_disp_pwm_ops = { @@ -202,14 +222,6 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev) if (IS_ERR(mdp->clk_mm)) return PTR_ERR(mdp->clk_mm); - ret = clk_prepare(mdp->clk_main); - if (ret < 0) - return ret; - - ret = clk_prepare(mdp->clk_mm); - if (ret < 0) - goto disable_clk_main; - mdp->chip.dev = &pdev->dev; mdp->chip.ops = &mtk_disp_pwm_ops; mdp->chip.base = -1; @@ -217,32 +229,13 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev) ret = pwmchip_add(&mdp->chip); if (ret < 0) { - dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); - goto disable_clk_mm; + dev_err(&pdev->dev, "pwmchip_add() failed: %pe\n", ERR_PTR(ret)); + return ret; } platform_set_drvdata(pdev, mdp); - /* - * For MT2701, disable double buffer before writing register - * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH. - */ - if (!mdp->data->has_commit) { - mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug, - mdp->data->bls_debug_mask, - mdp->data->bls_debug_mask); - mtk_disp_pwm_update_bits(mdp, mdp->data->con0, - mdp->data->con0_sel, - mdp->data->con0_sel); - } - return 0; - -disable_clk_mm: - clk_unprepare(mdp->clk_mm); -disable_clk_main: - clk_unprepare(mdp->clk_main); - return ret; } static int mtk_disp_pwm_remove(struct platform_device *pdev) @@ -250,8 +243,6 @@ static int mtk_disp_pwm_remove(struct platform_device *pdev) struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev); pwmchip_remove(&mdp->chip); - clk_unprepare(mdp->clk_mm); - clk_unprepare(mdp->clk_main); return 0; } From 4a9117b117a0d8ba302ceffe2314946dc01f848f Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Mon, 3 Apr 2023 15:30:53 +0200 Subject: [PATCH 121/190] pwm: mtk-disp: Disable shadow registers before setting backlight values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 36dd7f530ae7d9ce9e853ffb8aa337de65c6600b ] If shadow registers usage is not desired, disable that before performing any write to CON0/1 registers in the .apply() callback, otherwise we may lose clkdiv or period/width updates. Fixes: cd4b45ac449a ("pwm: Add MediaTek MT2701 display PWM driver support") Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Nícolas F. R. A. Prado Tested-by: Nícolas F. R. A. Prado Reviewed-by: Alexandre Mergnat Tested-by: Alexandre Mergnat Signed-off-by: Thierry Reding Signed-off-by: Sasha Levin --- drivers/pwm/pwm-mtk-disp.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c index 6d0893886604..c49b1e696b8c 100644 --- a/drivers/pwm/pwm-mtk-disp.c +++ b/drivers/pwm/pwm-mtk-disp.c @@ -122,6 +122,19 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, high_width = div64_u64(rate * duty_ns, div); value = period | (high_width << PWM_HIGH_WIDTH_SHIFT); + if (mdp->data->bls_debug && !mdp->data->has_commit) { + /* + * For MT2701, disable double buffer before writing register + * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH. + */ + mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug, + mdp->data->bls_debug_mask, + mdp->data->bls_debug_mask); + mtk_disp_pwm_update_bits(mdp, mdp->data->con0, + mdp->data->con0_sel, + mdp->data->con0_sel); + } + mtk_disp_pwm_update_bits(mdp, mdp->data->con0, PWM_CLKDIV_MASK, clk_div << PWM_CLKDIV_SHIFT); @@ -136,17 +149,6 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, mtk_disp_pwm_update_bits(mdp, mdp->data->commit, mdp->data->commit_mask, 0x0); - } else { - /* - * For MT2701, disable double buffer before writing register - * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH. - */ - mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug, - mdp->data->bls_debug_mask, - mdp->data->bls_debug_mask); - mtk_disp_pwm_update_bits(mdp, mdp->data->con0, - mdp->data->con0_sel, - mdp->data->con0_sel); } clk_disable_unprepare(mdp->clk_mm); From 9b0d1ffbd76487bb153821020fc5b376a734442a Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Tue, 29 Nov 2022 19:16:34 +0800 Subject: [PATCH 122/190] phy: tegra: xusb: Add missing tegra_xusb_port_unregister for usb2_port and ulpi_port [ Upstream commit e024854048e733391b31fe5a398704b31b9af803 ] The tegra_xusb_port_unregister should be called when usb2_port and ulpi_port map fails in tegra_xusb_add_usb2_port() or in tegra_xusb_add_ulpi_port(), fix it. Fixes: 53d2a715c240 ("phy: Add Tegra XUSB pad controller support") Signed-off-by: Gaosheng Cui Acked-by: Thierry Reding Link: https://lore.kernel.org/r/20221129111634.1547747-1-cuigaosheng1@huawei.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/phy/tegra/xusb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index 39c01ef57d83..17211b31e1ed 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -583,6 +583,7 @@ static int tegra_xusb_add_usb2_port(struct tegra_xusb_padctl *padctl, usb2->base.lane = usb2->base.ops->map(&usb2->base); if (IS_ERR(usb2->base.lane)) { err = PTR_ERR(usb2->base.lane); + tegra_xusb_port_unregister(&usb2->base); goto out; } @@ -635,6 +636,7 @@ static int tegra_xusb_add_ulpi_port(struct tegra_xusb_padctl *padctl, ulpi->base.lane = ulpi->base.ops->map(&ulpi->base); if (IS_ERR(ulpi->base.lane)) { err = PTR_ERR(ulpi->base.lane); + tegra_xusb_port_unregister(&ulpi->base); goto out; } From 78728cd5543019454b620a32f0b9ba1af7c50212 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Tue, 14 Feb 2023 17:18:25 +0200 Subject: [PATCH 123/190] dmaengine: at_xdmac: do not enable all cyclic channels [ Upstream commit f8435befd81dd85b7b610598551fadf675849bc1 ] Do not global enable all the cyclic channels in at_xdmac_resume(). Instead save the global status in at_xdmac_suspend() and re-enable the cyclic channel only if it was active before suspend. Fixes: e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel eXtended DMA Controller driver") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230214151827.1050280-6-claudiu.beznea@microchip.com Signed-off-by: Vinod Koul Signed-off-by: Sasha Levin --- drivers/dma/at_xdmac.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index a451ecae1669..33ea7abd8cc9 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -223,6 +223,7 @@ struct at_xdmac { int irq; struct clk *clk; u32 save_gim; + u32 save_gs; struct dma_pool *at_xdmac_desc_pool; struct at_xdmac_chan chan[0]; }; @@ -1878,6 +1879,7 @@ static int atmel_xdmac_suspend(struct device *dev) } } atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM); + atxdmac->save_gs = at_xdmac_read(atxdmac, AT_XDMAC_GS); at_xdmac_off(atxdmac); clk_disable_unprepare(atxdmac->clk); @@ -1914,7 +1916,8 @@ static int atmel_xdmac_resume(struct device *dev) at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc); at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim); wmb(); - at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); + if (atxdmac->save_gs & atchan->mask) + at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); } } return 0; From f2025a1d8603cbb22cd2e8388cf6d0c7ad507c80 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 3 May 2023 16:39:56 +0200 Subject: [PATCH 124/190] parisc: Fix argument pointer in real64_call_asm() commit 6e3220ba3323a2c24be834aebf5d6e9f89d0993f upstream. Fix the argument pointer (ap) to point to real-mode memory instead of virtual memory. It's interesting that this issue hasn't shown up earlier, as this could have happened with any 64-bit PDC ROM code. I just noticed it because I suddenly faced a HPMC while trying to execute the 64-bit STI ROM code of an Visualize-FXe graphics card for the STI text console. Signed-off-by: Helge Deller Cc: Signed-off-by: Greg Kroah-Hartman --- arch/parisc/kernel/real2.S | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S index 2b16d8d6598f..c37010a13586 100644 --- a/arch/parisc/kernel/real2.S +++ b/arch/parisc/kernel/real2.S @@ -248,9 +248,6 @@ ENTRY_CFI(real64_call_asm) /* save fn */ copy %arg2, %r31 - /* set up the new ap */ - ldo 64(%arg1), %r29 - /* load up the arg registers from the saved arg area */ /* 32-bit calling convention passes first 4 args in registers */ ldd 0*REG_SZ(%arg1), %arg0 /* note overwriting arg0 */ @@ -262,7 +259,9 @@ ENTRY_CFI(real64_call_asm) ldd 7*REG_SZ(%arg1), %r19 ldd 1*REG_SZ(%arg1), %arg1 /* do this one last! */ + /* set up real-mode stack and real-mode ap */ tophys_r1 %sp + ldo -16(%sp), %r29 /* Reference param save area */ b,l rfi_virt2real,%r2 nop From e9c5412c5972124776c1b873533eb39e287a4dfa Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Thu, 27 Apr 2023 10:15:26 +0900 Subject: [PATCH 125/190] nilfs2: do not write dirty data after degenerating to read-only commit 28a65b49eb53e172d23567005465019658bfdb4d upstream. According to syzbot's report, mark_buffer_dirty() called from nilfs_segctor_do_construct() outputs a warning with some patterns after nilfs2 detects metadata corruption and degrades to read-only mode. After such read-only degeneration, page cache data may be cleared through nilfs_clear_dirty_page() which may also clear the uptodate flag for their buffer heads. However, even after the degeneration, log writes are still performed by unmount processing etc., which causes mark_buffer_dirty() to be called for buffer heads without the "uptodate" flag and causes the warning. Since any writes should not be done to a read-only file system in the first place, this fixes the warning in mark_buffer_dirty() by letting nilfs_segctor_do_construct() abort early if in read-only mode. This also changes the retry check of nilfs_segctor_write_out() to avoid unnecessary log write retries if it detects -EROFS that nilfs_segctor_do_construct() returned. Link: https://lkml.kernel.org/r/20230427011526.13457-1-konishi.ryusuke@gmail.com Signed-off-by: Ryusuke Konishi Tested-by: Ryusuke Konishi Reported-by: syzbot+2af3bc9585be7f23f290@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=2af3bc9585be7f23f290 Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/nilfs2/segment.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index b23ed9a35e5e..3091d1a3edde 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -2039,6 +2039,9 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) struct the_nilfs *nilfs = sci->sc_super->s_fs_info; int err; + if (sb_rdonly(sci->sc_super)) + return -EROFS; + nilfs_sc_cstage_set(sci, NILFS_ST_INIT); sci->sc_cno = nilfs->ns_cno; @@ -2724,7 +2727,7 @@ static void nilfs_segctor_write_out(struct nilfs_sc_info *sci) flush_work(&sci->sc_iput_work); - } while (ret && retrycount-- > 0); + } while (ret && ret != -EROFS && retrycount-- > 0); } /** From d536f9976bb04e9c84cf80045a9355975e418f41 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Mon, 1 May 2023 04:30:46 +0900 Subject: [PATCH 126/190] nilfs2: fix infinite loop in nilfs_mdt_get_block() commit a6a491c048882e7e424d407d32cba0b52d9ef2bf upstream. If the disk image that nilfs2 mounts is corrupted and a virtual block address obtained by block lookup for a metadata file is invalid, nilfs_bmap_lookup_at_level() may return the same internal return code as -ENOENT, meaning the block does not exist in the metadata file. This duplication of return codes confuses nilfs_mdt_get_block(), causing it to read and create a metadata block indefinitely. In particular, if this happens to the inode metadata file, ifile, semaphore i_rwsem can be left held, causing task hangs in lock_mount. Fix this issue by making nilfs_bmap_lookup_at_level() treat virtual block address translation failures with -ENOENT as metadata corruption instead of returning the error code. Link: https://lkml.kernel.org/r/20230430193046.6769-1-konishi.ryusuke@gmail.com Signed-off-by: Ryusuke Konishi Tested-by: Ryusuke Konishi Reported-by: syzbot+221d75710bde87fa0e97@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=221d75710bde87fa0e97 Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/nilfs2/bmap.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c index fb5a9a8a13cf..2ba57e4b4f0a 100644 --- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c @@ -67,20 +67,28 @@ int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level, down_read(&bmap->b_sem); ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp); - if (ret < 0) { - ret = nilfs_bmap_convert_error(bmap, __func__, ret); + if (ret < 0) goto out; - } + if (NILFS_BMAP_USE_VBN(bmap)) { ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp, &blocknr); if (!ret) *ptrp = blocknr; + else if (ret == -ENOENT) { + /* + * If there was no valid entry in DAT for the block + * address obtained by b_ops->bop_lookup, then pass + * internal code -EINVAL to nilfs_bmap_convert_error + * to treat it as metadata corruption. + */ + ret = -EINVAL; + } } out: up_read(&bmap->b_sem); - return ret; + return nilfs_bmap_convert_error(bmap, __func__, ret); } int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp, From 38d33593260536840b49fd1dcac9aedfd14a9d42 Mon Sep 17 00:00:00 2001 From: Li Nan Date: Wed, 22 Feb 2023 12:10:00 +0800 Subject: [PATCH 127/190] md/raid10: fix null-ptr-deref in raid10_sync_request commit a405c6f0229526160aa3f177f65e20c86fce84c5 upstream. init_resync() inits mempool and sets conf->have_replacemnt at the beginning of sync, close_sync() frees the mempool when sync is completed. After [1] recovery might be skipped and init_resync() is called but close_sync() is not. null-ptr-deref occurs with r10bio->dev[i].repl_bio. The following is one way to reproduce the issue. 1) create a array, wait for resync to complete, mddev->recovery_cp is set to MaxSector. 2) recovery is woken and it is skipped. conf->have_replacement is set to 0 in init_resync(). close_sync() not called. 3) some io errors and rdev A is set to WantReplacement. 4) a new device is added and set to A's replacement. 5) recovery is woken, A have replacement, but conf->have_replacemnt is 0. r10bio->dev[i].repl_bio will not be alloced and null-ptr-deref occurs. Fix it by not calling init_resync() if recovery skipped. [1] commit 7e83ccbecd60 ("md/raid10: Allow skipping recovery when clean arrays are assembled") Fixes: 7e83ccbecd60 ("md/raid10: Allow skipping recovery when clean arrays are assembled") Cc: stable@vger.kernel.org Signed-off-by: Li Nan Signed-off-by: Song Liu Link: https://lore.kernel.org/r/20230222041000.3341651-3-linan666@huaweicloud.com Signed-off-by: Greg Kroah-Hartman --- drivers/md/raid10.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index dc625f9cfa9d..f6d2be1d2386 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2957,10 +2957,6 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, sector_t chunk_mask = conf->geo.chunk_mask; int page_idx = 0; - if (!mempool_initialized(&conf->r10buf_pool)) - if (init_resync(conf)) - return 0; - /* * Allow skipping a full rebuild for incremental assembly * of a clean array, like RAID1 does. @@ -2976,6 +2972,10 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, return mddev->dev_sectors - sector_nr; } + if (!mempool_initialized(&conf->r10buf_pool)) + if (init_resync(conf)) + return 0; + skipped: max_sector = mddev->dev_sectors; if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) || From d65ba6390eaf095a40bc976fd94a2ff8fcaaa9e9 Mon Sep 17 00:00:00 2001 From: Bitterblue Smith Date: Mon, 13 Mar 2023 15:42:59 +0200 Subject: [PATCH 128/190] wifi: rtl8xxxu: RTL8192EU always needs full init commit d46e04ccd40457a0119b76e11ab64a2ad403e138 upstream. Always run the entire init sequence (rtl8xxxu_init_device()) for RTL8192EU. It's what the vendor driver does too. This fixes a bug where the device is unable to connect after rebooting: wlp3s0f3u2: send auth to ... (try 1/3) wlp3s0f3u2: send auth to ... (try 2/3) wlp3s0f3u2: send auth to ... (try 3/3) wlp3s0f3u2: authentication with ... timed out Rebooting leaves the device powered on (partially? at least the firmware is still running), but not really in a working state. Cc: stable@vger.kernel.org Signed-off-by: Bitterblue Smith Acked-by: Jes Sorensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/4eb111a9-d4c4-37d0-b376-4e202de7153c@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c index eb8f046ae20d..f936ad6c5728 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c @@ -1710,6 +1710,7 @@ struct rtl8xxxu_fileops rtl8192eu_fops = { .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24), .has_s0s1 = 0, .gen2_thermal_meter = 1, + .needs_full_init = 1, .adda_1t_init = 0x0fc01616, .adda_1t_path_on = 0x0fc01616, .adda_2t_path_on_a = 0x0fc01616, From 24637afbe756cdb1f09168c05a8babb5dd3bc518 Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Thu, 17 Nov 2022 13:04:31 +0100 Subject: [PATCH 129/190] clk: rockchip: rk3399: allow clk_cifout to force clk_cifout_src to reparent commit 933bf364e152cd60902cf9585c2ba310d593e69f upstream. clk_cifout is derived from clk_cifout_src through an integer divider limited to 32. clk_cifout_src is a child of either cpll, gpll or npll without any possibility of a divider of any sort. The default clock parent is cpll. Let's allow clk_cifout to ask its parent clk_cifout_src to reparent in order to find the real closest possible rate for clk_cifout and not one derived from cpll only. Cc: stable@vger.kernel.org # 4.10+ Fixes: fd8bc829336a ("clk: rockchip: fix the rk3399 cifout clock") Signed-off-by: Quentin Schulz Link: https://lore.kernel.org/r/20221117-rk3399-cifout-set-rate-parent-v1-0-432548d04081@theobroma-systems.com Signed-off-by: Heiko Stuebner Signed-off-by: Greg Kroah-Hartman --- drivers/clk/rockchip/clk-rk3399.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c index 5a628148f3f0..ec9850db5bf9 100644 --- a/drivers/clk/rockchip/clk-rk3399.c +++ b/drivers/clk/rockchip/clk-rk3399.c @@ -1267,7 +1267,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { RK3399_CLKSEL_CON(56), 6, 2, MFLAGS, RK3399_CLKGATE_CON(10), 7, GFLAGS), - COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, 0, + COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, CLK_SET_RATE_PARENT, RK3399_CLKSEL_CON(56), 5, 1, MFLAGS, 0, 5, DFLAGS), /* gic */ From fdca36e1689c5ee68de9ee09a42e0b311c7e2160 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Thu, 6 Apr 2023 13:00:34 +0800 Subject: [PATCH 130/190] btrfs: scrub: reject unsupported scrub flags commit 604e6681e114d05a2e384c4d1e8ef81918037ef5 upstream. Since the introduction of scrub interface, the only flag that we support is BTRFS_SCRUB_READONLY. Thus there is no sanity checks, if there are some undefined flags passed in, we just ignore them. This is problematic if we want to introduce new scrub flags, as we have no way to determine if such flags are supported. Address the problem by introducing a check for the flags, and if unsupported flags are set, return -EOPNOTSUPP to inform the user space. This check should be backported for all supported kernels before any new scrub flags are introduced. CC: stable@vger.kernel.org # 4.14+ Reviewed-by: Anand Jain Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/ioctl.c | 5 +++++ include/uapi/linux/btrfs.h | 1 + 2 files changed, 6 insertions(+) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 4f2513388567..f009d585e72f 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4722,6 +4722,11 @@ static long btrfs_ioctl_scrub(struct file *file, void __user *arg) if (IS_ERR(sa)) return PTR_ERR(sa); + if (sa->flags & ~BTRFS_SCRUB_SUPPORTED_FLAGS) { + ret = -EOPNOTSUPP; + goto out; + } + if (!(sa->flags & BTRFS_SCRUB_READONLY)) { ret = mnt_want_write_file(file); if (ret) diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index 5ca1d21fc4a7..dd7a7b3e53f4 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -162,6 +162,7 @@ struct btrfs_scrub_progress { }; #define BTRFS_SCRUB_READONLY 1 +#define BTRFS_SCRUB_SUPPORTED_FLAGS (BTRFS_SCRUB_READONLY) struct btrfs_ioctl_scrub_args { __u64 devid; /* in */ __u64 start; /* in */ From 5a50e842c54702d2182f8a382d3106ab296f0904 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Wed, 5 Apr 2023 16:20:17 +0200 Subject: [PATCH 131/190] s390/dasd: fix hanging blockdevice after request requeue commit d8898ee50edecacdf0141f26fd90acf43d7e9cd7 upstream. The DASD driver does not kick the requeue list when requeuing IO requests to the blocklayer. This might lead to hanging blockdevice when there is no other trigger for this. Fix by automatically kick the requeue list when requeuing DASD requests to the blocklayer. Fixes: e443343e509a ("s390/dasd: blk-mq conversion") CC: stable@vger.kernel.org # 4.14+ Signed-off-by: Stefan Haberland Reviewed-by: Jan Hoeppner Reviewed-by: Halil Pasic Link: https://lore.kernel.org/r/20230405142017.2446986-8-sth@linux.ibm.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/s390/block/dasd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 7beda20cf122..c1cf277d0d89 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2841,7 +2841,7 @@ static int _dasd_requeue_request(struct dasd_ccw_req *cqr) return 0; spin_lock_irq(&cqr->dq->lock); req = (struct request *) cqr->callback_data; - blk_mq_requeue_request(req, false); + blk_mq_requeue_request(req, true); spin_unlock_irq(&cqr->dq->lock); return 0; From ca8b634fdf07dee3f6dfde57079c4511480b525e Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Tue, 4 Apr 2023 13:34:28 -0400 Subject: [PATCH 132/190] dm integrity: call kmem_cache_destroy() in dm_integrity_init() error path commit 6b79a428c02769f2a11f8ae76bf866226d134887 upstream. Otherwise the journal_io_cache will leak if dm_register_target() fails. Cc: stable@vger.kernel.org Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-integrity.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index b054271066ac..0a4e440948f0 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -3689,11 +3689,13 @@ int __init dm_integrity_init(void) } r = dm_register_target(&integrity_target); - - if (r < 0) + if (r < 0) { DMERR("register failed %d", r); + kmem_cache_destroy(journal_io_cache); + return r; + } - return r; + return 0; } void dm_integrity_exit(void) From 12849ed107c0b2869fb775c81208050899006f07 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 18 Apr 2023 15:57:47 -0400 Subject: [PATCH 133/190] dm flakey: fix a crash with invalid table line commit 98dba02d9a93eec11bffbb93c7c51624290702d2 upstream. This command will crash with NULL pointer dereference: dmsetup create flakey --table \ "0 `blockdev --getsize /dev/ram0` flakey /dev/ram0 0 0 1 2 corrupt_bio_byte 512" Fix the crash by checking if arg_name is non-NULL before comparing it. Cc: stable@vger.kernel.org Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-flakey.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 1f1614af5e97..5116856ea81d 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -124,9 +124,9 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, * Direction r or w? */ arg_name = dm_shift_arg(as); - if (!strcasecmp(arg_name, "w")) + if (arg_name && !strcasecmp(arg_name, "w")) fc->corrupt_bio_rw = WRITE; - else if (!strcasecmp(arg_name, "r")) + else if (arg_name && !strcasecmp(arg_name, "r")) fc->corrupt_bio_rw = READ; else { ti->error = "Invalid corrupt bio direction (r or w)"; From b4b94b25c78ed03be0e07fa4e76fe51e64dac533 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Mon, 17 Apr 2023 11:59:56 -0400 Subject: [PATCH 134/190] dm ioctl: fix nested locking in table_clear() to remove deadlock concern commit 3d32aaa7e66d5c1479a3c31d6c2c5d45dd0d3b89 upstream. syzkaller found the following problematic rwsem locking (with write lock already held): down_read+0x9d/0x450 kernel/locking/rwsem.c:1509 dm_get_inactive_table+0x2b/0xc0 drivers/md/dm-ioctl.c:773 __dev_status+0x4fd/0x7c0 drivers/md/dm-ioctl.c:844 table_clear+0x197/0x280 drivers/md/dm-ioctl.c:1537 In table_clear, it first acquires a write lock https://elixir.bootlin.com/linux/v6.2/source/drivers/md/dm-ioctl.c#L1520 down_write(&_hash_lock); Then before the lock is released at L1539, there is a path shown above: table_clear -> __dev_status -> dm_get_inactive_table -> down_read https://elixir.bootlin.com/linux/v6.2/source/drivers/md/dm-ioctl.c#L773 down_read(&_hash_lock); It tries to acquire the same read lock again, resulting in the deadlock problem. Fix this by moving table_clear()'s __dev_status() call to after its up_write(&_hash_lock); Cc: stable@vger.kernel.org Reported-by: Zheng Zhang Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-ioctl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 0c8ddf37ef39..e1603c17e346 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1410,11 +1410,12 @@ static int table_clear(struct file *filp, struct dm_ioctl *param, size_t param_s hc->new_map = NULL; } - param->flags &= ~DM_INACTIVE_PRESENT_FLAG; - - __dev_status(hc->md, param); md = hc->md; up_write(&_hash_lock); + + param->flags &= ~DM_INACTIVE_PRESENT_FLAG; + __dev_status(md, param); + if (old_map) { dm_sync_table(md); dm_table_destroy(old_map); From 409b4fa76466231db305643d75ef477a5b779f99 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 3 Apr 2023 18:48:30 +0300 Subject: [PATCH 135/190] perf auxtrace: Fix address filter entire kernel size commit 1f9f33ccf0320be21703d9195dd2b36a1c9a07cb upstream. kallsyms is not completely in address order. In find_entire_kern_cb(), calculate the kernel end from the maximum address not the last symbol. Example: Before: $ sudo cat /proc/kallsyms | grep ' [twTw] ' | tail -1 ffffffffc00b8bd0 t bpf_prog_6deef7357e7b4530 [bpf] $ sudo cat /proc/kallsyms | grep ' [twTw] ' | sort | tail -1 ffffffffc15e0cc0 t iwl_mvm_exit [iwlmvm] $ perf.d093603a05aa record -v --kcore -e intel_pt// --filter 'filter *' -- uname |& grep filter Address filter: filter 0xffffffff93200000/0x2ceba000 After: $ perf.8fb0f7a01f8e record -v --kcore -e intel_pt// --filter 'filter *' -- uname |& grep filter Address filter: filter 0xffffffff93200000/0x2e3e2000 Fixes: 1b36c03e356936d6 ("perf record: Add support for using symbols in address filters") Signed-off-by: Adrian Hunter Cc: Adrian Hunter Cc: Ian Rogers Cc: Jiri Olsa Cc: Namhyung Kim Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230403154831.8651-2-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Greg Kroah-Hartman --- tools/perf/util/auxtrace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 1e607403c94c..5ae37a83dca3 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -1793,6 +1793,7 @@ static int find_entire_kern_cb(void *arg, const char *name __maybe_unused, char type, u64 start) { struct sym_args *args = arg; + u64 size; if (!kallsyms__is_function(type)) return 0; @@ -1802,7 +1803,9 @@ static int find_entire_kern_cb(void *arg, const char *name __maybe_unused, args->start = start; } /* Don't know exactly where the kernel ends, so we add a page */ - args->size = round_up(start, page_size) + page_size - args->start; + size = round_up(start, page_size) + page_size - args->start; + if (size > args->size) + args->size = size; return 0; } From f653ce4db543cdbb417be1d8732684b5becb90eb Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 1 May 2023 17:42:06 +0200 Subject: [PATCH 136/190] debugobject: Ensure pool refill (again) commit 0af462f19e635ad522f28981238334620881badc upstream. The recent fix to ensure atomicity of lookup and allocation inadvertently broke the pool refill mechanism. Prior to that change debug_objects_activate() and debug_objecs_assert_init() invoked debug_objecs_init() to set up the tracking object for statically initialized objects. That's not longer the case and debug_objecs_init() is now the only place which does pool refills. Depending on the number of statically initialized objects this can be enough to actually deplete the pool, which was observed by Ido via a debugobjects OOM warning. Restore the old behaviour by adding explicit refill opportunities to debug_objects_activate() and debug_objecs_assert_init(). Fixes: 63a759694eed ("debugobject: Prevent init race with static objects") Reported-by: Ido Schimmel Signed-off-by: Thomas Gleixner Tested-by: Ido Schimmel Link: https://lore.kernel.org/r/871qk05a9d.ffs@tglx Signed-off-by: Greg Kroah-Hartman --- lib/debugobjects.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/debugobjects.c b/lib/debugobjects.c index 2315a75c45c3..5f23d896df55 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -460,6 +460,16 @@ static struct debug_obj *lookup_object_or_alloc(void *addr, struct debug_bucket return NULL; } +static void debug_objects_fill_pool(void) +{ + /* + * On RT enabled kernels the pool refill must happen in preemptible + * context: + */ + if (!IS_ENABLED(CONFIG_PREEMPT_RT) || preemptible()) + fill_pool(); +} + static void __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) { @@ -468,7 +478,7 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) struct debug_obj *obj; unsigned long flags; - fill_pool(); + debug_objects_fill_pool(); db = get_bucket((unsigned long) addr); @@ -553,6 +563,8 @@ int debug_object_activate(void *addr, struct debug_obj_descr *descr) if (!debug_objects_enabled) return 0; + debug_objects_fill_pool(); + db = get_bucket((unsigned long) addr); raw_spin_lock_irqsave(&db->lock, flags); @@ -762,6 +774,8 @@ void debug_object_assert_init(void *addr, struct debug_obj_descr *descr) if (!debug_objects_enabled) return; + debug_objects_fill_pool(); + db = get_bucket((unsigned long) addr); raw_spin_lock_irqsave(&db->lock, flags); From c6989314fd809c5eaf4980d6fa474f19fc653d6c Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 2 May 2023 10:25:24 +0200 Subject: [PATCH 137/190] netfilter: nf_tables: deactivate anonymous set from preparation phase commit c1592a89942e9678f7d9c8030efa777c0d57edab upstream. Toggle deleted anonymous sets as inactive in the next generation, so users cannot perform any update on it. Clear the generation bitmask in case the transaction is aborted. The following KASAN splat shows a set element deletion for a bound anonymous set that has been already removed in the same transaction. [ 64.921510] ================================================================== [ 64.923123] BUG: KASAN: wild-memory-access in nf_tables_commit+0xa24/0x1490 [nf_tables] [ 64.924745] Write of size 8 at addr dead000000000122 by task test/890 [ 64.927903] CPU: 3 PID: 890 Comm: test Not tainted 6.3.0+ #253 [ 64.931120] Call Trace: [ 64.932699] [ 64.934292] dump_stack_lvl+0x33/0x50 [ 64.935908] ? nf_tables_commit+0xa24/0x1490 [nf_tables] [ 64.937551] kasan_report+0xda/0x120 [ 64.939186] ? nf_tables_commit+0xa24/0x1490 [nf_tables] [ 64.940814] nf_tables_commit+0xa24/0x1490 [nf_tables] [ 64.942452] ? __kasan_slab_alloc+0x2d/0x60 [ 64.944070] ? nf_tables_setelem_notify+0x190/0x190 [nf_tables] [ 64.945710] ? kasan_set_track+0x21/0x30 [ 64.947323] nfnetlink_rcv_batch+0x709/0xd90 [nfnetlink] [ 64.948898] ? nfnetlink_rcv_msg+0x480/0x480 [nfnetlink] Signed-off-by: Pablo Neira Ayuso Signed-off-by: Greg Kroah-Hartman --- include/net/netfilter/nf_tables.h | 1 + net/netfilter/nf_tables_api.c | 12 ++++++++++++ net/netfilter/nft_dynset.c | 2 +- net/netfilter/nft_lookup.c | 2 +- net/netfilter/nft_objref.c | 2 +- 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 93253ba1eeac..78f5f0426e6b 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -471,6 +471,7 @@ struct nft_set_binding { }; enum nft_trans_phase; +void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set); void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, struct nft_set_binding *binding, enum nft_trans_phase phase); diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index d7a082d5cd70..e20bde9cc7b1 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3758,12 +3758,24 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set, } EXPORT_SYMBOL_GPL(nf_tables_unbind_set); +void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set) +{ + if (nft_set_is_anonymous(set)) + nft_clear(ctx->net, set); + + set->use++; +} +EXPORT_SYMBOL_GPL(nf_tables_activate_set); + void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, struct nft_set_binding *binding, enum nft_trans_phase phase) { switch (phase) { case NFT_TRANS_PREPARE: + if (nft_set_is_anonymous(set)) + nft_deactivate_next(ctx->net, set); + set->use--; return; case NFT_TRANS_ABORT: diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c index cc076d535e14..ea73130427eb 100644 --- a/net/netfilter/nft_dynset.c +++ b/net/netfilter/nft_dynset.c @@ -248,7 +248,7 @@ static void nft_dynset_activate(const struct nft_ctx *ctx, { struct nft_dynset *priv = nft_expr_priv(expr); - priv->set->use++; + nf_tables_activate_set(ctx, priv->set); } static void nft_dynset_destroy(const struct nft_ctx *ctx, diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c index 55754d9939b5..cb9e937a5ce0 100644 --- a/net/netfilter/nft_lookup.c +++ b/net/netfilter/nft_lookup.c @@ -132,7 +132,7 @@ static void nft_lookup_activate(const struct nft_ctx *ctx, { struct nft_lookup *priv = nft_expr_priv(expr); - priv->set->use++; + nf_tables_activate_set(ctx, priv->set); } static void nft_lookup_destroy(const struct nft_ctx *ctx, diff --git a/net/netfilter/nft_objref.c b/net/netfilter/nft_objref.c index bf92a40dd1b2..eff2173db7e4 100644 --- a/net/netfilter/nft_objref.c +++ b/net/netfilter/nft_objref.c @@ -182,7 +182,7 @@ static void nft_objref_map_activate(const struct nft_ctx *ctx, { struct nft_objref_map *priv = nft_expr_priv(expr); - priv->set->use++; + nf_tables_activate_set(ctx, priv->set); } static void nft_objref_map_destroy(const struct nft_ctx *ctx, From fe2ae32a7ec9fa64f61993b808f25315b9996b03 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 24 Jul 2019 15:22:59 +0200 Subject: [PATCH 138/190] nohz: Add TICK_DEP_BIT_RCU [ Upstream commit 01b4c39901e087ceebae2733857248de81476bd8 ] If a nohz_full CPU is looping in the kernel, the scheduling-clock tick might nevertheless remain disabled. In !PREEMPT kernels, this can prevent RCU's attempts to enlist the aid of that CPU's executions of cond_resched(), which can in turn result in an arbitrarily delayed grace period and thus an OOM. RCU therefore needs a way to enable a holdout nohz_full CPU's scheduler-clock interrupt. This commit therefore provides a new TICK_DEP_BIT_RCU value which RCU can pass to tick_dep_set_cpu() and friends to force on the scheduler-clock interrupt for a specified CPU or task. In some cases, rcutorture needs to turn on the scheduler-clock tick, so this commit also exports the relevant symbols to GPL-licensed modules. Signed-off-by: Frederic Weisbecker Signed-off-by: Paul E. McKenney Stable-dep-of: 58d766824264 ("tick/nohz: Fix cpu_is_hotpluggable() by checking with nohz subsystem") Signed-off-by: Sasha Levin --- include/linux/tick.h | 7 ++++++- include/trace/events/timer.h | 3 ++- kernel/time/tick-sched.c | 7 +++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/linux/tick.h b/include/linux/tick.h index 55388ab45fd4..965163bdfe41 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -102,7 +102,8 @@ enum tick_dep_bits { TICK_DEP_BIT_POSIX_TIMER = 0, TICK_DEP_BIT_PERF_EVENTS = 1, TICK_DEP_BIT_SCHED = 2, - TICK_DEP_BIT_CLOCK_UNSTABLE = 3 + TICK_DEP_BIT_CLOCK_UNSTABLE = 3, + TICK_DEP_BIT_RCU = 4 }; #define TICK_DEP_MASK_NONE 0 @@ -110,6 +111,7 @@ enum tick_dep_bits { #define TICK_DEP_MASK_PERF_EVENTS (1 << TICK_DEP_BIT_PERF_EVENTS) #define TICK_DEP_MASK_SCHED (1 << TICK_DEP_BIT_SCHED) #define TICK_DEP_MASK_CLOCK_UNSTABLE (1 << TICK_DEP_BIT_CLOCK_UNSTABLE) +#define TICK_DEP_MASK_RCU (1 << TICK_DEP_BIT_RCU) #ifdef CONFIG_NO_HZ_COMMON extern bool tick_nohz_enabled; @@ -257,6 +259,9 @@ static inline bool tick_nohz_full_enabled(void) { return false; } static inline bool tick_nohz_full_cpu(int cpu) { return false; } static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { } +static inline void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit) { } +static inline void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { } + static inline void tick_dep_set(enum tick_dep_bits bit) { } static inline void tick_dep_clear(enum tick_dep_bits bit) { } static inline void tick_dep_set_cpu(int cpu, enum tick_dep_bits bit) { } diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h index a57e4ee989d6..350b046e7576 100644 --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h @@ -362,7 +362,8 @@ TRACE_EVENT(itimer_expire, tick_dep_name(POSIX_TIMER) \ tick_dep_name(PERF_EVENTS) \ tick_dep_name(SCHED) \ - tick_dep_name_end(CLOCK_UNSTABLE) + tick_dep_name(CLOCK_UNSTABLE) \ + tick_dep_name_end(RCU) #undef tick_dep_name #undef tick_dep_mask_name diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 48403fb653c2..7228bdd2eabe 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -199,6 +199,11 @@ static bool check_tick_dependency(atomic_t *dep) return true; } + if (val & TICK_DEP_MASK_RCU) { + trace_tick_stop(0, TICK_DEP_MASK_RCU); + return true; + } + return false; } @@ -325,6 +330,7 @@ void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit) preempt_enable(); } } +EXPORT_SYMBOL_GPL(tick_nohz_dep_set_cpu); void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { @@ -332,6 +338,7 @@ void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit) atomic_andnot(BIT(bit), &ts->tick_dep_mask); } +EXPORT_SYMBOL_GPL(tick_nohz_dep_clear_cpu); /* * Set a per-task tick dependency. Posix CPU timers need this in order to elapse From ea134c3e80599a40b9efd7ab14898fef0737d4d3 Mon Sep 17 00:00:00 2001 From: "Joel Fernandes (Google)" Date: Tue, 24 Jan 2023 17:31:26 +0000 Subject: [PATCH 139/190] tick/nohz: Fix cpu_is_hotpluggable() by checking with nohz subsystem [ Upstream commit 58d7668242647e661a20efe065519abd6454287e ] For CONFIG_NO_HZ_FULL systems, the tick_do_timer_cpu cannot be offlined. However, cpu_is_hotpluggable() still returns true for those CPUs. This causes torture tests that do offlining to end up trying to offline this CPU causing test failures. Such failure happens on all architectures. Fix the repeated error messages thrown by this (even if the hotplug errors are harmless) by asking the opinion of the nohz subsystem on whether the CPU can be hotplugged. [ Apply Frederic Weisbecker feedback on refactoring tick_nohz_cpu_down(). ] For drivers/base/ portion: Acked-by: Greg Kroah-Hartman Acked-by: Frederic Weisbecker Cc: Frederic Weisbecker Cc: "Paul E. McKenney" Cc: Zhouyi Zhou Cc: Will Deacon Cc: Marc Zyngier Cc: rcu Cc: stable@vger.kernel.org Fixes: 2987557f52b9 ("driver-core/cpu: Expose hotpluggability to the rest of the kernel") Signed-off-by: Paul E. McKenney Signed-off-by: Joel Fernandes (Google) Signed-off-by: Sasha Levin --- drivers/base/cpu.c | 3 ++- include/linux/tick.h | 2 ++ kernel/time/tick-sched.c | 11 ++++++++--- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index ce5b3ffbd6ee..878ed43d8753 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -494,7 +494,8 @@ static const struct attribute_group *cpu_root_attr_groups[] = { bool cpu_is_hotpluggable(unsigned cpu) { struct device *dev = get_cpu_device(cpu); - return dev && container_of(dev, struct cpu, dev)->hotpluggable; + return dev && container_of(dev, struct cpu, dev)->hotpluggable + && tick_nohz_cpu_hotpluggable(cpu); } EXPORT_SYMBOL_GPL(cpu_is_hotpluggable); diff --git a/include/linux/tick.h b/include/linux/tick.h index 965163bdfe41..443726085f6c 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -197,6 +197,7 @@ extern void tick_nohz_dep_set_signal(struct signal_struct *signal, enum tick_dep_bits bit); extern void tick_nohz_dep_clear_signal(struct signal_struct *signal, enum tick_dep_bits bit); +extern bool tick_nohz_cpu_hotpluggable(unsigned int cpu); /* * The below are tick_nohz_[set,clear]_dep() wrappers that optimize off-cases @@ -261,6 +262,7 @@ static inline void tick_nohz_full_add_cpus_to(struct cpumask *mask) { } static inline void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit) { } static inline void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { } +static inline bool tick_nohz_cpu_hotpluggable(unsigned int cpu) { return true; } static inline void tick_dep_set(enum tick_dep_bits bit) { } static inline void tick_dep_clear(enum tick_dep_bits bit) { } diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 7228bdd2eabe..25c6efa2c557 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -406,7 +406,7 @@ void __init tick_nohz_full_setup(cpumask_var_t cpumask) tick_nohz_full_running = true; } -static int tick_nohz_cpu_down(unsigned int cpu) +bool tick_nohz_cpu_hotpluggable(unsigned int cpu) { /* * The boot CPU handles housekeeping duty (unbound timers, @@ -414,8 +414,13 @@ static int tick_nohz_cpu_down(unsigned int cpu) * CPUs. It must remain online when nohz full is enabled. */ if (tick_nohz_full_running && tick_do_timer_cpu == cpu) - return -EBUSY; - return 0; + return false; + return true; +} + +static int tick_nohz_cpu_down(unsigned int cpu) +{ + return tick_nohz_cpu_hotpluggable(cpu) ? 0 : -EBUSY; } void __init tick_nohz_init(void) From ffbbcbd325463581163dfc9a6f683e5d61ca4830 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Mon, 22 Oct 2018 15:30:57 -0500 Subject: [PATCH 140/190] ipmi: Fix SSIF flag requests [ Upstream commit a1466ec5b671651b848df17fc9233ecbb7d35f9f ] Commit 89986496de141 ("ipmi: Turn off all activity on an idle ipmi interface") modified the IPMI code to only request events when the driver had somethine waiting for events. The SSIF code, however, was using the event fetch request to also fetch the flags. Add a timer and the proper handling for the upper layer telling whether flags fetches are required. Reported-by: Kamlakant Patel Signed-off-by: Corey Minyard Tested-by: Kamlakant Patel Stable-dep-of: 6d2555cde291 ("ipmi: fix SSIF not responding under certain cond.") Signed-off-by: Sasha Levin --- drivers/char/ipmi/ipmi_ssif.c | 64 ++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index fd1a487443f0..469da2290c2a 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -88,6 +88,12 @@ #define SSIF_MSG_JIFFIES ((SSIF_MSG_USEC * 1000) / TICK_NSEC) #define SSIF_MSG_PART_JIFFIES ((SSIF_MSG_PART_USEC * 1000) / TICK_NSEC) +/* + * Timeout for the watch, only used for get flag timer. + */ +#define SSIF_WATCH_TIMEOUT_MSEC 100 +#define SSIF_WATCH_TIMEOUT_JIFFIES msecs_to_jiffies(SSIF_WATCH_TIMEOUT_MSEC) + enum ssif_intf_state { SSIF_NORMAL, SSIF_GETTING_FLAGS, @@ -268,6 +274,9 @@ struct ssif_info { struct timer_list retry_timer; int retries_left; + bool need_watch; /* Need to look for flags? */ + struct timer_list watch_timer; /* Flag fetch timer. */ + /* Info from SSIF cmd */ unsigned char max_xmit_msg_size; unsigned char max_recv_msg_size; @@ -558,6 +567,26 @@ static void retry_timeout(struct timer_list *t) start_get(ssif_info); } +static void watch_timeout(struct timer_list *t) +{ + struct ssif_info *ssif_info = from_timer(ssif_info, t, watch_timer); + unsigned long oflags, *flags; + + if (ssif_info->stopping) + return; + + flags = ipmi_ssif_lock_cond(ssif_info, &oflags); + if (ssif_info->need_watch) { + mod_timer(&ssif_info->watch_timer, + jiffies + SSIF_WATCH_TIMEOUT_JIFFIES); + if (SSIF_IDLE(ssif_info)) { + start_flag_fetch(ssif_info, flags); /* Releases lock */ + return; + } + ssif_info->req_flags = true; + } + ipmi_ssif_unlock_cond(ssif_info, flags); +} static void ssif_alert(struct i2c_client *client, enum i2c_alert_protocol type, unsigned int data) @@ -1103,8 +1132,7 @@ static int get_smi_info(void *send_info, struct ipmi_smi_info *data) } /* - * Instead of having our own timer to periodically check the message - * flags, we let the message handler drive us. + * Upper layer wants us to request events. */ static void request_events(void *send_info) { @@ -1115,18 +1143,27 @@ static void request_events(void *send_info) return; flags = ipmi_ssif_lock_cond(ssif_info, &oflags); - /* - * Request flags first, not events, because the lower layer - * doesn't have a way to send an attention. But make sure - * event checking still happens. - */ ssif_info->req_events = true; - if (SSIF_IDLE(ssif_info)) - start_flag_fetch(ssif_info, flags); - else { - ssif_info->req_flags = true; - ipmi_ssif_unlock_cond(ssif_info, flags); + ipmi_ssif_unlock_cond(ssif_info, flags); +} + +/* + * Upper layer is changing the flag saying whether we need to request + * flags periodically or not. + */ +static void ssif_set_need_watch(void *send_info, bool enable) +{ + struct ssif_info *ssif_info = (struct ssif_info *) send_info; + unsigned long oflags, *flags; + + flags = ipmi_ssif_lock_cond(ssif_info, &oflags); + if (enable != ssif_info->need_watch) { + ssif_info->need_watch = enable; + if (ssif_info->need_watch) + mod_timer(&ssif_info->watch_timer, + jiffies + SSIF_WATCH_TIMEOUT_JIFFIES); } + ipmi_ssif_unlock_cond(ssif_info, flags); } static int ssif_start_processing(void *send_info, @@ -1253,6 +1290,7 @@ static void shutdown_ssif(void *send_info) schedule_timeout(1); ssif_info->stopping = true; + del_timer_sync(&ssif_info->watch_timer); del_timer_sync(&ssif_info->retry_timer); if (ssif_info->thread) { complete(&ssif_info->wake_thread); @@ -1632,6 +1670,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) spin_lock_init(&ssif_info->lock); ssif_info->ssif_state = SSIF_NORMAL; timer_setup(&ssif_info->retry_timer, retry_timeout, 0); + timer_setup(&ssif_info->watch_timer, watch_timeout, 0); for (i = 0; i < SSIF_NUM_STATS; i++) atomic_set(&ssif_info->stats[i], 0); @@ -1645,6 +1684,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) ssif_info->handlers.get_smi_info = get_smi_info; ssif_info->handlers.sender = sender; ssif_info->handlers.request_events = request_events; + ssif_info->handlers.set_need_watch = ssif_set_need_watch; { unsigned int thread_num; From b4a34aa6dfbca67610e56ad84a3595f537c85af9 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Tue, 23 Oct 2018 11:29:02 -0500 Subject: [PATCH 141/190] ipmi: Fix how the lower layers are told to watch for messages [ Upstream commit c65ea996595005be470fbfa16711deba414fd33b ] The IPMI driver has a mechanism to tell the lower layers it needs to watch for messages, commands, and watchdogs (so it doesn't needlessly poll). However, it needed some extensions, it needed a way to tell what is being waited for so it could set the timeout appropriately. The update to the lower layer was also being done once a second at best because it was done in the main timeout handler. However, if a command is sent and a response message is coming back, it needed to be started immediately. So modify the code to update immediately if it needs to be enabled. Disable is still lazy. Signed-off-by: Corey Minyard Tested-by: Kamlakant Patel Stable-dep-of: 6d2555cde291 ("ipmi: fix SSIF not responding under certain cond.") Signed-off-by: Sasha Levin --- drivers/char/ipmi/ipmi_msghandler.c | 119 ++++++++++++++++++++-------- drivers/char/ipmi/ipmi_si_intf.c | 5 +- drivers/char/ipmi/ipmi_ssif.c | 26 +++--- include/linux/ipmi_smi.h | 36 +++++++-- 4 files changed, 134 insertions(+), 52 deletions(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 4265e8d3e71c..31cfa47d2498 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -536,9 +536,22 @@ struct ipmi_smi { unsigned int waiting_events_count; /* How many events in queue? */ char delivering_events; char event_msg_printed; + + /* How many users are waiting for events? */ atomic_t event_waiters; unsigned int ticks_to_req_ev; - int last_needs_timer; + + /* How many users are waiting for commands? */ + atomic_t command_waiters; + + /* How many users are waiting for watchdogs? */ + atomic_t watchdog_waiters; + + /* + * Tells what the lower layer has last been asked to watch for, + * messages and/or watchdogs. Protected by xmit_msgs_lock. + */ + unsigned int last_watch_mask; /* * The event receiver for my BMC, only really used at panic @@ -1085,6 +1098,29 @@ static int intf_err_seq(struct ipmi_smi *intf, return rv; } +/* Must be called with xmit_msgs_lock held. */ +static void smi_tell_to_watch(struct ipmi_smi *intf, + unsigned int flags, + struct ipmi_smi_msg *smi_msg) +{ + if (flags & IPMI_WATCH_MASK_CHECK_MESSAGES) { + if (!smi_msg) + return; + + if (!smi_msg->needs_response) + return; + } + + if (!intf->handlers->set_need_watch) + return; + + if ((intf->last_watch_mask & flags) == flags) + return; + + intf->last_watch_mask |= flags; + intf->handlers->set_need_watch(intf->send_info, + intf->last_watch_mask); +} static void free_user_work(struct work_struct *work) { @@ -1164,8 +1200,9 @@ int ipmi_create_user(unsigned int if_num, spin_unlock_irqrestore(&intf->seq_lock, flags); if (handler->ipmi_watchdog_pretimeout) { /* User wants pretimeouts, so make sure to watch for them. */ - if (atomic_inc_return(&intf->event_waiters) == 1) - need_waiter(intf); + if (atomic_inc_return(&intf->watchdog_waiters) == 1) + smi_tell_to_watch(intf, IPMI_WATCH_MASK_CHECK_WATCHDOG, + NULL); } srcu_read_unlock(&ipmi_interfaces_srcu, index); *user = new_user; @@ -1239,7 +1276,7 @@ static void _ipmi_destroy_user(struct ipmi_user *user) user->handler->shutdown(user->handler_data); if (user->handler->ipmi_watchdog_pretimeout) - atomic_dec(&intf->event_waiters); + atomic_dec(&intf->watchdog_waiters); if (user->gets_events) atomic_dec(&intf->event_waiters); @@ -1597,8 +1634,8 @@ int ipmi_register_for_cmd(struct ipmi_user *user, goto out_unlock; } - if (atomic_inc_return(&intf->event_waiters) == 1) - need_waiter(intf); + if (atomic_inc_return(&intf->command_waiters) == 1) + smi_tell_to_watch(intf, IPMI_WATCH_MASK_CHECK_COMMANDS, NULL); list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); @@ -1648,7 +1685,7 @@ int ipmi_unregister_for_cmd(struct ipmi_user *user, synchronize_rcu(); release_ipmi_user(user, index); while (rcvrs) { - atomic_dec(&intf->event_waiters); + atomic_dec(&intf->command_waiters); rcvr = rcvrs; rcvrs = rcvr->next; kfree(rcvr); @@ -1765,22 +1802,21 @@ static struct ipmi_smi_msg *smi_add_send_msg(struct ipmi_smi *intf, return smi_msg; } - static void smi_send(struct ipmi_smi *intf, const struct ipmi_smi_handlers *handlers, struct ipmi_smi_msg *smi_msg, int priority) { int run_to_completion = intf->run_to_completion; + unsigned long flags = 0; - if (run_to_completion) { - smi_msg = smi_add_send_msg(intf, smi_msg, priority); - } else { - unsigned long flags; - + if (!run_to_completion) spin_lock_irqsave(&intf->xmit_msgs_lock, flags); - smi_msg = smi_add_send_msg(intf, smi_msg, priority); + smi_msg = smi_add_send_msg(intf, smi_msg, priority); + + smi_tell_to_watch(intf, IPMI_WATCH_MASK_CHECK_MESSAGES, smi_msg); + + if (!run_to_completion) spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); - } if (smi_msg) handlers->sender(intf->send_info, smi_msg); @@ -1978,6 +2014,9 @@ static int i_ipmi_req_ipmb(struct ipmi_smi *intf, ipmb_seq, broadcast, source_address, source_lun); + /* We will be getting a response in the BMC message queue. */ + smi_msg->needs_response = true; + /* * Copy the message into the recv message data, so we * can retransmit it later if necessary. @@ -2165,6 +2204,7 @@ static int i_ipmi_request(struct ipmi_user *user, goto out; } } + smi_msg->needs_response = false; rcu_read_lock(); if (intf->in_shutdown) { @@ -3386,6 +3426,8 @@ int ipmi_add_smi(struct module *owner, INIT_LIST_HEAD(&intf->hp_xmit_msgs); spin_lock_init(&intf->events_lock); atomic_set(&intf->event_waiters, 0); + atomic_set(&intf->watchdog_waiters, 0); + atomic_set(&intf->command_waiters, 0); intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME; INIT_LIST_HEAD(&intf->waiting_events); intf->waiting_events_count = 0; @@ -4404,6 +4446,9 @@ static void smi_recv_tasklet(unsigned long val) intf->curr_msg = newmsg; } } + + smi_tell_to_watch(intf, IPMI_WATCH_MASK_CHECK_MESSAGES, newmsg); + if (!run_to_completion) spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); if (newmsg) @@ -4531,7 +4576,7 @@ static void check_msg_timeout(struct ipmi_smi *intf, struct seq_table *ent, struct list_head *timeouts, unsigned long timeout_period, int slot, unsigned long *flags, - unsigned int *waiting_msgs) + unsigned int *watch_mask) { struct ipmi_recv_msg *msg; @@ -4543,7 +4588,7 @@ static void check_msg_timeout(struct ipmi_smi *intf, struct seq_table *ent, if (timeout_period < ent->timeout) { ent->timeout -= timeout_period; - (*waiting_msgs)++; + *watch_mask |= IPMI_WATCH_MASK_CHECK_MESSAGES; return; } @@ -4562,7 +4607,7 @@ static void check_msg_timeout(struct ipmi_smi *intf, struct seq_table *ent, struct ipmi_smi_msg *smi_msg; /* More retries, send again. */ - (*waiting_msgs)++; + *watch_mask |= IPMI_WATCH_MASK_CHECK_MESSAGES; /* * Start with the max timer, set to normal timer after @@ -4614,13 +4659,13 @@ static unsigned int ipmi_timeout_handler(struct ipmi_smi *intf, struct ipmi_recv_msg *msg, *msg2; unsigned long flags; int i; - unsigned int waiting_msgs = 0; + unsigned int watch_mask = 0; if (!intf->bmc_registered) { kref_get(&intf->refcount); if (!schedule_work(&intf->bmc_reg_work)) { kref_put(&intf->refcount, intf_free); - waiting_msgs++; + watch_mask |= IPMI_WATCH_MASK_INTERNAL; } } @@ -4640,7 +4685,7 @@ static unsigned int ipmi_timeout_handler(struct ipmi_smi *intf, for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) check_msg_timeout(intf, &intf->seq_table[i], &timeouts, timeout_period, i, - &flags, &waiting_msgs); + &flags, &watch_mask); spin_unlock_irqrestore(&intf->seq_lock, flags); list_for_each_entry_safe(msg, msg2, &timeouts, link) @@ -4671,7 +4716,7 @@ static unsigned int ipmi_timeout_handler(struct ipmi_smi *intf, tasklet_schedule(&intf->recv_tasklet); - return waiting_msgs; + return watch_mask; } static void ipmi_request_event(struct ipmi_smi *intf) @@ -4691,37 +4736,43 @@ static atomic_t stop_operation; static void ipmi_timeout(struct timer_list *unused) { struct ipmi_smi *intf; - int nt = 0, index; + unsigned int watch_mask = 0; + int index; + unsigned long flags; if (atomic_read(&stop_operation)) return; index = srcu_read_lock(&ipmi_interfaces_srcu); list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { - int lnt = 0; - if (atomic_read(&intf->event_waiters)) { intf->ticks_to_req_ev--; if (intf->ticks_to_req_ev == 0) { ipmi_request_event(intf); intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME; } - lnt++; + watch_mask |= IPMI_WATCH_MASK_INTERNAL; } - lnt += ipmi_timeout_handler(intf, IPMI_TIMEOUT_TIME); + if (atomic_read(&intf->watchdog_waiters)) + watch_mask |= IPMI_WATCH_MASK_CHECK_WATCHDOG; - lnt = !!lnt; - if (lnt != intf->last_needs_timer && + if (atomic_read(&intf->command_waiters)) + watch_mask |= IPMI_WATCH_MASK_CHECK_COMMANDS; + + watch_mask |= ipmi_timeout_handler(intf, IPMI_TIMEOUT_TIME); + + spin_lock_irqsave(&intf->xmit_msgs_lock, flags); + if (watch_mask != intf->last_watch_mask && intf->handlers->set_need_watch) - intf->handlers->set_need_watch(intf->send_info, lnt); - intf->last_needs_timer = lnt; - - nt += lnt; + intf->handlers->set_need_watch(intf->send_info, + watch_mask); + intf->last_watch_mask = watch_mask; + spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); } srcu_read_unlock(&ipmi_interfaces_srcu, index); - if (nt) + if (watch_mask) mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES); } diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index a5e1dce042e8..429fe063e33f 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -1073,10 +1073,13 @@ static void request_events(void *send_info) atomic_set(&smi_info->req_events, 1); } -static void set_need_watch(void *send_info, bool enable) +static void set_need_watch(void *send_info, unsigned int watch_mask) { struct smi_info *smi_info = send_info; unsigned long flags; + int enable; + + enable = !!(watch_mask & ~IPMI_WATCH_MASK_INTERNAL); atomic_set(&smi_info->need_watch, enable); spin_lock_irqsave(&smi_info->si_lock, flags); diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 469da2290c2a..e760501e50b2 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -91,8 +91,8 @@ /* * Timeout for the watch, only used for get flag timer. */ -#define SSIF_WATCH_TIMEOUT_MSEC 100 -#define SSIF_WATCH_TIMEOUT_JIFFIES msecs_to_jiffies(SSIF_WATCH_TIMEOUT_MSEC) +#define SSIF_WATCH_MSG_TIMEOUT msecs_to_jiffies(10) +#define SSIF_WATCH_WATCHDOG_TIMEOUT msecs_to_jiffies(250) enum ssif_intf_state { SSIF_NORMAL, @@ -274,7 +274,7 @@ struct ssif_info { struct timer_list retry_timer; int retries_left; - bool need_watch; /* Need to look for flags? */ + long watch_timeout; /* Timeout for flags check, 0 if off. */ struct timer_list watch_timer; /* Flag fetch timer. */ /* Info from SSIF cmd */ @@ -576,9 +576,9 @@ static void watch_timeout(struct timer_list *t) return; flags = ipmi_ssif_lock_cond(ssif_info, &oflags); - if (ssif_info->need_watch) { + if (ssif_info->watch_timeout) { mod_timer(&ssif_info->watch_timer, - jiffies + SSIF_WATCH_TIMEOUT_JIFFIES); + jiffies + ssif_info->watch_timeout); if (SSIF_IDLE(ssif_info)) { start_flag_fetch(ssif_info, flags); /* Releases lock */ return; @@ -1151,17 +1151,23 @@ static void request_events(void *send_info) * Upper layer is changing the flag saying whether we need to request * flags periodically or not. */ -static void ssif_set_need_watch(void *send_info, bool enable) +static void ssif_set_need_watch(void *send_info, unsigned int watch_mask) { struct ssif_info *ssif_info = (struct ssif_info *) send_info; unsigned long oflags, *flags; + long timeout = 0; + + if (watch_mask & IPMI_WATCH_MASK_CHECK_MESSAGES) + timeout = SSIF_WATCH_MSG_TIMEOUT; + else if (watch_mask & ~IPMI_WATCH_MASK_INTERNAL) + timeout = SSIF_WATCH_WATCHDOG_TIMEOUT; flags = ipmi_ssif_lock_cond(ssif_info, &oflags); - if (enable != ssif_info->need_watch) { - ssif_info->need_watch = enable; - if (ssif_info->need_watch) + if (timeout != ssif_info->watch_timeout) { + ssif_info->watch_timeout = timeout; + if (ssif_info->watch_timeout) mod_timer(&ssif_info->watch_timer, - jiffies + SSIF_WATCH_TIMEOUT_JIFFIES); + jiffies + ssif_info->watch_timeout); } ipmi_ssif_unlock_cond(ssif_info, flags); } diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h index 1995ce146789..86b119400f30 100644 --- a/include/linux/ipmi_smi.h +++ b/include/linux/ipmi_smi.h @@ -30,6 +30,17 @@ struct device; /* Structure for the low-level drivers. */ typedef struct ipmi_smi *ipmi_smi_t; +/* + * Flags for set_check_watch() below. Tells if the SMI should be + * waiting for watchdog timeouts, commands and/or messages. There is + * also an internal flag for the message handler, SMIs should ignore + * it. + */ +#define IPMI_WATCH_MASK_INTERNAL (1 << 0) +#define IPMI_WATCH_MASK_CHECK_MESSAGES (1 << 1) +#define IPMI_WATCH_MASK_CHECK_WATCHDOG (1 << 2) +#define IPMI_WATCH_MASK_CHECK_COMMANDS (1 << 3) + /* * Messages to/from the lower layer. The smi interface will take one * of these to send. After the send has occurred and a response has @@ -55,8 +66,16 @@ struct ipmi_smi_msg { int rsp_size; unsigned char rsp[IPMI_MAX_MSG_LENGTH]; - /* Will be called when the system is done with the message - (presumably to free it). */ + /* + * There should be a response message coming back in the BMC + * message queue. + */ + bool needs_response; + + /* + * Will be called when the system is done with the message + * (presumably to free it). + */ void (*done)(struct ipmi_smi_msg *msg); }; @@ -105,12 +124,15 @@ struct ipmi_smi_handlers { /* * Called by the upper layer when some user requires that the - * interface watch for events, received messages, watchdog - * pretimeouts, or not. Used by the SMI to know if it should - * watch for these. This may be NULL if the SMI does not - * implement it. + * interface watch for received messages and watchdog + * pretimeouts (basically do a "Get Flags", or not. Used by + * the SMI to know if it should watch for these. This may be + * NULL if the SMI does not implement it. watch_mask is from + * IPMI_WATCH_MASK_xxx above. The interface should run slower + * timeouts for just watchdog checking or faster timeouts when + * waiting for the message queue. */ - void (*set_need_watch)(void *send_info, bool enable); + void (*set_need_watch)(void *send_info, unsigned int watch_mask); /* * Called when flushing all pending messages. From 13b3a05b5b03b4fce5a9ea03dc91159dea1f6ef9 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Wed, 25 Jan 2023 10:13:13 -0600 Subject: [PATCH 142/190] ipmi_ssif: Rename idle state and check [ Upstream commit 8230831c43a328c2be6d28c65d3f77e14c59986b ] Rename the SSIF_IDLE() to IS_SSIF_IDLE(), since that is more clear, and rename SSIF_NORMAL to SSIF_IDLE, since that's more accurate. Cc: stable@vger.kernel.org Signed-off-by: Corey Minyard Stable-dep-of: 6d2555cde291 ("ipmi: fix SSIF not responding under certain cond.") Signed-off-by: Sasha Levin --- drivers/char/ipmi/ipmi_ssif.c | 46 +++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index e760501e50b2..566be60fa137 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -95,7 +95,7 @@ #define SSIF_WATCH_WATCHDOG_TIMEOUT msecs_to_jiffies(250) enum ssif_intf_state { - SSIF_NORMAL, + SSIF_IDLE, SSIF_GETTING_FLAGS, SSIF_GETTING_EVENTS, SSIF_CLEARING_FLAGS, @@ -103,8 +103,8 @@ enum ssif_intf_state { /* FIXME - add watchdog stuff. */ }; -#define SSIF_IDLE(ssif) ((ssif)->ssif_state == SSIF_NORMAL \ - && (ssif)->curr_msg == NULL) +#define IS_SSIF_IDLE(ssif) ((ssif)->ssif_state == SSIF_IDLE \ + && (ssif)->curr_msg == NULL) /* * Indexes into stats[] in ssif_info below. @@ -349,9 +349,9 @@ static void return_hosed_msg(struct ssif_info *ssif_info, /* * Must be called with the message lock held. This will release the - * message lock. Note that the caller will check SSIF_IDLE and start a - * new operation, so there is no need to check for new messages to - * start in here. + * message lock. Note that the caller will check IS_SSIF_IDLE and + * start a new operation, so there is no need to check for new + * messages to start in here. */ static void start_clear_flags(struct ssif_info *ssif_info, unsigned long *flags) { @@ -368,7 +368,7 @@ static void start_clear_flags(struct ssif_info *ssif_info, unsigned long *flags) if (start_send(ssif_info, msg, 3) != 0) { /* Error, just go to normal state. */ - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; } } @@ -383,7 +383,7 @@ static void start_flag_fetch(struct ssif_info *ssif_info, unsigned long *flags) mb[0] = (IPMI_NETFN_APP_REQUEST << 2); mb[1] = IPMI_GET_MSG_FLAGS_CMD; if (start_send(ssif_info, mb, 2) != 0) - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; } static void check_start_send(struct ssif_info *ssif_info, unsigned long *flags, @@ -394,7 +394,7 @@ static void check_start_send(struct ssif_info *ssif_info, unsigned long *flags, flags = ipmi_ssif_lock_cond(ssif_info, &oflags); ssif_info->curr_msg = NULL; - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); ipmi_free_smi_msg(msg); } @@ -408,7 +408,7 @@ static void start_event_fetch(struct ssif_info *ssif_info, unsigned long *flags) msg = ipmi_alloc_smi_msg(); if (!msg) { - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); return; } @@ -431,7 +431,7 @@ static void start_recv_msg_fetch(struct ssif_info *ssif_info, msg = ipmi_alloc_smi_msg(); if (!msg) { - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); return; } @@ -449,9 +449,9 @@ static void start_recv_msg_fetch(struct ssif_info *ssif_info, /* * Must be called with the message lock held. This will release the - * message lock. Note that the caller will check SSIF_IDLE and start a - * new operation, so there is no need to check for new messages to - * start in here. + * message lock. Note that the caller will check IS_SSIF_IDLE and + * start a new operation, so there is no need to check for new + * messages to start in here. */ static void handle_flags(struct ssif_info *ssif_info, unsigned long *flags) { @@ -467,7 +467,7 @@ static void handle_flags(struct ssif_info *ssif_info, unsigned long *flags) /* Events available. */ start_event_fetch(ssif_info, flags); else { - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); } } @@ -579,7 +579,7 @@ static void watch_timeout(struct timer_list *t) if (ssif_info->watch_timeout) { mod_timer(&ssif_info->watch_timer, jiffies + ssif_info->watch_timeout); - if (SSIF_IDLE(ssif_info)) { + if (IS_SSIF_IDLE(ssif_info)) { start_flag_fetch(ssif_info, flags); /* Releases lock */ return; } @@ -776,7 +776,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, } switch (ssif_info->ssif_state) { - case SSIF_NORMAL: + case SSIF_IDLE: ipmi_ssif_unlock_cond(ssif_info, flags); if (!msg) break; @@ -794,7 +794,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, * Error fetching flags, or invalid length, * just give up for now. */ - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); pr_warn(PFX "Error getting flags: %d %d, %x\n", result, len, (len >= 3) ? data[2] : 0); @@ -825,7 +825,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, pr_warn(PFX "Invalid response clearing flags: %x %x\n", data[0], data[1]); } - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); break; @@ -901,7 +901,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, } flags = ipmi_ssif_lock_cond(ssif_info, &oflags); - if (SSIF_IDLE(ssif_info) && !ssif_info->stopping) { + if (IS_SSIF_IDLE(ssif_info) && !ssif_info->stopping) { if (ssif_info->req_events) start_event_fetch(ssif_info, flags); else if (ssif_info->req_flags) @@ -1070,7 +1070,7 @@ static void start_next_msg(struct ssif_info *ssif_info, unsigned long *flags) unsigned long oflags; restart: - if (!SSIF_IDLE(ssif_info)) { + if (!IS_SSIF_IDLE(ssif_info)) { ipmi_ssif_unlock_cond(ssif_info, flags); return; } @@ -1292,7 +1292,7 @@ static void shutdown_ssif(void *send_info) dev_set_drvdata(&ssif_info->client->dev, NULL); /* make sure the driver is not looking for flags any more. */ - while (ssif_info->ssif_state != SSIF_NORMAL) + while (ssif_info->ssif_state != SSIF_IDLE) schedule_timeout(1); ssif_info->stopping = true; @@ -1674,7 +1674,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) } spin_lock_init(&ssif_info->lock); - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; timer_setup(&ssif_info->retry_timer, retry_timeout, 0); timer_setup(&ssif_info->watch_timer, watch_timeout, 0); From ba810999356bffa4627985123c15327c692318e5 Mon Sep 17 00:00:00 2001 From: Zhang Yuchen Date: Wed, 12 Apr 2023 15:49:07 +0800 Subject: [PATCH 143/190] ipmi: fix SSIF not responding under certain cond. [ Upstream commit 6d2555cde2918409b0331560e66f84a0ad4849c6 ] The ipmi communication is not restored after a specific version of BMC is upgraded on our server. The ipmi driver does not respond after printing the following log: ipmi_ssif: Invalid response getting flags: 1c 1 I found that after entering this branch, ssif_info->ssif_state always holds SSIF_GETTING_FLAGS and never return to IDLE. As a result, the driver cannot be loaded, because the driver status is checked during the unload process and must be IDLE in shutdown_ssif(): while (ssif_info->ssif_state != SSIF_IDLE) schedule_timeout(1); The process trigger this problem is: 1. One msg timeout and next msg start send, and call ssif_set_need_watch(). 2. ssif_set_need_watch()->watch_timeout()->start_flag_fetch() change ssif_state to SSIF_GETTING_FLAGS. 3. In msg_done_handler() ssif_state == SSIF_GETTING_FLAGS, if an error message is received, the second branch does not modify the ssif_state. 4. All retry action need IS_SSIF_IDLE() == True. Include retry action in watch_timeout(), msg_done_handler(). Sending msg does not work either. SSIF_IDLE is also checked in start_next_msg(). 5. The only thing that can be triggered in the SSIF driver is watch_timeout(), after destory_user(), this timer will stop too. So, if enter this branch, the ssif_state will remain SSIF_GETTING_FLAGS and can't send msg, no timer started, can't unload. We did a comparative test before and after adding this patch, and the result is effective. Fixes: 259307074bfc ("ipmi: Add SMBus interface driver (SSIF)") Cc: stable@vger.kernel.org Signed-off-by: Zhang Yuchen Message-Id: <20230412074907.80046-1-zhangyuchen.lcr@bytedance.com> Signed-off-by: Corey Minyard Signed-off-by: Sasha Levin --- drivers/char/ipmi/ipmi_ssif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 566be60fa137..34c5b287c412 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -801,9 +801,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, } else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || data[1] != IPMI_GET_MSG_FLAGS_CMD) { /* - * Don't abort here, maybe it was a queued - * response to a previous command. + * Recv error response, give up. */ + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); pr_warn(PFX "Invalid response getting flags: %x %x\n", data[0], data[1]); From bde2a8599e734d86537b207ecda5703763712d1f Mon Sep 17 00:00:00 2001 From: Akilesh Kailash Date: Mon, 13 Sep 2021 09:26:42 +0000 Subject: [PATCH 144/190] dm verity: skip redundant verity_handle_err() on I/O errors [ Upstream commit 2c0468e054c0adb660ac055fc396622ec7235df9 ] Without FEC, dm-verity won't call verity_handle_err() when I/O fails, but with FEC enabled, it currently does even if an I/O error has occurred. If there is an I/O error and FEC correction fails, return the error instead of calling verity_handle_err() again. Suggested-by: Sami Tolvanen Signed-off-by: Akilesh Kailash Reviewed-by: Sami Tolvanen Signed-off-by: Mike Snitzer Stable-dep-of: e8c5d45f82ce ("dm verity: fix error handling for check_at_most_once on FEC") Signed-off-by: Sasha Levin --- drivers/md/dm-verity-target.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index 36945030520a..08a135f7ef43 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -471,6 +471,7 @@ static int verity_verify_io(struct dm_verity_io *io) struct bvec_iter start; unsigned b; struct crypto_wait wait; + struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size); for (b = 0; b < io->n_blocks; b++) { int r; @@ -525,9 +526,17 @@ static int verity_verify_io(struct dm_verity_io *io) else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_DATA, cur_block, NULL, &start) == 0) continue; - else if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA, - cur_block)) - return -EIO; + else { + if (bio->bi_status) { + /* + * Error correction failed; Just return error + */ + return -EIO; + } + if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA, + cur_block)) + return -EIO; + } } return 0; From 0cdddbc0c7b4f54da3651a6cc2b68b6abb8b1880 Mon Sep 17 00:00:00 2001 From: Yeongjin Gil Date: Mon, 20 Mar 2023 15:59:32 +0900 Subject: [PATCH 145/190] dm verity: fix error handling for check_at_most_once on FEC [ Upstream commit e8c5d45f82ce0c238a4817739892fe8897a3dcc3 ] In verity_end_io(), if bi_status is not BLK_STS_OK, it can be return directly. But if FEC configured, it is desired to correct the data page through verity_verify_io. And the return value will be converted to blk_status and passed to verity_finish_io(). BTW, when a bit is set in v->validated_blocks, verity_verify_io() skips verification regardless of I/O error for the corresponding bio. In this case, the I/O error could not be returned properly, and as a result, there is a problem that abnormal data could be read for the corresponding block. To fix this problem, when an I/O error occurs, do not skip verification even if the bit related is set in v->validated_blocks. Fixes: 843f38d382b1 ("dm verity: add 'check_at_most_once' option to only validate hashes once") Cc: stable@vger.kernel.org Reviewed-by: Sungjong Seo Signed-off-by: Yeongjin Gil Signed-off-by: Mike Snitzer Signed-off-by: Sasha Levin --- drivers/md/dm-verity-target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index 08a135f7ef43..d116495a3445 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -478,7 +478,7 @@ static int verity_verify_io(struct dm_verity_io *io) sector_t cur_block = io->block + b; struct ahash_request *req = verity_io_hash_req(v, io); - if (v->validated_blocks && + if (v->validated_blocks && bio->bi_status == BLK_STS_OK && likely(test_bit(cur_block, v->validated_blocks))) { verity_bv_skip_block(v, io, &io->iter); continue; From 2a6c63d04d89227ee45d0234c8059e2bccc15d73 Mon Sep 17 00:00:00 2001 From: Pengcheng Yang Date: Thu, 4 Jun 2020 16:51:30 -0700 Subject: [PATCH 146/190] kernel/relay.c: fix read_pos error when multiple readers [ Upstream commit 341a7213e5c1ce274cc0f02270054905800ea660 ] When reading, read_pos should start with bytes_consumed, not file->f_pos. Because when there is more than one reader, the read_pos corresponding to file->f_pos may have been consumed, which will cause the data that has been consumed to be read and the bytes_consumed update error. Signed-off-by: Pengcheng Yang Signed-off-by: Andrew Morton Reviewed-by: Jens Axboe Cc: Greg Kroah-Hartman Cc: Jann Horn Cc: Al Viro e Link: http://lkml.kernel.org/r/1579691175-28949-1-git-send-email-yangpc@wangsu.com Signed-off-by: Linus Torvalds Stable-dep-of: 43ec16f1450f ("relayfs: fix out-of-bounds access in relay_file_read") Signed-off-by: Sasha Levin --- kernel/relay.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/kernel/relay.c b/kernel/relay.c index b7aa7df43955..0f027e04b009 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -997,14 +997,14 @@ static void relay_file_read_consume(struct rchan_buf *buf, /* * relay_file_read_avail - boolean, are there unconsumed bytes available? */ -static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos) +static int relay_file_read_avail(struct rchan_buf *buf) { size_t subbuf_size = buf->chan->subbuf_size; size_t n_subbufs = buf->chan->n_subbufs; size_t produced = buf->subbufs_produced; size_t consumed = buf->subbufs_consumed; - relay_file_read_consume(buf, read_pos, 0); + relay_file_read_consume(buf, 0, 0); consumed = buf->subbufs_consumed; @@ -1065,23 +1065,20 @@ static size_t relay_file_read_subbuf_avail(size_t read_pos, /** * relay_file_read_start_pos - find the first available byte to read - * @read_pos: file read position * @buf: relay channel buffer * - * If the @read_pos is in the middle of padding, return the + * If the read_pos is in the middle of padding, return the * position of the first actually available byte, otherwise * return the original value. */ -static size_t relay_file_read_start_pos(size_t read_pos, - struct rchan_buf *buf) +static size_t relay_file_read_start_pos(struct rchan_buf *buf) { size_t read_subbuf, padding, padding_start, padding_end; size_t subbuf_size = buf->chan->subbuf_size; size_t n_subbufs = buf->chan->n_subbufs; size_t consumed = buf->subbufs_consumed % n_subbufs; + size_t read_pos = consumed * subbuf_size + buf->bytes_consumed; - if (!read_pos) - read_pos = consumed * subbuf_size + buf->bytes_consumed; read_subbuf = read_pos / subbuf_size; padding = buf->padding[read_subbuf]; padding_start = (read_subbuf + 1) * subbuf_size - padding; @@ -1137,10 +1134,10 @@ static ssize_t relay_file_read(struct file *filp, do { void *from; - if (!relay_file_read_avail(buf, *ppos)) + if (!relay_file_read_avail(buf)) break; - read_start = relay_file_read_start_pos(*ppos, buf); + read_start = relay_file_read_start_pos(buf); avail = relay_file_read_subbuf_avail(read_start, buf); if (!avail) break; From ed32488417669568308b65ba5d45799418f9ed49 Mon Sep 17 00:00:00 2001 From: Zhang Zhengming Date: Wed, 19 Apr 2023 12:02:03 +0800 Subject: [PATCH 147/190] relayfs: fix out-of-bounds access in relay_file_read [ Upstream commit 43ec16f1450f4936025a9bdf1a273affdb9732c1 ] There is a crash in relay_file_read, as the var from point to the end of last subbuf. The oops looks something like: pc : __arch_copy_to_user+0x180/0x310 lr : relay_file_read+0x20c/0x2c8 Call trace: __arch_copy_to_user+0x180/0x310 full_proxy_read+0x68/0x98 vfs_read+0xb0/0x1d0 ksys_read+0x6c/0xf0 __arm64_sys_read+0x20/0x28 el0_svc_common.constprop.3+0x84/0x108 do_el0_svc+0x74/0x90 el0_svc+0x1c/0x28 el0_sync_handler+0x88/0xb0 el0_sync+0x148/0x180 We get the condition by analyzing the vmcore: 1). The last produced byte and last consumed byte both at the end of the last subbuf 2). A softirq calls function(e.g __blk_add_trace) to write relay buffer occurs when an program is calling relay_file_read_avail(). relay_file_read relay_file_read_avail relay_file_read_consume(buf, 0, 0); //interrupted by softirq who will write subbuf .... return 1; //read_start point to the end of the last subbuf read_start = relay_file_read_start_pos //avail is equal to subsize avail = relay_file_read_subbuf_avail //from points to an invalid memory address from = buf->start + read_start //system is crashed copy_to_user(buffer, from, avail) Link: https://lkml.kernel.org/r/20230419040203.37676-1-zhang.zhengming@h3c.com Fixes: 8d62fdebdaf9 ("relay file read: start-pos fix") Signed-off-by: Zhang Zhengming Reviewed-by: Zhao Lei Reviewed-by: Zhou Kete Reviewed-by: Pengcheng Yang Cc: Jens Axboe Cc: Signed-off-by: Andrew Morton Signed-off-by: Sasha Levin --- kernel/relay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/relay.c b/kernel/relay.c index 0f027e04b009..e6f70f4c41a3 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -1077,7 +1077,8 @@ static size_t relay_file_read_start_pos(struct rchan_buf *buf) size_t subbuf_size = buf->chan->subbuf_size; size_t n_subbufs = buf->chan->n_subbufs; size_t consumed = buf->subbufs_consumed % n_subbufs; - size_t read_pos = consumed * subbuf_size + buf->bytes_consumed; + size_t read_pos = (consumed * subbuf_size + buf->bytes_consumed) + % (n_subbufs * subbuf_size); read_subbuf = read_pos / subbuf_size; padding = buf->padding[read_subbuf]; From 6ac6a564ed661139fa854b6b0f2a533e37e6db68 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Wed, 26 Apr 2023 23:00:06 -0700 Subject: [PATCH 148/190] sit: update dev->needed_headroom in ipip6_tunnel_bind_dev() [ Upstream commit c88f8d5cd95fd039cff95d682b8e71100c001df0 ] When a tunnel device is bound with the underlying device, its dev->needed_headroom needs to be updated properly. IPv4 tunnels already do the same in ip_tunnel_bind_dev(). Otherwise we may not have enough header room for skb, especially after commit b17f709a2401 ("gue: TX support for using remote checksum offload option"). Fixes: 32b8a8e59c9c ("sit: add IPv4 over IPv4 support") Reported-by: Palash Oswal Link: https://lore.kernel.org/netdev/CAGyP=7fDcSPKu6nttbGwt7RXzE3uyYxLjCSE97J64pRxJP8jPA@mail.gmail.com/ Cc: Kuniyuki Iwashima Cc: Eric Dumazet Signed-off-by: Cong Wang Reviewed-by: Eric Dumazet Reviewed-by: Kuniyuki Iwashima Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv6/sit.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index df734fe64d10..ec1de1e6b8e3 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1053,12 +1053,13 @@ tx_err: static void ipip6_tunnel_bind_dev(struct net_device *dev) { + struct ip_tunnel *tunnel = netdev_priv(dev); + int t_hlen = tunnel->hlen + sizeof(struct iphdr); struct net_device *tdev = NULL; - struct ip_tunnel *tunnel; + int hlen = LL_MAX_HEADER; const struct iphdr *iph; struct flowi4 fl4; - tunnel = netdev_priv(dev); iph = &tunnel->parms.iph; if (iph->daddr) { @@ -1081,14 +1082,15 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev) tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link); if (tdev && !netif_is_l3_master(tdev)) { - int t_hlen = tunnel->hlen + sizeof(struct iphdr); int mtu; mtu = tdev->mtu - t_hlen; if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU; WRITE_ONCE(dev->mtu, mtu); + hlen = tdev->hard_header_len + tdev->needed_headroom; } + dev->needed_headroom = t_hlen + hlen; } static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p, From d7f8c0b4b93fce14841daa95051aaf166d329ae0 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Wed, 19 Dec 2018 18:28:54 +0100 Subject: [PATCH 149/190] net: dsa: mv88e6xxx: Add missing watchdog ops for 6320 family [ Upstream commit 9c7f37e5ca14f5b04894b1b699a9903885cdafa6 ] The 6320 family of switches uses the same watchdog registers as the 6390. Signed-off-by: Andrew Lunn Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller Stable-dep-of: 6686317855c6 ("net: dsa: mv88e6xxx: add mv88e6321 rsvd2cpu") Signed-off-by: Sasha Levin --- drivers/net/dsa/mv88e6xxx/chip.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 6b310f723580..fddd7e4f3de7 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -3601,6 +3601,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = { .stats_get_stats = mv88e6320_stats_get_stats, .set_cpu_port = mv88e6095_g1_set_cpu_port, .set_egress_port = mv88e6095_g1_set_egress_port, + .watchdog_ops = &mv88e6390_watchdog_ops, .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, .reset = mv88e6352_g1_reset, @@ -3643,6 +3644,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = { .stats_get_stats = mv88e6320_stats_get_stats, .set_cpu_port = mv88e6095_g1_set_cpu_port, .set_egress_port = mv88e6095_g1_set_egress_port, + .watchdog_ops = &mv88e6390_watchdog_ops, .reset = mv88e6352_g1_reset, .vtu_getnext = mv88e6185_g1_vtu_getnext, .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, From d39851b461ad6869dc694370da913eab27416b4d Mon Sep 17 00:00:00 2001 From: Angelo Dureghello Date: Wed, 26 Apr 2023 22:28:15 +0200 Subject: [PATCH 150/190] net: dsa: mv88e6xxx: add mv88e6321 rsvd2cpu [ Upstream commit 6686317855c6997671982d4489ccdd946f644957 ] Add rsvd2cpu capability for mv88e6321 model, to allow proper bpdu processing. Signed-off-by: Angelo Dureghello Fixes: 51c901a775621 ("net: dsa: mv88e6xxx: distinguish Global 2 Rsvd2CPU") Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/dsa/mv88e6xxx/chip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index fddd7e4f3de7..b593e4d85e9c 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -3645,6 +3645,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = { .set_cpu_port = mv88e6095_g1_set_cpu_port, .set_egress_port = mv88e6095_g1_set_egress_port, .watchdog_ops = &mv88e6390_watchdog_ops, + .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, .reset = mv88e6352_g1_reset, .vtu_getnext = mv88e6185_g1_vtu_getnext, .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, From 6d7a2f3b39a8b2ac3ba07ac1e0f30afddf2ef072 Mon Sep 17 00:00:00 2001 From: Maxim Korotkov Date: Thu, 19 Jan 2023 13:44:43 +0300 Subject: [PATCH 151/190] writeback: fix call of incorrect macro [ Upstream commit 3e46c89c74f2c38e5337d2cf44b0b551adff1cb4 ] the variable 'history' is of type u16, it may be an error that the hweight32 macro was used for it I guess macro hweight16 should be used Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 2a81490811d0 ("writeback: implement foreign cgroup inode detection") Signed-off-by: Maxim Korotkov Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230119104443.3002-1-korotkov.maxim.s@gmail.com Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- fs/fs-writeback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 4d687e2e2373..61dc0dc139f8 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -702,7 +702,7 @@ void wbc_detach_inode(struct writeback_control *wbc) * is okay. The main goal is avoiding keeping an inode on * the wrong wb for an extended period of time. */ - if (hweight32(history) > WB_FRN_HIST_THR_SLOTS) + if (hweight16(history) > WB_FRN_HIST_THR_SLOTS) inode_switch_wbs(inode, max_id); } From 0a220fc247aac1ae0d9f74a981b75903c831e8b9 Mon Sep 17 00:00:00 2001 From: Victor Nogueira Date: Wed, 26 Apr 2023 15:19:40 +0000 Subject: [PATCH 152/190] net/sched: act_mirred: Add carrier check [ Upstream commit 526f28bd0fbdc699cda31426928802650c1528e5 ] There are cases where the device is adminstratively UP, but operationally down. For example, we have a physical device (Nvidia ConnectX-6 Dx, 25Gbps) who's cable was pulled out, here is its ip link output: 5: ens2f1: mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000 link/ether b8:ce:f6:4b:68:35 brd ff:ff:ff:ff:ff:ff altname enp179s0f1np1 As you can see, it's administratively UP but operationally down. In this case, sending a packet to this port caused a nasty kernel hang (so nasty that we were unable to capture it). Aborting a transmit based on operational status (in addition to administrative status) fixes the issue. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Acked-by: Jamal Hadi Salim Signed-off-by: Victor Nogueira v1->v2: Add fixes tag v2->v3: Remove blank line between tags + add change log, suggested by Leon Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/sched/act_mirred.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index a30c17a28281..9aad86e4a0fb 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -220,7 +220,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, goto out; } - if (unlikely(!(dev->flags & IFF_UP))) { + if (unlikely(!(dev->flags & IFF_UP)) || !netif_carrier_ok(dev)) { net_notice_ratelimited("tc mirred to Houston: device %s is down\n", dev->name); goto out; From e2adcb45806cab79a43968abf5214f5c5cadf7e6 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 28 Apr 2023 21:27:54 +0100 Subject: [PATCH 153/190] rxrpc: Fix hard call timeout units [ Upstream commit 0d098d83c5d9e107b2df7f5e11f81492f56d2fe7 ] The hard call timeout is specified in the RXRPC_SET_CALL_TIMEOUT cmsg in seconds, so fix the point at which sendmsg() applies it to the call to convert to jiffies from seconds, not milliseconds. Fixes: a158bdd3247b ("rxrpc: Fix timeout of a call that hasn't yet been granted a channel") Signed-off-by: David Howells cc: Marc Dionne cc: "David S. Miller" cc: Eric Dumazet cc: Jakub Kicinski cc: Paolo Abeni cc: linux-afs@lists.infradead.org cc: netdev@vger.kernel.org cc: linux-kernel@vger.kernel.org Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/rxrpc/sendmsg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index a7a09eb04d93..eaa032c498c9 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c @@ -709,7 +709,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) /* Fall through */ case 1: if (p.call.timeouts.hard > 0) { - j = msecs_to_jiffies(p.call.timeouts.hard); + j = p.call.timeouts.hard * HZ; now = jiffies; j += now; WRITE_ONCE(call->expect_term_by, j); From 0a607752b4ef5d48d81b1a1be6ac010f991fdf63 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Mon, 1 May 2023 13:28:57 -0700 Subject: [PATCH 154/190] af_packet: Don't send zero-byte data in packet_sendmsg_spkt(). [ Upstream commit 6a341729fb31b4c5df9f74f24b4b1c98410c9b87 ] syzkaller reported a warning below [0]. We can reproduce it by sending 0-byte data from the (AF_PACKET, SOCK_PACKET) socket via some devices whose dev->hard_header_len is 0. struct sockaddr_pkt addr = { .spkt_family = AF_PACKET, .spkt_device = "tun0", }; int fd; fd = socket(AF_PACKET, SOCK_PACKET, 0); sendto(fd, NULL, 0, 0, (struct sockaddr *)&addr, sizeof(addr)); We have a similar fix for the (AF_PACKET, SOCK_RAW) socket as commit dc633700f00f ("net/af_packet: check len when min_header_len equals to 0"). Let's add the same test for the SOCK_PACKET socket. [0]: skb_assert_len WARNING: CPU: 1 PID: 19945 at include/linux/skbuff.h:2552 skb_assert_len include/linux/skbuff.h:2552 [inline] WARNING: CPU: 1 PID: 19945 at include/linux/skbuff.h:2552 __dev_queue_xmit+0x1f26/0x31d0 net/core/dev.c:4159 Modules linked in: CPU: 1 PID: 19945 Comm: syz-executor.0 Not tainted 6.3.0-rc7-02330-gca6270c12e20 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 RIP: 0010:skb_assert_len include/linux/skbuff.h:2552 [inline] RIP: 0010:__dev_queue_xmit+0x1f26/0x31d0 net/core/dev.c:4159 Code: 89 de e8 1d a2 85 fd 84 db 75 21 e8 64 a9 85 fd 48 c7 c6 80 2a 1f 86 48 c7 c7 c0 06 1f 86 c6 05 23 cf 27 04 01 e8 fa ee 56 fd <0f> 0b e8 43 a9 85 fd 0f b6 1d 0f cf 27 04 31 ff 89 de e8 e3 a1 85 RSP: 0018:ffff8880217af6e0 EFLAGS: 00010282 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffc90001133000 RDX: 0000000000040000 RSI: ffffffff81186922 RDI: 0000000000000001 RBP: ffff8880217af8b0 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000001 R12: ffff888030045640 R13: ffff8880300456b0 R14: ffff888030045650 R15: ffff888030045718 FS: 00007fc5864da640(0000) GS:ffff88806cd00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020005740 CR3: 000000003f856003 CR4: 0000000000770ee0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: dev_queue_xmit include/linux/netdevice.h:3085 [inline] packet_sendmsg_spkt+0xc4b/0x1230 net/packet/af_packet.c:2066 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0x1b4/0x200 net/socket.c:747 ____sys_sendmsg+0x331/0x970 net/socket.c:2503 ___sys_sendmsg+0x11d/0x1c0 net/socket.c:2557 __sys_sendmmsg+0x18c/0x430 net/socket.c:2643 __do_sys_sendmmsg net/socket.c:2672 [inline] __se_sys_sendmmsg net/socket.c:2669 [inline] __x64_sys_sendmmsg+0x9c/0x100 net/socket.c:2669 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3c/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc RIP: 0033:0x7fc58791de5d Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 9f 1b 00 f7 d8 64 89 01 48 RSP: 002b:00007fc5864d9cc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: ffffffffffffffda RBX: 00000000004bbf80 RCX: 00007fc58791de5d RDX: 0000000000000001 RSI: 0000000020005740 RDI: 0000000000000004 RBP: 00000000004bbf80 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000000b R14: 00007fc58797e530 R15: 0000000000000000 ---[ end trace 0000000000000000 ]--- skb len=0 headroom=16 headlen=0 tailroom=304 mac=(16,0) net=(16,-1) trans=-1 shinfo(txflags=0 nr_frags=0 gso(size=0 type=0 segs=0)) csum(0x0 ip_summed=0 complete_sw=0 valid=0 level=0) hash(0x0 sw=0 l4=0) proto=0x0000 pkttype=0 iif=0 dev name=sit0 feat=0x00000006401d7869 sk family=17 type=10 proto=0 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: syzbot Signed-off-by: Kuniyuki Iwashima Reviewed-by: Willem de Bruijn Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/packet/af_packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 60986c209311..aa12bee4133a 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1955,7 +1955,7 @@ retry: goto retry; } - if (!dev_validate_header(dev, skb->data, len)) { + if (!dev_validate_header(dev, skb->data, len) || !skb->len) { err = -EINVAL; goto out_unlock; } From 0403be7864d9a386ddb72d58355e96319ca64d63 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Mon, 30 Jul 2018 16:59:09 +0800 Subject: [PATCH 155/190] drm/amdgpu: Add amdgpu_gfx_off_ctrl function [ Upstream commit d23ee13fba23a3039971a976b2c4857cb5ba9c73 ] v2: 1. drop the special handling for the hw IP suggested by hawking and Christian. 2. refine the variable name suggested by Flora. This funciton as the entry of gfx off feature. we arbitrat gfx off feature enable/disable in this function. Reviewed-by: Hawking Zhang Reviewed-by: Felix Kuehling Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher Stable-dep-of: 2397e3d8d2e1 ("drm/amdgpu: add a missing lock for AMDGPU_SCHED") Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 5 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 36 ++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index acbd33fcb73d..624864148f1d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -950,6 +950,10 @@ struct amdgpu_gfx { /* NGG */ struct amdgpu_ngg ngg; + /* gfx off */ + bool gfx_off_state; /* true: enabled, false: disabled */ + struct mutex gfx_off_mutex; + uint32_t gfx_off_req_count; /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */ /* pipe reservation */ struct mutex pipe_reserve_mutex; DECLARE_BITMAP (pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES); @@ -1776,6 +1780,7 @@ void amdgpu_device_program_register_sequence(struct amdgpu_device *adev, const u32 array_size); bool amdgpu_device_is_px(struct drm_device *dev); +void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable); /* atpx handler */ #if defined(CONFIG_VGA_SWITCHEROO) void amdgpu_register_atpx_handler(void); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 102b05b8f0c2..fed1097c6469 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2369,6 +2369,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, mutex_init(&adev->gfx.gpu_clock_mutex); mutex_init(&adev->srbm_mutex); mutex_init(&adev->gfx.pipe_reserve_mutex); + mutex_init(&adev->gfx.gfx_off_mutex); mutex_init(&adev->grbm_idx_mutex); mutex_init(&adev->mn_lock); mutex_init(&adev->virt.vf_errors.lock); @@ -2396,6 +2397,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, INIT_DELAYED_WORK(&adev->late_init_work, amdgpu_device_ip_late_init_func_handler); + adev->gfx.gfx_off_req_count = 1; adev->pm.ac_power = power_supply_is_system_supplied() > 0 ? true : false; /* Registers mapping */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index eeaa2e825858..889d1266f3ae 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -340,3 +340,39 @@ void amdgpu_gfx_compute_mqd_sw_fini(struct amdgpu_device *adev) &ring->mqd_gpu_addr, &ring->mqd_ptr); } + +/* amdgpu_gfx_off_ctrl - Handle gfx off feature enable/disable + * + * @adev: amdgpu_device pointer + * @bool enable true: enable gfx off feature, false: disable gfx off feature + * + * 1. gfx off feature will be enabled by gfx ip after gfx cg gp enabled. + * 2. other client can send request to disable gfx off feature, the request should be honored. + * 3. other client can cancel their request of disable gfx off feature + * 4. other client should not send request to enable gfx off feature before disable gfx off feature. + */ + +void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) +{ + if (!(adev->powerplay.pp_feature & PP_GFXOFF_MASK)) + return; + + if (!adev->powerplay.pp_funcs->set_powergating_by_smu) + return; + + mutex_lock(&adev->gfx.gfx_off_mutex); + + if (!enable) + adev->gfx.gfx_off_req_count++; + else if (adev->gfx.gfx_off_req_count > 0) + adev->gfx.gfx_off_req_count--; + + if (enable && !adev->gfx.gfx_off_state && !adev->gfx.gfx_off_req_count) { + if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true)) + adev->gfx.gfx_off_state = true; + } else if (!enable && adev->gfx.gfx_off_state) { + if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false)) + adev->gfx.gfx_off_state = false; + } + mutex_unlock(&adev->gfx.gfx_off_mutex); +} From c9d825138667edec044c953687d7497aa15b2575 Mon Sep 17 00:00:00 2001 From: Rex Zhu Date: Fri, 27 Jul 2018 21:06:30 +0800 Subject: [PATCH 156/190] drm/amdgpu: Put enable gfx off feature to a delay thread [ Upstream commit 1e317b99f0c244bd8830918fdae9715210baf4fe ] delay to enable gfx off feature to avoid gfx on/off frequently suggested by Alex and Evan. Reviewed-by: Hawking Zhang Reviewed-by: Felix Kuehling Signed-off-by: Rex Zhu Signed-off-by: Alex Deucher Stable-dep-of: 2397e3d8d2e1 ("drm/amdgpu: add a missing lock for AMDGPU_SCHED") Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 15 +++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 8 ++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 624864148f1d..45e6dfa330ad 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -954,6 +954,8 @@ struct amdgpu_gfx { bool gfx_off_state; /* true: enabled, false: disabled */ struct mutex gfx_off_mutex; uint32_t gfx_off_req_count; /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */ + struct delayed_work gfx_off_delay_work; + /* pipe reservation */ struct mutex pipe_reserve_mutex; DECLARE_BITMAP (pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index fed1097c6469..787cbeea8dc5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1927,6 +1927,19 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work) DRM_ERROR("ib ring test failed (%d).\n", r); } +static void amdgpu_device_delay_enable_gfx_off(struct work_struct *work) +{ + struct amdgpu_device *adev = + container_of(work, struct amdgpu_device, gfx.gfx_off_delay_work.work); + + mutex_lock(&adev->gfx.gfx_off_mutex); + if (!adev->gfx.gfx_off_state && !adev->gfx.gfx_off_req_count) { + if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true)) + adev->gfx.gfx_off_state = true; + } + mutex_unlock(&adev->gfx.gfx_off_mutex); +} + /** * amdgpu_device_ip_suspend_phase1 - run suspend for hardware IPs (phase 1) * @@ -2396,6 +2409,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, INIT_DELAYED_WORK(&adev->late_init_work, amdgpu_device_ip_late_init_func_handler); + INIT_DELAYED_WORK(&adev->gfx.gfx_off_delay_work, + amdgpu_device_delay_enable_gfx_off); adev->gfx.gfx_off_req_count = 1; adev->pm.ac_power = power_supply_is_system_supplied() > 0 ? true : false; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 889d1266f3ae..af42c2464a59 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -26,6 +26,9 @@ #include "amdgpu.h" #include "amdgpu_gfx.h" +/* 0.5 second timeout */ +#define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(500) + /* * GPU scratch registers helpers function. */ @@ -360,6 +363,7 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) if (!adev->powerplay.pp_funcs->set_powergating_by_smu) return; + mutex_lock(&adev->gfx.gfx_off_mutex); if (!enable) @@ -368,11 +372,11 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) adev->gfx.gfx_off_req_count--; if (enable && !adev->gfx.gfx_off_state && !adev->gfx.gfx_off_req_count) { - if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true)) - adev->gfx.gfx_off_state = true; + schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE); } else if (!enable && adev->gfx.gfx_off_state) { if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false)) adev->gfx.gfx_off_state = false; } + mutex_unlock(&adev->gfx.gfx_off_mutex); } From 1d290cd3724c054746d7e750deaf10684fb51586 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Wed, 30 Jan 2019 02:53:22 +0100 Subject: [PATCH 157/190] drm/amdgpu: Add command to override the context priority. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit b5bb37eddb63b16b7ab959598d108b1c444be77d ] Given a master fd we can then override the priority of the context in another fd. Using these overrides was recommended by Christian instead of trying to submit from a master fd, and I am adding a way to override a single context instead of the entire process so we can only upgrade a single Vulkan queue and not effectively the entire process. Reused the flags field as it was checked to be 0 anyways, so nothing used it. This is source-incompatible (due to the name change), but ABI compatible. Signed-off-by: Bas Nieuwenhuizen Reviewed-by: Christian König Signed-off-by: Alex Deucher Stable-dep-of: 2397e3d8d2e1 ("drm/amdgpu: add a missing lock for AMDGPU_SCHED") Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 41 ++++++++++++++++++++++- include/uapi/drm/amdgpu_drm.h | 3 +- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index 0b70410488b6..0767a93e4d91 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -76,6 +76,39 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev, return 0; } +static int amdgpu_sched_context_priority_override(struct amdgpu_device *adev, + int fd, + unsigned ctx_id, + enum drm_sched_priority priority) +{ + struct file *filp = fget(fd); + struct amdgpu_fpriv *fpriv; + struct amdgpu_ctx *ctx; + int r; + + if (!filp) + return -EINVAL; + + r = amdgpu_file_to_fpriv(filp, &fpriv); + if (r) { + fput(filp); + return r; + } + + ctx = amdgpu_ctx_get(fpriv, ctx_id); + + if (!ctx) { + fput(filp); + return -EINVAL; + } + + amdgpu_ctx_priority_override(ctx, priority); + amdgpu_ctx_put(ctx); + fput(filp); + + return 0; +} + int amdgpu_sched_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { @@ -85,7 +118,7 @@ int amdgpu_sched_ioctl(struct drm_device *dev, void *data, int r; priority = amdgpu_to_sched_priority(args->in.priority); - if (args->in.flags || priority == DRM_SCHED_PRIORITY_INVALID) + if (priority == DRM_SCHED_PRIORITY_INVALID) return -EINVAL; switch (args->in.op) { @@ -94,6 +127,12 @@ int amdgpu_sched_ioctl(struct drm_device *dev, void *data, args->in.fd, priority); break; + case AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE: + r = amdgpu_sched_context_priority_override(adev, + args->in.fd, + args->in.ctx_id, + priority); + break; default: DRM_ERROR("Invalid sched op specified: %d\n", args->in.op); r = -EINVAL; diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 1ceec56de015..b72aeb766fc7 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -272,13 +272,14 @@ union drm_amdgpu_vm { /* sched ioctl */ #define AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE 1 +#define AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE 2 struct drm_amdgpu_sched_in { /* AMDGPU_SCHED_OP_* */ __u32 op; __u32 fd; __s32 priority; - __u32 flags; + __u32 ctx_id; }; union drm_amdgpu_sched { From 516477e8dabd680afa34444bfa369f34fd0dd3a2 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 26 Apr 2023 15:54:55 -0700 Subject: [PATCH 158/190] drm/amdgpu: add a missing lock for AMDGPU_SCHED MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 2397e3d8d2e120355201a8310b61929f5a8bd2c0 ] mgr->ctx_handles should be protected by mgr->lock. v2: improve commit message v3: add a Fixes tag Signed-off-by: Chia-I Wu Reviewed-by: Christian König Fixes: 52c6a62c64fa ("drm/amdgpu: add interface for editing a foreign process's priority v3") Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index 0767a93e4d91..018f06f154b8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -55,6 +55,7 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev, { struct file *filp = fget(fd); struct amdgpu_fpriv *fpriv; + struct amdgpu_ctx_mgr *mgr; struct amdgpu_ctx *ctx; uint32_t id; int r; @@ -68,8 +69,11 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev, return r; } - idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id) + mgr = &fpriv->ctx_mgr; + mutex_lock(&mgr->lock); + idr_for_each_entry(&mgr->ctx_handles, ctx, id) amdgpu_ctx_priority_override(ctx, priority); + mutex_unlock(&mgr->lock); fput(filp); From 8b495e218e3229ff2a1666154b709c0b786ea90a Mon Sep 17 00:00:00 2001 From: Ruliang Lin Date: Thu, 4 May 2023 14:50:53 +0800 Subject: [PATCH 159/190] ALSA: caiaq: input: Add error handling for unsupported input methods in `snd_usb_caiaq_input_init` [ Upstream commit 0d727e1856ef22dd9337199430258cb64cbbc658 ] Smatch complains that: snd_usb_caiaq_input_init() warn: missing error code 'ret' This patch adds a new case to handle the situation where the device does not support any input methods in the `snd_usb_caiaq_input_init` function. It returns an `-EINVAL` error code to indicate that no input methods are supported on the device. Fixes: 523f1dce3743 ("[ALSA] Add Native Instrument usb audio device support") Signed-off-by: Ruliang Lin Reviewed-by: Dongliang Mu Acked-by: Daniel Mack Link: https://lore.kernel.org/r/20230504065054.3309-1-u202112092@hust.edu.cn Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/usb/caiaq/input.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c index e883659ea6e7..19951e1dbbb0 100644 --- a/sound/usb/caiaq/input.c +++ b/sound/usb/caiaq/input.c @@ -817,6 +817,7 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev) default: /* no input methods supported on this device */ + ret = -EINVAL; goto exit_free_idev; } From fbf762b475ef49168a07ed6064f5091f3275a859 Mon Sep 17 00:00:00 2001 From: Xuan Zhuo Date: Mon, 1 Aug 2022 14:38:59 +0800 Subject: [PATCH 160/190] virtio_net: split free_unused_bufs() [ Upstream commit 6e345f8c7cd029ad3aaece15ad4425ac26e4eb63 ] This patch separates two functions for freeing sq buf and rq buf from free_unused_bufs(). When supporting the enable/disable tx/rq queue in the future, it is necessary to support separate recovery of a sq buf or a rq buf. Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20220801063902.129329-40-xuanzhuo@linux.alibaba.com> Signed-off-by: Michael S. Tsirkin Stable-dep-of: f8bb51043945 ("virtio_net: suppress cpu stall when free_unused_bufs") Signed-off-by: Sasha Levin --- drivers/net/virtio_net.c | 41 ++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 0cd46735e395..9b72b3f0b5bf 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -2655,6 +2655,27 @@ static void free_receive_page_frags(struct virtnet_info *vi) put_page(vi->rq[i].alloc_frag.page); } +static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf) +{ + if (!is_xdp_frame(buf)) + dev_kfree_skb(buf); + else + xdp_return_frame(ptr_to_xdp(buf)); +} + +static void virtnet_rq_free_unused_buf(struct virtqueue *vq, void *buf) +{ + struct virtnet_info *vi = vq->vdev->priv; + int i = vq2rxq(vq); + + if (vi->mergeable_rx_bufs) + put_page(virt_to_head_page(buf)); + else if (vi->big_packets) + give_pages(&vi->rq[i], buf); + else + put_page(virt_to_head_page(buf)); +} + static void free_unused_bufs(struct virtnet_info *vi) { void *buf; @@ -2662,26 +2683,14 @@ static void free_unused_bufs(struct virtnet_info *vi) for (i = 0; i < vi->max_queue_pairs; i++) { struct virtqueue *vq = vi->sq[i].vq; - while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) { - if (!is_xdp_frame(buf)) - dev_kfree_skb(buf); - else - xdp_return_frame(ptr_to_xdp(buf)); - } + while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) + virtnet_sq_free_unused_buf(vq, buf); } for (i = 0; i < vi->max_queue_pairs; i++) { struct virtqueue *vq = vi->rq[i].vq; - - while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) { - if (vi->mergeable_rx_bufs) { - put_page(virt_to_head_page(buf)); - } else if (vi->big_packets) { - give_pages(&vi->rq[i], buf); - } else { - put_page(virt_to_head_page(buf)); - } - } + while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) + virtnet_rq_free_unused_buf(vq, buf); } } From 5f4d3f6b27d99a7863727e97859e259fc291ea8e Mon Sep 17 00:00:00 2001 From: Wenliang Wang Date: Thu, 4 May 2023 10:27:06 +0800 Subject: [PATCH 161/190] virtio_net: suppress cpu stall when free_unused_bufs [ Upstream commit f8bb5104394560e29017c25bcade4c6b7aabd108 ] For multi-queue and large ring-size use case, the following error occurred when free_unused_bufs: rcu: INFO: rcu_sched self-detected stall on CPU. Fixes: 986a4f4d452d ("virtio_net: multiqueue support") Signed-off-by: Wenliang Wang Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/virtio_net.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 9b72b3f0b5bf..d45e8de79f28 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -2685,12 +2685,14 @@ static void free_unused_bufs(struct virtnet_info *vi) struct virtqueue *vq = vi->sq[i].vq; while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) virtnet_sq_free_unused_buf(vq, buf); + cond_resched(); } for (i = 0; i < vi->max_queue_pairs; i++) { struct virtqueue *vq = vi->rq[i].vq; while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) virtnet_rq_free_unused_buf(vq, buf); + cond_resched(); } } From 24ef88ca58938c3c15017305238b3a77df534894 Mon Sep 17 00:00:00 2001 From: Kajol Jain Date: Tue, 28 Mar 2023 16:59:08 +0530 Subject: [PATCH 162/190] perf vendor events power9: Remove UTF-8 characters from JSON files [ Upstream commit 5d9df8731c0941f3add30f96745a62586a0c9d52 ] Commit 3c22ba5243040c13 ("perf vendor events powerpc: Update POWER9 events") added and updated power9 PMU JSON events. However some of the JSON events which are part of other.json and pipeline.json files, contains UTF-8 characters in their brief description. Having UTF-8 character could breaks the perf build on some distros. Fix this issue by removing the UTF-8 characters from other.json and pipeline.json files. Result without the fix: [command]# file -i pmu-events/arch/powerpc/power9/* pmu-events/arch/powerpc/power9/cache.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/floating-point.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/frontend.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/marked.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/memory.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/metrics.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/nest_metrics.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/other.json: application/json; charset=utf-8 pmu-events/arch/powerpc/power9/pipeline.json: application/json; charset=utf-8 pmu-events/arch/powerpc/power9/pmc.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/translation.json: application/json; charset=us-ascii [command]# Result with the fix: [command]# file -i pmu-events/arch/powerpc/power9/* pmu-events/arch/powerpc/power9/cache.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/floating-point.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/frontend.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/marked.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/memory.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/metrics.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/nest_metrics.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/other.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/pipeline.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/pmc.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/translation.json: application/json; charset=us-ascii [command]# Fixes: 3c22ba5243040c13 ("perf vendor events powerpc: Update POWER9 events") Reported-by: Arnaldo Carvalho de Melo Signed-off-by: Kajol Jain Acked-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Cc: Athira Rajeev Cc: Disha Goel Cc: Jiri Olsa Cc: Madhavan Srinivasan Cc: Sukadev Bhattiprolu Cc: linuxppc-dev@lists.ozlabs.org Link: https://lore.kernel.org/lkml/ZBxP77deq7ikTxwG@kernel.org/ Link: https://lore.kernel.org/r/20230328112908.113158-1-kjain@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/pmu-events/arch/powerpc/power9/other.json | 4 ++-- tools/perf/pmu-events/arch/powerpc/power9/pipeline.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/pmu-events/arch/powerpc/power9/other.json b/tools/perf/pmu-events/arch/powerpc/power9/other.json index 48cf4f920b3f..064341c0df57 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/other.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/other.json @@ -1417,7 +1417,7 @@ {, "EventCode": "0x45054", "EventName": "PM_FMA_CMPL", - "BriefDescription": "two flops operation completed (fmadd, fnmadd, fmsub, fnmsub) Scalar instructions only. " + "BriefDescription": "two flops operation completed (fmadd, fnmadd, fmsub, fnmsub) Scalar instructions only." }, {, "EventCode": "0x201E8", @@ -2017,7 +2017,7 @@ {, "EventCode": "0xC0BC", "EventName": "PM_LSU_FLUSH_OTHER", - "BriefDescription": "Other LSU flushes including: Sync (sync ack from L2 caused search of LRQ for oldest snooped load, This will either signal a Precise Flush of the oldest snooped loa or a Flush Next PPC); Data Valid Flush Next (several cases of this, one example is store and reload are lined up such that a store-hit-reload scenario exists and the CDF has already launched and has gotten bad/stale data); Bad Data Valid Flush Next (might be a few cases of this, one example is a larxa (D$ hit) return data and dval but can't allocate to LMQ (LMQ full or other reason). Already gave dval but can't watch it for snoop_hit_larx. Need to take the “bad dval” back and flush all younger ops)" + "BriefDescription": "Other LSU flushes including: Sync (sync ack from L2 caused search of LRQ for oldest snooped load, This will either signal a Precise Flush of the oldest snooped loa or a Flush Next PPC); Data Valid Flush Next (several cases of this, one example is store and reload are lined up such that a store-hit-reload scenario exists and the CDF has already launched and has gotten bad/stale data); Bad Data Valid Flush Next (might be a few cases of this, one example is a larxa (D$ hit) return data and dval but can't allocate to LMQ (LMQ full or other reason). Already gave dval but can't watch it for snoop_hit_larx. Need to take the 'bad dval' back and flush all younger ops)" }, {, "EventCode": "0x5094", diff --git a/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json b/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json index b4772f54a271..e2f2ed0a3549 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json @@ -442,7 +442,7 @@ {, "EventCode": "0x4D052", "EventName": "PM_2FLOP_CMPL", - "BriefDescription": "DP vector version of fmul, fsub, fcmp, fsel, fabs, fnabs, fres ,fsqrte, fneg " + "BriefDescription": "DP vector version of fmul, fsub, fcmp, fsel, fabs, fnabs, fres ,fsqrte, fneg" }, {, "EventCode": "0x1F142", From 1ecddbc0f9120aa61acdd8dd05c0fdb8ea6221db Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 13 Apr 2023 14:46:39 +0200 Subject: [PATCH 163/190] perf map: Delete two variable initialisations before null pointer checks in sort__sym_from_cmp() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit c160118a90d4acf335993d8d59b02ae2147a524e ] Addresses of two data structure members were determined before corresponding null pointer checks in the implementation of the function “sort__sym_from_cmp”. Thus avoid the risk for undefined behaviour by removing extra initialisations for the local variables “from_l” and “from_r” (also because they were already reassigned with the same value behind this pointer check). This issue was detected by using the Coccinelle software. Fixes: 1b9e97a2a95e4941 ("perf tools: Fix report -F symbol_from for data without branch info") Signed-off-by: Acked-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Andi Kleen Cc: German Gomez Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Mark Rutland Cc: Namhyung Kim Link: https://lore.kernel.org/cocci/54a21fea-64e3-de67-82ef-d61b90ffad05@web.de/ Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/util/sort.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 85ff4f68adc0..66e11e6bb719 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -735,8 +735,7 @@ static int hist_entry__dso_to_filter(struct hist_entry *he, int type, static int64_t sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right) { - struct addr_map_symbol *from_l = &left->branch_info->from; - struct addr_map_symbol *from_r = &right->branch_info->from; + struct addr_map_symbol *from_l, *from_r; if (!left->branch_info || !right->branch_info) return cmp_null(left->branch_info, right->branch_info); From c6908920d857a113807fb954feb3985f414bc069 Mon Sep 17 00:00:00 2001 From: Yang Jihong Date: Thu, 27 Apr 2023 01:28:41 +0000 Subject: [PATCH 164/190] perf symbols: Fix return incorrect build_id size in elf_read_build_id() [ Upstream commit 1511e4696acb715a4fe48be89e1e691daec91c0e ] In elf_read_build_id(), if gnu build_id is found, should return the size of the actually copied data. If descsz is greater thanBuild_ID_SIZE, write_buildid data access may occur. Fixes: be96ea8ffa788dcc ("perf symbols: Fix issue with binaries using 16-bytes buildids (v2)") Reported-by: Will Ochowicz Signed-off-by: Yang Jihong Tested-by: Will Ochowicz Acked-by: Adrian Hunter Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Leo Yan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/lkml/CWLP265MB49702F7BA3D6D8F13E4B1A719C649@CWLP265MB4970.GBRP265.PROD.OUTLOOK.COM/T/ Link: https://lore.kernel.org/r/20230427012841.231729-1-yangjihong1@huawei.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin --- tools/perf/util/symbol-elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 8dde4369fbcd..227dfe33063c 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -517,7 +517,7 @@ static int elf_read_build_id(Elf *elf, void *bf, size_t size) size_t sz = min(size, descsz); memcpy(bf, ptr, sz); memset(bf + sz, 0, size - sz); - err = descsz; + err = sz; break; } } From 561bf5cc3a0bb83cfbdabf03e5a1d69fcadb9cc5 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Wed, 12 Apr 2023 11:33:09 +0100 Subject: [PATCH 165/190] btrfs: fix btrfs_prev_leaf() to not return the same key twice commit 6f932d4ef007d6a4ae03badcb749fbb8f49196f6 upstream. A call to btrfs_prev_leaf() may end up returning a path that points to the same item (key) again. This happens if while btrfs_prev_leaf(), after we release the path, a concurrent insertion happens, which moves items off from a sibling into the front of the previous leaf, and an item with the computed previous key does not exists. For example, suppose we have the two following leaves: Leaf A ------------------------------------------------------------- | ... key (300 96 10) key (300 96 15) key (300 96 16) | ------------------------------------------------------------- slot 20 slot 21 slot 22 Leaf B ------------------------------------------------------------- | key (300 96 20) key (300 96 21) key (300 96 22) ... | ------------------------------------------------------------- slot 0 slot 1 slot 2 If we call btrfs_prev_leaf(), from btrfs_previous_item() for example, with a path pointing to leaf B and slot 0 and the following happens: 1) At btrfs_prev_leaf() we compute the previous key to search as: (300 96 19), which is a key that does not exists in the tree; 2) Then we call btrfs_release_path() at btrfs_prev_leaf(); 3) Some other task inserts a key at leaf A, that sorts before the key at slot 20, for example it has an objectid of 299. In order to make room for the new key, the key at slot 22 is moved to the front of leaf B. This happens at push_leaf_right(), called from split_leaf(). After this leaf B now looks like: -------------------------------------------------------------------------------- | key (300 96 16) key (300 96 20) key (300 96 21) key (300 96 22) ... | -------------------------------------------------------------------------------- slot 0 slot 1 slot 2 slot 3 4) At btrfs_prev_leaf() we call btrfs_search_slot() for the computed previous key: (300 96 19). Since the key does not exists, btrfs_search_slot() returns 1 and with a path pointing to leaf B and slot 1, the item with key (300 96 20); 5) This makes btrfs_prev_leaf() return a path that points to slot 1 of leaf B, the same key as before it was called, since the key at slot 0 of leaf B (300 96 16) is less than the computed previous key, which is (300 96 19); 6) As a consequence btrfs_previous_item() returns a path that points again to the item with key (300 96 20). For some users of btrfs_prev_leaf() or btrfs_previous_item() this may not be functional a problem, despite not making sense to return a new path pointing again to the same item/key. However for a caller such as tree-log.c:log_dir_items(), this has a bad consequence, as it can result in not logging some dir index deletions in case the directory is being logged without holding the inode's VFS lock (logging triggered while logging a child inode for example) - for the example scenario above, in case the dir index keys 17, 18 and 19 were deleted in the current transaction. CC: stable@vger.kernel.org # 4.14+ Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/ctree.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 00dc1b5c8737..34d56f0fa750 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -5151,10 +5151,12 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) { struct btrfs_key key; + struct btrfs_key orig_key; struct btrfs_disk_key found_key; int ret; btrfs_item_key_to_cpu(path->nodes[0], &key, 0); + orig_key = key; if (key.offset > 0) { key.offset--; @@ -5171,8 +5173,36 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) btrfs_release_path(path); ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); - if (ret < 0) + if (ret <= 0) return ret; + + /* + * Previous key not found. Even if we were at slot 0 of the leaf we had + * before releasing the path and calling btrfs_search_slot(), we now may + * be in a slot pointing to the same original key - this can happen if + * after we released the path, one of more items were moved from a + * sibling leaf into the front of the leaf we had due to an insertion + * (see push_leaf_right()). + * If we hit this case and our slot is > 0 and just decrement the slot + * so that the caller does not process the same key again, which may or + * may not break the caller, depending on its logic. + */ + if (path->slots[0] < btrfs_header_nritems(path->nodes[0])) { + btrfs_item_key(path->nodes[0], &found_key, path->slots[0]); + ret = comp_keys(&found_key, &orig_key); + if (ret == 0) { + if (path->slots[0] > 0) { + path->slots[0]--; + return 0; + } + /* + * At slot 0, same key as before, it means orig_key is + * the lowest, leftmost, key in the tree. We're done. + */ + return 1; + } + } + btrfs_item_key(path->nodes[0], &found_key, 0); ret = comp_keys(&found_key, &key); /* From 4199d58c73cf7f568c4f1e9c5192f4fda2afe22b Mon Sep 17 00:00:00 2001 From: Anastasia Belova Date: Wed, 26 Apr 2023 14:53:23 +0300 Subject: [PATCH 166/190] btrfs: print-tree: parent bytenr must be aligned to sector size commit c87f318e6f47696b4040b58f460d5c17ea0280e6 upstream. Check nodesize to sectorsize in alignment check in print_extent_item. The comment states that and this is correct, similar check is done elsewhere in the functions. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: ea57788eb76d ("btrfs: require only sector size alignment for parent eb bytenr") CC: stable@vger.kernel.org # 4.14+ Reviewed-by: Qu Wenruo Signed-off-by: Anastasia Belova Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/print-tree.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index 4b217e9a581c..e3de0c4ecbfc 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c @@ -109,10 +109,10 @@ static void print_extent_item(struct extent_buffer *eb, int slot, int type) pr_cont("shared data backref parent %llu count %u\n", offset, btrfs_shared_data_ref_count(eb, sref)); /* - * offset is supposed to be a tree block which - * must be aligned to nodesize. + * Offset is supposed to be a tree block which must be + * aligned to sectorsize. */ - if (!IS_ALIGNED(offset, eb->fs_info->nodesize)) + if (!IS_ALIGNED(offset, eb->fs_info->sectorsize)) pr_info( "\t\t\t(parent %llu not aligned to sectorsize %u)\n", offset, eb->fs_info->sectorsize); From b7687d8ad13f3f0cd2addd2d679df0250eed48c5 Mon Sep 17 00:00:00 2001 From: Pawel Witek Date: Fri, 5 May 2023 17:14:59 +0200 Subject: [PATCH 167/190] cifs: fix pcchunk length type in smb2_copychunk_range commit d66cde50c3c868af7abddafce701bb86e4a93039 upstream. Change type of pcchunk->Length from u32 to u64 to match smb2_copychunk_range arguments type. Fixes the problem where performing server-side copy with CIFS_IOC_COPYCHUNK_FILE ioctl resulted in incomplete copy of large files while returning -EINVAL. Fixes: 9bf0c9cd4314 ("CIFS: Fix SMB2/SMB3 Copy offload support (refcopy) for large files") Cc: Signed-off-by: Pawel Witek Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/cifs/smb2ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 118bcb351af9..c07dcb2af2eb 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -1180,7 +1180,7 @@ smb2_copychunk_range(const unsigned int xid, pcchunk->SourceOffset = cpu_to_le64(src_off); pcchunk->TargetOffset = cpu_to_le64(dest_off); pcchunk->Length = - cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk)); + cpu_to_le32(min_t(u64, len, tcon->max_bytes_chunk)); /* Request server copy to target from src identified by key */ kfree(retbuf); From 78ee7a7da525353f4f6ba2ee3e035c72c58aac79 Mon Sep 17 00:00:00 2001 From: Andrey Avdeev Date: Sun, 30 Apr 2023 11:01:10 +0300 Subject: [PATCH 168/190] platform/x86: touchscreen_dmi: Add info for the Dexp Ursus KX210i commit 4b65f95c87c35699bc6ad540d6b9dd7f950d0924 upstream. Add touchscreen info for the Dexp Ursus KX210i Signed-off-by: Andrey Avdeev Link: https://lore.kernel.org/r/ZE4gRgzRQCjXFYD0@avdeevavpc Cc: stable@vger.kernel.org Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/touchscreen_dmi.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c index f122a0263a1b..e26e2279ba6c 100644 --- a/drivers/platform/x86/touchscreen_dmi.c +++ b/drivers/platform/x86/touchscreen_dmi.c @@ -147,6 +147,22 @@ static const struct ts_dmi_data dexp_ursus_7w_data = { .properties = dexp_ursus_7w_props, }; +static const struct property_entry dexp_ursus_kx210i_props[] = { + PROPERTY_ENTRY_U32("touchscreen-min-x", 5), + PROPERTY_ENTRY_U32("touchscreen-min-y", 2), + PROPERTY_ENTRY_U32("touchscreen-size-x", 1720), + PROPERTY_ENTRY_U32("touchscreen-size-y", 1137), + PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-dexp-ursus-kx210i.fw"), + PROPERTY_ENTRY_U32("silead,max-fingers", 10), + PROPERTY_ENTRY_BOOL("silead,home-button"), + { } +}; + +static const struct ts_dmi_data dexp_ursus_kx210i_data = { + .acpi_name = "MSSL1680:00", + .properties = dexp_ursus_kx210i_props, +}; + static const struct property_entry digma_citi_e200_props[] = { PROPERTY_ENTRY_U32("touchscreen-size-x", 1980), PROPERTY_ENTRY_U32("touchscreen-size-y", 1500), @@ -502,6 +518,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "7W"), }, }, + { + /* DEXP Ursus KX210i */ + .driver_data = (void *)&dexp_ursus_kx210i_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "INSYDE Corp."), + DMI_MATCH(DMI_PRODUCT_NAME, "S107I"), + }, + }, { /* Digma Citi E200 */ .driver_data = (void *)&digma_citi_e200_data, From 6556d31984c968228e58ee1f2ca688d4df359816 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 5 Mar 2023 20:00:34 -0800 Subject: [PATCH 169/190] sh: math-emu: fix macro redefined warning commit 58a49ad90939386a8682e842c474a0d2c00ec39c upstream. Fix a warning that was reported by the kernel test robot: In file included from ../include/math-emu/soft-fp.h:27, from ../arch/sh/math-emu/math.c:22: ../arch/sh/include/asm/sfp-machine.h:17: warning: "__BYTE_ORDER" redefined 17 | #define __BYTE_ORDER __BIG_ENDIAN In file included from ../arch/sh/math-emu/math.c:21: ../arch/sh/math-emu/sfp-util.h:71: note: this is the location of the previous definition 71 | #define __BYTE_ORDER __LITTLE_ENDIAN Fixes: b929926f01f2 ("sh: define __BIG_ENDIAN for math-emu") Signed-off-by: Randy Dunlap Reported-by: kernel test robot Link: lore.kernel.org/r/202111121827.6v6SXtVv-lkp@intel.com Cc: John Paul Adrian Glaubitz Cc: Yoshinori Sato Cc: Rich Felker Cc: linux-sh@vger.kernel.org Reviewed-by: Geert Uytterhoeven Cc: stable@vger.kernel.org Reviewed-by: John Paul Adrian Glaubitz Link: https://lore.kernel.org/r/20230306040037.20350-5-rdunlap@infradead.org Signed-off-by: John Paul Adrian Glaubitz Signed-off-by: Greg Kroah-Hartman --- arch/sh/math-emu/sfp-util.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/sh/math-emu/sfp-util.h b/arch/sh/math-emu/sfp-util.h index 784f541344f3..bda50762b3d3 100644 --- a/arch/sh/math-emu/sfp-util.h +++ b/arch/sh/math-emu/sfp-util.h @@ -67,7 +67,3 @@ } while (0) #define abort() return 0 - -#define __BYTE_ORDER __LITTLE_ENDIAN - - From 0429b2b4a06dde2990ad8d80c9e8a57df3ebb1b0 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 5 Mar 2023 20:00:33 -0800 Subject: [PATCH 170/190] sh: init: use OF_EARLY_FLATTREE for early init commit 6cba655543c7959f8a6d2979b9d40a6a66b7ed4f upstream. When CONFIG_OF_EARLY_FLATTREE and CONFIG_SH_DEVICE_TREE are not set, SH3 build fails with a call to early_init_dt_scan(), so in arch/sh/kernel/setup.c and arch/sh/kernel/head_32.S, use CONFIG_OF_EARLY_FLATTREE instead of CONFIG_OF_FLATTREE. Fixes this build error: ../arch/sh/kernel/setup.c: In function 'sh_fdt_init': ../arch/sh/kernel/setup.c:262:26: error: implicit declaration of function 'early_init_dt_scan' [-Werror=implicit-function-declaration] 262 | if (!dt_virt || !early_init_dt_scan(dt_virt)) { Fixes: 03767daa1387 ("sh: fix build regression with CONFIG_OF && !CONFIG_OF_FLATTREE") Fixes: eb6b6930a70f ("sh: fix memory corruption of unflattened device tree") Signed-off-by: Randy Dunlap Suggested-by: Rob Herring Cc: Frank Rowand Cc: devicetree@vger.kernel.org Cc: Rich Felker Cc: Yoshinori Sato Cc: Geert Uytterhoeven Cc: John Paul Adrian Glaubitz Cc: linux-sh@vger.kernel.org Cc: stable@vger.kernel.org Reviewed-by: John Paul Adrian Glaubitz Link: https://lore.kernel.org/r/20230306040037.20350-4-rdunlap@infradead.org Signed-off-by: John Paul Adrian Glaubitz Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/head_32.S | 6 +++--- arch/sh/kernel/setup.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index 4e352c3f79e6..fb505cda25fc 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -67,7 +67,7 @@ ENTRY(_stext) ldc r0, r6_bank #endif -#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_OF_EARLY_FLATTREE mov r4, r12 ! Store device tree blob pointer in r12 #endif @@ -318,7 +318,7 @@ ENTRY(_stext) 10: #endif -#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_OF_EARLY_FLATTREE mov.l 8f, r0 ! Make flat device tree available early. jsr @r0 mov r12, r4 @@ -349,7 +349,7 @@ ENTRY(stack_start) 5: .long start_kernel 6: .long cpu_init 7: .long init_thread_union -#if defined(CONFIG_OF_FLATTREE) +#if defined(CONFIG_OF_EARLY_FLATTREE) 8: .long sh_fdt_init #endif diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index c286cf5da6e7..b2f44eb7ce19 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -242,7 +242,7 @@ void __init __weak plat_early_device_setup(void) { } -#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_OF_EARLY_FLATTREE void __ref sh_fdt_init(phys_addr_t dt_phys) { static int done = 0; @@ -329,7 +329,7 @@ void __init setup_arch(char **cmdline_p) /* Let earlyprintk output early console messages */ early_platform_driver_probe("earlyprintk", 1, 1); -#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_OF_EARLY_FLATTREE #ifdef CONFIG_USE_BUILTIN_DTB unflatten_and_copy_device_tree(); #else From d9bdaa40933137180dffd9c7f708061f19413b40 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 5 Mar 2023 20:00:32 -0800 Subject: [PATCH 171/190] sh: nmi_debug: fix return value of __setup handler commit d1155e4132de712a9d3066e2667ceaad39a539c5 upstream. __setup() handlers should return 1 to obsolete_checksetup() in init/main.c to indicate that the boot option has been handled. A return of 0 causes the boot option/value to be listed as an Unknown kernel parameter and added to init's (limited) argument or environment strings. Also, error return codes don't mean anything to obsolete_checksetup() -- only non-zero (usually 1) or zero. So return 1 from nmi_debug_setup(). Fixes: 1e1030dccb10 ("sh: nmi_debug support.") Signed-off-by: Randy Dunlap Reported-by: Igor Zhbanov Link: lore.kernel.org/r/64644a2f-4a20-bab3-1e15-3b2cdd0defe3@omprussia.ru Cc: John Paul Adrian Glaubitz Cc: Yoshinori Sato Cc: Rich Felker Cc: linux-sh@vger.kernel.org Cc: stable@vger.kernel.org Reviewed-by: John Paul Adrian Glaubitz Link: https://lore.kernel.org/r/20230306040037.20350-3-rdunlap@infradead.org Signed-off-by: John Paul Adrian Glaubitz Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/nmi_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sh/kernel/nmi_debug.c b/arch/sh/kernel/nmi_debug.c index 730d928f0d12..d37b54f9cec6 100644 --- a/arch/sh/kernel/nmi_debug.c +++ b/arch/sh/kernel/nmi_debug.c @@ -52,7 +52,7 @@ static int __init nmi_debug_setup(char *str) register_die_notifier(&nmi_debug_nb); if (*str != '=') - return 0; + return 1; for (p = str + 1; *p; p = sep + 1) { sep = strchr(p, ','); @@ -73,6 +73,6 @@ static int __init nmi_debug_setup(char *str) break; } - return 0; + return 1; } __setup("nmi_debug", nmi_debug_setup); From e7d8e5f49d2e65e75a5822653d22f81a782ca6bb Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 17 Feb 2023 16:06:27 +0100 Subject: [PATCH 172/190] ARM: dts: exynos: fix WM8960 clock name in Itop Elite commit 6c950c20da38debf1ed531e0b972bd8b53d1c11f upstream. The WM8960 Linux driver expects the clock to be named "mclk". Otherwise the clock will be ignored and not prepared/enabled by the driver. Cc: Fixes: 339b2fb36a67 ("ARM: dts: exynos: Add TOPEET itop elite based board") Link: https://lore.kernel.org/r/20230217150627.779764-3-krzysztof.kozlowski@linaro.org Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/exynos4412-itop-elite.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/exynos4412-itop-elite.dts b/arch/arm/boot/dts/exynos4412-itop-elite.dts index 0dedeba89b5f..d2350561b051 100644 --- a/arch/arm/boot/dts/exynos4412-itop-elite.dts +++ b/arch/arm/boot/dts/exynos4412-itop-elite.dts @@ -184,7 +184,7 @@ compatible = "wlf,wm8960"; reg = <0x1a>; clocks = <&pmu_system_controller 0>; - clock-names = "MCLK1"; + clock-names = "mclk"; wlf,shared-lrclk; #sound-dai-cells = <0>; }; From 748f2e0f60b5a81b5eac62fa00897f97ee0c017c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 12 Feb 2023 19:58:18 +0100 Subject: [PATCH 173/190] ARM: dts: s5pv210: correct MIPI CSIS clock name commit 665b9459bb53b8f19bd1541567e1fe9782c83c4b upstream. The Samsung S5P/Exynos MIPI CSIS bindings and Linux driver expect first clock name to be "csis". Otherwise the driver fails to probe. Fixes: 94ad0f6d9278 ("ARM: dts: Add Device tree for s5pv210 SoC") Cc: Link: https://lore.kernel.org/r/20230212185818.43503-2-krzysztof.kozlowski@linaro.org Signed-off-by: Krzysztof Kozlowski Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/s5pv210.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/s5pv210.dtsi b/arch/arm/boot/dts/s5pv210.dtsi index 020a864623ff..781ddfdc5f87 100644 --- a/arch/arm/boot/dts/s5pv210.dtsi +++ b/arch/arm/boot/dts/s5pv210.dtsi @@ -560,7 +560,7 @@ interrupts = <29>; clocks = <&clocks CLK_CSIS>, <&clocks SCLK_CSIS>; - clock-names = "clk_csis", + clock-names = "csis", "sclk_csis"; bus-width = <4>; status = "disabled"; From b847123d55fd3fb0c6168edfb095bc4c0442d81b Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Wed, 12 Apr 2023 17:35:07 +0000 Subject: [PATCH 174/190] drm/panel: otm8009a: Set backlight parent to panel device commit ab4f869fba6119997f7630d600049762a2b014fa upstream. This is the logical place to put the backlight device, and it also fixes a kernel crash if the MIPI host is removed. Previously the backlight device would be unregistered twice when this happened - once as a child of the MIPI host through `mipi_dsi_host_unregister`, and once when the panel device is destroyed. Fixes: 12a6cbd4f3f1 ("drm/panel: otm8009a: Use new backlight API") Signed-off-by: James Cowgill Cc: stable@vger.kernel.org Reviewed-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20230412173450.199592-1-james.cowgill@blaize.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/panel/panel-orisetech-otm8009a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c index 58ccf648b70f..e88a7d95a00c 100644 --- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c +++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c @@ -454,7 +454,7 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi) ctx->panel.funcs = &otm8009a_drm_funcs; ctx->bl_dev = devm_backlight_device_register(dev, dev_name(dev), - dsi->host->dev, ctx, + dev, ctx, &otm8009a_backlight_ops, NULL); if (IS_ERR(ctx->bl_dev)) { From 827ffa27b2f222271ceb7aae8a54700bc3f33c01 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Sun, 9 Apr 2023 09:42:29 -0700 Subject: [PATCH 175/190] HID: wacom: Set a default resolution for older tablets commit 08a46b4190d345544d04ce4fe2e1844b772b8535 upstream. Some older tablets may not report physical maximum for X/Y coordinates. Set a default to prevent undefined resolution. Signed-off-by: Ping Cheng Link: https://lore.kernel.org/r/20230409164229.29777-1-ping.cheng@wacom.com Signed-off-by: Benjamin Tissoires Signed-off-by: Greg Kroah-Hartman --- drivers/hid/wacom_wac.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index bc4d6474d8f5..da6053deb954 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1791,6 +1791,7 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage, int fmax = field->logical_maximum; unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid); int resolution_code = code; + int resolution = hidinput_calc_abs_res(field, resolution_code); if (equivalent_usage == HID_DG_TWIST) { resolution_code = ABS_RZ; @@ -1813,8 +1814,15 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage, switch (type) { case EV_ABS: input_set_abs_params(input, code, fmin, fmax, fuzz, 0); - input_abs_set_res(input, code, - hidinput_calc_abs_res(field, resolution_code)); + + /* older tablet may miss physical usage */ + if ((code == ABS_X || code == ABS_Y) && !resolution) { + resolution = WACOM_INTUOS_RES; + hid_warn(input, + "Wacom usage (%d) missing resolution \n", + code); + } + input_abs_set_res(input, code, resolution); break; case EV_KEY: input_set_capability(input, EV_KEY, code); From 775b00ba23f6f916fe2ac60c5ff7fd0fe4f28d0d Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Mon, 16 Jan 2023 10:00:15 +0800 Subject: [PATCH 176/190] ext4: fix WARNING in mb_find_extent commit fa08a7b61dff8a4df11ff1e84abfc214b487caf7 upstream. Syzbot found the following issue: EXT4-fs: Warning: mounting with data=journal disables delayed allocation, dioread_nolock, O_DIRECT and fast_commit support! EXT4-fs (loop0): orphan cleanup on readonly fs ------------[ cut here ]------------ WARNING: CPU: 1 PID: 5067 at fs/ext4/mballoc.c:1869 mb_find_extent+0x8a1/0xe30 Modules linked in: CPU: 1 PID: 5067 Comm: syz-executor307 Not tainted 6.2.0-rc1-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 RIP: 0010:mb_find_extent+0x8a1/0xe30 fs/ext4/mballoc.c:1869 RSP: 0018:ffffc90003c9e098 EFLAGS: 00010293 RAX: ffffffff82405731 RBX: 0000000000000041 RCX: ffff8880783457c0 RDX: 0000000000000000 RSI: 0000000000000041 RDI: 0000000000000040 RBP: 0000000000000040 R08: ffffffff82405723 R09: ffffed10053c9402 R10: ffffed10053c9402 R11: 1ffff110053c9401 R12: 0000000000000000 R13: ffffc90003c9e538 R14: dffffc0000000000 R15: ffffc90003c9e2cc FS: 0000555556665300(0000) GS:ffff8880b9900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000056312f6796f8 CR3: 0000000022437000 CR4: 00000000003506e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: ext4_mb_complex_scan_group+0x353/0x1100 fs/ext4/mballoc.c:2307 ext4_mb_regular_allocator+0x1533/0x3860 fs/ext4/mballoc.c:2735 ext4_mb_new_blocks+0xddf/0x3db0 fs/ext4/mballoc.c:5605 ext4_ext_map_blocks+0x1868/0x6880 fs/ext4/extents.c:4286 ext4_map_blocks+0xa49/0x1cc0 fs/ext4/inode.c:651 ext4_getblk+0x1b9/0x770 fs/ext4/inode.c:864 ext4_bread+0x2a/0x170 fs/ext4/inode.c:920 ext4_quota_write+0x225/0x570 fs/ext4/super.c:7105 write_blk fs/quota/quota_tree.c:64 [inline] get_free_dqblk+0x34a/0x6d0 fs/quota/quota_tree.c:130 do_insert_tree+0x26b/0x1aa0 fs/quota/quota_tree.c:340 do_insert_tree+0x722/0x1aa0 fs/quota/quota_tree.c:375 do_insert_tree+0x722/0x1aa0 fs/quota/quota_tree.c:375 do_insert_tree+0x722/0x1aa0 fs/quota/quota_tree.c:375 dq_insert_tree fs/quota/quota_tree.c:401 [inline] qtree_write_dquot+0x3b6/0x530 fs/quota/quota_tree.c:420 v2_write_dquot+0x11b/0x190 fs/quota/quota_v2.c:358 dquot_acquire+0x348/0x670 fs/quota/dquot.c:444 ext4_acquire_dquot+0x2dc/0x400 fs/ext4/super.c:6740 dqget+0x999/0xdc0 fs/quota/dquot.c:914 __dquot_initialize+0x3d0/0xcf0 fs/quota/dquot.c:1492 ext4_process_orphan+0x57/0x2d0 fs/ext4/orphan.c:329 ext4_orphan_cleanup+0xb60/0x1340 fs/ext4/orphan.c:474 __ext4_fill_super fs/ext4/super.c:5516 [inline] ext4_fill_super+0x81cd/0x8700 fs/ext4/super.c:5644 get_tree_bdev+0x400/0x620 fs/super.c:1282 vfs_get_tree+0x88/0x270 fs/super.c:1489 do_new_mount+0x289/0xad0 fs/namespace.c:3145 do_mount fs/namespace.c:3488 [inline] __do_sys_mount fs/namespace.c:3697 [inline] __se_sys_mount+0x2d3/0x3c0 fs/namespace.c:3674 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 Add some debug information: mb_find_extent: mb_find_extent block=41, order=0 needed=64 next=0 ex=0/41/1@3735929054 64 64 7 block_bitmap: ff 3f 0c 00 fc 01 00 00 d2 3d 00 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff Acctually, blocks per group is 64, but block bitmap indicate at least has 128 blocks. Now, ext4_validate_block_bitmap() didn't check invalid block's bitmap if set. To resolve above issue, add check like fsck "Padding at end of block bitmap is not set". Cc: stable@kernel.org Reported-by: syzbot+68223fe9f6c95ad43bed@syzkaller.appspotmail.com Signed-off-by: Ye Bin Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230116020015.1506120-1-yebin@huaweicloud.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/balloc.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index f9645de9d04c..9761aeb4b224 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -303,6 +303,22 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, return desc; } +static ext4_fsblk_t ext4_valid_block_bitmap_padding(struct super_block *sb, + ext4_group_t block_group, + struct buffer_head *bh) +{ + ext4_grpblk_t next_zero_bit; + unsigned long bitmap_size = sb->s_blocksize * 8; + unsigned int offset = num_clusters_in_group(sb, block_group); + + if (bitmap_size <= offset) + return 0; + + next_zero_bit = ext4_find_next_zero_bit(bh->b_data, bitmap_size, offset); + + return (next_zero_bit < bitmap_size ? next_zero_bit : 0); +} + /* * Return the block number which was discovered to be invalid, or 0 if * the block bitmap is valid. @@ -395,6 +411,15 @@ static int ext4_validate_block_bitmap(struct super_block *sb, EXT4_GROUP_INFO_BBITMAP_CORRUPT); return -EFSCORRUPTED; } + blk = ext4_valid_block_bitmap_padding(sb, block_group, bh); + if (unlikely(blk != 0)) { + ext4_unlock_group(sb, block_group); + ext4_error(sb, "bg %u: block %llu: padding at end of block bitmap is not set", + block_group, blk); + ext4_mark_group_bitmap_corrupted(sb, block_group, + EXT4_GROUP_INFO_BBITMAP_CORRUPT); + return -EFSCORRUPTED; + } set_buffer_verified(bh); verified: ext4_unlock_group(sb, block_group); From a733c466cedd1013a41fd8908d5810f2c161072f Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Thu, 4 May 2023 12:15:25 +0000 Subject: [PATCH 177/190] ext4: avoid a potential slab-out-of-bounds in ext4_group_desc_csum commit 4f04351888a83e595571de672e0a4a8b74f4fb31 upstream. When modifying the block device while it is mounted by the filesystem, syzbot reported the following: BUG: KASAN: slab-out-of-bounds in crc16+0x206/0x280 lib/crc16.c:58 Read of size 1 at addr ffff888075f5c0a8 by task syz-executor.2/15586 CPU: 1 PID: 15586 Comm: syz-executor.2 Not tainted 6.2.0-rc5-syzkaller-00205-gc96618275234 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/12/2023 Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1b1/0x290 lib/dump_stack.c:106 print_address_description+0x74/0x340 mm/kasan/report.c:306 print_report+0x107/0x1f0 mm/kasan/report.c:417 kasan_report+0xcd/0x100 mm/kasan/report.c:517 crc16+0x206/0x280 lib/crc16.c:58 ext4_group_desc_csum+0x81b/0xb20 fs/ext4/super.c:3187 ext4_group_desc_csum_set+0x195/0x230 fs/ext4/super.c:3210 ext4_mb_clear_bb fs/ext4/mballoc.c:6027 [inline] ext4_free_blocks+0x191a/0x2810 fs/ext4/mballoc.c:6173 ext4_remove_blocks fs/ext4/extents.c:2527 [inline] ext4_ext_rm_leaf fs/ext4/extents.c:2710 [inline] ext4_ext_remove_space+0x24ef/0x46a0 fs/ext4/extents.c:2958 ext4_ext_truncate+0x177/0x220 fs/ext4/extents.c:4416 ext4_truncate+0xa6a/0xea0 fs/ext4/inode.c:4342 ext4_setattr+0x10c8/0x1930 fs/ext4/inode.c:5622 notify_change+0xe50/0x1100 fs/attr.c:482 do_truncate+0x200/0x2f0 fs/open.c:65 handle_truncate fs/namei.c:3216 [inline] do_open fs/namei.c:3561 [inline] path_openat+0x272b/0x2dd0 fs/namei.c:3714 do_filp_open+0x264/0x4f0 fs/namei.c:3741 do_sys_openat2+0x124/0x4e0 fs/open.c:1310 do_sys_open fs/open.c:1326 [inline] __do_sys_creat fs/open.c:1402 [inline] __se_sys_creat fs/open.c:1396 [inline] __x64_sys_creat+0x11f/0x160 fs/open.c:1396 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 RIP: 0033:0x7f72f8a8c0c9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 19 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f72f97e3168 EFLAGS: 00000246 ORIG_RAX: 0000000000000055 RAX: ffffffffffffffda RBX: 00007f72f8bac050 RCX: 00007f72f8a8c0c9 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000020000280 RBP: 00007f72f8ae7ae9 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007ffd165348bf R14: 00007f72f97e3300 R15: 0000000000022000 Replace le16_to_cpu(sbi->s_es->s_desc_size) with sbi->s_desc_size It reduces ext4's compiled text size, and makes the code more efficient (we remove an extra indirect reference and a potential byte swap on big endian systems), and there is no downside. It also avoids the potential KASAN / syzkaller failure, as a bonus. Reported-by: syzbot+fc51227e7100c9294894@syzkaller.appspotmail.com Reported-by: syzbot+8785e41224a3afd04321@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=70d28d11ab14bd7938f3e088365252aa923cff42 Link: https://syzkaller.appspot.com/bug?id=b85721b38583ecc6b5e72ff524c67302abbc30f3 Link: https://lore.kernel.org/all/000000000000ece18705f3b20934@google.com/ Fixes: 717d50e4971b ("Ext4: Uninitialized Block Groups") Cc: stable@vger.kernel.org Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20230504121525.3275886-1-tudor.ambarus@linaro.org Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/super.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e54a5be15636..146e10318243 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2423,11 +2423,9 @@ static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group, crc = crc16(crc, (__u8 *)gdp, offset); offset += sizeof(gdp->bg_checksum); /* skip checksum */ /* for checksum of struct ext4_group_desc do the rest...*/ - if (ext4_has_feature_64bit(sb) && - offset < le16_to_cpu(sbi->s_es->s_desc_size)) + if (ext4_has_feature_64bit(sb) && offset < sbi->s_desc_size) crc = crc16(crc, (__u8 *)gdp + offset, - le16_to_cpu(sbi->s_es->s_desc_size) - - offset); + sbi->s_desc_size - offset); out: return cpu_to_le16(crc); From 37302d4c2724dc92be5f90a3718eafa29834d586 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 5 May 2023 22:20:29 -0400 Subject: [PATCH 178/190] ext4: improve error recovery code paths in __ext4_remount() commit 4c0b4818b1f636bc96359f7817a2d8bab6370162 upstream. If there are failures while changing the mount options in __ext4_remount(), we need to restore the old mount options. This commit fixes two problem. The first is there is a chance that we will free the old quota file names before a potential failure leading to a use-after-free. The second problem addressed in this commit is if there is a failed read/write to read-only transition, if the quota has already been suspended, we need to renable quota handling. Cc: stable@kernel.org Link: https://lore.kernel.org/r/20230506142419.984260-2-tytso@mit.edu Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/super.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 146e10318243..ce5abd25eb99 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -5501,9 +5501,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) } #ifdef CONFIG_QUOTA - /* Release old quota file names */ - for (i = 0; i < EXT4_MAXQUOTAS; i++) - kfree(old_opts.s_qf_names[i]); if (enable_quota) { if (sb_any_quota_suspended(sb)) dquot_resume(sb, -1); @@ -5513,6 +5510,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) goto restore_opts; } } + /* Release old quota file names */ + for (i = 0; i < EXT4_MAXQUOTAS; i++) + kfree(old_opts.s_qf_names[i]); #endif if (!test_opt(sb, BLOCK_VALIDITY) && sbi->system_blks) ext4_release_system_zone(sb); @@ -5529,6 +5529,13 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) return 0; restore_opts: + /* + * If there was a failing r/w to ro transition, we may need to + * re-enable quota + */ + if ((sb->s_flags & SB_RDONLY) && !(old_sb_flags & SB_RDONLY) && + sb_any_quota_suspended(sb)) + dquot_resume(sb, -1); sb->s_flags = old_sb_flags; sbi->s_mount_opt = old_opts.s_mount_opt; sbi->s_mount_opt2 = old_opts.s_mount_opt2; From 3d7b8fbcd2273e2b9f4c6de5ce2f4c0cd3cb1205 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 12 May 2023 15:11:02 -0400 Subject: [PATCH 179/190] ext4: add bounds checking in get_max_inline_xattr_value_size() commit 2220eaf90992c11d888fe771055d4de330385f01 upstream. Normally the extended attributes in the inode body would have been checked when the inode is first opened, but if someone is writing to the block device while the file system is mounted, it's possible for the inode table to get corrupted. Add bounds checking to avoid reading beyond the end of allocated memory if this happens. Reported-by: syzbot+1966db24521e5f6e23f7@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=1966db24521e5f6e23f7 Cc: stable@kernel.org Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inline.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 72387e142e28..980a24b98b17 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -32,6 +32,7 @@ static int get_max_inline_xattr_value_size(struct inode *inode, struct ext4_xattr_ibody_header *header; struct ext4_xattr_entry *entry; struct ext4_inode *raw_inode; + void *end; int free, min_offs; if (!EXT4_INODE_HAS_XATTR_SPACE(inode)) @@ -55,14 +56,23 @@ static int get_max_inline_xattr_value_size(struct inode *inode, raw_inode = ext4_raw_inode(iloc); header = IHDR(inode, raw_inode); entry = IFIRST(header); + end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; /* Compute min_offs. */ - for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { + while (!IS_LAST_ENTRY(entry)) { + void *next = EXT4_XATTR_NEXT(entry); + + if (next >= end) { + EXT4_ERROR_INODE(inode, + "corrupt xattr in inline inode"); + return 0; + } if (!entry->e_value_inum && entry->e_value_size) { size_t offs = le16_to_cpu(entry->e_value_offs); if (offs < min_offs) min_offs = offs; } + entry = next; } free = min_offs - ((void *)entry - (void *)IFIRST(header)) - sizeof(__u32); From c012309abecb6f9e2f628c0dbf7c74d06ef2640a Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 12 May 2023 15:16:27 -0400 Subject: [PATCH 180/190] ext4: bail out of ext4_xattr_ibody_get() fails for any reason commit 2a534e1d0d1591e951f9ece2fb460b2ff92edabd upstream. In ext4_update_inline_data(), if ext4_xattr_ibody_get() fails for any reason, it's best if we just fail as opposed to stumbling on, especially if the failure is EFSCORRUPTED. Cc: stable@kernel.org Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 980a24b98b17..71bb3cfc5933 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -358,7 +358,7 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode, error = ext4_xattr_ibody_get(inode, i.name_index, i.name, value, len); - if (error == -ENODATA) + if (error < 0) goto out; BUFFER_TRACE(is.iloc.bh, "get_write_access"); From ef16d8a1798db1a1604ac44ca1bd73ec6bebf483 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 29 Apr 2023 16:14:46 -0400 Subject: [PATCH 181/190] ext4: remove a BUG_ON in ext4_mb_release_group_pa() commit 463808f237cf73e98a1a45ff7460c2406a150a0b upstream. If a malicious fuzzer overwrites the ext4 superblock while it is mounted such that the s_first_data_block is set to a very large number, the calculation of the block group can underflow, and trigger a BUG_ON check. Change this to be an ext4_warning so that we don't crash the kernel. Cc: stable@kernel.org Link: https://lore.kernel.org/r/20230430154311.579720-3-tytso@mit.edu Reported-by: syzbot+e2efa3efc15a1c9e95c3@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=69b28112e098b070f639efb356393af3ffec4220 Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/mballoc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 4ea4fe92eb8c..70e1121d0a30 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -3893,7 +3893,11 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b, trace_ext4_mb_release_group_pa(sb, pa); BUG_ON(pa->pa_deleted == 0); ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); - BUG_ON(group != e4b->bd_group && pa->pa_len != 0); + if (unlikely(group != e4b->bd_group && pa->pa_len != 0)) { + ext4_warning(sb, "bad group: expected %u, group %u, pa_start %llu", + e4b->bd_group, group, pa->pa_pstart); + return 0; + } mb_free_blocks(pa->pa_inode, e4b, bit, pa->pa_len); atomic_add(pa->pa_len, &EXT4_SB(sb)->s_mb_discarded); trace_ext4_mballoc_discard(sb, NULL, group, bit, pa->pa_len); From f30f3391d089dc91aef91d08f4b04a6c0df2b067 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sun, 30 Apr 2023 03:04:13 -0400 Subject: [PATCH 182/190] ext4: fix invalid free tracking in ext4_xattr_move_to_block() commit b87c7cdf2bed4928b899e1ce91ef0d147017ba45 upstream. In ext4_xattr_move_to_block(), the value of the extended attribute which we need to move to an external block may be allocated by kvmalloc() if the value is stored in an external inode. So at the end of the function the code tried to check if this was the case by testing entry->e_value_inum. However, at this point, the pointer to the xattr entry is no longer valid, because it was removed from the original location where it had been stored. So we could end up calling kvfree() on a pointer which was not allocated by kvmalloc(); or we could also potentially leak memory by not freeing the buffer when it should be freed. Fix this by storing whether it should be freed in a separate variable. Cc: stable@kernel.org Link: https://lore.kernel.org/r/20230430160426.581366-1-tytso@mit.edu Link: https://syzkaller.appspot.com/bug?id=5c2aee8256e30b55ccf57312c16d88417adbd5e1 Link: https://syzkaller.appspot.com/bug?id=41a6b5d4917c0412eb3b3c3c604965bed7d7420b Reported-by: syzbot+64b645917ce07d89bde5@syzkaller.appspotmail.com Reported-by: syzbot+0d042627c4f2ad332195@syzkaller.appspotmail.com Signed-off-by: Theodore Ts'o Signed-off-by: Greg Kroah-Hartman --- fs/ext4/xattr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 1b73a7f8189d..700822c9851a 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -2573,6 +2573,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode, .in_inode = !!entry->e_value_inum, }; struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode); + int needs_kvfree = 0; int error; is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS); @@ -2595,7 +2596,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode, error = -ENOMEM; goto out; } - + needs_kvfree = 1; error = ext4_xattr_inode_get(inode, entry, buffer, value_size); if (error) goto out; @@ -2634,7 +2635,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode, out: kfree(b_entry_name); - if (entry->e_value_inum && buffer) + if (needs_kvfree && buffer) kvfree(buffer); if (is) brelse(is->iloc.bh); From 3271859c2d2709515db4ad7a6cbdd3617da04405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Thu, 11 May 2023 15:32:43 +0300 Subject: [PATCH 183/190] tty: Prevent writing chars during tcsetattr TCSADRAIN/FLUSH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If userspace races tcsetattr() with a write, the drained condition might not be guaranteed by the kernel. There is a race window after checking Tx is empty before tty_set_termios() takes termios_rwsem for write. During that race window, more characters can be queued by a racing writer. Any ongoing transmission might produce garbage during HW's ->set_termios() call. The intent of TCSADRAIN/FLUSH seems to be preventing such a character corruption. If those flags are set, take tty's write lock to stop any writer before performing the lower layer Tx empty check and wait for the pending characters to be sent (if any). The initial wait for all-writers-done must be placed outside of tty's write lock to avoid deadlock which makes it impossible to use tty_wait_until_sent(). The write lock is retried if a racing write is detected. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20230317113318.31327-2-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 094fb49a2d0d6827c86d2e0840873e6db0c491d2) Signed-off-by: Ilpo Järvinen Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 4 ++-- drivers/tty/tty_ioctl.c | 47 +++++++++++++++++++++++++++++------------ include/linux/tty.h | 2 ++ 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index d3e6b6615553..72091b1f5626 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -875,13 +875,13 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, return i; } -static void tty_write_unlock(struct tty_struct *tty) +void tty_write_unlock(struct tty_struct *tty) { mutex_unlock(&tty->atomic_write_lock); wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT); } -static int tty_write_lock(struct tty_struct *tty, int ndelay) +int tty_write_lock(struct tty_struct *tty, int ndelay) { if (!mutex_trylock(&tty->atomic_write_lock)) { if (ndelay) diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index d99fec44036c..095c8780e210 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -397,22 +397,43 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios); - ld = tty_ldisc_ref(tty); + if (opt & (TERMIOS_FLUSH|TERMIOS_WAIT)) { +retry_write_wait: + retval = wait_event_interruptible(tty->write_wait, !tty_chars_in_buffer(tty)); + if (retval < 0) + return retval; - if (ld != NULL) { - if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) - ld->ops->flush_buffer(tty); - tty_ldisc_deref(ld); + if (tty_write_lock(tty, 0) < 0) + goto retry_write_wait; + + /* Racing writer? */ + if (tty_chars_in_buffer(tty)) { + tty_write_unlock(tty); + goto retry_write_wait; + } + + ld = tty_ldisc_ref(tty); + if (ld != NULL) { + if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) + ld->ops->flush_buffer(tty); + tty_ldisc_deref(ld); + } + + if ((opt & TERMIOS_WAIT) && tty->ops->wait_until_sent) { + tty->ops->wait_until_sent(tty, 0); + if (signal_pending(current)) { + tty_write_unlock(tty); + return -ERESTARTSYS; + } + } + + tty_set_termios(tty, &tmp_termios); + + tty_write_unlock(tty); + } else { + tty_set_termios(tty, &tmp_termios); } - if (opt & TERMIOS_WAIT) { - tty_wait_until_sent(tty, 0); - if (signal_pending(current)) - return -ERESTARTSYS; - } - - tty_set_termios(tty, &tmp_termios); - /* FIXME: Arguably if tmp_termios == tty->termios AND the actual requested termios was not tmp_termios then we may want to return an error as no user requested change has diff --git a/include/linux/tty.h b/include/linux/tty.h index d808ab9c9aff..487ce56b88e8 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -480,6 +480,8 @@ extern void __stop_tty(struct tty_struct *tty); extern void stop_tty(struct tty_struct *tty); extern void __start_tty(struct tty_struct *tty); extern void start_tty(struct tty_struct *tty); +void tty_write_unlock(struct tty_struct *tty); +int tty_write_lock(struct tty_struct *tty, int ndelay); extern int tty_register_driver(struct tty_driver *driver); extern int tty_unregister_driver(struct tty_driver *driver); extern struct device *tty_register_device(struct tty_driver *driver, From 3f9cab5766daa1c1e5b389cd12b6e717ce95852f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Thu, 11 May 2023 15:32:44 +0300 Subject: [PATCH 184/190] serial: 8250: Fix serial8250_tx_empty() race with DMA Tx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's a potential race before THRE/TEMT deasserts when DMA Tx is starting up (or the next batch of continuous Tx is being submitted). This can lead to misdetecting Tx empty condition. It is entirely normal for THRE/TEMT to be set for some time after the DMA Tx had been setup in serial8250_tx_dma(). As Tx side is definitely not empty at that point, it seems incorrect for serial8250_tx_empty() claim Tx is empty. Fix the race by also checking in serial8250_tx_empty() whether there's DMA Tx active. Note: This fix only addresses in-kernel race mainly to make using TCSADRAIN/FLUSH robust. Userspace can still cause other races but they seem userspace concurrency control problems. Fixes: 9ee4b83e51f74 ("serial: 8250: Add support for dmaengine") Cc: stable@vger.kernel.org Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20230317113318.31327-3-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 146a37e05d620cef4ad430e5d1c9c077fe6fa76f) Signed-off-by: Ilpo Järvinen Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250.h | 12 ++++++++++++ drivers/tty/serial/8250/8250_port.c | 12 +++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index ebfb0bd5bef5..8c8aa3b9c298 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -217,6 +217,13 @@ extern int serial8250_rx_dma(struct uart_8250_port *); extern void serial8250_rx_dma_flush(struct uart_8250_port *); extern int serial8250_request_dma(struct uart_8250_port *); extern void serial8250_release_dma(struct uart_8250_port *); + +static inline bool serial8250_tx_dma_running(struct uart_8250_port *p) +{ + struct uart_8250_dma *dma = p->dma; + + return dma && dma->tx_running; +} #else static inline int serial8250_tx_dma(struct uart_8250_port *p) { @@ -232,6 +239,11 @@ static inline int serial8250_request_dma(struct uart_8250_port *p) return -1; } static inline void serial8250_release_dma(struct uart_8250_port *p) { } + +static inline bool serial8250_tx_dma_running(struct uart_8250_port *p) +{ + return false; +} #endif static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 81574efff3c1..cba4888bc482 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1967,19 +1967,25 @@ static int serial8250_tx_threshold_handle_irq(struct uart_port *port) static unsigned int serial8250_tx_empty(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); + unsigned int result = 0; unsigned long flags; unsigned int lsr; serial8250_rpm_get(up); spin_lock_irqsave(&port->lock, flags); - lsr = serial_port_in(port, UART_LSR); - up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + if (!serial8250_tx_dma_running(up)) { + lsr = serial_port_in(port, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + + if ((lsr & BOTH_EMPTY) == BOTH_EMPTY) + result = TIOCSER_TEMT; + } spin_unlock_irqrestore(&port->lock, flags); serial8250_rpm_put(up); - return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; + return result; } unsigned int serial8250_do_get_mctrl(struct uart_port *port) From cef22acbe3452efb14d08639b579ffa1b596729c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=B6hmwalder?= Date: Wed, 3 May 2023 14:19:37 +0200 Subject: [PATCH 185/190] drbd: correctly submit flush bio on barrier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 3899d94e3831ee07ea6821c032dc297aec80586a upstream. When we receive a flush command (or "barrier" in DRBD), we currently use a REQ_OP_FLUSH with the REQ_PREFLUSH flag set. The correct way to submit a flush bio is by using a REQ_OP_WRITE without any data, and set the REQ_PREFLUSH flag. Since commit b4a6bb3a67aa ("block: add a sanity check for non-write flush/fua bios"), this triggers a warning in the block layer, but this has been broken for quite some time before that. So use the correct set of flags to actually make the flush happen. Cc: Christoph Hellwig Cc: stable@vger.kernel.org Fixes: f9ff0da56437 ("drbd: allow parallel flushes for multi-volume resources") Reported-by: Thomas Voegtle Signed-off-by: Christoph Böhmwalder Reviewed-by: Christoph Hellwig Link: https://lore.kernel.org/r/20230503121937.17232-1-christoph.boehmwalder@linbit.com Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/block/drbd/drbd_receiver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index cbb6ef719978..d1d6a7af7e78 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1310,7 +1310,7 @@ static void submit_one_flush(struct drbd_device *device, struct issue_flush_cont bio_set_dev(bio, device->ldev->backing_bdev); bio->bi_private = octx; bio->bi_end_io = one_flush_endio; - bio->bi_opf = REQ_OP_FLUSH | REQ_PREFLUSH; + bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; device->flush_jif = jiffies; set_bit(FLUSH_PENDING, &device->flags); From 9f9899657a40901f0e6195814fa098d4b602a7df Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 9 May 2023 14:55:09 +0200 Subject: [PATCH 186/190] PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep errors commit 085a9f43433f30cbe8a1ade62d9d7827c3217f4d upstream. Use down_read_nested() and down_write_nested() when taking the ctrl->reset_lock rw-sem, passing the number of PCIe hotplug controllers in the path to the PCI root bus as lock subclass parameter. This fixes the following false-positive lockdep report when unplugging a Lenovo X1C8 from a Lenovo 2nd gen TB3 dock: pcieport 0000:06:01.0: pciehp: Slot(1): Link Down pcieport 0000:06:01.0: pciehp: Slot(1): Card not present ============================================ WARNING: possible recursive locking detected 5.16.0-rc2+ #621 Not tainted -------------------------------------------- irq/124-pciehp/86 is trying to acquire lock: ffff8e5ac4299ef8 (&ctrl->reset_lock){.+.+}-{3:3}, at: pciehp_check_presence+0x23/0x80 but task is already holding lock: ffff8e5ac4298af8 (&ctrl->reset_lock){.+.+}-{3:3}, at: pciehp_ist+0xf3/0x180 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&ctrl->reset_lock); lock(&ctrl->reset_lock); *** DEADLOCK *** May be due to missing lock nesting notation 3 locks held by irq/124-pciehp/86: #0: ffff8e5ac4298af8 (&ctrl->reset_lock){.+.+}-{3:3}, at: pciehp_ist+0xf3/0x180 #1: ffffffffa3b024e8 (pci_rescan_remove_lock){+.+.}-{3:3}, at: pciehp_unconfigure_device+0x31/0x110 #2: ffff8e5ac1ee2248 (&dev->mutex){....}-{3:3}, at: device_release_driver+0x1c/0x40 stack backtrace: CPU: 4 PID: 86 Comm: irq/124-pciehp Not tainted 5.16.0-rc2+ #621 Hardware name: LENOVO 20U90SIT19/20U90SIT19, BIOS N2WET30W (1.20 ) 08/26/2021 Call Trace: dump_stack_lvl+0x59/0x73 __lock_acquire.cold+0xc5/0x2c6 lock_acquire+0xb5/0x2b0 down_read+0x3e/0x50 pciehp_check_presence+0x23/0x80 pciehp_runtime_resume+0x5c/0xa0 device_for_each_child+0x45/0x70 pcie_port_device_runtime_resume+0x20/0x30 pci_pm_runtime_resume+0xa7/0xc0 __rpm_callback+0x41/0x110 rpm_callback+0x59/0x70 rpm_resume+0x512/0x7b0 __pm_runtime_resume+0x4a/0x90 __device_release_driver+0x28/0x240 device_release_driver+0x26/0x40 pci_stop_bus_device+0x68/0x90 pci_stop_bus_device+0x2c/0x90 pci_stop_and_remove_bus_device+0xe/0x20 pciehp_unconfigure_device+0x6c/0x110 pciehp_disable_slot+0x5b/0xe0 pciehp_handle_presence_or_link_change+0xc3/0x2f0 pciehp_ist+0x179/0x180 This lockdep warning is triggered because with Thunderbolt, hotplug ports are nested. When removing multiple devices in a daisy-chain, each hotplug port's reset_lock may be acquired recursively. It's never the same lock, so the lockdep splat is a false positive. Because locks at the same hierarchy level are never acquired recursively, a per-level lockdep class is sufficient to fix the lockdep warning. The choice to use one lockdep subclass per pcie-hotplug controller in the path to the root-bus was made to conserve class keys because their number is limited and the complexity grows quadratically with number of keys according to Documentation/locking/lockdep-design.rst. Link: https://lore.kernel.org/linux-pci/20190402021933.GA2966@mit.edu/ Link: https://lore.kernel.org/linux-pci/de684a28-9038-8fc6-27ca-3f6f2f6400d7@redhat.com/ Link: https://lore.kernel.org/r/20211217141709.379663-1-hdegoede@redhat.com Link: https://bugzilla.kernel.org/show_bug.cgi?id=208855 Reported-by: "Theodore Ts'o" Signed-off-by: Hans de Goede Signed-off-by: Bjorn Helgaas Reviewed-by: Lukas Wunner Cc: stable@vger.kernel.org [lukas: backport to v4.19-stable] Signed-off-by: Lukas Wunner Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp.h | 3 +++ drivers/pci/hotplug/pciehp_core.c | 2 +- drivers/pci/hotplug/pciehp_hpc.c | 19 +++++++++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index ef6071807072..522719ca1c2b 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -84,6 +84,8 @@ struct slot { * @reset_lock: prevents access to the Data Link Layer Link Active bit in the * Link Status register and to the Presence Detect State bit in the Slot * Status register during a slot reset which may cause them to flap + * @depth: Number of additional hotplug ports in the path to the root bus, + * used as lock subclass for @reset_lock * @slot: pointer to the controller's slot structure * @queue: wait queue to wake up on reception of a Command Completed event, * used for synchronous writes to the Slot Control register @@ -115,6 +117,7 @@ struct controller { struct mutex ctrl_lock; struct pcie_device *pcie; struct rw_semaphore reset_lock; + unsigned int depth; struct slot *slot; wait_queue_head_t queue; u32 slot_cap; diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 518c46f8e63b..5ebfff9356c7 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -215,7 +215,7 @@ static void pciehp_check_presence(struct controller *ctrl) struct slot *slot = ctrl->slot; u8 occupied; - down_read(&ctrl->reset_lock); + down_read_nested(&ctrl->reset_lock, ctrl->depth); mutex_lock(&slot->lock); pciehp_get_adapter_status(slot, &occupied); diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 2795445233b3..7392b26e9f15 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -674,7 +674,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) * Disable requests have higher priority than Presence Detect Changed * or Data Link Layer State Changed events. */ - down_read(&ctrl->reset_lock); + down_read_nested(&ctrl->reset_lock, ctrl->depth); if (events & DISABLE_SLOT) pciehp_handle_disable_request(slot); else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC)) @@ -785,7 +785,7 @@ int pciehp_reset_slot(struct slot *slot, int probe) if (probe) return 0; - down_write(&ctrl->reset_lock); + down_write_nested(&ctrl->reset_lock, ctrl->depth); if (!ATTN_BUTTN(ctrl)) { ctrl_mask |= PCI_EXP_SLTCTL_PDCE; @@ -872,6 +872,20 @@ static inline void dbg_ctrl(struct controller *ctrl) #define FLAG(x, y) (((x) & (y)) ? '+' : '-') +static inline int pcie_hotplug_depth(struct pci_dev *dev) +{ + struct pci_bus *bus = dev->bus; + int depth = 0; + + while (bus->parent) { + bus = bus->parent; + if (bus->self && bus->self->is_hotplug_bridge) + depth++; + } + + return depth; +} + struct controller *pcie_init(struct pcie_device *dev) { struct controller *ctrl; @@ -884,6 +898,7 @@ struct controller *pcie_init(struct pcie_device *dev) goto abort; ctrl->pcie = dev; + ctrl->depth = pcie_hotplug_depth(dev->port); pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap); if (pdev->hotplug_user_indicators) From 2a226e8ca95107cd434d967ecfd83409e26a730e Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Tue, 9 May 2023 14:55:19 +0200 Subject: [PATCH 187/190] PCI: pciehp: Fix AB-BA deadlock between reset_lock and device_lock commit f5eff5591b8f9c5effd25c92c758a127765f74c1 upstream. In 2013, commits 2e35afaefe64 ("PCI: pciehp: Add reset_slot() method") 608c388122c7 ("PCI: Add slot reset option to pci_dev_reset()") amended PCIe hotplug to mask Presence Detect Changed events during a Secondary Bus Reset. The reset thus no longer causes gratuitous slot bringdown and bringup. However the commits neglected to serialize reset with code paths reading slot registers. For instance, a slot bringup due to an earlier hotplug event may see the Presence Detect State bit cleared during a concurrent Secondary Bus Reset. In 2018, commit 5b3f7b7d062b ("PCI: pciehp: Avoid slot access during reset") retrofitted the missing locking. It introduced a reset_lock which serializes a Secondary Bus Reset with other parts of pciehp. Unfortunately the locking turns out to be overzealous: reset_lock is held for the entire enumeration and de-enumeration of hotplugged devices, including driver binding and unbinding. Driver binding and unbinding acquires device_lock while the reset_lock of the ancestral hotplug port is held. A concurrent Secondary Bus Reset acquires the ancestral reset_lock while already holding the device_lock. The asymmetric locking order in the two code paths can lead to AB-BA deadlocks. Michael Haeuptle reports such deadlocks on simultaneous hot-removal and vfio release (the latter implies a Secondary Bus Reset): pciehp_ist() # down_read(reset_lock) pciehp_handle_presence_or_link_change() pciehp_disable_slot() __pciehp_disable_slot() remove_board() pciehp_unconfigure_device() pci_stop_and_remove_bus_device() pci_stop_bus_device() pci_stop_dev() device_release_driver() device_release_driver_internal() __device_driver_lock() # device_lock() SYS_munmap() vfio_device_fops_release() vfio_device_group_close() vfio_device_close() vfio_device_last_close() vfio_pci_core_close_device() vfio_pci_core_disable() # device_lock() __pci_reset_function_locked() pci_reset_bus_function() pci_dev_reset_slot_function() pci_reset_hotplug_slot() pciehp_reset_slot() # down_write(reset_lock) Ian May reports the same deadlock on simultaneous hot-removal and an AER-induced Secondary Bus Reset: aer_recover_work_func() pcie_do_recovery() aer_root_reset() pci_bus_error_reset() pci_slot_reset() pci_slot_lock() # device_lock() pci_reset_hotplug_slot() pciehp_reset_slot() # down_write(reset_lock) Fix by releasing the reset_lock during driver binding and unbinding, thereby splitting and shrinking the critical section. Driver binding and unbinding is protected by the device_lock() and thus serialized with a Secondary Bus Reset. There's no need to additionally protect it with the reset_lock. However, pciehp does not bind and unbind devices directly, but rather invokes PCI core functions which also perform certain enumeration and de-enumeration steps. The reset_lock's purpose is to protect slot registers, not enumeration and de-enumeration of hotplugged devices. That would arguably be the job of the PCI core, not the PCIe hotplug driver. After all, an AER-induced Secondary Bus Reset may as well happen during boot-time enumeration of the PCI hierarchy and there's no locking to prevent that either. Exempting *de-enumeration* from the reset_lock is relatively harmless: A concurrent Secondary Bus Reset may foil config space accesses such as PME interrupt disablement. But if the device is physically gone, those accesses are pointless anyway. If the device is physically present and only logically removed through an Attention Button press or the sysfs "power" attribute, PME interrupts as well as DMA cannot come through because pciehp_unconfigure_device() disables INTx and Bus Master bits. That's still protected by the reset_lock in the present commit. Exempting *enumeration* from the reset_lock also has limited impact: The exempted call to pci_bus_add_device() may perform device accesses through pcibios_bus_add_device() and pci_fixup_device() which are now no longer protected from a concurrent Secondary Bus Reset. Otherwise there should be no impact. In essence, the present commit seeks to fix the AB-BA deadlocks while still retaining a best-effort reset protection for enumeration and de-enumeration of hotplugged devices -- until a general solution is implemented in the PCI core. Link: https://lore.kernel.org/linux-pci/CS1PR8401MB0728FC6FDAB8A35C22BD90EC95F10@CS1PR8401MB0728.NAMPRD84.PROD.OUTLOOK.COM Link: https://lore.kernel.org/linux-pci/20200615143250.438252-1-ian.may@canonical.com Link: https://lore.kernel.org/linux-pci/ce878dab-c0c4-5bd0-a725-9805a075682d@amd.com Link: https://lore.kernel.org/linux-pci/ed831249-384a-6d35-0831-70af191e9bce@huawei.com Link: https://bugzilla.kernel.org/show_bug.cgi?id=215590 Fixes: 5b3f7b7d062b ("PCI: pciehp: Avoid slot access during reset") Link: https://lore.kernel.org/r/fef2b2e9edf245c049a8c5b94743c0f74ff5008a.1681191902.git.lukas@wunner.de Reported-by: Michael Haeuptle Reported-by: Ian May Reported-by: Andrey Grodzovsky Reported-by: Rahul Kumar Reported-by: Jialin Zhang Tested-by: Anatoli Antonovitch Signed-off-by: Lukas Wunner Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org # v4.19+ Cc: Dan Stein Cc: Ashok Raj Cc: Alex Michon Cc: Xiongfeng Wang Cc: Alex Williamson Cc: Mika Westerberg Cc: Sathyanarayanan Kuppuswamy Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/pciehp_pci.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 5c58c22e0c08..a32023afa25b 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -55,7 +55,14 @@ int pciehp_configure_device(struct slot *p_slot) pci_assign_unassigned_bridge_resources(bridge); pcie_bus_configure_settings(parent); + + /* + * Release reset_lock during driver binding + * to avoid AB-BA deadlock with device_lock. + */ + up_read(&ctrl->reset_lock); pci_bus_add_devices(parent); + down_read_nested(&ctrl->reset_lock, ctrl->depth); out: pci_unlock_rescan_remove(); @@ -91,7 +98,15 @@ void pciehp_unconfigure_device(struct slot *p_slot) pci_walk_bus(dev->subordinate, pci_dev_set_disconnected, NULL); } + + /* + * Release reset_lock during driver unbinding + * to avoid AB-BA deadlock with device_lock. + */ + up_read(&ctrl->reset_lock); pci_stop_and_remove_bus_device(dev); + down_read_nested(&ctrl->reset_lock, ctrl->depth); + /* * Ensure that no new Requests will be generated from * the device. From 09b28fe9ff2fce03efc7d71dc79b58a49b01d0e9 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Sun, 14 May 2023 13:41:40 +0900 Subject: [PATCH 188/190] printk: declare printk_deferred_{enter,safe}() in include/linux/printk.h commit 85e3e7fbbb720b9897fba9a99659e31cbd1c082e upstream. [This patch implements subset of original commit 85e3e7fbbb72 ("printk: remove NMI tracking") where commit 1007843a9190 ("mm/page_alloc: fix potential deadlock on zonelist_update_seq seqlock") depends on, for commit 3d36424b3b58 ("mm/page_alloc: fix race condition between build_all_zonelists and page allocation") was backported to stable.] All NMI contexts are handled the same as the safe context: store the message and defer printing. There is no need to have special NMI context tracking for this. Using in_nmi() is enough. There are several parts of the kernel that are manually calling into the printk NMI context tracking in order to cause general printk deferred printing: arch/arm/kernel/smp.c arch/powerpc/kexec/crash.c kernel/trace/trace.c For arm/kernel/smp.c and powerpc/kexec/crash.c, provide a new function pair printk_deferred_enter/exit that explicitly achieves the same objective. For ftrace, remove the printk context manipulation completely. It was added in commit 03fc7f9c99c1 ("printk/nmi: Prevent deadlock when accessing the main log buffer in NMI"). The purpose was to enforce storing messages directly into the ring buffer even in NMI context. It really should have only modified the behavior in NMI context. There is no need for a special behavior any longer. All messages are always stored directly now. The console deferring is handled transparently in vprintk(). Signed-off-by: John Ogness [pmladek@suse.com: Remove special handling in ftrace.c completely. Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20210715193359.25946-5-john.ogness@linutronix.de [penguin-kernel: Copy only printk_deferred_{enter,safe}() definition ] Signed-off-by: Tetsuo Handa Signed-off-by: Greg Kroah-Hartman --- include/linux/printk.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/linux/printk.h b/include/linux/printk.h index 6dd867e39365..f4d7e643f010 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -525,4 +525,23 @@ static inline void print_hex_dump_debug(const char *prefix_str, int prefix_type, } #endif +#ifdef CONFIG_PRINTK +extern void __printk_safe_enter(void); +extern void __printk_safe_exit(void); +/* + * The printk_deferred_enter/exit macros are available only as a hack for + * some code paths that need to defer all printk console printing. Interrupts + * must be disabled for the deferred duration. + */ +#define printk_deferred_enter __printk_safe_enter +#define printk_deferred_exit __printk_safe_exit +#else +static inline void printk_deferred_enter(void) +{ +} +static inline void printk_deferred_exit(void) +{ +} +#endif + #endif From 90c4e02baef3eed8640c9375bd0e75bddd0ec08d Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Tue, 4 Apr 2023 23:31:58 +0900 Subject: [PATCH 189/190] mm/page_alloc: fix potential deadlock on zonelist_update_seq seqlock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 1007843a91909a4995ee78a538f62d8665705b66 upstream. syzbot is reporting circular locking dependency which involves zonelist_update_seq seqlock [1], for this lock is checked by memory allocation requests which do not need to be retried. One deadlock scenario is kmalloc(GFP_ATOMIC) from an interrupt handler. CPU0 ---- __build_all_zonelists() { write_seqlock(&zonelist_update_seq); // makes zonelist_update_seq.seqcount odd // e.g. timer interrupt handler runs at this moment some_timer_func() { kmalloc(GFP_ATOMIC) { __alloc_pages_slowpath() { read_seqbegin(&zonelist_update_seq) { // spins forever because zonelist_update_seq.seqcount is odd } } } } // e.g. timer interrupt handler finishes write_sequnlock(&zonelist_update_seq); // makes zonelist_update_seq.seqcount even } This deadlock scenario can be easily eliminated by not calling read_seqbegin(&zonelist_update_seq) from !__GFP_DIRECT_RECLAIM allocation requests, for retry is applicable to only __GFP_DIRECT_RECLAIM allocation requests. But Michal Hocko does not know whether we should go with this approach. Another deadlock scenario which syzbot is reporting is a race between kmalloc(GFP_ATOMIC) from tty_insert_flip_string_and_push_buffer() with port->lock held and printk() from __build_all_zonelists() with zonelist_update_seq held. CPU0 CPU1 ---- ---- pty_write() { tty_insert_flip_string_and_push_buffer() { __build_all_zonelists() { write_seqlock(&zonelist_update_seq); build_zonelists() { printk() { vprintk() { vprintk_default() { vprintk_emit() { console_unlock() { console_flush_all() { console_emit_next_record() { con->write() = serial8250_console_write() { spin_lock_irqsave(&port->lock, flags); tty_insert_flip_string() { tty_insert_flip_string_fixed_flag() { __tty_buffer_request_room() { tty_buffer_alloc() { kmalloc(GFP_ATOMIC | __GFP_NOWARN) { __alloc_pages_slowpath() { zonelist_iter_begin() { read_seqbegin(&zonelist_update_seq); // spins forever because zonelist_update_seq.seqcount is odd spin_lock_irqsave(&port->lock, flags); // spins forever because port->lock is held } } } } } } } } spin_unlock_irqrestore(&port->lock, flags); // message is printed to console spin_unlock_irqrestore(&port->lock, flags); } } } } } } } } } write_sequnlock(&zonelist_update_seq); } } } This deadlock scenario can be eliminated by preventing interrupt context from calling kmalloc(GFP_ATOMIC) and preventing printk() from calling console_flush_all() while zonelist_update_seq.seqcount is odd. Since Petr Mladek thinks that __build_all_zonelists() can become a candidate for deferring printk() [2], let's address this problem by disabling local interrupts in order to avoid kmalloc(GFP_ATOMIC) and disabling synchronous printk() in order to avoid console_flush_all() . As a side effect of minimizing duration of zonelist_update_seq.seqcount being odd by disabling synchronous printk(), latency at read_seqbegin(&zonelist_update_seq) for both !__GFP_DIRECT_RECLAIM and __GFP_DIRECT_RECLAIM allocation requests will be reduced. Although, from lockdep perspective, not calling read_seqbegin(&zonelist_update_seq) (i.e. do not record unnecessary locking dependency) from interrupt context is still preferable, even if we don't allow calling kmalloc(GFP_ATOMIC) inside write_seqlock(&zonelist_update_seq)/write_sequnlock(&zonelist_update_seq) section... Link: https://lkml.kernel.org/r/8796b95c-3da3-5885-fddd-6ef55f30e4d3@I-love.SAKURA.ne.jp Fixes: 3d36424b3b58 ("mm/page_alloc: fix race condition between build_all_zonelists and page allocation") Link: https://lkml.kernel.org/r/ZCrs+1cDqPWTDFNM@alley [2] Reported-by: syzbot Link: https://syzkaller.appspot.com/bug?extid=223c7461c58c58a4cb10 [1] Signed-off-by: Tetsuo Handa Acked-by: Michal Hocko Acked-by: Mel Gorman Cc: Petr Mladek Cc: David Hildenbrand Cc: Ilpo Järvinen Cc: John Ogness Cc: Patrick Daly Cc: Sergey Senozhatsky Cc: Steven Rostedt Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- mm/page_alloc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 1cffd4e1fd8f..4553cc848abc 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5425,7 +5425,21 @@ static void __build_all_zonelists(void *data) int nid; int __maybe_unused cpu; pg_data_t *self = data; + unsigned long flags; + /* + * Explicitly disable this CPU's interrupts before taking seqlock + * to prevent any IRQ handler from calling into the page allocator + * (e.g. GFP_ATOMIC) that could hit zonelist_iter_begin and livelock. + */ + local_irq_save(flags); + /* + * Explicitly disable this CPU's synchronous printk() before taking + * seqlock to prevent any printk() from trying to hold port->lock, for + * tty_insert_flip_string_and_push_buffer() on other CPU might be + * calling kmalloc(GFP_ATOMIC | __GFP_NOWARN) with port->lock held. + */ + printk_deferred_enter(); write_seqlock(&zonelist_update_seq); #ifdef CONFIG_NUMA @@ -5460,6 +5474,8 @@ static void __build_all_zonelists(void *data) } write_sequnlock(&zonelist_update_seq); + printk_deferred_exit(); + local_irq_restore(flags); } static noinline void __init From 3f57fb8b1bd06b277556601133823bec370d723f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 17 May 2023 11:13:28 +0200 Subject: [PATCH 190/190] Linux 4.19.283 Link: https://lore.kernel.org/r/20230515161707.203549282@linuxfoundation.org Tested-by: Chris Paterson (CIP) Tested-by: Shuah Khan Tested-by: Sudip Mukherjee Tested-by: Guenter Roeck Tested-by: Jon Hunter Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6ed7f3fe3a4e..71416fde7348 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 4 PATCHLEVEL = 19 -SUBLEVEL = 282 +SUBLEVEL = 283 EXTRAVERSION = NAME = "People's Front"