From: Sasha Levin Date: Fri, 3 May 2024 16:37:04 +0000 (-0400) Subject: Fixes for 6.8 X-Git-Tag: v4.19.314~134 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0240c2dd91afd1e1df2de2f1dc71da8c173dd318;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.8 Signed-off-by: Sasha Levin --- diff --git a/queue-6.8/bluetooth-qca-fix-invalid-device-address-check.patch b/queue-6.8/bluetooth-qca-fix-invalid-device-address-check.patch new file mode 100644 index 00000000000..9c0d8e02e78 --- /dev/null +++ b/queue-6.8/bluetooth-qca-fix-invalid-device-address-check.patch @@ -0,0 +1,123 @@ +From 2179ab410adb7c29e2feed5d1c15138e23b5e76e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Apr 2024 11:15:09 +0200 +Subject: Bluetooth: qca: fix invalid device address check + +From: Johan Hovold + +[ Upstream commit 32868e126c78876a8a5ddfcb6ac8cb2fffcf4d27 ] + +Qualcomm Bluetooth controllers may not have been provisioned with a +valid device address and instead end up using the default address +00:00:00:00:5a:ad. + +This was previously believed to be due to lack of persistent storage for +the address but it may also be due to integrators opting to not use the +on-chip OTP memory and instead store the address elsewhere (e.g. in +storage managed by secure world firmware). + +According to Qualcomm, at least WCN6750, WCN6855 and WCN7850 have +on-chip OTP storage for the address. + +As the device type alone cannot be used to determine when the address is +valid, instead read back the address during setup() and only set the +HCI_QUIRK_USE_BDADDR_PROPERTY flag when needed. + +This specifically makes sure that controllers that have been provisioned +with an address do not start as unconfigured. + +Reported-by: Janaki Ramaiah Thota +Link: https://lore.kernel.org/r/124a7d54-5a18-4be7-9a76-a12017f6cce5@quicinc.com/ +Fixes: 5971752de44c ("Bluetooth: hci_qca: Set HCI_QUIRK_USE_BDADDR_PROPERTY for wcn3990") +Fixes: e668eb1e1578 ("Bluetooth: hci_core: Don't stop BT if the BD address missing in dts") +Fixes: 6945795bc81a ("Bluetooth: fix use-bdaddr-property quirk") +Cc: stable@vger.kernel.org # 6.5 +Cc: Matthias Kaehlcke +Signed-off-by: Johan Hovold +Reported-by: Janaki Ramaiah Thota +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btqca.c | 38 +++++++++++++++++++++++++++++++++++++ + drivers/bluetooth/hci_qca.c | 2 -- + 2 files changed, 38 insertions(+), 2 deletions(-) + +diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c +index 19cfc342fc7bb..216826c31ee34 100644 +--- a/drivers/bluetooth/btqca.c ++++ b/drivers/bluetooth/btqca.c +@@ -15,6 +15,8 @@ + + #define VERSION "0.1" + ++#define QCA_BDADDR_DEFAULT (&(bdaddr_t) {{ 0xad, 0x5a, 0x00, 0x00, 0x00, 0x00 }}) ++ + int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver, + enum qca_btsoc_type soc_type) + { +@@ -612,6 +614,38 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) + } + EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome); + ++static int qca_check_bdaddr(struct hci_dev *hdev) ++{ ++ struct hci_rp_read_bd_addr *bda; ++ struct sk_buff *skb; ++ int err; ++ ++ if (bacmp(&hdev->public_addr, BDADDR_ANY)) ++ return 0; ++ ++ skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL, ++ HCI_INIT_TIMEOUT); ++ if (IS_ERR(skb)) { ++ err = PTR_ERR(skb); ++ bt_dev_err(hdev, "Failed to read device address (%d)", err); ++ return err; ++ } ++ ++ if (skb->len != sizeof(*bda)) { ++ bt_dev_err(hdev, "Device address length mismatch"); ++ kfree_skb(skb); ++ return -EIO; ++ } ++ ++ bda = (struct hci_rp_read_bd_addr *)skb->data; ++ if (!bacmp(&bda->bdaddr, QCA_BDADDR_DEFAULT)) ++ set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); ++ ++ kfree_skb(skb); ++ ++ return 0; ++} ++ + static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size, + struct qca_btsoc_version ver, u8 rom_ver, u16 bid) + { +@@ -818,6 +852,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + break; + } + ++ err = qca_check_bdaddr(hdev); ++ if (err) ++ return err; ++ + bt_dev_info(hdev, "QCA setup on UART is completed"); + + return 0; +diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c +index ce5c2aa743b08..0c9c9ee56592d 100644 +--- a/drivers/bluetooth/hci_qca.c ++++ b/drivers/bluetooth/hci_qca.c +@@ -1908,8 +1908,6 @@ static int qca_setup(struct hci_uart *hu) + case QCA_WCN6750: + case QCA_WCN6855: + case QCA_WCN7850: +- set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); +- + qcadev = serdev_device_get_drvdata(hu->serdev); + if (qcadev->bdaddr_property_broken) + set_bit(HCI_QUIRK_BDADDR_PROPERTY_BROKEN, &hdev->quirks); +-- +2.43.0 + diff --git a/queue-6.8/nfs-expose-proc-net-sunrpc-nfs-in-net-namespaces.patch b/queue-6.8/nfs-expose-proc-net-sunrpc-nfs-in-net-namespaces.patch new file mode 100644 index 00000000000..a45f6210eb7 --- /dev/null +++ b/queue-6.8/nfs-expose-proc-net-sunrpc-nfs-in-net-namespaces.patch @@ -0,0 +1,71 @@ +From 5d60423a35702fbe6056f8be6da2eae5812b4c71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 14:57:31 -0500 +Subject: nfs: expose /proc/net/sunrpc/nfs in net namespaces + +From: Josef Bacik + +[ Upstream commit d47151b79e3220e72ae323b8b8e9d6da20dc884e ] + +We're using nfs mounts inside of containers in production and noticed +that the nfs stats are not exposed in /proc. This is a problem for us +as we use these stats for monitoring, and have to do this awkward bind +mount from the main host into the container in order to get to these +states. + +Add the rpc_proc_register call to the pernet operations entry and exit +points so these stats can be exposed inside of network namespaces. + +Signed-off-by: Josef Bacik +Signed-off-by: Trond Myklebust +Stable-dep-of: 24457f1be29f ("nfs: Handle error of rpc_proc_register() in nfs_net_init().") +Signed-off-by: Sasha Levin +--- + fs/nfs/inode.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index ebb8d60e11526..e11e9c34aa569 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -2427,11 +2427,13 @@ EXPORT_SYMBOL_GPL(nfs_net_id); + static int nfs_net_init(struct net *net) + { + nfs_clients_init(net); ++ rpc_proc_register(net, &nfs_rpcstat); + return nfs_fs_proc_net_init(net); + } + + static void nfs_net_exit(struct net *net) + { ++ rpc_proc_unregister(net, "nfs"); + nfs_fs_proc_net_exit(net); + nfs_clients_exit(net); + } +@@ -2486,15 +2488,12 @@ static int __init init_nfs_fs(void) + if (err) + goto out1; + +- rpc_proc_register(&init_net, &nfs_rpcstat); +- + err = register_nfs_fs(); + if (err) + goto out0; + + return 0; + out0: +- rpc_proc_unregister(&init_net, "nfs"); + nfs_destroy_directcache(); + out1: + nfs_destroy_writepagecache(); +@@ -2524,7 +2523,6 @@ static void __exit exit_nfs_fs(void) + nfs_destroy_inodecache(); + nfs_destroy_nfspagecache(); + unregister_pernet_subsys(&nfs_net_ops); +- rpc_proc_unregister(&init_net, "nfs"); + unregister_nfs_fs(); + nfs_fs_proc_exit(); + nfsiod_stop(); +-- +2.43.0 + diff --git a/queue-6.8/nfs-handle-error-of-rpc_proc_register-in-nfs_net_ini.patch b/queue-6.8/nfs-handle-error-of-rpc_proc_register-in-nfs_net_ini.patch new file mode 100644 index 00000000000..da679c8e9e4 --- /dev/null +++ b/queue-6.8/nfs-handle-error-of-rpc_proc_register-in-nfs_net_ini.patch @@ -0,0 +1,104 @@ +From 54966d9f2e306b3e453786f348e05c4a70ad0a1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Apr 2024 15:12:00 -0700 +Subject: nfs: Handle error of rpc_proc_register() in nfs_net_init(). + +From: Kuniyuki Iwashima + +[ Upstream commit 24457f1be29f1e7042e50a7749f5c2dde8c433c8 ] + +syzkaller reported a warning [0] triggered while destroying immature +netns. + +rpc_proc_register() was called in init_nfs_fs(), but its error +has been ignored since at least the initial commit 1da177e4c3f4 +("Linux-2.6.12-rc2"). + +Recently, commit d47151b79e32 ("nfs: expose /proc/net/sunrpc/nfs +in net namespaces") converted the procfs to per-netns and made +the problem more visible. + +Even when rpc_proc_register() fails, nfs_net_init() could succeed, +and thus nfs_net_exit() will be called while destroying the netns. + +Then, remove_proc_entry() will be called for non-existing proc +directory and trigger the warning below. + +Let's handle the error of rpc_proc_register() properly in nfs_net_init(). + +[0]: +name 'nfs' +WARNING: CPU: 1 PID: 1710 at fs/proc/generic.c:711 remove_proc_entry+0x1bb/0x2d0 fs/proc/generic.c:711 +Modules linked in: +CPU: 1 PID: 1710 Comm: syz-executor.2 Not tainted 6.8.0-12822-gcd51db110a7e #12 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 +RIP: 0010:remove_proc_entry+0x1bb/0x2d0 fs/proc/generic.c:711 +Code: 41 5d 41 5e c3 e8 85 09 b5 ff 48 c7 c7 88 58 64 86 e8 09 0e 71 02 e8 74 09 b5 ff 4c 89 e6 48 c7 c7 de 1b 80 84 e8 c5 ad 97 ff <0f> 0b eb b1 e8 5c 09 b5 ff 48 c7 c7 88 58 64 86 e8 e0 0d 71 02 eb +RSP: 0018:ffffc9000c6d7ce0 EFLAGS: 00010286 +RAX: 0000000000000000 RBX: ffff8880422b8b00 RCX: ffffffff8110503c +RDX: ffff888030652f00 RSI: ffffffff81105045 RDI: 0000000000000001 +RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000 +R10: 0000000000000001 R11: ffffffff81bb62cb R12: ffffffff84807ffc +R13: ffff88804ad6fcc0 R14: ffffffff84807ffc R15: ffffffff85741ff8 +FS: 00007f30cfba8640(0000) GS:ffff88807dd00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007ff51afe8000 CR3: 000000005a60a005 CR4: 0000000000770ef0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +PKRU: 55555554 +Call Trace: + + rpc_proc_unregister+0x64/0x70 net/sunrpc/stats.c:310 + nfs_net_exit+0x1c/0x30 fs/nfs/inode.c:2438 + ops_exit_list+0x62/0xb0 net/core/net_namespace.c:170 + setup_net+0x46c/0x660 net/core/net_namespace.c:372 + copy_net_ns+0x244/0x590 net/core/net_namespace.c:505 + create_new_namespaces+0x2ed/0x770 kernel/nsproxy.c:110 + unshare_nsproxy_namespaces+0xae/0x160 kernel/nsproxy.c:228 + ksys_unshare+0x342/0x760 kernel/fork.c:3322 + __do_sys_unshare kernel/fork.c:3393 [inline] + __se_sys_unshare kernel/fork.c:3391 [inline] + __x64_sys_unshare+0x1f/0x30 kernel/fork.c:3391 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0x4f/0x110 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x46/0x4e +RIP: 0033:0x7f30d0febe5d +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:00007f30cfba7cc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000110 +RAX: ffffffffffffffda RBX: 00000000004bbf80 RCX: 00007f30d0febe5d +RDX: 0000000000000000 RSI: 0000000000000000 RDI: 000000006c020600 +RBP: 00000000004bbf80 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000002 +R13: 000000000000000b R14: 00007f30d104c530 R15: 0000000000000000 + + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzkaller +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/inode.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index 91b4d811958a4..6fe4b47c39287 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -2429,7 +2429,12 @@ static int nfs_net_init(struct net *net) + struct nfs_net *nn = net_generic(net, nfs_net_id); + + nfs_clients_init(net); +- rpc_proc_register(net, &nn->rpcstats); ++ ++ if (!rpc_proc_register(net, &nn->rpcstats)) { ++ nfs_clients_exit(net); ++ return -ENOMEM; ++ } ++ + return nfs_fs_proc_net_init(net); + } + +-- +2.43.0 + diff --git a/queue-6.8/nfs-make-the-rpc_stat-per-net-namespace.patch b/queue-6.8/nfs-make-the-rpc_stat-per-net-namespace.patch new file mode 100644 index 00000000000..a3197e7119d --- /dev/null +++ b/queue-6.8/nfs-make-the-rpc_stat-per-net-namespace.patch @@ -0,0 +1,113 @@ +From 101cc16135d631c7d97cea0cd00e643cd299e42e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 14:57:32 -0500 +Subject: nfs: make the rpc_stat per net namespace + +From: Josef Bacik + +[ Upstream commit 1548036ef1204df65ca5a16e8b199c858cb80075 ] + +Now that we're exposing the rpc stats on a per-network namespace basis, +move this struct into struct nfs_net and use that to make sure only the +per-network namespace stats are exposed. + +Signed-off-by: Josef Bacik +Signed-off-by: Trond Myklebust +Stable-dep-of: 24457f1be29f ("nfs: Handle error of rpc_proc_register() in nfs_net_init().") +Signed-off-by: Sasha Levin +--- + fs/nfs/client.c | 5 ++++- + fs/nfs/inode.c | 4 +++- + fs/nfs/internal.h | 2 -- + fs/nfs/netns.h | 2 ++ + 4 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/fs/nfs/client.c b/fs/nfs/client.c +index fbdc9ca80f714..a8fad331dff6b 100644 +--- a/fs/nfs/client.c ++++ b/fs/nfs/client.c +@@ -73,7 +73,6 @@ const struct rpc_program nfs_program = { + .number = NFS_PROGRAM, + .nrvers = ARRAY_SIZE(nfs_version), + .version = nfs_version, +- .stats = &nfs_rpcstat, + .pipe_dir_name = NFS_PIPE_DIRNAME, + }; + +@@ -502,6 +501,7 @@ int nfs_create_rpc_client(struct nfs_client *clp, + const struct nfs_client_initdata *cl_init, + rpc_authflavor_t flavor) + { ++ struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id); + struct rpc_clnt *clnt = NULL; + struct rpc_create_args args = { + .net = clp->cl_net, +@@ -513,6 +513,7 @@ int nfs_create_rpc_client(struct nfs_client *clp, + .servername = clp->cl_hostname, + .nodename = cl_init->nodename, + .program = &nfs_program, ++ .stats = &nn->rpcstats, + .version = clp->rpc_ops->version, + .authflavor = flavor, + .cred = cl_init->cred, +@@ -1182,6 +1183,8 @@ void nfs_clients_init(struct net *net) + #endif + spin_lock_init(&nn->nfs_client_lock); + nn->boot_time = ktime_get_real(); ++ memset(&nn->rpcstats, 0, sizeof(nn->rpcstats)); ++ nn->rpcstats.program = &nfs_program; + + nfs_netns_sysfs_setup(nn, net); + } +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index e11e9c34aa569..91b4d811958a4 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -2426,8 +2426,10 @@ EXPORT_SYMBOL_GPL(nfs_net_id); + + static int nfs_net_init(struct net *net) + { ++ struct nfs_net *nn = net_generic(net, nfs_net_id); ++ + nfs_clients_init(net); +- rpc_proc_register(net, &nfs_rpcstat); ++ rpc_proc_register(net, &nn->rpcstats); + return nfs_fs_proc_net_init(net); + } + +diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h +index e3722ce6722e2..06253695fe53f 100644 +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -449,8 +449,6 @@ int nfs_try_get_tree(struct fs_context *); + int nfs_get_tree_common(struct fs_context *); + void nfs_kill_super(struct super_block *); + +-extern struct rpc_stat nfs_rpcstat; +- + extern int __init register_nfs_fs(void); + extern void __exit unregister_nfs_fs(void); + extern bool nfs_sb_active(struct super_block *sb); +diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h +index c8374f74dce11..a68b21603ea9a 100644 +--- a/fs/nfs/netns.h ++++ b/fs/nfs/netns.h +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + struct bl_dev_msg { + int32_t status; +@@ -34,6 +35,7 @@ struct nfs_net { + struct nfs_netns_client *nfs_client; + spinlock_t nfs_client_lock; + ktime_t boot_time; ++ struct rpc_stat rpcstats; + #ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc_nfsfs; + #endif +-- +2.43.0 + diff --git a/queue-6.8/nfsd-add-support-for-cb_getattr-callback.patch b/queue-6.8/nfsd-add-support-for-cb_getattr-callback.patch new file mode 100644 index 00000000000..45c36d272ff --- /dev/null +++ b/queue-6.8/nfsd-add-support-for-cb_getattr-callback.patch @@ -0,0 +1,230 @@ +From 27fea31c3205b3bc115a72aa40646c6866296d50 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 14:05:21 -0800 +Subject: NFSD: add support for CB_GETATTR callback + +From: Dai Ngo + +[ Upstream commit 6487a13b5c6bee2ca3fc931f8ad28c8ae887a41f ] + +Includes: + . CB_GETATTR proc for nfs4_cb_procedures[] + . XDR encoding and decoding function for CB_GETATTR request/reply + . add nfs4_cb_fattr to nfs4_delegation for sending CB_GETATTR + and store file attributes from client's reply. + +Signed-off-by: Dai Ngo +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Stable-dep-of: 18180a4550d0 ("NFSD: Fix nfsd4_encode_fattr4() crasher") +Signed-off-by: Sasha Levin +--- + fs/nfsd/nfs4callback.c | 97 +++++++++++++++++++++++++++++++++++++++++- + fs/nfsd/state.h | 14 ++++++ + fs/nfsd/xdr4cb.h | 18 ++++++++ + 3 files changed, 128 insertions(+), 1 deletion(-) + +diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c +index 926c29879c6ab..30aa241038eb4 100644 +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -85,7 +85,21 @@ static void encode_uint32(struct xdr_stream *xdr, u32 n) + static void encode_bitmap4(struct xdr_stream *xdr, const __u32 *bitmap, + size_t len) + { +- WARN_ON_ONCE(xdr_stream_encode_uint32_array(xdr, bitmap, len) < 0); ++ xdr_stream_encode_uint32_array(xdr, bitmap, len); ++} ++ ++static int decode_cb_fattr4(struct xdr_stream *xdr, uint32_t *bitmap, ++ struct nfs4_cb_fattr *fattr) ++{ ++ fattr->ncf_cb_change = 0; ++ fattr->ncf_cb_fsize = 0; ++ if (bitmap[0] & FATTR4_WORD0_CHANGE) ++ if (xdr_stream_decode_u64(xdr, &fattr->ncf_cb_change) < 0) ++ return -NFSERR_BAD_XDR; ++ if (bitmap[0] & FATTR4_WORD0_SIZE) ++ if (xdr_stream_decode_u64(xdr, &fattr->ncf_cb_fsize) < 0) ++ return -NFSERR_BAD_XDR; ++ return 0; + } + + static void encode_nfs_cb_opnum4(struct xdr_stream *xdr, enum nfs_cb_opnum4 op) +@@ -333,6 +347,30 @@ encode_cb_recallany4args(struct xdr_stream *xdr, + hdr->nops++; + } + ++/* ++ * CB_GETATTR4args ++ * struct CB_GETATTR4args { ++ * nfs_fh4 fh; ++ * bitmap4 attr_request; ++ * }; ++ * ++ * The size and change attributes are the only one ++ * guaranteed to be serviced by the client. ++ */ ++static void ++encode_cb_getattr4args(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr, ++ struct nfs4_cb_fattr *fattr) ++{ ++ struct nfs4_delegation *dp = ++ container_of(fattr, struct nfs4_delegation, dl_cb_fattr); ++ struct knfsd_fh *fh = &dp->dl_stid.sc_file->fi_fhandle; ++ ++ encode_nfs_cb_opnum4(xdr, OP_CB_GETATTR); ++ encode_nfs_fh4(xdr, fh); ++ encode_bitmap4(xdr, fattr->ncf_cb_bmap, ARRAY_SIZE(fattr->ncf_cb_bmap)); ++ hdr->nops++; ++} ++ + /* + * CB_SEQUENCE4args + * +@@ -468,6 +506,26 @@ static void nfs4_xdr_enc_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr, + xdr_reserve_space(xdr, 0); + } + ++/* ++ * 20.1. Operation 3: CB_GETATTR - Get Attributes ++ */ ++static void nfs4_xdr_enc_cb_getattr(struct rpc_rqst *req, ++ struct xdr_stream *xdr, const void *data) ++{ ++ const struct nfsd4_callback *cb = data; ++ struct nfs4_cb_fattr *ncf = ++ container_of(cb, struct nfs4_cb_fattr, ncf_getattr); ++ struct nfs4_cb_compound_hdr hdr = { ++ .ident = cb->cb_clp->cl_cb_ident, ++ .minorversion = cb->cb_clp->cl_minorversion, ++ }; ++ ++ encode_cb_compound4args(xdr, &hdr); ++ encode_cb_sequence4args(xdr, cb, &hdr); ++ encode_cb_getattr4args(xdr, &hdr, ncf); ++ encode_cb_nops(&hdr); ++} ++ + /* + * 20.2. Operation 4: CB_RECALL - Recall a Delegation + */ +@@ -523,6 +581,42 @@ static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr, + return 0; + } + ++/* ++ * 20.1. Operation 3: CB_GETATTR - Get Attributes ++ */ ++static int nfs4_xdr_dec_cb_getattr(struct rpc_rqst *rqstp, ++ struct xdr_stream *xdr, ++ void *data) ++{ ++ struct nfsd4_callback *cb = data; ++ struct nfs4_cb_compound_hdr hdr; ++ int status; ++ u32 bitmap[3] = {0}; ++ u32 attrlen; ++ struct nfs4_cb_fattr *ncf = ++ container_of(cb, struct nfs4_cb_fattr, ncf_getattr); ++ ++ status = decode_cb_compound4res(xdr, &hdr); ++ if (unlikely(status)) ++ return status; ++ ++ status = decode_cb_sequence4res(xdr, cb); ++ if (unlikely(status || cb->cb_seq_status)) ++ return status; ++ ++ status = decode_cb_op_status(xdr, OP_CB_GETATTR, &cb->cb_status); ++ if (status) ++ return status; ++ if (xdr_stream_decode_uint32_array(xdr, bitmap, 3) < 0) ++ return -NFSERR_BAD_XDR; ++ if (xdr_stream_decode_u32(xdr, &attrlen) < 0) ++ return -NFSERR_BAD_XDR; ++ if (attrlen > (sizeof(ncf->ncf_cb_change) + sizeof(ncf->ncf_cb_fsize))) ++ return -NFSERR_BAD_XDR; ++ status = decode_cb_fattr4(xdr, bitmap, ncf); ++ return status; ++} ++ + /* + * 20.2. Operation 4: CB_RECALL - Recall a Delegation + */ +@@ -831,6 +925,7 @@ static const struct rpc_procinfo nfs4_cb_procedures[] = { + PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock), + PROC(CB_OFFLOAD, COMPOUND, cb_offload, cb_offload), + PROC(CB_RECALL_ANY, COMPOUND, cb_recall_any, cb_recall_any), ++ PROC(CB_GETATTR, COMPOUND, cb_getattr, cb_getattr), + }; + + static unsigned int nfs4_cb_counts[ARRAY_SIZE(nfs4_cb_procedures)]; +diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h +index 41bdc913fa715..0bbbe57e027d3 100644 +--- a/fs/nfsd/state.h ++++ b/fs/nfsd/state.h +@@ -117,6 +117,16 @@ struct nfs4_cpntf_state { + time64_t cpntf_time; /* last time stateid used */ + }; + ++struct nfs4_cb_fattr { ++ struct nfsd4_callback ncf_getattr; ++ u32 ncf_cb_status; ++ u32 ncf_cb_bmap[1]; ++ ++ /* from CB_GETATTR reply */ ++ u64 ncf_cb_change; ++ u64 ncf_cb_fsize; ++}; ++ + /* + * Represents a delegation stateid. The nfs4_client holds references to these + * and they are put when it is being destroyed or when the delegation is +@@ -150,6 +160,9 @@ struct nfs4_delegation { + int dl_retries; + struct nfsd4_callback dl_recall; + bool dl_recalled; ++ ++ /* for CB_GETATTR */ ++ struct nfs4_cb_fattr dl_cb_fattr; + }; + + #define cb_to_delegation(cb) \ +@@ -640,6 +653,7 @@ enum nfsd4_cb_op { + NFSPROC4_CLNT_CB_SEQUENCE, + NFSPROC4_CLNT_CB_NOTIFY_LOCK, + NFSPROC4_CLNT_CB_RECALL_ANY, ++ NFSPROC4_CLNT_CB_GETATTR, + }; + + /* Returns true iff a is later than b: */ +diff --git a/fs/nfsd/xdr4cb.h b/fs/nfsd/xdr4cb.h +index 0d39af1b00a0f..e8b00309c449f 100644 +--- a/fs/nfsd/xdr4cb.h ++++ b/fs/nfsd/xdr4cb.h +@@ -54,3 +54,21 @@ + #define NFS4_dec_cb_recall_any_sz (cb_compound_dec_hdr_sz + \ + cb_sequence_dec_sz + \ + op_dec_sz) ++ ++/* ++ * 1: CB_GETATTR opcode (32-bit) ++ * N: file_handle ++ * 1: number of entry in attribute array (32-bit) ++ * 1: entry 0 in attribute array (32-bit) ++ */ ++#define NFS4_enc_cb_getattr_sz (cb_compound_enc_hdr_sz + \ ++ cb_sequence_enc_sz + \ ++ 1 + enc_nfs4_fh_sz + 1 + 1) ++/* ++ * 4: fattr_bitmap_maxsz ++ * 1: attribute array len ++ * 2: change attr (64-bit) ++ * 2: size (64-bit) ++ */ ++#define NFS4_dec_cb_getattr_sz (cb_compound_dec_hdr_sz + \ ++ cb_sequence_dec_sz + 4 + 1 + 2 + 2 + op_dec_sz) +-- +2.43.0 + diff --git a/queue-6.8/nfsd-expose-proc-net-sunrpc-nfsd-in-net-namespaces.patch b/queue-6.8/nfsd-expose-proc-net-sunrpc-nfsd-in-net-namespaces.patch new file mode 100644 index 00000000000..9fb4cc2d60c --- /dev/null +++ b/queue-6.8/nfsd-expose-proc-net-sunrpc-nfsd-in-net-namespaces.patch @@ -0,0 +1,143 @@ +From c958b75493408bd398bd5c92f0c0936ac97a3986 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Jan 2024 10:39:46 -0500 +Subject: nfsd: expose /proc/net/sunrpc/nfsd in net namespaces + +From: Josef Bacik + +[ Upstream commit 93483ac5fec62cc1de166051b219d953bb5e4ef4 ] + +We are running nfsd servers inside of containers with their own network +namespace, and we want to monitor these services using the stats found +in /proc. However these are not exposed in the proc inside of the +container, so we have to bind mount the host /proc into our containers +to get at this information. + +Separate out the stat counters init and the proc registration, and move +the proc registration into the pernet operations entry and exit points +so that these stats can be exposed inside of network namespaces. + +This is an intermediate step, this just exposes the global counters in +the network namespace. Subsequent patches will move these counters into +the per-network namespace container. + +Signed-off-by: Josef Bacik +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Stable-dep-of: 18180a4550d0 ("NFSD: Fix nfsd4_encode_fattr4() crasher") +Signed-off-by: Sasha Levin +--- + fs/nfsd/nfsctl.c | 8 +++++--- + fs/nfsd/stats.c | 21 ++++++--------------- + fs/nfsd/stats.h | 6 ++++-- + 3 files changed, 15 insertions(+), 20 deletions(-) + +diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c +index f206ca32e7f53..b57480b50e350 100644 +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -1679,6 +1679,7 @@ static __net_init int nfsd_net_init(struct net *net) + nfsd4_init_leases_net(nn); + get_random_bytes(&nn->siphash_key, sizeof(nn->siphash_key)); + seqlock_init(&nn->writeverf_lock); ++ nfsd_proc_stat_init(net); + + return 0; + +@@ -1699,6 +1700,7 @@ static __net_exit void nfsd_net_exit(struct net *net) + { + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + ++ nfsd_proc_stat_shutdown(net); + nfsd_net_reply_cache_destroy(nn); + nfsd_idmap_shutdown(net); + nfsd_export_shutdown(net); +@@ -1722,7 +1724,7 @@ static int __init init_nfsd(void) + retval = nfsd4_init_pnfs(); + if (retval) + goto out_free_slabs; +- retval = nfsd_stat_init(); /* Statistics */ ++ retval = nfsd_stat_counters_init(); /* Statistics */ + if (retval) + goto out_free_pnfs; + retval = nfsd_drc_slab_create(); +@@ -1762,7 +1764,7 @@ static int __init init_nfsd(void) + nfsd_lockd_shutdown(); + nfsd_drc_slab_free(); + out_free_stat: +- nfsd_stat_shutdown(); ++ nfsd_stat_counters_destroy(); + out_free_pnfs: + nfsd4_exit_pnfs(); + out_free_slabs: +@@ -1780,7 +1782,7 @@ static void __exit exit_nfsd(void) + nfsd_drc_slab_free(); + remove_proc_entry("fs/nfs/exports", NULL); + remove_proc_entry("fs/nfs", NULL); +- nfsd_stat_shutdown(); ++ nfsd_stat_counters_destroy(); + nfsd_lockd_shutdown(); + nfsd4_free_slabs(); + nfsd4_exit_pnfs(); +diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c +index 12d79f5d4eb1a..394a65a33942d 100644 +--- a/fs/nfsd/stats.c ++++ b/fs/nfsd/stats.c +@@ -108,31 +108,22 @@ void nfsd_percpu_counters_destroy(struct percpu_counter counters[], int num) + percpu_counter_destroy(&counters[i]); + } + +-static int nfsd_stat_counters_init(void) ++int nfsd_stat_counters_init(void) + { + return nfsd_percpu_counters_init(nfsdstats.counter, NFSD_STATS_COUNTERS_NUM); + } + +-static void nfsd_stat_counters_destroy(void) ++void nfsd_stat_counters_destroy(void) + { + nfsd_percpu_counters_destroy(nfsdstats.counter, NFSD_STATS_COUNTERS_NUM); + } + +-int nfsd_stat_init(void) ++void nfsd_proc_stat_init(struct net *net) + { +- int err; +- +- err = nfsd_stat_counters_init(); +- if (err) +- return err; +- +- svc_proc_register(&init_net, &nfsd_svcstats, &nfsd_proc_ops); +- +- return 0; ++ svc_proc_register(net, &nfsd_svcstats, &nfsd_proc_ops); + } + +-void nfsd_stat_shutdown(void) ++void nfsd_proc_stat_shutdown(struct net *net) + { +- nfsd_stat_counters_destroy(); +- svc_proc_unregister(&init_net, "nfsd"); ++ svc_proc_unregister(net, "nfsd"); + } +diff --git a/fs/nfsd/stats.h b/fs/nfsd/stats.h +index 7ed4325ac6912..38811aa7d13e1 100644 +--- a/fs/nfsd/stats.h ++++ b/fs/nfsd/stats.h +@@ -40,8 +40,10 @@ extern struct svc_stat nfsd_svcstats; + int nfsd_percpu_counters_init(struct percpu_counter *counters, int num); + void nfsd_percpu_counters_reset(struct percpu_counter *counters, int num); + void nfsd_percpu_counters_destroy(struct percpu_counter *counters, int num); +-int nfsd_stat_init(void); +-void nfsd_stat_shutdown(void); ++int nfsd_stat_counters_init(void); ++void nfsd_stat_counters_destroy(void); ++void nfsd_proc_stat_init(struct net *net); ++void nfsd_proc_stat_shutdown(struct net *net); + + static inline void nfsd_stats_rc_hits_inc(void) + { +-- +2.43.0 + diff --git a/queue-6.8/nfsd-fix-nfsd4_encode_fattr4-crasher.patch b/queue-6.8/nfsd-fix-nfsd4_encode_fattr4-crasher.patch new file mode 100644 index 00000000000..6c6cbb465b7 --- /dev/null +++ b/queue-6.8/nfsd-fix-nfsd4_encode_fattr4-crasher.patch @@ -0,0 +1,44 @@ +From 5cf9c97f983e1150776345e773894520d245cdff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Apr 2024 17:46:26 -0400 +Subject: NFSD: Fix nfsd4_encode_fattr4() crasher + +From: Chuck Lever + +[ Upstream commit 18180a4550d08be4eb0387fe83f02f703f92d4e7 ] + +Ensure that args.acl is initialized early. It is used in an +unconditional call to kfree() on the way out of +nfsd4_encode_fattr4(). + +Reported-by: Scott Mayhew +Fixes: 83ab8678ad0c ("NFSD: Add struct nfsd4_fattr_args") +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/nfs4xdr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c +index c17bdf973c18d..24db9f9ea86a2 100644 +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -3513,6 +3513,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, + args.exp = exp; + args.dentry = dentry; + args.ignore_crossmnt = (ignore_crossmnt != 0); ++ args.acl = NULL; + + /* + * Make a local copy of the attribute bitmap that can be modified. +@@ -3567,7 +3568,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, + } else + args.fhp = fhp; + +- args.acl = NULL; + if (attrmask[0] & FATTR4_WORD0_ACL) { + err = nfsd4_get_nfs4_acl(rqstp, dentry, &args.acl); + if (err == -EOPNOTSUPP) +-- +2.43.0 + diff --git a/queue-6.8/nfsd-make-all-of-the-nfsd-stats-per-network-namespac.patch b/queue-6.8/nfsd-make-all-of-the-nfsd-stats-per-network-namespac.patch new file mode 100644 index 00000000000..ccd79eac976 --- /dev/null +++ b/queue-6.8/nfsd-make-all-of-the-nfsd-stats-per-network-namespac.patch @@ -0,0 +1,493 @@ +From 290289625a942780ca32f191cdb81d7d521c600a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Jan 2024 10:39:47 -0500 +Subject: nfsd: make all of the nfsd stats per-network namespace + +From: Josef Bacik + +[ Upstream commit 4b14885411f74b2b0ce0eb2b39d0fffe54e5ca0d ] + +We have a global set of counters that we modify for all of the nfsd +operations, but now that we're exposing these stats across all network +namespaces we need to make the stats also be per-network namespace. We +already have some caching stats that are per-network namespace, so move +these definitions into the same counter and then adjust all the helpers +and users of these stats to provide the appropriate nfsd_net struct so +that the stats are maintained for the per-network namespace objects. + +Signed-off-by: Josef Bacik +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Stable-dep-of: 18180a4550d0 ("NFSD: Fix nfsd4_encode_fattr4() crasher") +Signed-off-by: Sasha Levin +--- + fs/nfsd/cache.h | 2 -- + fs/nfsd/netns.h | 17 ++++++++++++-- + fs/nfsd/nfs4proc.c | 6 ++--- + fs/nfsd/nfs4state.c | 3 ++- + fs/nfsd/nfscache.c | 36 ++++++------------------------ + fs/nfsd/nfsctl.c | 12 +++------- + fs/nfsd/nfsfh.c | 3 ++- + fs/nfsd/stats.c | 26 ++++++++++++---------- + fs/nfsd/stats.h | 54 ++++++++++++++++----------------------------- + fs/nfsd/vfs.c | 6 +++-- + 10 files changed, 69 insertions(+), 96 deletions(-) + +diff --git a/fs/nfsd/cache.h b/fs/nfsd/cache.h +index 4cbe0434cbb8c..66a05fefae98e 100644 +--- a/fs/nfsd/cache.h ++++ b/fs/nfsd/cache.h +@@ -80,8 +80,6 @@ enum { + + int nfsd_drc_slab_create(void); + void nfsd_drc_slab_free(void); +-int nfsd_net_reply_cache_init(struct nfsd_net *nn); +-void nfsd_net_reply_cache_destroy(struct nfsd_net *nn); + int nfsd_reply_cache_init(struct nfsd_net *); + void nfsd_reply_cache_shutdown(struct nfsd_net *); + int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, +diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h +index e3605cb5f044d..0cef4bb407a9c 100644 +--- a/fs/nfsd/netns.h ++++ b/fs/nfsd/netns.h +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -29,7 +30,19 @@ enum { + NFSD_STATS_PAYLOAD_MISSES, + /* amount of memory (in bytes) currently consumed by the DRC */ + NFSD_STATS_DRC_MEM_USAGE, +- NFSD_NET_COUNTERS_NUM ++ NFSD_STATS_RC_HITS, /* repcache hits */ ++ NFSD_STATS_RC_MISSES, /* repcache misses */ ++ NFSD_STATS_RC_NOCACHE, /* uncached reqs */ ++ NFSD_STATS_FH_STALE, /* FH stale error */ ++ NFSD_STATS_IO_READ, /* bytes returned to read requests */ ++ NFSD_STATS_IO_WRITE, /* bytes passed in write requests */ ++#ifdef CONFIG_NFSD_V4 ++ NFSD_STATS_FIRST_NFS4_OP, /* count of individual nfsv4 operations */ ++ NFSD_STATS_LAST_NFS4_OP = NFSD_STATS_FIRST_NFS4_OP + LAST_NFS4_OP, ++#define NFSD_STATS_NFS4_OP(op) (NFSD_STATS_FIRST_NFS4_OP + (op)) ++ NFSD_STATS_WDELEG_GETATTR, /* count of getattr conflict with wdeleg */ ++#endif ++ NFSD_STATS_COUNTERS_NUM + }; + + /* +@@ -164,7 +177,7 @@ struct nfsd_net { + atomic_t num_drc_entries; + + /* Per-netns stats counters */ +- struct percpu_counter counter[NFSD_NET_COUNTERS_NUM]; ++ struct percpu_counter counter[NFSD_STATS_COUNTERS_NUM]; + + /* longest hash chain seen */ + unsigned int longest_chain; +diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c +index 14712fa08f769..648ff427005e6 100644 +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -2490,10 +2490,10 @@ nfsd4_proc_null(struct svc_rqst *rqstp) + return rpc_success; + } + +-static inline void nfsd4_increment_op_stats(u32 opnum) ++static inline void nfsd4_increment_op_stats(struct nfsd_net *nn, u32 opnum) + { + if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP) +- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_NFS4_OP(opnum)]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_NFS4_OP(opnum)]); + } + + static const struct nfsd4_operation nfsd4_ops[]; +@@ -2768,7 +2768,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) + status, nfsd4_op_name(op->opnum)); + + nfsd4_cstate_clear_replay(cstate); +- nfsd4_increment_op_stats(op->opnum); ++ nfsd4_increment_op_stats(nn, op->opnum); + } + + fh_put(current_fh); +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index 692ede488254a..71f9442c5c9fc 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -8447,6 +8447,7 @@ __be32 + nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct inode *inode) + { + __be32 status; ++ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + struct file_lock_context *ctx; + struct file_lock *fl; + struct nfs4_delegation *dp; +@@ -8476,7 +8477,7 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct inode *inode) + } + break_lease: + spin_unlock(&ctx->flc_lock); +- nfsd_stats_wdeleg_getattr_inc(); ++ nfsd_stats_wdeleg_getattr_inc(nn); + status = nfserrno(nfsd_open_break_lease(inode, NFSD_MAY_READ)); + if (status != nfserr_jukebox || + !nfsd_wait_for_delegreturn(rqstp, inode)) +diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c +index 3d4a9d181c43e..cfcc6ac8f255a 100644 +--- a/fs/nfsd/nfscache.c ++++ b/fs/nfsd/nfscache.c +@@ -176,27 +176,6 @@ void nfsd_drc_slab_free(void) + kmem_cache_destroy(drc_slab); + } + +-/** +- * nfsd_net_reply_cache_init - per net namespace reply cache set-up +- * @nn: nfsd_net being initialized +- * +- * Returns zero on succes; otherwise a negative errno is returned. +- */ +-int nfsd_net_reply_cache_init(struct nfsd_net *nn) +-{ +- return nfsd_percpu_counters_init(nn->counter, NFSD_NET_COUNTERS_NUM); +-} +- +-/** +- * nfsd_net_reply_cache_destroy - per net namespace reply cache tear-down +- * @nn: nfsd_net being freed +- * +- */ +-void nfsd_net_reply_cache_destroy(struct nfsd_net *nn) +-{ +- nfsd_percpu_counters_destroy(nn->counter, NFSD_NET_COUNTERS_NUM); +-} +- + int nfsd_reply_cache_init(struct nfsd_net *nn) + { + unsigned int hashsize; +@@ -501,7 +480,7 @@ nfsd_cache_insert(struct nfsd_drc_bucket *b, struct nfsd_cacherep *key, + int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, + unsigned int len, struct nfsd_cacherep **cacherep) + { +- struct nfsd_net *nn; ++ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + struct nfsd_cacherep *rp, *found; + __wsum csum; + struct nfsd_drc_bucket *b; +@@ -510,7 +489,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, + int rtn = RC_DOIT; + + if (type == RC_NOCACHE) { +- nfsd_stats_rc_nocache_inc(); ++ nfsd_stats_rc_nocache_inc(nn); + goto out; + } + +@@ -520,7 +499,6 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, + * Since the common case is a cache miss followed by an insert, + * preallocate an entry. + */ +- nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + rp = nfsd_cacherep_alloc(rqstp, csum, nn); + if (!rp) + goto out; +@@ -537,7 +515,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, + + nfsd_cacherep_dispose(&dispose); + +- nfsd_stats_rc_misses_inc(); ++ nfsd_stats_rc_misses_inc(nn); + atomic_inc(&nn->num_drc_entries); + nfsd_stats_drc_mem_usage_add(nn, sizeof(*rp)); + goto out; +@@ -545,7 +523,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, + found_entry: + /* We found a matching entry which is either in progress or done. */ + nfsd_reply_cache_free_locked(NULL, rp, nn); +- nfsd_stats_rc_hits_inc(); ++ nfsd_stats_rc_hits_inc(nn); + rtn = RC_DROPIT; + rp = found; + +@@ -689,11 +667,11 @@ int nfsd_reply_cache_stats_show(struct seq_file *m, void *v) + seq_printf(m, "mem usage: %lld\n", + percpu_counter_sum_positive(&nn->counter[NFSD_STATS_DRC_MEM_USAGE])); + seq_printf(m, "cache hits: %lld\n", +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_HITS])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_HITS])); + seq_printf(m, "cache misses: %lld\n", +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_MISSES])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_MISSES])); + seq_printf(m, "not cached: %lld\n", +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_NOCACHE])); + seq_printf(m, "payload misses: %lld\n", + percpu_counter_sum_positive(&nn->counter[NFSD_STATS_PAYLOAD_MISSES])); + seq_printf(m, "longest chain len: %u\n", nn->longest_chain); +diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c +index b57480b50e350..ea3c8114245c2 100644 +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -1671,7 +1671,7 @@ static __net_init int nfsd_net_init(struct net *net) + retval = nfsd_idmap_init(net); + if (retval) + goto out_idmap_error; +- retval = nfsd_net_reply_cache_init(nn); ++ retval = nfsd_stat_counters_init(nn); + if (retval) + goto out_repcache_error; + nn->nfsd_versions = NULL; +@@ -1701,7 +1701,7 @@ static __net_exit void nfsd_net_exit(struct net *net) + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + + nfsd_proc_stat_shutdown(net); +- nfsd_net_reply_cache_destroy(nn); ++ nfsd_stat_counters_destroy(nn); + nfsd_idmap_shutdown(net); + nfsd_export_shutdown(net); + nfsd_netns_free_versions(nn); +@@ -1724,12 +1724,9 @@ static int __init init_nfsd(void) + retval = nfsd4_init_pnfs(); + if (retval) + goto out_free_slabs; +- retval = nfsd_stat_counters_init(); /* Statistics */ +- if (retval) +- goto out_free_pnfs; + retval = nfsd_drc_slab_create(); + if (retval) +- goto out_free_stat; ++ goto out_free_pnfs; + nfsd_lockd_init(); /* lockd->nfsd callbacks */ + retval = create_proc_exports_entry(); + if (retval) +@@ -1763,8 +1760,6 @@ static int __init init_nfsd(void) + out_free_lockd: + nfsd_lockd_shutdown(); + nfsd_drc_slab_free(); +-out_free_stat: +- nfsd_stat_counters_destroy(); + out_free_pnfs: + nfsd4_exit_pnfs(); + out_free_slabs: +@@ -1782,7 +1777,6 @@ static void __exit exit_nfsd(void) + nfsd_drc_slab_free(); + remove_proc_entry("fs/nfs/exports", NULL); + remove_proc_entry("fs/nfs", NULL); +- nfsd_stat_counters_destroy(); + nfsd_lockd_shutdown(); + nfsd4_free_slabs(); + nfsd4_exit_pnfs(); +diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c +index dbfa0ac13564a..40fecf7b224f2 100644 +--- a/fs/nfsd/nfsfh.c ++++ b/fs/nfsd/nfsfh.c +@@ -327,6 +327,7 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) + __be32 + fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) + { ++ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + struct svc_export *exp = NULL; + struct dentry *dentry; + __be32 error; +@@ -395,7 +396,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) + out: + trace_nfsd_fh_verify_err(rqstp, fhp, type, access, error); + if (error == nfserr_stale) +- nfsd_stats_fh_stale_inc(exp); ++ nfsd_stats_fh_stale_inc(nn, exp); + return error; + } + +diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c +index 394a65a33942d..44e275324b06e 100644 +--- a/fs/nfsd/stats.c ++++ b/fs/nfsd/stats.c +@@ -34,15 +34,17 @@ struct svc_stat nfsd_svcstats = { + + static int nfsd_show(struct seq_file *seq, void *v) + { ++ struct net *net = pde_data(file_inode(seq->file)); ++ struct nfsd_net *nn = net_generic(net, nfsd_net_id); + int i; + + seq_printf(seq, "rc %lld %lld %lld\nfh %lld 0 0 0 0\nio %lld %lld\n", +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_HITS]), +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_MISSES]), +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE]), +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_FH_STALE]), +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_IO_READ]), +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_IO_WRITE])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_HITS]), ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_MISSES]), ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_NOCACHE]), ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_FH_STALE]), ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_IO_READ]), ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_IO_WRITE])); + + /* thread usage: */ + seq_printf(seq, "th %u 0", atomic_read(&nfsdstats.th_cnt)); +@@ -63,10 +65,10 @@ static int nfsd_show(struct seq_file *seq, void *v) + seq_printf(seq, "proc4ops %u", LAST_NFS4_OP + 1); + for (i = 0; i <= LAST_NFS4_OP; i++) { + seq_printf(seq, " %lld", +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_NFS4_OP(i)])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_NFS4_OP(i)])); + } + seq_printf(seq, "\nwdeleg_getattr %lld", +- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_WDELEG_GETATTR])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_WDELEG_GETATTR])); + + seq_putc(seq, '\n'); + #endif +@@ -108,14 +110,14 @@ void nfsd_percpu_counters_destroy(struct percpu_counter counters[], int num) + percpu_counter_destroy(&counters[i]); + } + +-int nfsd_stat_counters_init(void) ++int nfsd_stat_counters_init(struct nfsd_net *nn) + { +- return nfsd_percpu_counters_init(nfsdstats.counter, NFSD_STATS_COUNTERS_NUM); ++ return nfsd_percpu_counters_init(nn->counter, NFSD_STATS_COUNTERS_NUM); + } + +-void nfsd_stat_counters_destroy(void) ++void nfsd_stat_counters_destroy(struct nfsd_net *nn) + { +- nfsd_percpu_counters_destroy(nfsdstats.counter, NFSD_STATS_COUNTERS_NUM); ++ nfsd_percpu_counters_destroy(nn->counter, NFSD_STATS_COUNTERS_NUM); + } + + void nfsd_proc_stat_init(struct net *net) +diff --git a/fs/nfsd/stats.h b/fs/nfsd/stats.h +index 38811aa7d13e1..c24be4ddbe7d7 100644 +--- a/fs/nfsd/stats.h ++++ b/fs/nfsd/stats.h +@@ -10,26 +10,7 @@ + #include + #include + +- +-enum { +- NFSD_STATS_RC_HITS, /* repcache hits */ +- NFSD_STATS_RC_MISSES, /* repcache misses */ +- NFSD_STATS_RC_NOCACHE, /* uncached reqs */ +- NFSD_STATS_FH_STALE, /* FH stale error */ +- NFSD_STATS_IO_READ, /* bytes returned to read requests */ +- NFSD_STATS_IO_WRITE, /* bytes passed in write requests */ +-#ifdef CONFIG_NFSD_V4 +- NFSD_STATS_FIRST_NFS4_OP, /* count of individual nfsv4 operations */ +- NFSD_STATS_LAST_NFS4_OP = NFSD_STATS_FIRST_NFS4_OP + LAST_NFS4_OP, +-#define NFSD_STATS_NFS4_OP(op) (NFSD_STATS_FIRST_NFS4_OP + (op)) +- NFSD_STATS_WDELEG_GETATTR, /* count of getattr conflict with wdeleg */ +-#endif +- NFSD_STATS_COUNTERS_NUM +-}; +- + struct nfsd_stats { +- struct percpu_counter counter[NFSD_STATS_COUNTERS_NUM]; +- + atomic_t th_cnt; /* number of available threads */ + }; + +@@ -40,43 +21,46 @@ extern struct svc_stat nfsd_svcstats; + int nfsd_percpu_counters_init(struct percpu_counter *counters, int num); + void nfsd_percpu_counters_reset(struct percpu_counter *counters, int num); + void nfsd_percpu_counters_destroy(struct percpu_counter *counters, int num); +-int nfsd_stat_counters_init(void); +-void nfsd_stat_counters_destroy(void); ++int nfsd_stat_counters_init(struct nfsd_net *nn); ++void nfsd_stat_counters_destroy(struct nfsd_net *nn); + void nfsd_proc_stat_init(struct net *net); + void nfsd_proc_stat_shutdown(struct net *net); + +-static inline void nfsd_stats_rc_hits_inc(void) ++static inline void nfsd_stats_rc_hits_inc(struct nfsd_net *nn) + { +- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_RC_HITS]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_RC_HITS]); + } + +-static inline void nfsd_stats_rc_misses_inc(void) ++static inline void nfsd_stats_rc_misses_inc(struct nfsd_net *nn) + { +- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_RC_MISSES]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_RC_MISSES]); + } + +-static inline void nfsd_stats_rc_nocache_inc(void) ++static inline void nfsd_stats_rc_nocache_inc(struct nfsd_net *nn) + { +- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_RC_NOCACHE]); + } + +-static inline void nfsd_stats_fh_stale_inc(struct svc_export *exp) ++static inline void nfsd_stats_fh_stale_inc(struct nfsd_net *nn, ++ struct svc_export *exp) + { +- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_FH_STALE]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_FH_STALE]); + if (exp && exp->ex_stats) + percpu_counter_inc(&exp->ex_stats->counter[EXP_STATS_FH_STALE]); + } + +-static inline void nfsd_stats_io_read_add(struct svc_export *exp, s64 amount) ++static inline void nfsd_stats_io_read_add(struct nfsd_net *nn, ++ struct svc_export *exp, s64 amount) + { +- percpu_counter_add(&nfsdstats.counter[NFSD_STATS_IO_READ], amount); ++ percpu_counter_add(&nn->counter[NFSD_STATS_IO_READ], amount); + if (exp && exp->ex_stats) + percpu_counter_add(&exp->ex_stats->counter[EXP_STATS_IO_READ], amount); + } + +-static inline void nfsd_stats_io_write_add(struct svc_export *exp, s64 amount) ++static inline void nfsd_stats_io_write_add(struct nfsd_net *nn, ++ struct svc_export *exp, s64 amount) + { +- percpu_counter_add(&nfsdstats.counter[NFSD_STATS_IO_WRITE], amount); ++ percpu_counter_add(&nn->counter[NFSD_STATS_IO_WRITE], amount); + if (exp && exp->ex_stats) + percpu_counter_add(&exp->ex_stats->counter[EXP_STATS_IO_WRITE], amount); + } +@@ -97,9 +81,9 @@ static inline void nfsd_stats_drc_mem_usage_sub(struct nfsd_net *nn, s64 amount) + } + + #ifdef CONFIG_NFSD_V4 +-static inline void nfsd_stats_wdeleg_getattr_inc(void) ++static inline void nfsd_stats_wdeleg_getattr_inc(struct nfsd_net *nn) + { +- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_WDELEG_GETATTR]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_WDELEG_GETATTR]); + } + #endif + #endif /* _NFSD_STATS_H */ +diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c +index 4ed1e83defa23..9b5e20b2d0387 100644 +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -1002,7 +1002,9 @@ static __be32 nfsd_finish_read(struct svc_rqst *rqstp, struct svc_fh *fhp, + unsigned long *count, u32 *eof, ssize_t host_err) + { + if (host_err >= 0) { +- nfsd_stats_io_read_add(fhp->fh_export, host_err); ++ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); ++ ++ nfsd_stats_io_read_add(nn, fhp->fh_export, host_err); + *eof = nfsd_eof_on_read(file, offset, host_err, *count); + *count = host_err; + fsnotify_access(file); +@@ -1185,7 +1187,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, + goto out_nfserr; + } + *cnt = host_err; +- nfsd_stats_io_write_add(exp, *cnt); ++ nfsd_stats_io_write_add(nn, exp, *cnt); + fsnotify_modify(file); + host_err = filemap_check_wb_err(file->f_mapping, since); + if (host_err < 0) +-- +2.43.0 + diff --git a/queue-6.8/nfsd-rename-nfsd_net_-to-nfsd_stats_.patch b/queue-6.8/nfsd-rename-nfsd_net_-to-nfsd_stats_.patch new file mode 100644 index 00000000000..e037272f4ef --- /dev/null +++ b/queue-6.8/nfsd-rename-nfsd_net_-to-nfsd_stats_.patch @@ -0,0 +1,90 @@ +From f75cd0cd4bed09bfa35bb1c1173b96bfce16f3f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Jan 2024 10:39:45 -0500 +Subject: nfsd: rename NFSD_NET_* to NFSD_STATS_* + +From: Josef Bacik + +[ Upstream commit d98416cc2154053950610bb6880911e3dcbdf8c5 ] + +We're going to merge the stats all into per network namespace in +subsequent patches, rename these nn counters to be consistent with the +rest of the stats. + +Signed-off-by: Josef Bacik +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Stable-dep-of: 18180a4550d0 ("NFSD: Fix nfsd4_encode_fattr4() crasher") +Signed-off-by: Sasha Levin +--- + fs/nfsd/netns.h | 4 ++-- + fs/nfsd/nfscache.c | 4 ++-- + fs/nfsd/stats.h | 6 +++--- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h +index 74b4360779a11..e3605cb5f044d 100644 +--- a/fs/nfsd/netns.h ++++ b/fs/nfsd/netns.h +@@ -26,9 +26,9 @@ struct nfsd4_client_tracking_ops; + + enum { + /* cache misses due only to checksum comparison failures */ +- NFSD_NET_PAYLOAD_MISSES, ++ NFSD_STATS_PAYLOAD_MISSES, + /* amount of memory (in bytes) currently consumed by the DRC */ +- NFSD_NET_DRC_MEM_USAGE, ++ NFSD_STATS_DRC_MEM_USAGE, + NFSD_NET_COUNTERS_NUM + }; + +diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c +index 5c1a4a0aa6056..3d4a9d181c43e 100644 +--- a/fs/nfsd/nfscache.c ++++ b/fs/nfsd/nfscache.c +@@ -687,7 +687,7 @@ int nfsd_reply_cache_stats_show(struct seq_file *m, void *v) + atomic_read(&nn->num_drc_entries)); + seq_printf(m, "hash buckets: %u\n", 1 << nn->maskbits); + seq_printf(m, "mem usage: %lld\n", +- percpu_counter_sum_positive(&nn->counter[NFSD_NET_DRC_MEM_USAGE])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_DRC_MEM_USAGE])); + seq_printf(m, "cache hits: %lld\n", + percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_HITS])); + seq_printf(m, "cache misses: %lld\n", +@@ -695,7 +695,7 @@ int nfsd_reply_cache_stats_show(struct seq_file *m, void *v) + seq_printf(m, "not cached: %lld\n", + percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE])); + seq_printf(m, "payload misses: %lld\n", +- percpu_counter_sum_positive(&nn->counter[NFSD_NET_PAYLOAD_MISSES])); ++ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_PAYLOAD_MISSES])); + seq_printf(m, "longest chain len: %u\n", nn->longest_chain); + seq_printf(m, "cachesize at longest: %u\n", nn->longest_chain_cachesize); + return 0; +diff --git a/fs/nfsd/stats.h b/fs/nfsd/stats.h +index 14f50c660b619..7ed4325ac6912 100644 +--- a/fs/nfsd/stats.h ++++ b/fs/nfsd/stats.h +@@ -81,17 +81,17 @@ static inline void nfsd_stats_io_write_add(struct svc_export *exp, s64 amount) + + static inline void nfsd_stats_payload_misses_inc(struct nfsd_net *nn) + { +- percpu_counter_inc(&nn->counter[NFSD_NET_PAYLOAD_MISSES]); ++ percpu_counter_inc(&nn->counter[NFSD_STATS_PAYLOAD_MISSES]); + } + + static inline void nfsd_stats_drc_mem_usage_add(struct nfsd_net *nn, s64 amount) + { +- percpu_counter_add(&nn->counter[NFSD_NET_DRC_MEM_USAGE], amount); ++ percpu_counter_add(&nn->counter[NFSD_STATS_DRC_MEM_USAGE], amount); + } + + static inline void nfsd_stats_drc_mem_usage_sub(struct nfsd_net *nn, s64 amount) + { +- percpu_counter_sub(&nn->counter[NFSD_NET_DRC_MEM_USAGE], amount); ++ percpu_counter_sub(&nn->counter[NFSD_STATS_DRC_MEM_USAGE], amount); + } + + #ifdef CONFIG_NFSD_V4 +-- +2.43.0 + diff --git a/queue-6.8/pinctrl-baytrail-fix-selecting-gpio-pinctrl-state.patch b/queue-6.8/pinctrl-baytrail-fix-selecting-gpio-pinctrl-state.patch new file mode 100644 index 00000000000..0f79db28e25 --- /dev/null +++ b/queue-6.8/pinctrl-baytrail-fix-selecting-gpio-pinctrl-state.patch @@ -0,0 +1,164 @@ +From 7ab01156d39ca022519bda0ef85b46c0dbf7ea03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Apr 2024 19:50:48 +0200 +Subject: pinctrl: baytrail: Fix selecting gpio pinctrl state + +From: Hans de Goede + +[ Upstream commit fed6d9a8e6a60ecf6506d0ea004040fbaa109927 ] + +For all the "score" pin-groups all the intel_pingroup-s to select +the non GPIO function are re-used for byt_score_gpio_groups[]. + +But this is incorrect since a pin-group includes the mode setting, +which for the non GPIO functions generally is 1, where as to select +the GPIO function mode must be set to 0. + +So the GPIO function needs separate intel_pingroup-s with their own mode +value of 0. + +Add a new PIN_GROUP_GPIO macro which adds a foo_gpio entry to each +pin-group defined this way and update byt_score_gpio_groups[] to point +to the new foo_gpio entries. + +The "sus" usb_oc_grp usb_ulpi_grp and pcu_spi_grp pin-groups are special +because these have a non 0 mode value to select the GPIO functions and +these already have matching foo_gpio pin-groups, leave these are unchanged. + +The pmu_clk "sus" groups added in commit 2f46d7f7e959 ("pinctrl: baytrail: +Add pinconf group + function for the pmu_clk") do need to use the new +PIN_GROUP_GPIO macro. + +Fixes: 2f46d7f7e959 ("pinctrl: baytrail: Add pinconf group + function for the pmu_clk") +Signed-off-by: Hans de Goede +Signed-off-by: Andy Shevchenko +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/intel/pinctrl-baytrail.c | 74 ++++++++++++------------ + drivers/pinctrl/intel/pinctrl-intel.h | 4 ++ + 2 files changed, 42 insertions(+), 36 deletions(-) + +diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c +index ac97724c59bae..1edb6041fb424 100644 +--- a/drivers/pinctrl/intel/pinctrl-baytrail.c ++++ b/drivers/pinctrl/intel/pinctrl-baytrail.c +@@ -278,33 +278,33 @@ static const unsigned int byt_score_plt_clk5_pins[] = { 101 }; + static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 }; + + static const struct intel_pingroup byt_score_groups[] = { +- PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1), +- PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1), +- PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1), +- PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1), +- PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1), +- PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1), +- PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1), +- PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1), +- PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1), +- PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1), +- PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1), +- PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1), +- PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1), +- PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1), +- PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1), +- PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values), +- PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1), +- PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1), +- PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1), +- PIN_GROUP("sata_grp", byt_score_sata_pins, 1), +- PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1), +- PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1), +- PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1), +- PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1), +- PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1), +- PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1), +- PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1), ++ PIN_GROUP_GPIO("uart1_grp", byt_score_uart1_pins, 1), ++ PIN_GROUP_GPIO("uart2_grp", byt_score_uart2_pins, 1), ++ PIN_GROUP_GPIO("pwm0_grp", byt_score_pwm0_pins, 1), ++ PIN_GROUP_GPIO("pwm1_grp", byt_score_pwm1_pins, 1), ++ PIN_GROUP_GPIO("ssp2_grp", byt_score_ssp2_pins, 1), ++ PIN_GROUP_GPIO("sio_spi_grp", byt_score_sio_spi_pins, 1), ++ PIN_GROUP_GPIO("i2c5_grp", byt_score_i2c5_pins, 1), ++ PIN_GROUP_GPIO("i2c6_grp", byt_score_i2c6_pins, 1), ++ PIN_GROUP_GPIO("i2c4_grp", byt_score_i2c4_pins, 1), ++ PIN_GROUP_GPIO("i2c3_grp", byt_score_i2c3_pins, 1), ++ PIN_GROUP_GPIO("i2c2_grp", byt_score_i2c2_pins, 1), ++ PIN_GROUP_GPIO("i2c1_grp", byt_score_i2c1_pins, 1), ++ PIN_GROUP_GPIO("i2c0_grp", byt_score_i2c0_pins, 1), ++ PIN_GROUP_GPIO("ssp0_grp", byt_score_ssp0_pins, 1), ++ PIN_GROUP_GPIO("ssp1_grp", byt_score_ssp1_pins, 1), ++ PIN_GROUP_GPIO("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values), ++ PIN_GROUP_GPIO("sdio_grp", byt_score_sdio_pins, 1), ++ PIN_GROUP_GPIO("emmc_grp", byt_score_emmc_pins, 1), ++ PIN_GROUP_GPIO("lpc_grp", byt_score_ilb_lpc_pins, 1), ++ PIN_GROUP_GPIO("sata_grp", byt_score_sata_pins, 1), ++ PIN_GROUP_GPIO("plt_clk0_grp", byt_score_plt_clk0_pins, 1), ++ PIN_GROUP_GPIO("plt_clk1_grp", byt_score_plt_clk1_pins, 1), ++ PIN_GROUP_GPIO("plt_clk2_grp", byt_score_plt_clk2_pins, 1), ++ PIN_GROUP_GPIO("plt_clk3_grp", byt_score_plt_clk3_pins, 1), ++ PIN_GROUP_GPIO("plt_clk4_grp", byt_score_plt_clk4_pins, 1), ++ PIN_GROUP_GPIO("plt_clk5_grp", byt_score_plt_clk5_pins, 1), ++ PIN_GROUP_GPIO("smbus_grp", byt_score_smbus_pins, 1), + }; + + static const char * const byt_score_uart_groups[] = { +@@ -332,12 +332,14 @@ static const char * const byt_score_plt_clk_groups[] = { + }; + static const char * const byt_score_smbus_groups[] = { "smbus_grp" }; + static const char * const byt_score_gpio_groups[] = { +- "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp", +- "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp", +- "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp", +- "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp", +- "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", +- "plt_clk4_grp", "plt_clk5_grp", "smbus_grp", ++ "uart1_grp_gpio", "uart2_grp_gpio", "pwm0_grp_gpio", ++ "pwm1_grp_gpio", "ssp0_grp_gpio", "ssp1_grp_gpio", "ssp2_grp_gpio", ++ "sio_spi_grp_gpio", "i2c0_grp_gpio", "i2c1_grp_gpio", "i2c2_grp_gpio", ++ "i2c3_grp_gpio", "i2c4_grp_gpio", "i2c5_grp_gpio", "i2c6_grp_gpio", ++ "sdcard_grp_gpio", "sdio_grp_gpio", "emmc_grp_gpio", "lpc_grp_gpio", ++ "sata_grp_gpio", "plt_clk0_grp_gpio", "plt_clk1_grp_gpio", ++ "plt_clk2_grp_gpio", "plt_clk3_grp_gpio", "plt_clk4_grp_gpio", ++ "plt_clk5_grp_gpio", "smbus_grp_gpio", + }; + + static const struct intel_function byt_score_functions[] = { +@@ -456,8 +458,8 @@ static const struct intel_pingroup byt_sus_groups[] = { + PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values), + PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values), + PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values), +- PIN_GROUP("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1), +- PIN_GROUP("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1), ++ PIN_GROUP_GPIO("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1), ++ PIN_GROUP_GPIO("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1), + }; + + static const char * const byt_sus_usb_groups[] = { +@@ -469,7 +471,7 @@ static const char * const byt_sus_pmu_clk_groups[] = { + }; + static const char * const byt_sus_gpio_groups[] = { + "usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio", +- "pmu_clk1_grp", "pmu_clk2_grp", ++ "pmu_clk1_grp_gpio", "pmu_clk2_grp_gpio", + }; + + static const struct intel_function byt_sus_functions[] = { +diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h +index fde65e18cd145..6981e2fab93f3 100644 +--- a/drivers/pinctrl/intel/pinctrl-intel.h ++++ b/drivers/pinctrl/intel/pinctrl-intel.h +@@ -179,6 +179,10 @@ struct intel_community { + .modes = __builtin_choose_expr(__builtin_constant_p((m)), NULL, (m)), \ + } + ++#define PIN_GROUP_GPIO(n, p, m) \ ++ PIN_GROUP(n, p, m), \ ++ PIN_GROUP(n "_gpio", p, 0) ++ + #define FUNCTION(n, g) \ + { \ + .func = PINCTRL_PINFUNCTION((n), (g), ARRAY_SIZE(g)), \ +-- +2.43.0 + diff --git a/queue-6.8/pinctrl-core-delete-incorrect-free-in-pinctrl_enable.patch b/queue-6.8/pinctrl-core-delete-incorrect-free-in-pinctrl_enable.patch new file mode 100644 index 00000000000..60b5101d105 --- /dev/null +++ b/queue-6.8/pinctrl-core-delete-incorrect-free-in-pinctrl_enable.patch @@ -0,0 +1,47 @@ +From 10b978bff9bd3edbdb6fa1cf66071e97e47e24e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Mar 2024 09:38:39 +0300 +Subject: pinctrl: core: delete incorrect free in pinctrl_enable() + +From: Dan Carpenter + +[ Upstream commit 5038a66dad0199de60e5671603ea6623eb9e5c79 ] + +The "pctldev" struct is allocated in devm_pinctrl_register_and_init(). +It's a devm_ managed pointer that is freed by devm_pinctrl_dev_release(), +so freeing it in pinctrl_enable() will lead to a double free. + +The devm_pinctrl_dev_release() function frees the pindescs and destroys +the mutex as well. + +Fixes: 6118714275f0 ("pinctrl: core: Fix pinctrl_register_and_init() with pinctrl_enable()") +Signed-off-by: Dan Carpenter +Message-ID: <578fbe56-44e9-487c-ae95-29b695650f7c@moroto.mountain> +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/core.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c +index bbcdece83bf42..ae975e1365dfd 100644 +--- a/drivers/pinctrl/core.c ++++ b/drivers/pinctrl/core.c +@@ -2120,13 +2120,7 @@ int pinctrl_enable(struct pinctrl_dev *pctldev) + + error = pinctrl_claim_hogs(pctldev); + if (error) { +- dev_err(pctldev->dev, "could not claim hogs: %i\n", +- error); +- pinctrl_free_pindescs(pctldev, pctldev->desc->pins, +- pctldev->desc->npins); +- mutex_destroy(&pctldev->mutex); +- kfree(pctldev); +- ++ dev_err(pctldev->dev, "could not claim hogs: %i\n", error); + return error; + } + +-- +2.43.0 + diff --git a/queue-6.8/pinctrl-devicetree-fix-refcount-leak-in-pinctrl_dt_t.patch b/queue-6.8/pinctrl-devicetree-fix-refcount-leak-in-pinctrl_dt_t.patch new file mode 100644 index 00000000000..9da2feebacf --- /dev/null +++ b/queue-6.8/pinctrl-devicetree-fix-refcount-leak-in-pinctrl_dt_t.patch @@ -0,0 +1,52 @@ +From 2cef26e15bf82d237a28e3cfabf6f433a8561fdb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Apr 2024 18:53:28 +0800 +Subject: pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map() + +From: Zeng Heng + +[ Upstream commit a0cedbcc8852d6c77b00634b81e41f17f29d9404 ] + +If we fail to allocate propname buffer, we need to drop the reference +count we just took. Because the pinctrl_dt_free_maps() includes the +droping operation, here we call it directly. + +Fixes: 91d5c5060ee2 ("pinctrl: devicetree: fix null pointer dereferencing in pinctrl_dt_to_map") +Suggested-by: Dan Carpenter +Signed-off-by: Zeng Heng +Reviewed-by: Dan Carpenter +Message-ID: <20240415105328.3651441-1-zengheng4@huawei.com> +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/devicetree.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c +index df1efc2e52025..6a94ecd6a8dea 100644 +--- a/drivers/pinctrl/devicetree.c ++++ b/drivers/pinctrl/devicetree.c +@@ -220,14 +220,16 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev) + for (state = 0; ; state++) { + /* Retrieve the pinctrl-* property */ + propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state); +- if (!propname) +- return -ENOMEM; ++ if (!propname) { ++ ret = -ENOMEM; ++ goto err; ++ } + prop = of_find_property(np, propname, &size); + kfree(propname); + if (!prop) { + if (state == 0) { +- of_node_put(np); +- return -ENODEV; ++ ret = -ENODEV; ++ goto err; + } + break; + } +-- +2.43.0 + diff --git a/queue-6.8/pinctrl-mediatek-paris-fix-pin_config_input_schmitt_.patch b/queue-6.8/pinctrl-mediatek-paris-fix-pin_config_input_schmitt_.patch new file mode 100644 index 00000000000..182571b7489 --- /dev/null +++ b/queue-6.8/pinctrl-mediatek-paris-fix-pin_config_input_schmitt_.patch @@ -0,0 +1,46 @@ +From 68fe5ee50790406f880b9cdd6df9d721cabd9f1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Mar 2024 17:13:33 +0800 +Subject: pinctrl: mediatek: paris: Fix PIN_CONFIG_INPUT_SCHMITT_ENABLE + readback + +From: Chen-Yu Tsai + +[ Upstream commit 08f66a8edd08f6f7cfa769c81634b29a2b123908 ] + +In the generic pin config library, readback of some options are handled +differently compared to the setting of those options: the argument value +is used to convey enable/disable of an option in the set path, but +success or -EINVAL is used to convey if an option is enabled or disabled +in the debugfs readback path. + +PIN_CONFIG_INPUT_SCHMITT_ENABLE is one such option. Fix the readback of +the option in the mediatek-paris library, so that the debugfs dump is +not showing "input schmitt enabled" for pins that don't have it enabled. + +Fixes: 1bea6afbc842 ("pinctrl: mediatek: Refine mtk_pinconf_get()") +Signed-off-by: Chen-Yu Tsai +Reviewed-by: AngeloGioacchino Del Regno +Message-ID: <20240327091336.3434141-2-wenst@chromium.org> +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/mediatek/pinctrl-paris.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c +index b6bc31abd2b06..9353f78a52f05 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-paris.c ++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c +@@ -193,6 +193,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, + } + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret); ++ if (!ret) ++ err = -EINVAL; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + if (!hw->soc->drive_get) +-- +2.43.0 + diff --git a/queue-6.8/pinctrl-mediatek-paris-rework-support-for-pin_config.patch b/queue-6.8/pinctrl-mediatek-paris-rework-support-for-pin_config.patch new file mode 100644 index 00000000000..9dce15ebc3f --- /dev/null +++ b/queue-6.8/pinctrl-mediatek-paris-rework-support-for-pin_config.patch @@ -0,0 +1,107 @@ +From e7b38d68431f4d7092c8877a1df503cead6b2cb0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Mar 2024 17:13:34 +0800 +Subject: pinctrl: mediatek: paris: Rework support for + PIN_CONFIG_{INPUT,OUTPUT}_ENABLE + +From: Chen-Yu Tsai + +[ Upstream commit c5d3b64c568a344e998830e0e94a7c04e372f89b ] + +There is a misinterpretation of some of the PIN_CONFIG_* options in this +driver library. PIN_CONFIG_OUTPUT_ENABLE should refer to a buffer or +switch in the output direction of the electrical path. The MediaTek +hardware does not have such a thing. The driver incorrectly maps this +option to the GPIO function's direction. + +Likewise, PIN_CONFIG_INPUT_ENABLE should refer to a buffer or switch in +the input direction. The hardware does have such a mechanism, and is +mapped to the IES bit. The driver however sets the direction in addition +to the IES bit, which is incorrect. On readback, the IES bit isn't even +considered. + +Ironically, the driver does not support readback for PIN_CONFIG_OUTPUT, +while its readback of PIN_CONFIG_{INPUT,OUTPUT}_ENABLE is what it should +be doing for PIN_CONFIG_OUTPUT. + +Rework support for these three options, so that PIN_CONFIG_OUTPUT_ENABLE +is completely removed, PIN_CONFIG_INPUT_ENABLE is only linked to the IES +bit, and PIN_CONFIG_OUTPUT is linked to the GPIO function's direction +and output level. + +Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings") +Signed-off-by: Chen-Yu Tsai +Reviewed-by: AngeloGioacchino Del Regno +Message-ID: <20240327091336.3434141-3-wenst@chromium.org> +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/mediatek/pinctrl-paris.c | 38 +++++++----------------- + 1 file changed, 11 insertions(+), 27 deletions(-) + +diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c +index 9353f78a52f05..b19bc391705ee 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-paris.c ++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c +@@ -165,20 +165,21 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret); + break; + case PIN_CONFIG_INPUT_ENABLE: +- case PIN_CONFIG_OUTPUT_ENABLE: ++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_IES, &ret); ++ if (!ret) ++ err = -EINVAL; ++ break; ++ case PIN_CONFIG_OUTPUT: + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); + if (err) + break; +- /* CONFIG Current direction return value +- * ------------- ----------------- ---------------------- +- * OUTPUT_ENABLE output 1 (= HW value) +- * input 0 (= HW value) +- * INPUT_ENABLE output 0 (= reverse HW value) +- * input 1 (= reverse HW value) +- */ +- if (param == PIN_CONFIG_INPUT_ENABLE) +- ret = !ret; + ++ if (!ret) { ++ err = -EINVAL; ++ break; ++ } ++ ++ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DO, &ret); + break; + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); +@@ -283,26 +284,9 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, + break; + err = hw->soc->bias_set_combo(hw, desc, 0, arg); + break; +- case PIN_CONFIG_OUTPUT_ENABLE: +- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, +- MTK_DISABLE); +- /* Keep set direction to consider the case that a GPIO pin +- * does not have SMT control +- */ +- if (err != -ENOTSUPP) +- break; +- +- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, +- MTK_OUTPUT); +- break; + case PIN_CONFIG_INPUT_ENABLE: + /* regard all non-zero value as enable */ + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg); +- if (err) +- break; +- +- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, +- MTK_INPUT); + break; + case PIN_CONFIG_SLEW_RATE: + /* regard all non-zero value as enable */ +-- +2.43.0 + diff --git a/queue-6.8/pinctrl-meson-fix-typo-in-pdm-s-pin-name.patch b/queue-6.8/pinctrl-meson-fix-typo-in-pdm-s-pin-name.patch new file mode 100644 index 00000000000..aaf50c00783 --- /dev/null +++ b/queue-6.8/pinctrl-meson-fix-typo-in-pdm-s-pin-name.patch @@ -0,0 +1,56 @@ +From 8410033b79aae90c8d2078c1722804aae4cd3e8a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Mar 2024 14:30:58 +0300 +Subject: pinctrl/meson: fix typo in PDM's pin name + +From: Jan Dakinevich + +[ Upstream commit 368a90e651faeeb7049a876599cf2b0d74954796 ] + +Other pins have _a or _x suffix, but this one doesn't have any. Most +likely this is a typo. + +Fixes: dabad1ff8561 ("pinctrl: meson: add pinctrl driver support for Meson-A1 SoC") +Signed-off-by: Jan Dakinevich +Reviewed-by: Neil Armstrong +Message-ID: <20240325113058.248022-1-jan.dakinevich@salutedevices.com> +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/meson/pinctrl-meson-a1.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/pinctrl/meson/pinctrl-meson-a1.c b/drivers/pinctrl/meson/pinctrl-meson-a1.c +index 79f5d753d7e1a..50a87d9618a8e 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson-a1.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-a1.c +@@ -250,7 +250,7 @@ static const unsigned int pdm_dclk_x_pins[] = { GPIOX_10 }; + static const unsigned int pdm_din2_a_pins[] = { GPIOA_6 }; + static const unsigned int pdm_din1_a_pins[] = { GPIOA_7 }; + static const unsigned int pdm_din0_a_pins[] = { GPIOA_8 }; +-static const unsigned int pdm_dclk_pins[] = { GPIOA_9 }; ++static const unsigned int pdm_dclk_a_pins[] = { GPIOA_9 }; + + /* gen_clk */ + static const unsigned int gen_clk_x_pins[] = { GPIOX_7 }; +@@ -591,7 +591,7 @@ static struct meson_pmx_group meson_a1_periphs_groups[] = { + GROUP(pdm_din2_a, 3), + GROUP(pdm_din1_a, 3), + GROUP(pdm_din0_a, 3), +- GROUP(pdm_dclk, 3), ++ GROUP(pdm_dclk_a, 3), + GROUP(pwm_c_a, 3), + GROUP(pwm_b_a, 3), + +@@ -755,7 +755,7 @@ static const char * const spi_a_groups[] = { + + static const char * const pdm_groups[] = { + "pdm_din0_x", "pdm_din1_x", "pdm_din2_x", "pdm_dclk_x", "pdm_din2_a", +- "pdm_din1_a", "pdm_din0_a", "pdm_dclk", ++ "pdm_din1_a", "pdm_din0_a", "pdm_dclk_a", + }; + + static const char * const gen_clk_groups[] = { +-- +2.43.0 + diff --git a/queue-6.8/pinctrl-pinctrl-aspeed-g6-fix-register-offset-for-pi.patch b/queue-6.8/pinctrl-pinctrl-aspeed-g6-fix-register-offset-for-pi.patch new file mode 100644 index 00000000000..6703df450e4 --- /dev/null +++ b/queue-6.8/pinctrl-pinctrl-aspeed-g6-fix-register-offset-for-pi.patch @@ -0,0 +1,97 @@ +From 6f465cac20d68f5befb1d15400412fc77e7a4b62 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Mar 2024 17:28:09 +0800 +Subject: pinctrl: pinctrl-aspeed-g6: Fix register offset for pinconf of + GPIOR-T + +From: Billy Tsai + +[ Upstream commit c10cd03d69403fa0f00be8631bd4cb4690440ebd ] + +The register offset to disable the internal pull-down of GPIOR~T is 0x630 +instead of 0x620, as specified in the Ast2600 datasheet v15 +The datasheet can download from the official Aspeed website. + +Fixes: 15711ba6ff19 ("pinctrl: aspeed-g6: Add AST2600 pinconf support") +Reported-by: Delphine CC Chiu +Signed-off-by: Billy Tsai +Reviewed-by: Paul Menzel +Reviewed-by: Andrew Jeffery +Message-ID: <20240313092809.2596644-1-billy_tsai@aspeedtech.com> +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c | 34 +++++++++++----------- + 1 file changed, 17 insertions(+), 17 deletions(-) + +diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +index d376fa7114d1a..029efe16f8cc2 100644 +--- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c ++++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +@@ -43,7 +43,7 @@ + #define SCU614 0x614 /* Disable GPIO Internal Pull-Down #1 */ + #define SCU618 0x618 /* Disable GPIO Internal Pull-Down #2 */ + #define SCU61C 0x61c /* Disable GPIO Internal Pull-Down #3 */ +-#define SCU620 0x620 /* Disable GPIO Internal Pull-Down #4 */ ++#define SCU630 0x630 /* Disable GPIO Internal Pull-Down #4 */ + #define SCU634 0x634 /* Disable GPIO Internal Pull-Down #5 */ + #define SCU638 0x638 /* Disable GPIO Internal Pull-Down #6 */ + #define SCU690 0x690 /* Multi-function Pin Control #24 */ +@@ -2495,38 +2495,38 @@ static struct aspeed_pin_config aspeed_g6_configs[] = { + ASPEED_PULL_DOWN_PINCONF(D14, SCU61C, 0), + + /* GPIOS7 */ +- ASPEED_PULL_DOWN_PINCONF(T24, SCU620, 23), ++ ASPEED_PULL_DOWN_PINCONF(T24, SCU630, 23), + /* GPIOS6 */ +- ASPEED_PULL_DOWN_PINCONF(P23, SCU620, 22), ++ ASPEED_PULL_DOWN_PINCONF(P23, SCU630, 22), + /* GPIOS5 */ +- ASPEED_PULL_DOWN_PINCONF(P24, SCU620, 21), ++ ASPEED_PULL_DOWN_PINCONF(P24, SCU630, 21), + /* GPIOS4 */ +- ASPEED_PULL_DOWN_PINCONF(R26, SCU620, 20), ++ ASPEED_PULL_DOWN_PINCONF(R26, SCU630, 20), + /* GPIOS3*/ +- ASPEED_PULL_DOWN_PINCONF(R24, SCU620, 19), ++ ASPEED_PULL_DOWN_PINCONF(R24, SCU630, 19), + /* GPIOS2 */ +- ASPEED_PULL_DOWN_PINCONF(T26, SCU620, 18), ++ ASPEED_PULL_DOWN_PINCONF(T26, SCU630, 18), + /* GPIOS1 */ +- ASPEED_PULL_DOWN_PINCONF(T25, SCU620, 17), ++ ASPEED_PULL_DOWN_PINCONF(T25, SCU630, 17), + /* GPIOS0 */ +- ASPEED_PULL_DOWN_PINCONF(R23, SCU620, 16), ++ ASPEED_PULL_DOWN_PINCONF(R23, SCU630, 16), + + /* GPIOR7 */ +- ASPEED_PULL_DOWN_PINCONF(U26, SCU620, 15), ++ ASPEED_PULL_DOWN_PINCONF(U26, SCU630, 15), + /* GPIOR6 */ +- ASPEED_PULL_DOWN_PINCONF(W26, SCU620, 14), ++ ASPEED_PULL_DOWN_PINCONF(W26, SCU630, 14), + /* GPIOR5 */ +- ASPEED_PULL_DOWN_PINCONF(T23, SCU620, 13), ++ ASPEED_PULL_DOWN_PINCONF(T23, SCU630, 13), + /* GPIOR4 */ +- ASPEED_PULL_DOWN_PINCONF(U25, SCU620, 12), ++ ASPEED_PULL_DOWN_PINCONF(U25, SCU630, 12), + /* GPIOR3*/ +- ASPEED_PULL_DOWN_PINCONF(V26, SCU620, 11), ++ ASPEED_PULL_DOWN_PINCONF(V26, SCU630, 11), + /* GPIOR2 */ +- ASPEED_PULL_DOWN_PINCONF(V24, SCU620, 10), ++ ASPEED_PULL_DOWN_PINCONF(V24, SCU630, 10), + /* GPIOR1 */ +- ASPEED_PULL_DOWN_PINCONF(U24, SCU620, 9), ++ ASPEED_PULL_DOWN_PINCONF(U24, SCU630, 9), + /* GPIOR0 */ +- ASPEED_PULL_DOWN_PINCONF(V25, SCU620, 8), ++ ASPEED_PULL_DOWN_PINCONF(V25, SCU630, 8), + + /* GPIOX7 */ + ASPEED_PULL_DOWN_PINCONF(AB10, SCU634, 31), +-- +2.43.0 + diff --git a/queue-6.8/power-rt9455-hide-unused-rt9455_boost_voltage_values.patch b/queue-6.8/power-rt9455-hide-unused-rt9455_boost_voltage_values.patch new file mode 100644 index 00000000000..caaebd571ea --- /dev/null +++ b/queue-6.8/power-rt9455-hide-unused-rt9455_boost_voltage_values.patch @@ -0,0 +1,48 @@ +From a9edb16c3ce325ddbfe781a2c0967faa65930561 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Apr 2024 10:06:27 +0200 +Subject: power: rt9455: hide unused rt9455_boost_voltage_values + +From: Arnd Bergmann + +[ Upstream commit 452d8950db3e839aba1bb13bc5378f4bac11fa04 ] + +The rt9455_boost_voltage_values[] array is only used when USB PHY +support is enabled, causing a W=1 warning otherwise: + +drivers/power/supply/rt9455_charger.c:200:18: error: 'rt9455_boost_voltage_values' defined but not used [-Werror=unused-const-variable=] + +Enclose the definition in the same #ifdef as the references to it. + +Fixes: e86d69dd786e ("power_supply: Add support for Richtek RT9455 battery charger") +Signed-off-by: Arnd Bergmann +Link: https://lore.kernel.org/r/20240403080702.3509288-10-arnd@kernel.org +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/rt9455_charger.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/power/supply/rt9455_charger.c b/drivers/power/supply/rt9455_charger.c +index c345a77f9f78c..e4dbacd50a437 100644 +--- a/drivers/power/supply/rt9455_charger.c ++++ b/drivers/power/supply/rt9455_charger.c +@@ -192,6 +192,7 @@ static const int rt9455_voreg_values[] = { + 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000 + }; + ++#if IS_ENABLED(CONFIG_USB_PHY) + /* + * When the charger is in boost mode, REG02[7:2] represent boost output + * voltage. +@@ -207,6 +208,7 @@ static const int rt9455_boost_voltage_values[] = { + 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, + 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, + }; ++#endif + + /* REG07[3:0] (VMREG) in uV */ + static const int rt9455_vmreg_values[] = { +-- +2.43.0 + diff --git a/queue-6.8/power-supply-mt6360_charger-fix-of_match-for-usb-otg.patch b/queue-6.8/power-supply-mt6360_charger-fix-of_match-for-usb-otg.patch new file mode 100644 index 00000000000..1b845fc2988 --- /dev/null +++ b/queue-6.8/power-supply-mt6360_charger-fix-of_match-for-usb-otg.patch @@ -0,0 +1,46 @@ +From b067ae77f5463446dc69bdd0a9b8eaf136382e3e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Apr 2024 10:44:05 +0200 +Subject: power: supply: mt6360_charger: Fix of_match for usb-otg-vbus + regulator + +From: AngeloGioacchino Del Regno + +[ Upstream commit 1e0fb113646182e073539db96016b00cfeb18ecc ] + +The of_match shall correspond to the name of the regulator subnode, +or the deprecated `regulator-compatible` property must be used: +failing to do so, the regulator won't probe (and the driver will +as well not probe). + +Since the devicetree binding for this driver is actually correct +and wants DTs to use the "usb-otg-vbus-regulator" subnode name, +fix this driver by aligning the `of_match` string to what the DT +binding wants. + +Fixes: 0402e8ebb8b8 ("power: supply: mt6360_charger: add MT6360 charger support") +Signed-off-by: AngeloGioacchino Del Regno +Reviewed-by: Chen-Yu Tsai +Link: https://lore.kernel.org/r/20240410084405.1389378-1-angelogioacchino.delregno@collabora.com +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/mt6360_charger.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/power/supply/mt6360_charger.c b/drivers/power/supply/mt6360_charger.c +index 1305cba61edd4..aca123783efcc 100644 +--- a/drivers/power/supply/mt6360_charger.c ++++ b/drivers/power/supply/mt6360_charger.c +@@ -588,7 +588,7 @@ static const struct regulator_ops mt6360_chg_otg_ops = { + }; + + static const struct regulator_desc mt6360_otg_rdesc = { +- .of_match = "usb-otg-vbus", ++ .of_match = "usb-otg-vbus-regulator", + .name = "usb-otg-vbus", + .ops = &mt6360_chg_otg_ops, + .owner = THIS_MODULE, +-- +2.43.0 + diff --git a/queue-6.8/regulator-change-devm_regulator_get_enable_optional-.patch b/queue-6.8/regulator-change-devm_regulator_get_enable_optional-.patch new file mode 100644 index 00000000000..6ac59270493 --- /dev/null +++ b/queue-6.8/regulator-change-devm_regulator_get_enable_optional-.patch @@ -0,0 +1,52 @@ +From 468f65adbb374509f6a28311b92313307dd122de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Apr 2024 14:38:28 +0300 +Subject: regulator: change devm_regulator_get_enable_optional() stub to return + Ok + +From: Matti Vaittinen + +[ Upstream commit ff33132605c1a0acea59e4c523cb7c6fabe856b2 ] + +The devm_regulator_get_enable_optional() should be a 'call and forget' +API, meaning, when it is used to enable the regulators, the API does not +provide a handle to do any further control of the regulators. It gives +no real benefit to return an error from the stub if CONFIG_REGULATOR is +not set. + +On the contrary, returning an error is causing problems to drivers when +hardware is such it works out just fine with no regulator control. +Returning an error forces drivers to specifically handle the case where +CONFIG_REGULATOR is not set, making the mere existence of the stub +questionalble. + +Change the stub implementation for the +devm_regulator_get_enable_optional() to return Ok so drivers do not +separately handle the case where the CONFIG_REGULATOR is not set. + +Signed-off-by: Matti Vaittinen +Fixes: da279e6965b3 ("regulator: Add devm helpers for get and enable") +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/ZiedtOE00Zozd3XO@fedora +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + include/linux/regulator/consumer.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h +index 71232fb7dda31..ed180ca419dad 100644 +--- a/include/linux/regulator/consumer.h ++++ b/include/linux/regulator/consumer.h +@@ -326,7 +326,7 @@ static inline int devm_regulator_get_enable(struct device *dev, const char *id) + static inline int devm_regulator_get_enable_optional(struct device *dev, + const char *id) + { +- return -ENODEV; ++ return 0; + } + + static inline struct regulator *__must_check +-- +2.43.0 + diff --git a/queue-6.8/regulator-change-stubbed-devm_regulator_get_enable-t.patch b/queue-6.8/regulator-change-stubbed-devm_regulator_get_enable-t.patch new file mode 100644 index 00000000000..bc641c67eb8 --- /dev/null +++ b/queue-6.8/regulator-change-stubbed-devm_regulator_get_enable-t.patch @@ -0,0 +1,54 @@ +From bc395b896c786d1bcf818dfc87117d5c9488297d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Apr 2024 09:38:33 +0300 +Subject: regulator: change stubbed devm_regulator_get_enable to return Ok + +From: Matti Vaittinen + +[ Upstream commit 96e20adc43c4f81e9163a5188cee75a6dd393e09 ] + +The devm_regulator_get_enable() should be a 'call and forget' API, +meaning, when it is used to enable the regulators, the API does not +provide a handle to do any further control of the regulators. It gives +no real benefit to return an error from the stub if CONFIG_REGULATOR is +not set. + +On the contrary, returning and error is causing problems to drivers when +hardware is such it works out just fine with no regulator control. +Returning an error forces drivers to specifically handle the case where +CONFIG_REGULATOR is not set, making the mere existence of the stub +questionalble. Furthermore, the stub of the regulator_enable() seems to +be returning Ok. + +Change the stub implementation for the devm_regulator_get_enable() to +return Ok so drivers do not separately handle the case where the +CONFIG_REGULATOR is not set. + +Signed-off-by: Matti Vaittinen +Reported-by: Aleksander Mazur +Suggested-by: Guenter Roeck +Fixes: da279e6965b3 ("regulator: Add devm helpers for get and enable") +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/ZiYF6d1V1vSPcsJS@drtxq0yyyyyyyyyyyyyby-3.rev.dnainternet.fi +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + include/linux/regulator/consumer.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h +index 4660582a33022..71232fb7dda31 100644 +--- a/include/linux/regulator/consumer.h ++++ b/include/linux/regulator/consumer.h +@@ -320,7 +320,7 @@ devm_regulator_get_exclusive(struct device *dev, const char *id) + + static inline int devm_regulator_get_enable(struct device *dev, const char *id) + { +- return -ENODEV; ++ return 0; + } + + static inline int devm_regulator_get_enable_optional(struct device *dev, +-- +2.43.0 + diff --git a/queue-6.8/regulator-mt6360-de-capitalize-devicetree-regulator-.patch b/queue-6.8/regulator-mt6360-de-capitalize-devicetree-regulator-.patch new file mode 100644 index 00000000000..0b1a02c66ea --- /dev/null +++ b/queue-6.8/regulator-mt6360-de-capitalize-devicetree-regulator-.patch @@ -0,0 +1,93 @@ +From 723b0df2eb0c461b61eb7ee6c22587ad09517b1e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Apr 2024 16:44:38 +0200 +Subject: regulator: mt6360: De-capitalize devicetree regulator subnodes + +From: AngeloGioacchino Del Regno + +[ Upstream commit d3cf8a17498dd9104c04ad28eeac3ef3339f9f9f ] + +The MT6360 regulator binding, the example in the MT6360 mfd binding, and +the devicetree users of those bindings are rightfully declaring MT6360 +regulator subnodes with non-capital names, and luckily without using the +deprecated regulator-compatible property. + +With this driver declaring capitalized BUCKx/LDOx as of_match string for +the node names, obviously no regulator gets probed: fix that by changing +the MT6360_REGULATOR_DESC macro to add a "match" parameter which gets +assigned to the of_match. + +Fixes: d321571d5e4c ("regulator: mt6360: Add support for MT6360 regulator") +Signed-off-by: AngeloGioacchino Del Regno +Link: https://msgid.link/r/20240409144438.410060-1-angelogioacchino.delregno@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/mt6360-regulator.c | 32 +++++++++++++++++----------- + 1 file changed, 20 insertions(+), 12 deletions(-) + +diff --git a/drivers/regulator/mt6360-regulator.c b/drivers/regulator/mt6360-regulator.c +index ad6587a378d09..24cc9fc94e900 100644 +--- a/drivers/regulator/mt6360-regulator.c ++++ b/drivers/regulator/mt6360-regulator.c +@@ -319,15 +319,15 @@ static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode) + } + } + +-#define MT6360_REGULATOR_DESC(_name, _sname, ereg, emask, vreg, vmask, \ +- mreg, mmask, streg, stmask, vranges, \ +- vcnts, offon_delay, irq_tbls) \ ++#define MT6360_REGULATOR_DESC(match, _name, _sname, ereg, emask, vreg, \ ++ vmask, mreg, mmask, streg, stmask, \ ++ vranges, vcnts, offon_delay, irq_tbls) \ + { \ + .desc = { \ + .name = #_name, \ + .supply_name = #_sname, \ + .id = MT6360_REGULATOR_##_name, \ +- .of_match = of_match_ptr(#_name), \ ++ .of_match = of_match_ptr(match), \ + .regulators_node = of_match_ptr("regulator"), \ + .of_map_mode = mt6360_regulator_of_map_mode, \ + .owner = THIS_MODULE, \ +@@ -351,21 +351,29 @@ static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode) + } + + static const struct mt6360_regulator_desc mt6360_regulator_descs[] = { +- MT6360_REGULATOR_DESC(BUCK1, BUCK1_VIN, 0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04, ++ MT6360_REGULATOR_DESC("buck1", BUCK1, BUCK1_VIN, ++ 0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04, + buck_vout_ranges, 256, 0, buck1_irq_tbls), +- MT6360_REGULATOR_DESC(BUCK2, BUCK2_VIN, 0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04, ++ MT6360_REGULATOR_DESC("buck2", BUCK2, BUCK2_VIN, ++ 0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04, + buck_vout_ranges, 256, 0, buck2_irq_tbls), +- MT6360_REGULATOR_DESC(LDO6, LDO_VIN3, 0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04, ++ MT6360_REGULATOR_DESC("ldo6", LDO6, LDO_VIN3, ++ 0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04, + ldo_vout_ranges1, 256, 0, ldo6_irq_tbls), +- MT6360_REGULATOR_DESC(LDO7, LDO_VIN3, 0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04, ++ MT6360_REGULATOR_DESC("ldo7", LDO7, LDO_VIN3, ++ 0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04, + ldo_vout_ranges1, 256, 0, ldo7_irq_tbls), +- MT6360_REGULATOR_DESC(LDO1, LDO_VIN1, 0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04, ++ MT6360_REGULATOR_DESC("ldo1", LDO1, LDO_VIN1, ++ 0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04, + ldo_vout_ranges2, 256, 0, ldo1_irq_tbls), +- MT6360_REGULATOR_DESC(LDO2, LDO_VIN1, 0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04, ++ MT6360_REGULATOR_DESC("ldo2", LDO2, LDO_VIN1, ++ 0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04, + ldo_vout_ranges2, 256, 0, ldo2_irq_tbls), +- MT6360_REGULATOR_DESC(LDO3, LDO_VIN1, 0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04, ++ MT6360_REGULATOR_DESC("ldo3", LDO3, LDO_VIN1, ++ 0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04, + ldo_vout_ranges2, 256, 100, ldo3_irq_tbls), +- MT6360_REGULATOR_DESC(LDO5, LDO_VIN2, 0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04, ++ MT6360_REGULATOR_DESC("ldo5", LDO5, LDO_VIN2, ++ 0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04, + ldo_vout_ranges3, 128, 100, ldo5_irq_tbls), + }; + +-- +2.43.0 + diff --git a/queue-6.8/rust-macros-fix-soundness-issue-in-module-macro.patch b/queue-6.8/rust-macros-fix-soundness-issue-in-module-macro.patch new file mode 100644 index 00000000000..fd28e6288a7 --- /dev/null +++ b/queue-6.8/rust-macros-fix-soundness-issue-in-module-macro.patch @@ -0,0 +1,266 @@ +From 7ac85230cdab8d8b8466da4c9f80108909090f24 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Apr 2024 18:52:50 +0000 +Subject: rust: macros: fix soundness issue in `module!` macro +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Benno Lossin + +[ Upstream commit 7044dcff8301b29269016ebd17df27c4736140d2 ] + +The `module!` macro creates glue code that are called by C to initialize +the Rust modules using the `Module::init` function. Part of this glue +code are the local functions `__init` and `__exit` that are used to +initialize/destroy the Rust module. + +These functions are safe and also visible to the Rust mod in which the +`module!` macro is invoked. This means that they can be called by other +safe Rust code. But since they contain `unsafe` blocks that rely on only +being called at the right time, this is a soundness issue. + +Wrap these generated functions inside of two private modules, this +guarantees that the public functions cannot be called from the outside. +Make the safe functions `unsafe` and add SAFETY comments. + +Cc: stable@vger.kernel.org +Reported-by: Björn Roy Baron +Closes: https://github.com/Rust-for-Linux/linux/issues/629 +Fixes: 1fbde52bde73 ("rust: add `macros` crate") +Signed-off-by: Benno Lossin +Reviewed-by: Wedson Almeida Filho +Link: https://lore.kernel.org/r/20240401185222.12015-1-benno.lossin@proton.me +[ Moved `THIS_MODULE` out of the private-in-private modules since it + should remain public, as Dirk Behme noticed [1]. Capitalized comments, + avoided newline in non-list SAFETY comments and reworded to add + Reported-by and newline. ] +Link: https://rust-for-linux.zulipchat.com/#narrow/stream/291565-Help/topic/x/near/433512583 [1] +Signed-off-by: Miguel Ojeda +Signed-off-by: Sasha Levin +--- + rust/macros/module.rs | 190 +++++++++++++++++++++++++----------------- + 1 file changed, 115 insertions(+), 75 deletions(-) + +diff --git a/rust/macros/module.rs b/rust/macros/module.rs +index 27979e582e4b9..acd0393b50957 100644 +--- a/rust/macros/module.rs ++++ b/rust/macros/module.rs +@@ -199,17 +199,6 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { + /// Used by the printing macros, e.g. [`info!`]. + const __LOG_PREFIX: &[u8] = b\"{name}\\0\"; + +- /// The \"Rust loadable module\" mark. +- // +- // This may be best done another way later on, e.g. as a new modinfo +- // key or a new section. For the moment, keep it simple. +- #[cfg(MODULE)] +- #[doc(hidden)] +- #[used] +- static __IS_RUST_MODULE: () = (); +- +- static mut __MOD: Option<{type_}> = None; +- + // SAFETY: `__this_module` is constructed by the kernel at load time and will not be + // freed until the module is unloaded. + #[cfg(MODULE)] +@@ -221,81 +210,132 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { + kernel::ThisModule::from_ptr(core::ptr::null_mut()) + }}; + +- // Loadable modules need to export the `{{init,cleanup}}_module` identifiers. +- /// # Safety +- /// +- /// This function must not be called after module initialization, because it may be +- /// freed after that completes. +- #[cfg(MODULE)] +- #[doc(hidden)] +- #[no_mangle] +- #[link_section = \".init.text\"] +- pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{ +- __init() +- }} +- +- #[cfg(MODULE)] +- #[doc(hidden)] +- #[no_mangle] +- pub extern \"C\" fn cleanup_module() {{ +- __exit() +- }} ++ // Double nested modules, since then nobody can access the public items inside. ++ mod __module_init {{ ++ mod __module_init {{ ++ use super::super::{type_}; ++ ++ /// The \"Rust loadable module\" mark. ++ // ++ // This may be best done another way later on, e.g. as a new modinfo ++ // key or a new section. For the moment, keep it simple. ++ #[cfg(MODULE)] ++ #[doc(hidden)] ++ #[used] ++ static __IS_RUST_MODULE: () = (); ++ ++ static mut __MOD: Option<{type_}> = None; ++ ++ // Loadable modules need to export the `{{init,cleanup}}_module` identifiers. ++ /// # Safety ++ /// ++ /// This function must not be called after module initialization, because it may be ++ /// freed after that completes. ++ #[cfg(MODULE)] ++ #[doc(hidden)] ++ #[no_mangle] ++ #[link_section = \".init.text\"] ++ pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{ ++ // SAFETY: This function is inaccessible to the outside due to the double ++ // module wrapping it. It is called exactly once by the C side via its ++ // unique name. ++ unsafe {{ __init() }} ++ }} + +- // Built-in modules are initialized through an initcall pointer +- // and the identifiers need to be unique. +- #[cfg(not(MODULE))] +- #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))] +- #[doc(hidden)] +- #[link_section = \"{initcall_section}\"] +- #[used] +- pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init; ++ #[cfg(MODULE)] ++ #[doc(hidden)] ++ #[no_mangle] ++ pub extern \"C\" fn cleanup_module() {{ ++ // SAFETY: ++ // - This function is inaccessible to the outside due to the double ++ // module wrapping it. It is called exactly once by the C side via its ++ // unique name, ++ // - furthermore it is only called after `init_module` has returned `0` ++ // (which delegates to `__init`). ++ unsafe {{ __exit() }} ++ }} + +- #[cfg(not(MODULE))] +- #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] +- core::arch::global_asm!( +- r#\".section \"{initcall_section}\", \"a\" +- __{name}_initcall: +- .long __{name}_init - . +- .previous +- \"# +- ); ++ // Built-in modules are initialized through an initcall pointer ++ // and the identifiers need to be unique. ++ #[cfg(not(MODULE))] ++ #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))] ++ #[doc(hidden)] ++ #[link_section = \"{initcall_section}\"] ++ #[used] ++ pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init; ++ ++ #[cfg(not(MODULE))] ++ #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] ++ core::arch::global_asm!( ++ r#\".section \"{initcall_section}\", \"a\" ++ __{name}_initcall: ++ .long __{name}_init - . ++ .previous ++ \"# ++ ); ++ ++ #[cfg(not(MODULE))] ++ #[doc(hidden)] ++ #[no_mangle] ++ pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{ ++ // SAFETY: This function is inaccessible to the outside due to the double ++ // module wrapping it. It is called exactly once by the C side via its ++ // placement above in the initcall section. ++ unsafe {{ __init() }} ++ }} + +- #[cfg(not(MODULE))] +- #[doc(hidden)] +- #[no_mangle] +- pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{ +- __init() +- }} ++ #[cfg(not(MODULE))] ++ #[doc(hidden)] ++ #[no_mangle] ++ pub extern \"C\" fn __{name}_exit() {{ ++ // SAFETY: ++ // - This function is inaccessible to the outside due to the double ++ // module wrapping it. It is called exactly once by the C side via its ++ // unique name, ++ // - furthermore it is only called after `__{name}_init` has returned `0` ++ // (which delegates to `__init`). ++ unsafe {{ __exit() }} ++ }} + +- #[cfg(not(MODULE))] +- #[doc(hidden)] +- #[no_mangle] +- pub extern \"C\" fn __{name}_exit() {{ +- __exit() +- }} ++ /// # Safety ++ /// ++ /// This function must only be called once. ++ unsafe fn __init() -> core::ffi::c_int {{ ++ match <{type_} as kernel::Module>::init(&super::super::THIS_MODULE) {{ ++ Ok(m) => {{ ++ // SAFETY: No data race, since `__MOD` can only be accessed by this ++ // module and there only `__init` and `__exit` access it. These ++ // functions are only called once and `__exit` cannot be called ++ // before or during `__init`. ++ unsafe {{ ++ __MOD = Some(m); ++ }} ++ return 0; ++ }} ++ Err(e) => {{ ++ return e.to_errno(); ++ }} ++ }} ++ }} + +- fn __init() -> core::ffi::c_int {{ +- match <{type_} as kernel::Module>::init(&THIS_MODULE) {{ +- Ok(m) => {{ ++ /// # Safety ++ /// ++ /// This function must ++ /// - only be called once, ++ /// - be called after `__init` has been called and returned `0`. ++ unsafe fn __exit() {{ ++ // SAFETY: No data race, since `__MOD` can only be accessed by this module ++ // and there only `__init` and `__exit` access it. These functions are only ++ // called once and `__init` was already called. + unsafe {{ +- __MOD = Some(m); ++ // Invokes `drop()` on `__MOD`, which should be used for cleanup. ++ __MOD = None; + }} +- return 0; +- }} +- Err(e) => {{ +- return e.to_errno(); + }} +- }} +- }} + +- fn __exit() {{ +- unsafe {{ +- // Invokes `drop()` on `__MOD`, which should be used for cleanup. +- __MOD = None; ++ {modinfo} + }} + }} +- +- {modinfo} + ", + type_ = info.type_, + name = info.name, +-- +2.43.0 + diff --git a/queue-6.8/rust-module-place-generated-init_module-function-in-.patch b/queue-6.8/rust-module-place-generated-init_module-function-in-.patch new file mode 100644 index 00000000000..c42c9a022ac --- /dev/null +++ b/queue-6.8/rust-module-place-generated-init_module-function-in-.patch @@ -0,0 +1,74 @@ +From 8a3f314b75643431052edd923a52af28a7a92413 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Feb 2024 08:38:06 -0700 +Subject: rust: module: place generated init_module() function in .init.text + +From: Thomas Bertschinger + +[ Upstream commit 1b6170ff7a203a5e8354f19b7839fe8b897a9c0d ] + +Currently Rust kernel modules have their init code placed in the `.text` +section of the .ko file. I don't think this causes any real problems +for Rust modules as long as all code called during initialization lives +in `.text`. + +However, if a Rust `init_module()` function (that lives in `.text`) +calls a function marked with `__init` (in C) or +`#[link_section = ".init.text"]` (in Rust), then a warning is +generated by modpost because that function lives in `.init.text`. +For example: + +WARNING: modpost: fs/bcachefs/bcachefs: section mismatch in reference: init_module+0x6 (section: .text) -> _RNvXCsj7d3tFpT5JS_15bcachefs_moduleNtB2_8BcachefsNtCsjDtqRIL3JAG_6kernel6Module4init (section: .init.text) + +I ran into this while experimenting with converting the bcachefs kernel +module from C to Rust. The module's `init()`, written in Rust, calls C +functions like `bch2_vfs_init()` which are placed in `.init.text`. + +This patch places the macro-generated `init_module()` Rust function in +the `.init.text` section. It also marks `init_module()` as unsafe--now +it may not be called after module initialization completes because it +may be freed already. + +Note that this is not enough on its own to actually get all the module +initialization code in that section. The module author must still add +the `#[link_section = ".init.text"]` attribute to the Rust `init()` in +the `impl kernel::Module` block in order to then call `__init` +functions. However, this patch enables module authors do so, when +previously it would not be possible (without warnings). + +Signed-off-by: Thomas Bertschinger +Reviewed-by: Martin Rodriguez Reboredo +Reviewed-by: Alice Ryhl +Link: https://lore.kernel.org/r/20240206153806.567055-1-tahbertschinger@gmail.com +[ Reworded title to add prefix. ] +Signed-off-by: Miguel Ojeda +Stable-dep-of: 7044dcff8301 ("rust: macros: fix soundness issue in `module!` macro") +Signed-off-by: Sasha Levin +--- + rust/macros/module.rs | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/rust/macros/module.rs b/rust/macros/module.rs +index d62d8710d77ab..27979e582e4b9 100644 +--- a/rust/macros/module.rs ++++ b/rust/macros/module.rs +@@ -222,10 +222,15 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { + }}; + + // Loadable modules need to export the `{{init,cleanup}}_module` identifiers. ++ /// # Safety ++ /// ++ /// This function must not be called after module initialization, because it may be ++ /// freed after that completes. + #[cfg(MODULE)] + #[doc(hidden)] + #[no_mangle] +- pub extern \"C\" fn init_module() -> core::ffi::c_int {{ ++ #[link_section = \".init.text\"] ++ pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{ + __init() + }} + +-- +2.43.0 + diff --git a/queue-6.8/series b/queue-6.8/series new file mode 100644 index 00000000000..bf48a60225a --- /dev/null +++ b/queue-6.8/series @@ -0,0 +1,25 @@ +rust-module-place-generated-init_module-function-in-.patch +rust-macros-fix-soundness-issue-in-module-macro.patch +wifi-nl80211-don-t-free-null-coalescing-rule.patch +bluetooth-qca-fix-invalid-device-address-check.patch +pinctrl-pinctrl-aspeed-g6-fix-register-offset-for-pi.patch +pinctrl-meson-fix-typo-in-pdm-s-pin-name.patch +pinctrl-core-delete-incorrect-free-in-pinctrl_enable.patch +pinctrl-mediatek-paris-fix-pin_config_input_schmitt_.patch +pinctrl-mediatek-paris-rework-support-for-pin_config.patch +sunrpc-add-a-struct-rpc_stats-arg-to-rpc_create_args.patch +nfs-expose-proc-net-sunrpc-nfs-in-net-namespaces.patch +nfs-make-the-rpc_stat-per-net-namespace.patch +nfs-handle-error-of-rpc_proc_register-in-nfs_net_ini.patch +pinctrl-baytrail-fix-selecting-gpio-pinctrl-state.patch +power-rt9455-hide-unused-rt9455_boost_voltage_values.patch +power-supply-mt6360_charger-fix-of_match-for-usb-otg.patch +pinctrl-devicetree-fix-refcount-leak-in-pinctrl_dt_t.patch +nfsd-rename-nfsd_net_-to-nfsd_stats_.patch +nfsd-expose-proc-net-sunrpc-nfsd-in-net-namespaces.patch +nfsd-make-all-of-the-nfsd-stats-per-network-namespac.patch +nfsd-add-support-for-cb_getattr-callback.patch +nfsd-fix-nfsd4_encode_fattr4-crasher.patch +regulator-mt6360-de-capitalize-devicetree-regulator-.patch +regulator-change-stubbed-devm_regulator_get_enable-t.patch +regulator-change-devm_regulator_get_enable_optional-.patch diff --git a/queue-6.8/sunrpc-add-a-struct-rpc_stats-arg-to-rpc_create_args.patch b/queue-6.8/sunrpc-add-a-struct-rpc_stats-arg-to-rpc_create_args.patch new file mode 100644 index 00000000000..c222071d0ce --- /dev/null +++ b/queue-6.8/sunrpc-add-a-struct-rpc_stats-arg-to-rpc_create_args.patch @@ -0,0 +1,74 @@ +From dbe583569e0e349d7014af2819e8b9065415f6ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Feb 2024 14:57:30 -0500 +Subject: sunrpc: add a struct rpc_stats arg to rpc_create_args + +From: Josef Bacik + +[ Upstream commit 2057a48d0dd00c6a2a94ded7df2bf1d3f2a4a0da ] + +We want to be able to have our rpc stats handled in a per network +namespace manner, so add an option to rpc_create_args to specify a +different rpc_stats struct instead of using the one on the rpc_program. + +Signed-off-by: Josef Bacik +Signed-off-by: Trond Myklebust +Stable-dep-of: 24457f1be29f ("nfs: Handle error of rpc_proc_register() in nfs_net_init().") +Signed-off-by: Sasha Levin +--- + include/linux/sunrpc/clnt.h | 1 + + net/sunrpc/clnt.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h +index 5e9d1469c6fae..5321585c778fc 100644 +--- a/include/linux/sunrpc/clnt.h ++++ b/include/linux/sunrpc/clnt.h +@@ -139,6 +139,7 @@ struct rpc_create_args { + const char *servername; + const char *nodename; + const struct rpc_program *program; ++ struct rpc_stat *stats; + u32 prognumber; /* overrides program->number */ + u32 version; + rpc_authflavor_t authflavor; +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index cda0935a68c9d..28f3749f6dc6c 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -405,7 +405,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, + clnt->cl_maxproc = version->nrprocs; + clnt->cl_prog = args->prognumber ? : program->number; + clnt->cl_vers = version->number; +- clnt->cl_stats = program->stats; ++ clnt->cl_stats = args->stats ? : program->stats; + clnt->cl_metrics = rpc_alloc_iostats(clnt); + rpc_init_pipe_dir_head(&clnt->cl_pipedir_objects); + err = -ENOMEM; +@@ -691,6 +691,7 @@ struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt) + .version = clnt->cl_vers, + .authflavor = clnt->cl_auth->au_flavor, + .cred = clnt->cl_cred, ++ .stats = clnt->cl_stats, + }; + return __rpc_clone_client(&args, clnt); + } +@@ -713,6 +714,7 @@ rpc_clone_client_set_auth(struct rpc_clnt *clnt, rpc_authflavor_t flavor) + .version = clnt->cl_vers, + .authflavor = flavor, + .cred = clnt->cl_cred, ++ .stats = clnt->cl_stats, + }; + return __rpc_clone_client(&args, clnt); + } +@@ -1068,6 +1070,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old, + .version = vers, + .authflavor = old->cl_auth->au_flavor, + .cred = old->cl_cred, ++ .stats = old->cl_stats, + }; + struct rpc_clnt *clnt; + int err; +-- +2.43.0 + diff --git a/queue-6.8/wifi-nl80211-don-t-free-null-coalescing-rule.patch b/queue-6.8/wifi-nl80211-don-t-free-null-coalescing-rule.patch new file mode 100644 index 00000000000..a84d41d217c --- /dev/null +++ b/queue-6.8/wifi-nl80211-don-t-free-null-coalescing-rule.patch @@ -0,0 +1,37 @@ +From ab3c2f8585a572d93ed5434e319000d2e89b615c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Apr 2024 10:52:23 +0200 +Subject: wifi: nl80211: don't free NULL coalescing rule + +From: Johannes Berg + +[ Upstream commit 801ea33ae82d6a9d954074fbcf8ea9d18f1543a7 ] + +If the parsing fails, we can dereference a NULL pointer here. + +Cc: stable@vger.kernel.org +Fixes: be29b99a9b51 ("cfg80211/nl80211: Add packet coalesce support") +Reviewed-by: Miriam Rachel Korenblit +Link: https://msgid.link/20240418105220.b328f80406e7.Id75d961050deb05b3e4e354e024866f350c68103@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/nl80211.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index bd54a928bab41..daac83aa8988e 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -14092,6 +14092,8 @@ static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info) + error: + for (i = 0; i < new_coalesce.n_rules; i++) { + tmp_rule = &new_coalesce.rules[i]; ++ if (!tmp_rule) ++ continue; + for (j = 0; j < tmp_rule->n_patterns; j++) + kfree(tmp_rule->patterns[j].mask); + kfree(tmp_rule->patterns); +-- +2.43.0 +