This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 6.6.10-rc1
Pablo Neira Ayuso pablo@netfilter.org netfilter: nf_tables: skip set commit for deleted/destroyed sets
Léo Lam leo@leolam.fr wifi: nl80211: fix deadlock in nl80211_set_cqm_rssi (6.6.x)
Johannes Berg johannes.berg@intel.com wifi: cfg80211: fix CQM for non-range use
Steven Rostedt (Google) rostedt@goodmis.org tracing: Fix blocked reader of snapshot buffer
Steven Rostedt (Google) rostedt@goodmis.org ftrace: Fix modification of direct_function hash while in use
Steven Rostedt (Google) rostedt@goodmis.org ring-buffer: Fix wake ups when buffer_percent is set to 100
Keith Busch kbusch@kernel.org Revert "nvme-fc: fix race between error recovery and creating association"
Matthew Wilcox (Oracle) willy@infradead.org mm/memory-failure: check the mapcount of the precise page
Matthew Wilcox (Oracle) willy@infradead.org mm/memory-failure: cast index to loff_t before shifting it
Charan Teja Kalla quic_charante@quicinc.com mm: migrate high-order folios in swap cache correctly
Baokun Li libaokun1@huawei.com mm/filemap: avoid buffered read/write race to read inconsistent data
Muhammad Usama Anjum usama.anjum@collabora.com selftests: secretmem: floor the memory size to the multiple of page_size
Sidhartha Kumar sidhartha.kumar@oracle.com maple_tree: do not preallocate nodes for slot stores
Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe
Namjae Jeon linkinjeon@kernel.org ksmbd: fix slab-out-of-bounds in smb_strndup_from_utf16()
David E. Box david.e.box@linux.intel.com platform/x86/intel/pmc: Move GBE LTR ignore to suspend callback
David E. Box david.e.box@linux.intel.com platform/x86/intel/pmc: Allow reenabling LTRs
David E. Box david.e.box@linux.intel.com platform/x86/intel/pmc: Add suspend callback
Christoph Hellwig hch@lst.de block: renumber QUEUE_FLAG_HW_WC
Paolo Abeni pabeni@redhat.com mptcp: fix inconsistent state on fastopen race
Paolo Abeni pabeni@redhat.com mptcp: fix possible NULL pointer dereference on close
Paolo Abeni pabeni@redhat.com mptcp: refactor sndbuf auto-tuning
Helge Deller deller@gmx.de linux/export: Ensure natural alignment of kcrctab array
Helge Deller deller@gmx.de linux/export: Fix alignment for 64-bit ksymtab entries
Arnd Bergmann arnd@arndb.de kexec: select CRYPTO from KEXEC_FILE instead of depending on it
Arnd Bergmann arnd@arndb.de kexec: fix KEXEC_FILE dependencies
Xuan Zhuo xuanzhuo@linux.alibaba.com virtio_ring: fix syncs DMA memory with different direction
Zizhi Wo wozizhi@huawei.com fs: cifs: Fix atime update check
Jeff Layton jlayton@kernel.org client: convert to new timestamp accessors
Jeff Layton jlayton@kernel.org fs: new accessor methods for atime and mtime
Namjae Jeon linkinjeon@kernel.org ksmbd: avoid duplicate opinfo_put() call on error of smb21_lease_break_ack()
Namjae Jeon linkinjeon@kernel.org ksmbd: lazy v2 lease break on smb2_write()
Namjae Jeon linkinjeon@kernel.org ksmbd: send v2 lease break notification for directory
Namjae Jeon linkinjeon@kernel.org ksmbd: downgrade RWH lease caching state to RH for directory
Namjae Jeon linkinjeon@kernel.org ksmbd: set v2 lease capability
Namjae Jeon linkinjeon@kernel.org ksmbd: set epoch in create context v2 lease
Namjae Jeon linkinjeon@kernel.org ksmbd: don't update ->op_state as OPLOCK_STATE_NONE on error
Namjae Jeon linkinjeon@kernel.org ksmbd: move setting SMB2_FLAGS_ASYNC_COMMAND and AsyncId
Namjae Jeon linkinjeon@kernel.org ksmbd: release interim response after sending status pending response
Namjae Jeon linkinjeon@kernel.org ksmbd: move oplock handling after unlock parent dir
Namjae Jeon linkinjeon@kernel.org ksmbd: separately allocate ci per dentry
Zongmin Zhou zhouzongmin@kylinos.cn ksmbd: prevent memory leak on error return
Namjae Jeon linkinjeon@kernel.org ksmbd: fix kernel-doc comment of ksmbd_vfs_kern_path_locked()
Namjae Jeon linkinjeon@kernel.org ksmbd: no need to wait for binded connection termination at logoff
Namjae Jeon linkinjeon@kernel.org ksmbd: add support for surrogate pair conversion
Kangjing Huang huangkangjing@gmail.com ksmbd: fix missing RDMA-capable flag for IPoIB device in ksmbd_rdma_capable_netdev()
Namjae Jeon linkinjeon@kernel.org ksmbd: fix kernel-doc comment of ksmbd_vfs_setxattr()
Namjae Jeon linkinjeon@kernel.org ksmbd: reorganize ksmbd_iov_pin_rsp()
Cheng-Han Wu hank20010209@gmail.com ksmbd: Remove unused field in ksmbd_user struct
-------------
Diffstat:
Makefile | 4 +- arch/powerpc/Kconfig | 4 +- arch/riscv/Kconfig | 4 +- arch/s390/Kconfig | 4 +- arch/x86/Kconfig | 4 +- drivers/nvme/host/fc.c | 21 +-- drivers/platform/x86/intel/pmc/adl.c | 9 +- drivers/platform/x86/intel/pmc/cnp.c | 26 ++- drivers/platform/x86/intel/pmc/core.c | 12 +- drivers/platform/x86/intel/pmc/core.h | 7 +- drivers/platform/x86/intel/pmc/mtl.c | 9 +- drivers/platform/x86/intel/pmc/tgl.c | 9 +- drivers/platform/x86/p2sb.c | 178 ++++++++++++++++----- drivers/virtio/virtio_ring.c | 6 +- fs/libfs.c | 41 +++-- fs/smb/client/file.c | 18 ++- fs/smb/client/fscache.h | 6 +- fs/smb/client/inode.c | 17 +- fs/smb/client/smb2ops.c | 6 +- fs/smb/common/smb2pdu.h | 1 + fs/smb/server/connection.c | 16 -- fs/smb/server/ksmbd_work.c | 51 +++--- fs/smb/server/mgmt/user_config.h | 1 - fs/smb/server/oplock.c | 118 ++++++++++++-- fs/smb/server/oplock.h | 8 +- fs/smb/server/smb2misc.c | 15 +- fs/smb/server/smb2ops.c | 9 +- fs/smb/server/smb2pdu.c | 258 ++++++++++++++++-------------- fs/smb/server/transport_rdma.c | 40 +++-- fs/smb/server/unicode.c | 187 ++++++++++++++++------ fs/smb/server/vfs.c | 14 +- fs/smb/server/vfs_cache.c | 30 ++-- fs/smb/server/vfs_cache.h | 9 +- include/linux/blkdev.h | 2 +- include/linux/export-internal.h | 6 +- include/linux/fs.h | 85 ++++++++-- kernel/Kconfig.kexec | 2 + kernel/trace/ftrace.c | 100 ++++++------ kernel/trace/ring_buffer.c | 12 +- kernel/trace/trace.c | 20 ++- lib/maple_tree.c | 11 ++ mm/filemap.c | 9 ++ mm/memory-failure.c | 8 +- mm/migrate.c | 9 +- net/mptcp/protocol.c | 27 +++- net/mptcp/protocol.h | 63 +++++++- net/mptcp/sockopt.c | 5 +- net/mptcp/subflow.c | 29 ++-- net/netfilter/nf_tables_api.c | 2 +- net/wireless/core.h | 1 + net/wireless/nl80211.c | 56 ++++--- tools/testing/radix-tree/maple.c | 2 +- tools/testing/selftests/mm/memfd_secret.c | 3 + 53 files changed, 1070 insertions(+), 524 deletions(-)
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cheng-Han Wu hank20010209@gmail.com
[ Upstream commit eacc655e18d1dec9b50660d16a1ddeeb4d6c48f2 ]
fs/smb/server/mgmt/user_config.h:21: Remove the unused field 'failed_login_count' from the ksmbd_user struct.
Signed-off-by: Cheng-Han Wu hank20010209@gmail.com Acked-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/mgmt/user_config.h | 1 - 1 file changed, 1 deletion(-)
diff --git a/fs/smb/server/mgmt/user_config.h b/fs/smb/server/mgmt/user_config.h index 6a44109617f14..e068a19fd9049 100644 --- a/fs/smb/server/mgmt/user_config.h +++ b/fs/smb/server/mgmt/user_config.h @@ -18,7 +18,6 @@ struct ksmbd_user {
size_t passkey_sz; char *passkey; - unsigned int failed_login_count; };
static inline bool user_guest(struct ksmbd_user *user)
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 1819a904299942b309f687cc0f08b123500aa178 ]
If ksmbd_iov_pin_rsp fail, io vertor should be rollback. This patch moves memory allocations to before setting the io vector to avoid rollbacks.
Fixes: e2b76ab8b5c9 ("ksmbd: add support for read compound") Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/ksmbd_work.c | 43 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-)
diff --git a/fs/smb/server/ksmbd_work.c b/fs/smb/server/ksmbd_work.c index 51def3ca74c01..a2ed441e837ae 100644 --- a/fs/smb/server/ksmbd_work.c +++ b/fs/smb/server/ksmbd_work.c @@ -95,11 +95,28 @@ bool ksmbd_queue_work(struct ksmbd_work *work) return queue_work(ksmbd_wq, &work->work); }
-static int ksmbd_realloc_iov_pin(struct ksmbd_work *work, void *ib, - unsigned int ib_len) +static inline void __ksmbd_iov_pin(struct ksmbd_work *work, void *ib, + unsigned int ib_len) { + work->iov[++work->iov_idx].iov_base = ib; + work->iov[work->iov_idx].iov_len = ib_len; + work->iov_cnt++; +} + +static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, + void *aux_buf, unsigned int aux_size) +{ + struct aux_read *ar; + int need_iov_cnt = 1;
- if (work->iov_alloc_cnt <= work->iov_cnt) { + if (aux_size) { + need_iov_cnt++; + ar = kmalloc(sizeof(struct aux_read), GFP_KERNEL); + if (!ar) + return -ENOMEM; + } + + if (work->iov_alloc_cnt < work->iov_cnt + need_iov_cnt) { struct kvec *new;
work->iov_alloc_cnt += 4; @@ -111,16 +128,6 @@ static int ksmbd_realloc_iov_pin(struct ksmbd_work *work, void *ib, work->iov = new; }
- work->iov[++work->iov_idx].iov_base = ib; - work->iov[work->iov_idx].iov_len = ib_len; - work->iov_cnt++; - - return 0; -} - -static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, - void *aux_buf, unsigned int aux_size) -{ /* Plus rfc_length size on first iov */ if (!work->iov_idx) { work->iov[work->iov_idx].iov_base = work->response_buf; @@ -129,19 +136,13 @@ static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, work->iov_cnt++; }
- ksmbd_realloc_iov_pin(work, ib, len); + __ksmbd_iov_pin(work, ib, len); inc_rfc1001_len(work->iov[0].iov_base, len);
if (aux_size) { - struct aux_read *ar; - - ksmbd_realloc_iov_pin(work, aux_buf, aux_size); + __ksmbd_iov_pin(work, aux_buf, aux_size); inc_rfc1001_len(work->iov[0].iov_base, aux_size);
- ar = kmalloc(sizeof(struct aux_read), GFP_KERNEL); - if (!ar) - return -ENOMEM; - ar->buf = aux_buf; list_add(&ar->entry, &work->aux_read_list); }
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 3354db668808d5b6d7c5e0cb19ff4c9da4bb5e58 ]
Fix argument list that the kdoc format and script verified in ksmbd_vfs_setxattr().
fs/smb/server/vfs.c:929: warning: Function parameter or member 'path' not described in 'ksmbd_vfs_setxattr'
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/vfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index 5a41c0b4e9335..183e36cda59ec 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -906,7 +906,7 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap, /** * ksmbd_vfs_setxattr() - vfs helper for smb set extended attributes value * @idmap: idmap of the relevant mount - * @dentry: dentry to set XATTR at + * @path: path of dentry to set XATTR at * @attr_name: xattr name for setxattr * @attr_value: xattr value to set * @attr_size: size of xattr value
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kangjing Huang huangkangjing@gmail.com
[ Upstream commit ecce70cf17d91c3dd87a0c4ea00b2d1387729701 ]
Physical ib_device does not have an underlying net_device, thus its association with IPoIB net_device cannot be retrieved via ops.get_netdev() or ib_device_get_by_netdev(). ksmbd reads physical ib_device port GUID from the lower 16 bytes of the hardware addresses on IPoIB net_device and match its underlying ib_device using ib_find_gid()
Signed-off-by: Kangjing Huang huangkangjing@gmail.com Acked-by: Namjae Jeon linkinjeon@kernel.org Reviewed-by: Tom Talpey tom@talpey.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/transport_rdma.c | 40 +++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c index 3b269e1f523a1..c5629a68c8b73 100644 --- a/fs/smb/server/transport_rdma.c +++ b/fs/smb/server/transport_rdma.c @@ -2140,8 +2140,7 @@ static int smb_direct_ib_client_add(struct ib_device *ib_dev) if (ib_dev->node_type != RDMA_NODE_IB_CA) smb_direct_port = SMB_DIRECT_PORT_IWARP;
- if (!ib_dev->ops.get_netdev || - !rdma_frwr_is_supported(&ib_dev->attrs)) + if (!rdma_frwr_is_supported(&ib_dev->attrs)) return 0;
smb_dev = kzalloc(sizeof(*smb_dev), GFP_KERNEL); @@ -2241,17 +2240,38 @@ bool ksmbd_rdma_capable_netdev(struct net_device *netdev) for (i = 0; i < smb_dev->ib_dev->phys_port_cnt; i++) { struct net_device *ndev;
- ndev = smb_dev->ib_dev->ops.get_netdev(smb_dev->ib_dev, - i + 1); - if (!ndev) - continue; + if (smb_dev->ib_dev->ops.get_netdev) { + ndev = smb_dev->ib_dev->ops.get_netdev( + smb_dev->ib_dev, i + 1); + if (!ndev) + continue;
- if (ndev == netdev) { + if (ndev == netdev) { + dev_put(ndev); + rdma_capable = true; + goto out; + } dev_put(ndev); - rdma_capable = true; - goto out; + /* if ib_dev does not implement ops.get_netdev + * check for matching infiniband GUID in hw_addr + */ + } else if (netdev->type == ARPHRD_INFINIBAND) { + struct netdev_hw_addr *ha; + union ib_gid gid; + u32 port_num; + int ret; + + netdev_hw_addr_list_for_each( + ha, &netdev->dev_addrs) { + memcpy(&gid, ha->addr + 4, sizeof(gid)); + ret = ib_find_gid(smb_dev->ib_dev, &gid, + &port_num, NULL); + if (!ret) { + rdma_capable = true; + goto out; + } + } } - dev_put(ndev); } } out:
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 0c180317c654a494fe429adbf7bc9b0793caf9e2 ]
ksmbd is missing supporting to convert filename included surrogate pair characters. It triggers a "file or folder does not exist" error in Windows client.
[Steps to Reproduce for bug] 1. Create surrogate pair file touch $(echo -e '\xf0\x9d\x9f\xa3') touch $(echo -e '\xf0\x9d\x9f\xa4')
2. Try to open these files in ksmbd share through Windows client.
This patch update unicode functions not to consider about surrogate pair (and IVS).
Reviewed-by: Marios Makassikis mmakassikis@freebox.fr Tested-by: Marios Makassikis mmakassikis@freebox.fr Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/unicode.c | 187 +++++++++++++++++++++++++++++----------- 1 file changed, 138 insertions(+), 49 deletions(-)
diff --git a/fs/smb/server/unicode.c b/fs/smb/server/unicode.c index 393dd4a7432b6..43ed29ee44ead 100644 --- a/fs/smb/server/unicode.c +++ b/fs/smb/server/unicode.c @@ -13,46 +13,10 @@ #include "unicode.h" #include "smb_common.h"
-/* - * smb_utf16_bytes() - how long will a string be after conversion? - * @from: pointer to input string - * @maxbytes: don't go past this many bytes of input string - * @codepage: destination codepage - * - * Walk a utf16le string and return the number of bytes that the string will - * be after being converted to the given charset, not including any null - * termination required. Don't walk past maxbytes in the source buffer. - * - * Return: string length after conversion - */ -static int smb_utf16_bytes(const __le16 *from, int maxbytes, - const struct nls_table *codepage) -{ - int i; - int charlen, outlen = 0; - int maxwords = maxbytes / 2; - char tmp[NLS_MAX_CHARSET_SIZE]; - __u16 ftmp; - - for (i = 0; i < maxwords; i++) { - ftmp = get_unaligned_le16(&from[i]); - if (ftmp == 0) - break; - - charlen = codepage->uni2char(ftmp, tmp, NLS_MAX_CHARSET_SIZE); - if (charlen > 0) - outlen += charlen; - else - outlen++; - } - - return outlen; -} - /* * cifs_mapchar() - convert a host-endian char to proper char in codepage * @target: where converted character should be copied - * @src_char: 2 byte host-endian source character + * @from: host-endian source string * @cp: codepage to which character should be converted * @mapchar: should character be mapped according to mapchars mount option? * @@ -63,10 +27,13 @@ static int smb_utf16_bytes(const __le16 *from, int maxbytes, * Return: string length after conversion */ static int -cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp, +cifs_mapchar(char *target, const __u16 *from, const struct nls_table *cp, bool mapchar) { int len = 1; + __u16 src_char; + + src_char = *from;
if (!mapchar) goto cp_convert; @@ -104,12 +71,66 @@ cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp,
cp_convert: len = cp->uni2char(src_char, target, NLS_MAX_CHARSET_SIZE); - if (len <= 0) { - *target = '?'; - len = 1; - } + if (len <= 0) + goto surrogate_pair;
goto out; + +surrogate_pair: + /* convert SURROGATE_PAIR and IVS */ + if (strcmp(cp->charset, "utf8")) + goto unknown; + len = utf16s_to_utf8s(from, 3, UTF16_LITTLE_ENDIAN, target, 6); + if (len <= 0) + goto unknown; + return len; + +unknown: + *target = '?'; + len = 1; + goto out; +} + +/* + * smb_utf16_bytes() - compute converted string length + * @from: pointer to input string + * @maxbytes: input string length + * @codepage: destination codepage + * + * Walk a utf16le string and return the number of bytes that the string will + * be after being converted to the given charset, not including any null + * termination required. Don't walk past maxbytes in the source buffer. + * + * Return: string length after conversion + */ +static int smb_utf16_bytes(const __le16 *from, int maxbytes, + const struct nls_table *codepage) +{ + int i, j; + int charlen, outlen = 0; + int maxwords = maxbytes / 2; + char tmp[NLS_MAX_CHARSET_SIZE]; + __u16 ftmp[3]; + + for (i = 0; i < maxwords; i++) { + ftmp[0] = get_unaligned_le16(&from[i]); + if (ftmp[0] == 0) + break; + for (j = 1; j <= 2; j++) { + if (i + j < maxwords) + ftmp[j] = get_unaligned_le16(&from[i + j]); + else + ftmp[j] = 0; + } + + charlen = cifs_mapchar(tmp, ftmp, codepage, 0); + if (charlen > 0) + outlen += charlen; + else + outlen++; + } + + return outlen; }
/* @@ -139,12 +160,12 @@ cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp, static int smb_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, const struct nls_table *codepage, bool mapchar) { - int i, charlen, safelen; + int i, j, charlen, safelen; int outlen = 0; int nullsize = nls_nullsize(codepage); int fromwords = fromlen / 2; char tmp[NLS_MAX_CHARSET_SIZE]; - __u16 ftmp; + __u16 ftmp[3]; /* ftmp[3] = 3array x 2bytes = 6bytes UTF-16 */
/* * because the chars can be of varying widths, we need to take care @@ -155,9 +176,15 @@ static int smb_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, safelen = tolen - (NLS_MAX_CHARSET_SIZE + nullsize);
for (i = 0; i < fromwords; i++) { - ftmp = get_unaligned_le16(&from[i]); - if (ftmp == 0) + ftmp[0] = get_unaligned_le16(&from[i]); + if (ftmp[0] == 0) break; + for (j = 1; j <= 2; j++) { + if (i + j < fromwords) + ftmp[j] = get_unaligned_le16(&from[i + j]); + else + ftmp[j] = 0; + }
/* * check to see if converting this character might make the @@ -172,6 +199,19 @@ static int smb_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, /* put converted char into 'to' buffer */ charlen = cifs_mapchar(&to[outlen], ftmp, codepage, mapchar); outlen += charlen; + + /* + * charlen (=bytes of UTF-8 for 1 character) + * 4bytes UTF-8(surrogate pair) is charlen=4 + * (4bytes UTF-16 code) + * 7-8bytes UTF-8(IVS) is charlen=3+4 or 4+4 + * (2 UTF-8 pairs divided to 2 UTF-16 pairs) + */ + if (charlen == 4) + i++; + else if (charlen >= 5) + /* 5-6bytes UTF-8 */ + i += 2; }
/* properly null-terminate string */ @@ -306,6 +346,9 @@ int smbConvertToUTF16(__le16 *target, const char *source, int srclen, char src_char; __le16 dst_char; wchar_t tmp; + wchar_t wchar_to[6]; /* UTF-16 */ + int ret; + unicode_t u;
if (!mapchars) return smb_strtoUTF16(target, source, srclen, cp); @@ -348,11 +391,57 @@ int smbConvertToUTF16(__le16 *target, const char *source, int srclen, * if no match, use question mark, which at least in * some cases serves as wild card */ - if (charlen < 1) { - dst_char = cpu_to_le16(0x003f); - charlen = 1; + if (charlen > 0) + goto ctoUTF16; + + /* convert SURROGATE_PAIR */ + if (strcmp(cp->charset, "utf8")) + goto unknown; + if (*(source + i) & 0x80) { + charlen = utf8_to_utf32(source + i, 6, &u); + if (charlen < 0) + goto unknown; + } else + goto unknown; + ret = utf8s_to_utf16s(source + i, charlen, + UTF16_LITTLE_ENDIAN, + wchar_to, 6); + if (ret < 0) + goto unknown; + + i += charlen; + dst_char = cpu_to_le16(*wchar_to); + if (charlen <= 3) + /* 1-3bytes UTF-8 to 2bytes UTF-16 */ + put_unaligned(dst_char, &target[j]); + else if (charlen == 4) { + /* + * 4bytes UTF-8(surrogate pair) to 4bytes UTF-16 + * 7-8bytes UTF-8(IVS) divided to 2 UTF-16 + * (charlen=3+4 or 4+4) + */ + put_unaligned(dst_char, &target[j]); + dst_char = cpu_to_le16(*(wchar_to + 1)); + j++; + put_unaligned(dst_char, &target[j]); + } else if (charlen >= 5) { + /* 5-6bytes UTF-8 to 6bytes UTF-16 */ + put_unaligned(dst_char, &target[j]); + dst_char = cpu_to_le16(*(wchar_to + 1)); + j++; + put_unaligned(dst_char, &target[j]); + dst_char = cpu_to_le16(*(wchar_to + 2)); + j++; + put_unaligned(dst_char, &target[j]); } + continue; + +unknown: + dst_char = cpu_to_le16(0x003f); + charlen = 1; } + +ctoUTF16: /* * character may take more than one byte in the source string, * but will take exactly two bytes in the target string
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 67797da8a4b82446d42c52b6ee1419a3100d78ff ]
The connection could be binded to the existing session for Multichannel. session will be destroyed when binded connections are released. So no need to wait for that's connection at logoff.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/connection.c | 16 ---------------- 1 file changed, 16 deletions(-)
diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c index 4b38c3a285f60..b6fa1e285c401 100644 --- a/fs/smb/server/connection.c +++ b/fs/smb/server/connection.c @@ -167,23 +167,7 @@ void ksmbd_all_conn_set_status(u64 sess_id, u32 status)
void ksmbd_conn_wait_idle(struct ksmbd_conn *conn, u64 sess_id) { - struct ksmbd_conn *bind_conn; - wait_event(conn->req_running_q, atomic_read(&conn->req_running) < 2); - - down_read(&conn_list_lock); - list_for_each_entry(bind_conn, &conn_list, conns_list) { - if (bind_conn == conn) - continue; - - if ((bind_conn->binding || xa_load(&bind_conn->sessions, sess_id)) && - !ksmbd_conn_releasing(bind_conn) && - atomic_read(&bind_conn->req_running)) { - wait_event(bind_conn->req_running_q, - atomic_read(&bind_conn->req_running) == 0); - } - } - up_read(&conn_list_lock); }
int ksmbd_conn_write(struct ksmbd_work *work)
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit f6049712e520287ad695e9d4f1572ab76807fa0c ]
Fix argument list that the kdoc format and script verified in ksmbd_vfs_kern_path_locked().
fs/smb/server/vfs.c:1207: warning: Function parameter or member 'parent_path' not described in 'ksmbd_vfs_kern_path_locked'
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/vfs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index 183e36cda59ec..533257b46fc17 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -1186,9 +1186,10 @@ static int ksmbd_vfs_lookup_in_dir(const struct path *dir, char *name,
/** * ksmbd_vfs_kern_path_locked() - lookup a file and get path info - * @name: file path that is relative to share - * @flags: lookup flags - * @path: if lookup succeed, return path info + * @name: file path that is relative to share + * @flags: lookup flags + * @parent_path: if lookup succeed, return parent_path info + * @path: if lookup succeed, return path info * @caseless: caseless filename lookup * * Return: 0 on success, otherwise error
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zongmin Zhou zhouzongmin@kylinos.cn
[ Upstream commit 90044481e7cca6cb3125b3906544954a25f1309f ]
When allocated memory for 'new' failed,just return will cause memory leak of 'ar'.
Fixes: 1819a9042999 ("ksmbd: reorganize ksmbd_iov_pin_rsp()") Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter error27@gmail.com Closes: https://lore.kernel.org/r/202311031837.H3yo7JVl-lkp@intel.com/ Signed-off-by: Zongmin Zhouzhouzongmin@kylinos.cn Acked-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/ksmbd_work.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/smb/server/ksmbd_work.c b/fs/smb/server/ksmbd_work.c index a2ed441e837ae..2510b9f3c8c14 100644 --- a/fs/smb/server/ksmbd_work.c +++ b/fs/smb/server/ksmbd_work.c @@ -106,7 +106,7 @@ static inline void __ksmbd_iov_pin(struct ksmbd_work *work, void *ib, static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, void *aux_buf, unsigned int aux_size) { - struct aux_read *ar; + struct aux_read *ar = NULL; int need_iov_cnt = 1;
if (aux_size) { @@ -123,8 +123,11 @@ static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, new = krealloc(work->iov, sizeof(struct kvec) * work->iov_alloc_cnt, GFP_KERNEL | __GFP_ZERO); - if (!new) + if (!new) { + kfree(ar); + work->iov_alloc_cnt -= 4; return -ENOMEM; + } work->iov = new; }
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 4274a9dc6aeb9fea66bffba15697a35ae8983b6a ]
xfstests generic/002 test fail when enabling smb2 leases feature. This test create hard link file, but removeal failed. ci has a file open count to count file open through the smb client, but in the case of hard link files, The allocation of ci per inode cause incorrectly open count for file deletion. This patch allocate ci per dentry to counts open counts for hard link.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/smb2pdu.c | 2 +- fs/smb/server/vfs.c | 2 +- fs/smb/server/vfs_cache.c | 33 +++++++++++++-------------------- fs/smb/server/vfs_cache.h | 6 +++--- 4 files changed, 18 insertions(+), 25 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 2b248d45d40ae..28b61dad27498 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -3039,7 +3039,7 @@ int smb2_open(struct ksmbd_work *work) } }
- rc = ksmbd_query_inode_status(d_inode(path.dentry->d_parent)); + rc = ksmbd_query_inode_status(path.dentry->d_parent); if (rc == KSMBD_INODE_STATUS_PENDING_DELETE) { rc = -EBUSY; goto err_out; diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index 533257b46fc17..9091dcd7a3102 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -719,7 +719,7 @@ int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path, goto out3; }
- parent_fp = ksmbd_lookup_fd_inode(d_inode(old_child->d_parent)); + parent_fp = ksmbd_lookup_fd_inode(old_child->d_parent); if (parent_fp) { if (parent_fp->daccess & FILE_DELETE_LE) { pr_err("parent dir is opened with delete access\n"); diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c index c91eac6514dd9..ddf233994ddbb 100644 --- a/fs/smb/server/vfs_cache.c +++ b/fs/smb/server/vfs_cache.c @@ -66,14 +66,14 @@ static unsigned long inode_hash(struct super_block *sb, unsigned long hashval) return tmp & inode_hash_mask; }
-static struct ksmbd_inode *__ksmbd_inode_lookup(struct inode *inode) +static struct ksmbd_inode *__ksmbd_inode_lookup(struct dentry *de) { struct hlist_head *head = inode_hashtable + - inode_hash(inode->i_sb, inode->i_ino); + inode_hash(d_inode(de)->i_sb, (unsigned long)de); struct ksmbd_inode *ci = NULL, *ret_ci = NULL;
hlist_for_each_entry(ci, head, m_hash) { - if (ci->m_inode == inode) { + if (ci->m_de == de) { if (atomic_inc_not_zero(&ci->m_count)) ret_ci = ci; break; @@ -84,26 +84,16 @@ static struct ksmbd_inode *__ksmbd_inode_lookup(struct inode *inode)
static struct ksmbd_inode *ksmbd_inode_lookup(struct ksmbd_file *fp) { - return __ksmbd_inode_lookup(file_inode(fp->filp)); + return __ksmbd_inode_lookup(fp->filp->f_path.dentry); }
-static struct ksmbd_inode *ksmbd_inode_lookup_by_vfsinode(struct inode *inode) -{ - struct ksmbd_inode *ci; - - read_lock(&inode_hash_lock); - ci = __ksmbd_inode_lookup(inode); - read_unlock(&inode_hash_lock); - return ci; -} - -int ksmbd_query_inode_status(struct inode *inode) +int ksmbd_query_inode_status(struct dentry *dentry) { struct ksmbd_inode *ci; int ret = KSMBD_INODE_STATUS_UNKNOWN;
read_lock(&inode_hash_lock); - ci = __ksmbd_inode_lookup(inode); + ci = __ksmbd_inode_lookup(dentry); if (ci) { ret = KSMBD_INODE_STATUS_OK; if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) @@ -143,7 +133,7 @@ void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, static void ksmbd_inode_hash(struct ksmbd_inode *ci) { struct hlist_head *b = inode_hashtable + - inode_hash(ci->m_inode->i_sb, ci->m_inode->i_ino); + inode_hash(d_inode(ci->m_de)->i_sb, (unsigned long)ci->m_de);
hlist_add_head(&ci->m_hash, b); } @@ -157,7 +147,6 @@ static void ksmbd_inode_unhash(struct ksmbd_inode *ci)
static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp) { - ci->m_inode = file_inode(fp->filp); atomic_set(&ci->m_count, 1); atomic_set(&ci->op_count, 0); atomic_set(&ci->sop_count, 0); @@ -166,6 +155,7 @@ static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp) INIT_LIST_HEAD(&ci->m_fp_list); INIT_LIST_HEAD(&ci->m_op_list); rwlock_init(&ci->m_lock); + ci->m_de = fp->filp->f_path.dentry; return 0; }
@@ -488,12 +478,15 @@ struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid) return fp; }
-struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode) +struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry) { struct ksmbd_file *lfp; struct ksmbd_inode *ci; + struct inode *inode = d_inode(dentry);
- ci = ksmbd_inode_lookup_by_vfsinode(inode); + read_lock(&inode_hash_lock); + ci = __ksmbd_inode_lookup(dentry); + read_unlock(&inode_hash_lock); if (!ci) return NULL;
diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h index 03d0bf941216f..8325cf4527c46 100644 --- a/fs/smb/server/vfs_cache.h +++ b/fs/smb/server/vfs_cache.h @@ -51,7 +51,7 @@ struct ksmbd_inode { atomic_t op_count; /* opinfo count for streams */ atomic_t sop_count; - struct inode *m_inode; + struct dentry *m_de; unsigned int m_flags; struct hlist_node m_hash; struct list_head m_fp_list; @@ -140,7 +140,7 @@ struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, u64 id, void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp); struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id); struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid); -struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode); +struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry); unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp); struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp); void ksmbd_close_tree_conn_fds(struct ksmbd_work *work); @@ -164,7 +164,7 @@ enum KSMBD_INODE_STATUS { KSMBD_INODE_STATUS_PENDING_DELETE, };
-int ksmbd_query_inode_status(struct inode *inode); +int ksmbd_query_inode_status(struct dentry *dentry); bool ksmbd_inode_pending_delete(struct ksmbd_file *fp); void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp); void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp);
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 2e450920d58b4991a436c8cecf3484bcacd8e535 ]
ksmbd should process secound parallel smb2 create request during waiting oplock break ack. parent lock range that is too large in smb2_open() causes smb2_open() to be serialized. Move the oplock handling to the bottom of smb2_open() and make it called after parent unlock. This fixes the failure of smb2.lease.breaking1 testcase.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/smb2pdu.c | 121 +++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 56 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 28b61dad27498..e58504d0e9c1e 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -2691,7 +2691,7 @@ int smb2_open(struct ksmbd_work *work) *(char *)req->Buffer == '\') { pr_err("not allow directory name included leading slash\n"); rc = -EINVAL; - goto err_out1; + goto err_out2; }
name = smb2_get_name(req->Buffer, @@ -2702,7 +2702,7 @@ int smb2_open(struct ksmbd_work *work) if (rc != -ENOMEM) rc = -ENOENT; name = NULL; - goto err_out1; + goto err_out2; }
ksmbd_debug(SMB, "converted name = %s\n", name); @@ -2710,28 +2710,28 @@ int smb2_open(struct ksmbd_work *work) if (!test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_STREAMS)) { rc = -EBADF; - goto err_out1; + goto err_out2; } rc = parse_stream_name(name, &stream_name, &s_type); if (rc < 0) - goto err_out1; + goto err_out2; }
rc = ksmbd_validate_filename(name); if (rc < 0) - goto err_out1; + goto err_out2;
if (ksmbd_share_veto_filename(share, name)) { rc = -ENOENT; ksmbd_debug(SMB, "Reject open(), vetoed file: %s\n", name); - goto err_out1; + goto err_out2; } } else { name = kstrdup("", GFP_KERNEL); if (!name) { rc = -ENOMEM; - goto err_out1; + goto err_out2; } }
@@ -2744,14 +2744,14 @@ int smb2_open(struct ksmbd_work *work) le32_to_cpu(req->ImpersonationLevel)); rc = -EIO; rsp->hdr.Status = STATUS_BAD_IMPERSONATION_LEVEL; - goto err_out1; + goto err_out2; }
if (req->CreateOptions && !(req->CreateOptions & CREATE_OPTIONS_MASK_LE)) { pr_err("Invalid create options : 0x%x\n", le32_to_cpu(req->CreateOptions)); rc = -EINVAL; - goto err_out1; + goto err_out2; } else { if (req->CreateOptions & FILE_SEQUENTIAL_ONLY_LE && req->CreateOptions & FILE_RANDOM_ACCESS_LE) @@ -2761,13 +2761,13 @@ int smb2_open(struct ksmbd_work *work) (FILE_OPEN_BY_FILE_ID_LE | CREATE_TREE_CONNECTION | FILE_RESERVE_OPFILTER_LE)) { rc = -EOPNOTSUPP; - goto err_out1; + goto err_out2; }
if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) { if (req->CreateOptions & FILE_NON_DIRECTORY_FILE_LE) { rc = -EINVAL; - goto err_out1; + goto err_out2; } else if (req->CreateOptions & FILE_NO_COMPRESSION_LE) { req->CreateOptions = ~(FILE_NO_COMPRESSION_LE); } @@ -2779,21 +2779,21 @@ int smb2_open(struct ksmbd_work *work) pr_err("Invalid create disposition : 0x%x\n", le32_to_cpu(req->CreateDisposition)); rc = -EINVAL; - goto err_out1; + goto err_out2; }
if (!(req->DesiredAccess & DESIRED_ACCESS_MASK)) { pr_err("Invalid desired access : 0x%x\n", le32_to_cpu(req->DesiredAccess)); rc = -EACCES; - goto err_out1; + goto err_out2; }
if (req->FileAttributes && !(req->FileAttributes & FILE_ATTRIBUTE_MASK_LE)) { pr_err("Invalid file attribute : 0x%x\n", le32_to_cpu(req->FileAttributes)); rc = -EINVAL; - goto err_out1; + goto err_out2; }
if (req->CreateContextsOffset) { @@ -2801,19 +2801,19 @@ int smb2_open(struct ksmbd_work *work) context = smb2_find_context_vals(req, SMB2_CREATE_EA_BUFFER, 4); if (IS_ERR(context)) { rc = PTR_ERR(context); - goto err_out1; + goto err_out2; } else if (context) { ea_buf = (struct create_ea_buf_req *)context; if (le16_to_cpu(context->DataOffset) + le32_to_cpu(context->DataLength) < sizeof(struct create_ea_buf_req)) { rc = -EINVAL; - goto err_out1; + goto err_out2; } if (req->CreateOptions & FILE_NO_EA_KNOWLEDGE_LE) { rsp->hdr.Status = STATUS_ACCESS_DENIED; rc = -EACCES; - goto err_out1; + goto err_out2; } }
@@ -2821,7 +2821,7 @@ int smb2_open(struct ksmbd_work *work) SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST, 4); if (IS_ERR(context)) { rc = PTR_ERR(context); - goto err_out1; + goto err_out2; } else if (context) { ksmbd_debug(SMB, "get query maximal access context\n"); @@ -2832,11 +2832,11 @@ int smb2_open(struct ksmbd_work *work) SMB2_CREATE_TIMEWARP_REQUEST, 4); if (IS_ERR(context)) { rc = PTR_ERR(context); - goto err_out1; + goto err_out2; } else if (context) { ksmbd_debug(SMB, "get timewarp context\n"); rc = -EBADF; - goto err_out1; + goto err_out2; }
if (tcon->posix_extensions) { @@ -2844,7 +2844,7 @@ int smb2_open(struct ksmbd_work *work) SMB2_CREATE_TAG_POSIX, 16); if (IS_ERR(context)) { rc = PTR_ERR(context); - goto err_out1; + goto err_out2; } else if (context) { struct create_posix *posix = (struct create_posix *)context; @@ -2852,7 +2852,7 @@ int smb2_open(struct ksmbd_work *work) le32_to_cpu(context->DataLength) < sizeof(struct create_posix) - 4) { rc = -EINVAL; - goto err_out1; + goto err_out2; } ksmbd_debug(SMB, "get posix context\n");
@@ -2864,7 +2864,7 @@ int smb2_open(struct ksmbd_work *work)
if (ksmbd_override_fsids(work)) { rc = -ENOMEM; - goto err_out1; + goto err_out2; }
rc = ksmbd_vfs_kern_path_locked(work, name, LOOKUP_NO_SYMLINKS, @@ -3177,11 +3177,6 @@ int smb2_open(struct ksmbd_work *work)
fp->attrib_only = !(req->DesiredAccess & ~(FILE_READ_ATTRIBUTES_LE | FILE_WRITE_ATTRIBUTES_LE | FILE_SYNCHRONIZE_LE)); - if (!S_ISDIR(file_inode(filp)->i_mode) && open_flags & O_TRUNC && - !fp->attrib_only && !stream_name) { - smb_break_all_oplock(work, fp); - need_truncate = 1; - }
/* fp should be searchable through ksmbd_inode.m_fp_list * after daccess, saccess, attrib_only, and stream are @@ -3197,13 +3192,39 @@ int smb2_open(struct ksmbd_work *work) goto err_out; }
+ rc = ksmbd_vfs_getattr(&path, &stat); + if (rc) + goto err_out; + + if (stat.result_mask & STATX_BTIME) + fp->create_time = ksmbd_UnixTimeToNT(stat.btime); + else + fp->create_time = ksmbd_UnixTimeToNT(stat.ctime); + if (req->FileAttributes || fp->f_ci->m_fattr == 0) + fp->f_ci->m_fattr = + cpu_to_le32(smb2_get_dos_mode(&stat, le32_to_cpu(req->FileAttributes))); + + if (!created) + smb2_update_xattrs(tcon, &path, fp); + else + smb2_new_xattrs(tcon, &path, fp); + + if (file_present || created) + ksmbd_vfs_kern_path_unlock(&parent_path, &path); + + if (!S_ISDIR(file_inode(filp)->i_mode) && open_flags & O_TRUNC && + !fp->attrib_only && !stream_name) { + smb_break_all_oplock(work, fp); + need_truncate = 1; + } + share_ret = ksmbd_smb_check_shared_mode(fp->filp, fp); if (!test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_OPLOCKS) || (req_op_level == SMB2_OPLOCK_LEVEL_LEASE && !(conn->vals->capabilities & SMB2_GLOBAL_CAP_LEASING))) { if (share_ret < 0 && !S_ISDIR(file_inode(fp->filp)->i_mode)) { rc = share_ret; - goto err_out; + goto err_out1; } } else { if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) { @@ -3213,7 +3234,7 @@ int smb2_open(struct ksmbd_work *work) name, req_op_level, lc->req_state); rc = find_same_lease_key(sess, fp->f_ci, lc); if (rc) - goto err_out; + goto err_out1; } else if (open_flags == O_RDONLY && (req_op_level == SMB2_OPLOCK_LEVEL_BATCH || req_op_level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) @@ -3224,12 +3245,18 @@ int smb2_open(struct ksmbd_work *work) le32_to_cpu(req->hdr.Id.SyncId.TreeId), lc, share_ret); if (rc < 0) - goto err_out; + goto err_out1; }
if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) ksmbd_fd_set_delete_on_close(fp, file_info);
+ if (need_truncate) { + rc = smb2_create_truncate(&fp->filp->f_path); + if (rc) + goto err_out1; + } + if (req->CreateContextsOffset) { struct create_alloc_size_req *az_req;
@@ -3237,7 +3264,7 @@ int smb2_open(struct ksmbd_work *work) SMB2_CREATE_ALLOCATION_SIZE, 4); if (IS_ERR(az_req)) { rc = PTR_ERR(az_req); - goto err_out; + goto err_out1; } else if (az_req) { loff_t alloc_size; int err; @@ -3246,7 +3273,7 @@ int smb2_open(struct ksmbd_work *work) le32_to_cpu(az_req->ccontext.DataLength) < sizeof(struct create_alloc_size_req)) { rc = -EINVAL; - goto err_out; + goto err_out1; } alloc_size = le64_to_cpu(az_req->AllocationSize); ksmbd_debug(SMB, @@ -3264,30 +3291,13 @@ int smb2_open(struct ksmbd_work *work) context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID, 4); if (IS_ERR(context)) { rc = PTR_ERR(context); - goto err_out; + goto err_out1; } else if (context) { ksmbd_debug(SMB, "get query on disk id context\n"); query_disk_id = 1; } }
- rc = ksmbd_vfs_getattr(&path, &stat); - if (rc) - goto err_out; - - if (stat.result_mask & STATX_BTIME) - fp->create_time = ksmbd_UnixTimeToNT(stat.btime); - else - fp->create_time = ksmbd_UnixTimeToNT(stat.ctime); - if (req->FileAttributes || fp->f_ci->m_fattr == 0) - fp->f_ci->m_fattr = - cpu_to_le32(smb2_get_dos_mode(&stat, le32_to_cpu(req->FileAttributes))); - - if (!created) - smb2_update_xattrs(tcon, &path, fp); - else - smb2_new_xattrs(tcon, &path, fp); - memcpy(fp->client_guid, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
rsp->StructureSize = cpu_to_le16(89); @@ -3394,14 +3404,13 @@ int smb2_open(struct ksmbd_work *work) }
err_out: - if (file_present || created) + if (rc && (file_present || created)) ksmbd_vfs_kern_path_unlock(&parent_path, &path);
- if (fp && need_truncate) - rc = smb2_create_truncate(&fp->filp->f_path); - - ksmbd_revert_fsids(work); err_out1: + ksmbd_revert_fsids(work); + +err_out2: if (!rc) { ksmbd_update_fstate(&work->sess->file_table, fp, FP_INITED); rc = ksmbd_iov_pin_rsp(work, (void *)rsp, iov_len);
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 2a3f7857ec742e212d6cee7fbbf7b0e2ae7f5161 ]
Add missing release async id and delete interim response entry after sending status pending response. This only cause when smb2 lease is enable.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/ksmbd_work.c | 3 +++ fs/smb/server/oplock.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/fs/smb/server/ksmbd_work.c b/fs/smb/server/ksmbd_work.c index 2510b9f3c8c14..d7c676c151e20 100644 --- a/fs/smb/server/ksmbd_work.c +++ b/fs/smb/server/ksmbd_work.c @@ -56,6 +56,9 @@ void ksmbd_free_work_struct(struct ksmbd_work *work) kfree(work->tr_buf); kvfree(work->request_buf); kfree(work->iov); + if (!list_empty(&work->interim_entry)) + list_del(&work->interim_entry); + if (work->async_id) ksmbd_release_id(&work->conn->async_ida, work->async_id); kmem_cache_free(work_cache, work); diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c index 9bc0103720f57..50c68beb71d6c 100644 --- a/fs/smb/server/oplock.c +++ b/fs/smb/server/oplock.c @@ -833,7 +833,8 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo) interim_entry); setup_async_work(in_work, NULL, NULL); smb2_send_interim_resp(in_work, STATUS_PENDING); - list_del(&in_work->interim_entry); + list_del_init(&in_work->interim_entry); + release_async_work(in_work); } INIT_WORK(&work->work, __smb2_lease_break_noti); ksmbd_queue_work(work);
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 9ac45ac7cf65b0623ceeab9b28b307a08efa22dc ]
Directly set SMB2_FLAGS_ASYNC_COMMAND flags and AsyncId in smb2 header of interim response instead of current response header.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/smb2pdu.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index e58504d0e9c1e..de71532651d97 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -657,13 +657,9 @@ smb2_get_name(const char *src, const int maxlen, struct nls_table *local_nls)
int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg) { - struct smb2_hdr *rsp_hdr; struct ksmbd_conn *conn = work->conn; int id;
- rsp_hdr = ksmbd_resp_buf_next(work); - rsp_hdr->Flags |= SMB2_FLAGS_ASYNC_COMMAND; - id = ksmbd_acquire_async_msg_id(&conn->async_ida); if (id < 0) { pr_err("Failed to alloc async message id\n"); @@ -671,7 +667,6 @@ int setup_async_work(struct ksmbd_work *work, void (*fn)(void **), void **arg) } work->asynchronous = true; work->async_id = id; - rsp_hdr->Id.AsyncId = cpu_to_le64(id);
ksmbd_debug(SMB, "Send interim Response to inform async request id : %d\n", @@ -723,6 +718,8 @@ void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status) __SMB2_HEADER_STRUCTURE_SIZE);
rsp_hdr = smb2_get_msg(in_work->response_buf); + rsp_hdr->Flags |= SMB2_FLAGS_ASYNC_COMMAND; + rsp_hdr->Id.AsyncId = cpu_to_le64(work->async_id); smb2_set_err_rsp(in_work); rsp_hdr->Status = status;
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit cd80ce7e68f1624ac29cd0a6b057789d1236641e ]
ksmbd set ->op_state as OPLOCK_STATE_NONE on lease break ack error. op_state of lease should not be updated because client can send lease break ack again. This patch fix smb2.lease.breaking2 test failure.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/smb2pdu.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index de71532651d97..5bff6746234d4 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -8235,7 +8235,6 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) return;
err_out: - opinfo->op_state = OPLOCK_STATE_NONE; wake_up_interruptible_all(&opinfo->oplock_q); atomic_dec(&opinfo->breaking_cnt); wake_up_interruptible_all(&opinfo->oplock_brk);
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit d045850b628aaf931fc776c90feaf824dca5a1cf ]
To support v2 lease(directory lease), ksmbd set epoch in create context v2 lease response.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/oplock.c | 5 ++++- fs/smb/server/oplock.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c index 50c68beb71d6c..ff5c83b1fb85c 100644 --- a/fs/smb/server/oplock.c +++ b/fs/smb/server/oplock.c @@ -104,7 +104,7 @@ static int alloc_lease(struct oplock_info *opinfo, struct lease_ctx_info *lctx) lease->duration = lctx->duration; memcpy(lease->parent_lease_key, lctx->parent_lease_key, SMB2_LEASE_KEY_SIZE); lease->version = lctx->version; - lease->epoch = 0; + lease->epoch = le16_to_cpu(lctx->epoch); INIT_LIST_HEAD(&opinfo->lease_entry); opinfo->o_lease = lease;
@@ -1032,6 +1032,7 @@ static void copy_lease(struct oplock_info *op1, struct oplock_info *op2) SMB2_LEASE_KEY_SIZE); lease2->duration = lease1->duration; lease2->flags = lease1->flags; + lease2->epoch = lease1->epoch++; }
static int add_lease_global_list(struct oplock_info *opinfo) @@ -1364,6 +1365,7 @@ void create_lease_buf(u8 *rbuf, struct lease *lease) memcpy(buf->lcontext.LeaseKey, lease->lease_key, SMB2_LEASE_KEY_SIZE); buf->lcontext.LeaseFlags = lease->flags; + buf->lcontext.Epoch = cpu_to_le16(++lease->epoch); buf->lcontext.LeaseState = lease->state; memcpy(buf->lcontext.ParentLeaseKey, lease->parent_lease_key, SMB2_LEASE_KEY_SIZE); @@ -1423,6 +1425,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req) memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE); lreq->req_state = lc->lcontext.LeaseState; lreq->flags = lc->lcontext.LeaseFlags; + lreq->epoch = lc->lcontext.Epoch; lreq->duration = lc->lcontext.LeaseDuration; memcpy(lreq->parent_lease_key, lc->lcontext.ParentLeaseKey, SMB2_LEASE_KEY_SIZE); diff --git a/fs/smb/server/oplock.h b/fs/smb/server/oplock.h index 4b0fe6da76940..ad31439c61fef 100644 --- a/fs/smb/server/oplock.h +++ b/fs/smb/server/oplock.h @@ -34,6 +34,7 @@ struct lease_ctx_info { __le32 flags; __le64 duration; __u8 parent_lease_key[SMB2_LEASE_KEY_SIZE]; + __le16 epoch; int version; };
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 18dd1c367c31d0a060f737d48345747662369b64 ]
Set SMB2_GLOBAL_CAP_DIRECTORY_LEASING to ->capabilities to inform server support directory lease to client.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/oplock.c | 4 ---- fs/smb/server/smb2ops.c | 9 ++++++--- 2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c index ff5c83b1fb85c..5ef6af68d0de6 100644 --- a/fs/smb/server/oplock.c +++ b/fs/smb/server/oplock.c @@ -1105,10 +1105,6 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid, bool prev_op_has_lease; __le32 prev_op_state = 0;
- /* not support directory lease */ - if (S_ISDIR(file_inode(fp->filp)->i_mode)) - return 0; - opinfo = alloc_opinfo(work, pid, tid); if (!opinfo) return -ENOMEM; diff --git a/fs/smb/server/smb2ops.c b/fs/smb/server/smb2ops.c index aed7704a06728..27a9dce3e03ab 100644 --- a/fs/smb/server/smb2ops.c +++ b/fs/smb/server/smb2ops.c @@ -221,7 +221,8 @@ void init_smb3_0_server(struct ksmbd_conn *conn) conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) - conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING; + conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING | + SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION && conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION) @@ -245,7 +246,8 @@ void init_smb3_02_server(struct ksmbd_conn *conn) conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) - conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING; + conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING | + SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION || (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) && @@ -270,7 +272,8 @@ int init_smb3_11_server(struct ksmbd_conn *conn) conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) - conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING; + conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING | + SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION || (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit eb547407f3572d2110cb1194ecd8865b3371a7a4 ]
RWH(Read + Write + Handle) caching state is not supported for directory. ksmbd downgrade it to RH for directory if client send RWH caching lease state.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/oplock.c | 9 +++++++-- fs/smb/server/oplock.h | 2 +- fs/smb/server/smb2pdu.c | 8 ++++---- 3 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c index 5ef6af68d0de6..57950ba7e9257 100644 --- a/fs/smb/server/oplock.c +++ b/fs/smb/server/oplock.c @@ -1398,10 +1398,11 @@ void create_lease_buf(u8 *rbuf, struct lease *lease) /** * parse_lease_state() - parse lease context containted in file open request * @open_req: buffer containing smb2 file open(create) request + * @is_dir: whether leasing file is directory * * Return: oplock state, -ENOENT if create lease context not found */ -struct lease_ctx_info *parse_lease_state(void *open_req) +struct lease_ctx_info *parse_lease_state(void *open_req, bool is_dir) { struct create_context *cc; struct smb2_create_req *req = (struct smb2_create_req *)open_req; @@ -1419,7 +1420,11 @@ struct lease_ctx_info *parse_lease_state(void *open_req) struct create_lease_v2 *lc = (struct create_lease_v2 *)cc;
memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE); - lreq->req_state = lc->lcontext.LeaseState; + if (is_dir) + lreq->req_state = lc->lcontext.LeaseState & + ~SMB2_LEASE_WRITE_CACHING_LE; + else + lreq->req_state = lc->lcontext.LeaseState; lreq->flags = lc->lcontext.LeaseFlags; lreq->epoch = lc->lcontext.Epoch; lreq->duration = lc->lcontext.LeaseDuration; diff --git a/fs/smb/server/oplock.h b/fs/smb/server/oplock.h index ad31439c61fef..672127318c750 100644 --- a/fs/smb/server/oplock.h +++ b/fs/smb/server/oplock.h @@ -109,7 +109,7 @@ void opinfo_put(struct oplock_info *opinfo);
/* Lease related functions */ void create_lease_buf(u8 *rbuf, struct lease *lease); -struct lease_ctx_info *parse_lease_state(void *open_req); +struct lease_ctx_info *parse_lease_state(void *open_req, bool is_dir); __u8 smb2_map_lease_to_oplock(__le32 lease_state); int lease_read_to_write(struct oplock_info *opinfo);
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 5bff6746234d4..c4b6adce178a2 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -2732,10 +2732,6 @@ int smb2_open(struct ksmbd_work *work) } }
- req_op_level = req->RequestedOplockLevel; - if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) - lc = parse_lease_state(req); - if (le32_to_cpu(req->ImpersonationLevel) > le32_to_cpu(IL_DELEGATE)) { pr_err("Invalid impersonationlevel : 0x%x\n", le32_to_cpu(req->ImpersonationLevel)); @@ -3215,6 +3211,10 @@ int smb2_open(struct ksmbd_work *work) need_truncate = 1; }
+ req_op_level = req->RequestedOplockLevel; + if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) + lc = parse_lease_state(req, S_ISDIR(file_inode(filp)->i_mode)); + share_ret = ksmbd_smb_check_shared_mode(fp->filp, fp); if (!test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_OPLOCKS) || (req_op_level == SMB2_OPLOCK_LEVEL_LEASE &&
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit d47d9886aeef79feba7adac701a510d65f3682b5 ]
If client send different parent key, different client guid, or there is no parent lease key flags in create context v2 lease, ksmbd send lease break to client.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/common/smb2pdu.h | 1 + fs/smb/server/oplock.c | 56 +++++++++++++++++++++++++++++++++++---- fs/smb/server/oplock.h | 4 +++ fs/smb/server/smb2pdu.c | 7 +++++ fs/smb/server/vfs_cache.c | 13 ++++++++- fs/smb/server/vfs_cache.h | 2 ++ 6 files changed, 77 insertions(+), 6 deletions(-)
diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h index ec20c83cc8366..d58550c1c9378 100644 --- a/fs/smb/common/smb2pdu.h +++ b/fs/smb/common/smb2pdu.h @@ -1228,6 +1228,7 @@ struct create_mxac_rsp { #define SMB2_LEASE_WRITE_CACHING_LE cpu_to_le32(0x04)
#define SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE cpu_to_le32(0x02) +#define SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE cpu_to_le32(0x04)
#define SMB2_LEASE_KEY_SIZE 16
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c index 57950ba7e9257..147d98427ce89 100644 --- a/fs/smb/server/oplock.c +++ b/fs/smb/server/oplock.c @@ -102,6 +102,7 @@ static int alloc_lease(struct oplock_info *opinfo, struct lease_ctx_info *lctx) lease->new_state = 0; lease->flags = lctx->flags; lease->duration = lctx->duration; + lease->is_dir = lctx->is_dir; memcpy(lease->parent_lease_key, lctx->parent_lease_key, SMB2_LEASE_KEY_SIZE); lease->version = lctx->version; lease->epoch = le16_to_cpu(lctx->epoch); @@ -543,12 +544,13 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci, /* upgrading lease */ if ((atomic_read(&ci->op_count) + atomic_read(&ci->sop_count)) == 1) { - if (lease->state == - (lctx->req_state & lease->state)) { + if (lease->state != SMB2_LEASE_NONE_LE && + lease->state == (lctx->req_state & lease->state)) { lease->state |= lctx->req_state; if (lctx->req_state & SMB2_LEASE_WRITE_CACHING_LE) lease_read_to_write(opinfo); + } } else if ((atomic_read(&ci->op_count) + atomic_read(&ci->sop_count)) > 1) { @@ -900,7 +902,8 @@ static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level) lease->new_state = SMB2_LEASE_READ_CACHING_LE; } else { - if (lease->state & SMB2_LEASE_HANDLE_CACHING_LE) + if (lease->state & SMB2_LEASE_HANDLE_CACHING_LE && + !lease->is_dir) lease->new_state = SMB2_LEASE_READ_CACHING_LE; else @@ -1082,6 +1085,48 @@ static void set_oplock_level(struct oplock_info *opinfo, int level, } }
+void smb_send_parent_lease_break_noti(struct ksmbd_file *fp, + struct lease_ctx_info *lctx) +{ + struct oplock_info *opinfo; + struct ksmbd_inode *p_ci = NULL; + + if (lctx->version != 2) + return; + + p_ci = ksmbd_inode_lookup_lock(fp->filp->f_path.dentry->d_parent); + if (!p_ci) + return; + + read_lock(&p_ci->m_lock); + list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) { + if (!opinfo->is_lease) + continue; + + if (opinfo->o_lease->state != SMB2_OPLOCK_LEVEL_NONE && + (!(lctx->flags & SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE) || + !compare_guid_key(opinfo, fp->conn->ClientGUID, + lctx->parent_lease_key))) { + if (!atomic_inc_not_zero(&opinfo->refcount)) + continue; + + atomic_inc(&opinfo->conn->r_count); + if (ksmbd_conn_releasing(opinfo->conn)) { + atomic_dec(&opinfo->conn->r_count); + continue; + } + + read_unlock(&p_ci->m_lock); + oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE); + opinfo_conn_put(opinfo); + read_lock(&p_ci->m_lock); + } + } + read_unlock(&p_ci->m_lock); + + ksmbd_inode_put(p_ci); +} + /** * smb_grant_oplock() - handle oplock/lease request on file open * @work: smb work @@ -1420,10 +1465,11 @@ struct lease_ctx_info *parse_lease_state(void *open_req, bool is_dir) struct create_lease_v2 *lc = (struct create_lease_v2 *)cc;
memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE); - if (is_dir) + if (is_dir) { lreq->req_state = lc->lcontext.LeaseState & ~SMB2_LEASE_WRITE_CACHING_LE; - else + lreq->is_dir = true; + } else lreq->req_state = lc->lcontext.LeaseState; lreq->flags = lc->lcontext.LeaseFlags; lreq->epoch = lc->lcontext.Epoch; diff --git a/fs/smb/server/oplock.h b/fs/smb/server/oplock.h index 672127318c750..b64d1536882a1 100644 --- a/fs/smb/server/oplock.h +++ b/fs/smb/server/oplock.h @@ -36,6 +36,7 @@ struct lease_ctx_info { __u8 parent_lease_key[SMB2_LEASE_KEY_SIZE]; __le16 epoch; int version; + bool is_dir; };
struct lease_table { @@ -54,6 +55,7 @@ struct lease { __u8 parent_lease_key[SMB2_LEASE_KEY_SIZE]; int version; unsigned short epoch; + bool is_dir; struct lease_table *l_lb; };
@@ -125,4 +127,6 @@ struct oplock_info *lookup_lease_in_table(struct ksmbd_conn *conn, int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci, struct lease_ctx_info *lctx); void destroy_lease_table(struct ksmbd_conn *conn); +void smb_send_parent_lease_break_noti(struct ksmbd_file *fp, + struct lease_ctx_info *lctx); #endif /* __KSMBD_OPLOCK_H */ diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index c4b6adce178a2..cbd5c5572217d 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -3225,6 +3225,13 @@ int smb2_open(struct ksmbd_work *work) } } else { if (req_op_level == SMB2_OPLOCK_LEVEL_LEASE) { + /* + * Compare parent lease using parent key. If there is no + * a lease that has same parent key, Send lease break + * notification. + */ + smb_send_parent_lease_break_noti(fp, lc); + req_op_level = smb2_map_lease_to_oplock(lc->req_state); ksmbd_debug(SMB, "lease req for(%s) req oplock state 0x%x, lease state 0x%x\n", diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c index ddf233994ddbb..4e82ff627d122 100644 --- a/fs/smb/server/vfs_cache.c +++ b/fs/smb/server/vfs_cache.c @@ -87,6 +87,17 @@ static struct ksmbd_inode *ksmbd_inode_lookup(struct ksmbd_file *fp) return __ksmbd_inode_lookup(fp->filp->f_path.dentry); }
+struct ksmbd_inode *ksmbd_inode_lookup_lock(struct dentry *d) +{ + struct ksmbd_inode *ci; + + read_lock(&inode_hash_lock); + ci = __ksmbd_inode_lookup(d); + read_unlock(&inode_hash_lock); + + return ci; +} + int ksmbd_query_inode_status(struct dentry *dentry) { struct ksmbd_inode *ci; @@ -199,7 +210,7 @@ static void ksmbd_inode_free(struct ksmbd_inode *ci) kfree(ci); }
-static void ksmbd_inode_put(struct ksmbd_inode *ci) +void ksmbd_inode_put(struct ksmbd_inode *ci) { if (atomic_dec_and_test(&ci->m_count)) ksmbd_inode_free(ci); diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h index 8325cf4527c46..4d4938d6029b6 100644 --- a/fs/smb/server/vfs_cache.h +++ b/fs/smb/server/vfs_cache.h @@ -138,6 +138,8 @@ struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, u64 id); struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, u64 id, u64 pid); void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp); +struct ksmbd_inode *ksmbd_inode_lookup_lock(struct dentry *d); +void ksmbd_inode_put(struct ksmbd_inode *ci); struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id); struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid); struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry);
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit c2a721eead71202a0d8ddd9b56ec8dce652c71d1 ]
Don't immediately send directory lease break notification on smb2_write(). Instead, It postpones it until smb2_close().
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/oplock.c | 45 +++++++++++++++++++++++++++++++++++++-- fs/smb/server/oplock.h | 1 + fs/smb/server/vfs.c | 3 +++ fs/smb/server/vfs_cache.h | 1 + 4 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c index 147d98427ce89..562b180459a1a 100644 --- a/fs/smb/server/oplock.c +++ b/fs/smb/server/oplock.c @@ -396,8 +396,8 @@ void close_id_del_oplock(struct ksmbd_file *fp) { struct oplock_info *opinfo;
- if (S_ISDIR(file_inode(fp->filp)->i_mode)) - return; + if (fp->reserve_lease_break) + smb_lazy_parent_lease_break_close(fp);
opinfo = opinfo_get(fp); if (!opinfo) @@ -1127,6 +1127,47 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp, ksmbd_inode_put(p_ci); }
+void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp) +{ + struct oplock_info *opinfo; + struct ksmbd_inode *p_ci = NULL; + + rcu_read_lock(); + opinfo = rcu_dereference(fp->f_opinfo); + rcu_read_unlock(); + + if (!opinfo->is_lease || opinfo->o_lease->version != 2) + return; + + p_ci = ksmbd_inode_lookup_lock(fp->filp->f_path.dentry->d_parent); + if (!p_ci) + return; + + read_lock(&p_ci->m_lock); + list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) { + if (!opinfo->is_lease) + continue; + + if (opinfo->o_lease->state != SMB2_OPLOCK_LEVEL_NONE) { + if (!atomic_inc_not_zero(&opinfo->refcount)) + continue; + + atomic_inc(&opinfo->conn->r_count); + if (ksmbd_conn_releasing(opinfo->conn)) { + atomic_dec(&opinfo->conn->r_count); + continue; + } + read_unlock(&p_ci->m_lock); + oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE); + opinfo_conn_put(opinfo); + read_lock(&p_ci->m_lock); + } + } + read_unlock(&p_ci->m_lock); + + ksmbd_inode_put(p_ci); +} + /** * smb_grant_oplock() - handle oplock/lease request on file open * @work: smb work diff --git a/fs/smb/server/oplock.h b/fs/smb/server/oplock.h index b64d1536882a1..5b93ea9196c01 100644 --- a/fs/smb/server/oplock.h +++ b/fs/smb/server/oplock.h @@ -129,4 +129,5 @@ int find_same_lease_key(struct ksmbd_session *sess, struct ksmbd_inode *ci, void destroy_lease_table(struct ksmbd_conn *conn); void smb_send_parent_lease_break_noti(struct ksmbd_file *fp, struct lease_ctx_info *lctx); +void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp); #endif /* __KSMBD_OPLOCK_H */ diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index 9091dcd7a3102..4277750a6da1b 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -517,6 +517,9 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp, } }
+ /* Reserve lease break for parent dir at closing time */ + fp->reserve_lease_break = true; + /* Do we need to break any of a levelII oplock? */ smb_break_all_levII_oplock(work, fp, 1);
diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h index 4d4938d6029b6..a528f0cc775ae 100644 --- a/fs/smb/server/vfs_cache.h +++ b/fs/smb/server/vfs_cache.h @@ -105,6 +105,7 @@ struct ksmbd_file { struct ksmbd_readdir_data readdir_data; int dot_dotdot[2]; unsigned int f_state; + bool reserve_lease_break; };
static inline void set_ctx_actor(struct dir_context *ctx,
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 658609d9a618d8881bf549b5893c0ba8fcff4526 ]
opinfo_put() could be called twice on error of smb21_lease_break_ack(). It will cause UAF issue if opinfo is referenced on other places.
Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/smb2pdu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index cbd5c5572217d..fbd708bb4a5b2 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -8219,6 +8219,11 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) le32_to_cpu(req->LeaseState)); }
+ if (ret < 0) { + rsp->hdr.Status = err; + goto err_out; + } + lease_state = lease->state; opinfo->op_state = OPLOCK_STATE_NONE; wake_up_interruptible_all(&opinfo->oplock_q); @@ -8226,11 +8231,6 @@ static void smb21_lease_break_ack(struct ksmbd_work *work) wake_up_interruptible_all(&opinfo->oplock_brk); opinfo_put(opinfo);
- if (ret < 0) { - rsp->hdr.Status = err; - goto err_out; - } - rsp->StructureSize = cpu_to_le16(36); rsp->Reserved = 0; rsp->Flags = 0;
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton jlayton@kernel.org
[ Upstream commit 077c212f0344ae4198b2b51af128a94b614ccdf4 ]
Recently, we converted the ctime accesses in the kernel to use new accessor functions. Linus recently pointed out though that if we add accessors for the atime and mtime, then that would allow us to seamlessly change how these timestamps are stored in the inode.
Add new accessor functions for the atime and mtime that mirror the accessors for the ctime.
Signed-off-by: Jeff Layton jlayton@kernel.org Link: https://lore.kernel.org/r/20231004185239.80830-1-jlayton@kernel.org Signed-off-by: Christian Brauner brauner@kernel.org Stable-dep-of: 01fe654f78fd ("fs: cifs: Fix atime update check") Signed-off-by: Sasha Levin sashal@kernel.org --- fs/libfs.c | 41 ++++++++++++++++------ include/linux/fs.h | 85 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 102 insertions(+), 24 deletions(-)
diff --git a/fs/libfs.c b/fs/libfs.c index 189447cf4acf5..dc0f7519045f1 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -549,7 +549,8 @@ void simple_recursive_removal(struct dentry *dentry, dput(victim); // unpin it } if (victim == dentry) { - inode->i_mtime = inode_set_ctime_current(inode); + inode_set_mtime_to_ts(inode, + inode_set_ctime_current(inode)); if (d_is_dir(dentry)) drop_nlink(inode); inode_unlock(inode); @@ -590,7 +591,7 @@ static int pseudo_fs_fill_super(struct super_block *s, struct fs_context *fc) */ root->i_ino = 1; root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR; - root->i_atime = root->i_mtime = inode_set_ctime_current(root); + simple_inode_init_ts(root); s->s_root = d_make_root(root); if (!s->s_root) return -ENOMEM; @@ -646,8 +647,8 @@ int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *den { struct inode *inode = d_inode(old_dentry);
- dir->i_mtime = inode_set_ctime_to_ts(dir, - inode_set_ctime_current(inode)); + inode_set_mtime_to_ts(dir, + inode_set_ctime_to_ts(dir, inode_set_ctime_current(inode))); inc_nlink(inode); ihold(inode); dget(dentry); @@ -681,8 +682,8 @@ int simple_unlink(struct inode *dir, struct dentry *dentry) { struct inode *inode = d_inode(dentry);
- dir->i_mtime = inode_set_ctime_to_ts(dir, - inode_set_ctime_current(inode)); + inode_set_mtime_to_ts(dir, + inode_set_ctime_to_ts(dir, inode_set_ctime_current(inode))); drop_nlink(inode); dput(dentry); return 0; @@ -717,9 +718,10 @@ void simple_rename_timestamp(struct inode *old_dir, struct dentry *old_dentry, { struct inode *newino = d_inode(new_dentry);
- old_dir->i_mtime = inode_set_ctime_current(old_dir); + inode_set_mtime_to_ts(old_dir, inode_set_ctime_current(old_dir)); if (new_dir != old_dir) - new_dir->i_mtime = inode_set_ctime_current(new_dir); + inode_set_mtime_to_ts(new_dir, + inode_set_ctime_current(new_dir)); inode_set_ctime_current(d_inode(old_dentry)); if (newino) inode_set_ctime_current(newino); @@ -934,7 +936,7 @@ int simple_fill_super(struct super_block *s, unsigned long magic, */ inode->i_ino = 1; inode->i_mode = S_IFDIR | 0755; - inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode); + simple_inode_init_ts(inode); inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; set_nlink(inode, 2); @@ -960,7 +962,7 @@ int simple_fill_super(struct super_block *s, unsigned long magic, goto out; } inode->i_mode = S_IFREG | files->mode; - inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode); + simple_inode_init_ts(inode); inode->i_fop = files->ops; inode->i_ino = i; d_add(dentry, inode); @@ -1528,7 +1530,7 @@ struct inode *alloc_anon_inode(struct super_block *s) inode->i_uid = current_fsuid(); inode->i_gid = current_fsgid(); inode->i_flags |= S_PRIVATE; - inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode); + simple_inode_init_ts(inode); return inode; } EXPORT_SYMBOL(alloc_anon_inode); @@ -1920,3 +1922,20 @@ ssize_t direct_write_fallback(struct kiocb *iocb, struct iov_iter *iter, return direct_written + buffered_written; } EXPORT_SYMBOL_GPL(direct_write_fallback); + +/** + * simple_inode_init_ts - initialize the timestamps for a new inode + * @inode: inode to be initialized + * + * When a new inode is created, most filesystems set the timestamps to the + * current time. Add a helper to do this. + */ +struct timespec64 simple_inode_init_ts(struct inode *inode) +{ + struct timespec64 ts = inode_set_ctime_current(inode); + + inode_set_atime_to_ts(inode, ts); + inode_set_mtime_to_ts(inode, ts); + return ts; +} +EXPORT_SYMBOL(simple_inode_init_ts); diff --git a/include/linux/fs.h b/include/linux/fs.h index 4a40823c3c678..d08b97dacd2d9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1511,24 +1511,81 @@ static inline bool fsuidgid_has_mapping(struct super_block *sb, struct timespec64 current_time(struct inode *inode); struct timespec64 inode_set_ctime_current(struct inode *inode);
-/** - * inode_get_ctime - fetch the current ctime from the inode - * @inode: inode from which to fetch ctime - * - * Grab the current ctime from the inode and return it. - */ +static inline time64_t inode_get_atime_sec(const struct inode *inode) +{ + return inode->i_atime.tv_sec; +} + +static inline long inode_get_atime_nsec(const struct inode *inode) +{ + return inode->i_atime.tv_nsec; +} + +static inline struct timespec64 inode_get_atime(const struct inode *inode) +{ + return inode->i_atime; +} + +static inline struct timespec64 inode_set_atime_to_ts(struct inode *inode, + struct timespec64 ts) +{ + inode->i_atime = ts; + return ts; +} + +static inline struct timespec64 inode_set_atime(struct inode *inode, + time64_t sec, long nsec) +{ + struct timespec64 ts = { .tv_sec = sec, + .tv_nsec = nsec }; + return inode_set_atime_to_ts(inode, ts); +} + +static inline time64_t inode_get_mtime_sec(const struct inode *inode) +{ + return inode->i_mtime.tv_sec; +} + +static inline long inode_get_mtime_nsec(const struct inode *inode) +{ + return inode->i_mtime.tv_nsec; +} + +static inline struct timespec64 inode_get_mtime(const struct inode *inode) +{ + return inode->i_mtime; +} + +static inline struct timespec64 inode_set_mtime_to_ts(struct inode *inode, + struct timespec64 ts) +{ + inode->i_mtime = ts; + return ts; +} + +static inline struct timespec64 inode_set_mtime(struct inode *inode, + time64_t sec, long nsec) +{ + struct timespec64 ts = { .tv_sec = sec, + .tv_nsec = nsec }; + return inode_set_mtime_to_ts(inode, ts); +} + +static inline time64_t inode_get_ctime_sec(const struct inode *inode) +{ + return inode->__i_ctime.tv_sec; +} + +static inline long inode_get_ctime_nsec(const struct inode *inode) +{ + return inode->__i_ctime.tv_nsec; +} + static inline struct timespec64 inode_get_ctime(const struct inode *inode) { return inode->__i_ctime; }
-/** - * inode_set_ctime_to_ts - set the ctime in the inode - * @inode: inode in which to set the ctime - * @ts: value to set in the ctime field - * - * Set the ctime in @inode to @ts - */ static inline struct timespec64 inode_set_ctime_to_ts(struct inode *inode, struct timespec64 ts) { @@ -1553,6 +1610,8 @@ static inline struct timespec64 inode_set_ctime(struct inode *inode, return inode_set_ctime_to_ts(inode, ts); }
+struct timespec64 simple_inode_init_ts(struct inode *inode); + /* * Snapshotting support. */
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton jlayton@kernel.org
[ Upstream commit 8f22ce7088835444418f0775efb455d10b825596 ]
Convert to using the new inode timestamp accessor functions.
Signed-off-by: Jeff Layton jlayton@kernel.org Link: https://lore.kernel.org/r/20231004185347.80880-66-jlayton@kernel.org Signed-off-by: Christian Brauner brauner@kernel.org Stable-dep-of: 01fe654f78fd ("fs: cifs: Fix atime update check") Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/client/file.c | 18 ++++++++++-------- fs/smb/client/fscache.h | 6 +++--- fs/smb/client/inode.c | 17 ++++++++--------- fs/smb/client/smb2ops.c | 6 ++++-- 4 files changed, 25 insertions(+), 22 deletions(-)
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index 2108b3b40ce92..cf17e3dd703e6 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -1085,7 +1085,8 @@ int cifs_close(struct inode *inode, struct file *file) !test_bit(CIFS_INO_CLOSE_ON_LOCK, &cinode->flags) && dclose) { if (test_and_clear_bit(CIFS_INO_MODIFIED_ATTR, &cinode->flags)) { - inode->i_mtime = inode_set_ctime_current(inode); + inode_set_mtime_to_ts(inode, + inode_set_ctime_current(inode)); } spin_lock(&cinode->deferred_lock); cifs_add_deferred_close(cfile, dclose); @@ -2596,7 +2597,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) write_data, to - from, &offset); cifsFileInfo_put(open_file); /* Does mm or vfs already set times? */ - inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode); + simple_inode_init_ts(inode); if ((bytes_written > 0) && (offset)) rc = 0; else if (bytes_written < 0) @@ -4647,11 +4648,13 @@ static void cifs_readahead(struct readahead_control *ractl) static int cifs_readpage_worker(struct file *file, struct page *page, loff_t *poffset) { + struct inode *inode = file_inode(file); + struct timespec64 atime, mtime; char *read_data; int rc;
/* Is the page cached? */ - rc = cifs_readpage_from_fscache(file_inode(file), page); + rc = cifs_readpage_from_fscache(inode, page); if (rc == 0) goto read_complete;
@@ -4666,11 +4669,10 @@ static int cifs_readpage_worker(struct file *file, struct page *page, cifs_dbg(FYI, "Bytes read %d\n", rc);
/* we do not want atime to be less than mtime, it broke some apps */ - file_inode(file)->i_atime = current_time(file_inode(file)); - if (timespec64_compare(&(file_inode(file)->i_atime), &(file_inode(file)->i_mtime))) - file_inode(file)->i_atime = file_inode(file)->i_mtime; - else - file_inode(file)->i_atime = current_time(file_inode(file)); + atime = inode_set_atime_to_ts(inode, current_time(inode)); + mtime = inode_get_mtime(inode); + if (timespec64_compare(&atime, &mtime)) + inode_set_atime_to_ts(inode, inode_get_mtime(inode));
if (PAGE_SIZE > rc) memset(read_data + rc, 0, PAGE_SIZE - rc); diff --git a/fs/smb/client/fscache.h b/fs/smb/client/fscache.h index 84f3b09367d2c..a3d73720914f8 100644 --- a/fs/smb/client/fscache.h +++ b/fs/smb/client/fscache.h @@ -49,12 +49,12 @@ static inline void cifs_fscache_fill_coherency(struct inode *inode, struct cifs_fscache_inode_coherency_data *cd) { - struct cifsInodeInfo *cifsi = CIFS_I(inode); struct timespec64 ctime = inode_get_ctime(inode); + struct timespec64 mtime = inode_get_mtime(inode);
memset(cd, 0, sizeof(*cd)); - cd->last_write_time_sec = cpu_to_le64(cifsi->netfs.inode.i_mtime.tv_sec); - cd->last_write_time_nsec = cpu_to_le32(cifsi->netfs.inode.i_mtime.tv_nsec); + cd->last_write_time_sec = cpu_to_le64(mtime.tv_sec); + cd->last_write_time_nsec = cpu_to_le32(mtime.tv_nsec); cd->last_change_time_sec = cpu_to_le64(ctime.tv_sec); cd->last_change_time_nsec = cpu_to_le32(ctime.tv_nsec); } diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index 6a856945f2b42..09c5c0f5c96e2 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -82,6 +82,7 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) { struct cifs_fscache_inode_coherency_data cd; struct cifsInodeInfo *cifs_i = CIFS_I(inode); + struct timespec64 mtime;
cifs_dbg(FYI, "%s: revalidating inode %llu\n", __func__, cifs_i->uniqueid); @@ -101,7 +102,8 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
/* revalidate if mtime or size have changed */ fattr->cf_mtime = timestamp_truncate(fattr->cf_mtime, inode); - if (timespec64_equal(&inode->i_mtime, &fattr->cf_mtime) && + mtime = inode_get_mtime(inode); + if (timespec64_equal(&mtime, &fattr->cf_mtime) && cifs_i->server_eof == fattr->cf_eof) { cifs_dbg(FYI, "%s: inode %llu is unchanged\n", __func__, cifs_i->uniqueid); @@ -164,10 +166,10 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) fattr->cf_ctime = timestamp_truncate(fattr->cf_ctime, inode); /* we do not want atime to be less than mtime, it broke some apps */ if (timespec64_compare(&fattr->cf_atime, &fattr->cf_mtime) < 0) - inode->i_atime = fattr->cf_mtime; + inode_set_atime_to_ts(inode, fattr->cf_mtime); else - inode->i_atime = fattr->cf_atime; - inode->i_mtime = fattr->cf_mtime; + inode_set_atime_to_ts(inode, fattr->cf_atime); + inode_set_mtime_to_ts(inode, fattr->cf_mtime); inode_set_ctime_to_ts(inode, fattr->cf_ctime); inode->i_rdev = fattr->cf_rdev; cifs_nlink_fattr_to_inode(inode, fattr); @@ -1868,7 +1870,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) when needed */ inode_set_ctime_current(inode); } - dir->i_mtime = inode_set_ctime_current(dir); + inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); cifs_inode = CIFS_I(dir); CIFS_I(dir)->time = 0; /* force revalidate of dir as well */ unlink_out: @@ -2183,7 +2185,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) cifsInode->time = 0;
inode_set_ctime_current(d_inode(direntry)); - inode->i_mtime = inode_set_ctime_current(inode); + inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
rmdir_exit: free_dentry_path(page); @@ -2389,9 +2391,6 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir, /* force revalidate to go get info when needed */ CIFS_I(source_dir)->time = CIFS_I(target_dir)->time = 0;
- source_dir->i_mtime = target_dir->i_mtime = inode_set_ctime_to_ts(source_dir, - inode_set_ctime_current(target_dir)); - cifs_rename_exit: kfree(info_buf_source); free_dentry_path(page2); diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 2187921580ac6..e917eeba9c772 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -1409,12 +1409,14 @@ smb2_close_getattr(const unsigned int xid, struct cifs_tcon *tcon,
/* Creation time should not need to be updated on close */ if (file_inf.LastWriteTime) - inode->i_mtime = cifs_NTtimeToUnix(file_inf.LastWriteTime); + inode_set_mtime_to_ts(inode, + cifs_NTtimeToUnix(file_inf.LastWriteTime)); if (file_inf.ChangeTime) inode_set_ctime_to_ts(inode, cifs_NTtimeToUnix(file_inf.ChangeTime)); if (file_inf.LastAccessTime) - inode->i_atime = cifs_NTtimeToUnix(file_inf.LastAccessTime); + inode_set_atime_to_ts(inode, + cifs_NTtimeToUnix(file_inf.LastAccessTime));
/* * i_blocks is not related to (i_size / i_blksize),
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zizhi Wo wozizhi@huawei.com
[ Upstream commit 01fe654f78fd1ea4df046ef76b07ba92a35f8dbe ]
Commit 9b9c5bea0b96 ("cifs: do not return atime less than mtime") indicates that in cifs, if atime is less than mtime, some apps will break. Therefore, it introduce a function to compare this two variables in two places where atime is updated. If atime is less than mtime, update it to mtime.
However, the patch was handled incorrectly, resulting in atime and mtime being exactly equal. A previous commit 69738cfdfa70 ("fs: cifs: Fix atime update check vs mtime") fixed one place and forgot to fix another. Fix it.
Fixes: 9b9c5bea0b96 ("cifs: do not return atime less than mtime") Cc: stable@vger.kernel.org Signed-off-by: Zizhi Wo wozizhi@huawei.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/client/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index cf17e3dd703e6..32a8525415d96 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -4671,7 +4671,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page, /* we do not want atime to be less than mtime, it broke some apps */ atime = inode_set_atime_to_ts(inode, current_time(inode)); mtime = inode_get_mtime(inode); - if (timespec64_compare(&atime, &mtime)) + if (timespec64_compare(&atime, &mtime) < 0) inode_set_atime_to_ts(inode, inode_get_mtime(inode));
if (PAGE_SIZE > rc)
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xuan Zhuo xuanzhuo@linux.alibaba.com
[ Upstream commit 1f475cd572ea77ae6474a17e693a96bca927efe9 ]
Now the APIs virtqueue_dma_sync_single_range_for_{cpu,device} ignore the parameter 'dir', that is a mistake.
[ 6.101666] ------------[ cut here ]------------ [ 6.102079] DMA-API: virtio-pci 0000:00:04.0: device driver syncs DMA memory with different direction [device address=0x00000000ae010000] [size=32752 bytes] [mapped with DMA_FROM_DEVICE] [synced with DMA_BIDIRECTIONAL] [ 6.103630] WARNING: CPU: 6 PID: 0 at kernel/dma/debug.c:1125 check_sync+0x53e/0x6c0 [ 6.107420] CPU: 6 PID: 0 Comm: swapper/6 Tainted: G E 6.6.0+ #290 [ 6.108030] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 [ 6.108936] RIP: 0010:check_sync+0x53e/0x6c0 [ 6.109289] Code: 24 10 e8 f5 d9 74 00 4c 8b 4c 24 10 4c 8b 44 24 18 48 8b 4c 24 20 48 89 c6 41 56 4c 89 ea 48 c7 c7 b0 f1 50 82 e8 32 fc f3 ff <0f> 0b 48 c7 c7 48 4b 4a 82 e8 74 d9 fc ff 8b 73 4c 48 8d 7b 50 31 [ 6.110750] RSP: 0018:ffffc90000180cd8 EFLAGS: 00010092 [ 6.111178] RAX: 00000000000000ce RBX: ffff888100aa5900 RCX: 0000000000000000 [ 6.111744] RDX: 0000000000000104 RSI: ffffffff824c3208 RDI: 00000000ffffffff [ 6.112316] RBP: ffffc90000180d40 R08: 0000000000000000 R09: 00000000fffeffff [ 6.112893] R10: ffffc90000180b98 R11: ffffffff82f63308 R12: ffffffff83d5af00 [ 6.113460] R13: ffff888100998200 R14: ffffffff824a4b5f R15: 0000000000000286 [ 6.114027] FS: 0000000000000000(0000) GS:ffff88842fd80000(0000) knlGS:0000000000000000 [ 6.114665] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 6.115128] CR2: 00007f10f1e03030 CR3: 0000000108272004 CR4: 0000000000770ee0 [ 6.115701] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 6.116272] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 6.116842] PKRU: 55555554 [ 6.117069] Call Trace: [ 6.117275] <IRQ> [ 6.117452] ? __warn+0x84/0x140 [ 6.117727] ? check_sync+0x53e/0x6c0 [ 6.118034] ? __report_bug+0xea/0x100 [ 6.118353] ? check_sync+0x53e/0x6c0 [ 6.118653] ? report_bug+0x41/0xc0 [ 6.118944] ? handle_bug+0x3c/0x70 [ 6.119237] ? exc_invalid_op+0x18/0x70 [ 6.119551] ? asm_exc_invalid_op+0x1a/0x20 [ 6.119900] ? check_sync+0x53e/0x6c0 [ 6.120199] ? check_sync+0x53e/0x6c0 [ 6.120499] debug_dma_sync_single_for_cpu+0x5c/0x70 [ 6.120906] ? dma_sync_single_for_cpu+0xb7/0x100 [ 6.121291] virtnet_rq_unmap+0x158/0x170 [virtio_net] [ 6.121716] virtnet_receive+0x196/0x220 [virtio_net] [ 6.122135] virtnet_poll+0x48/0x1b0 [virtio_net] [ 6.122524] __napi_poll+0x29/0x1b0 [ 6.123083] net_rx_action+0x282/0x360 [ 6.123612] __do_softirq+0xf3/0x2fb [ 6.124138] __irq_exit_rcu+0x8e/0xf0 [ 6.124663] common_interrupt+0xbc/0xe0 [ 6.125202] </IRQ>
We need to enable CONFIG_DMA_API_DEBUG and work with need sync mode(such as swiotlb) to reproduce this warn.
Fixes: 8bd2f71054bd ("virtio_ring: introduce dma sync api for virtqueue") Reported-by: "Ning, Hongyu" hongyu.ning@linux.intel.com Closes: https://lore.kernel.org/all/f37cb55a-6fc8-4e21-8789-46d468325eea@linux.intel... Suggested-by: Jason Wang jasowang@redhat.com Signed-off-by: Xuan Zhuo xuanzhuo@linux.alibaba.com Message-Id: 20231201033303.25141-1-xuanzhuo@linux.alibaba.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Reviewed-by: Parav Pandit parav@nvidia.com Acked-by: Jason Wang jasowang@redhat.com Tested-by: Hongyu Ning hongyu.ning@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/virtio/virtio_ring.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 51d8f3299c105..49299b1f9ec74 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -3219,8 +3219,7 @@ void virtqueue_dma_sync_single_range_for_cpu(struct virtqueue *_vq, if (!vq->use_dma_api) return;
- dma_sync_single_range_for_cpu(dev, addr, offset, size, - DMA_BIDIRECTIONAL); + dma_sync_single_range_for_cpu(dev, addr, offset, size, dir); } EXPORT_SYMBOL_GPL(virtqueue_dma_sync_single_range_for_cpu);
@@ -3246,8 +3245,7 @@ void virtqueue_dma_sync_single_range_for_device(struct virtqueue *_vq, if (!vq->use_dma_api) return;
- dma_sync_single_range_for_device(dev, addr, offset, size, - DMA_BIDIRECTIONAL); + dma_sync_single_range_for_device(dev, addr, offset, size, dir); } EXPORT_SYMBOL_GPL(virtqueue_dma_sync_single_range_for_device);
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit c1ad12ee0efc07244be37f69311e6f7c4ac98e62 ]
The cleanup for the CONFIG_KEXEC Kconfig logic accidentally changed the 'depends on CRYPTO=y' dependency to a plain 'depends on CRYPTO', which causes a link failure when all the crypto support is in a loadable module and kexec_file support is built-in:
x86_64-linux-ld: vmlinux.o: in function `__x64_sys_kexec_file_load': (.text+0x32e30a): undefined reference to `crypto_alloc_shash' x86_64-linux-ld: (.text+0x32e58e): undefined reference to `crypto_shash_update' x86_64-linux-ld: (.text+0x32e6ee): undefined reference to `crypto_shash_final'
Both s390 and x86 have this problem, while ppc64 and riscv have the correct dependency already. On riscv, the dependency is only used for the purgatory, not for the kexec_file code itself, which may be a bit surprising as it means that with CONFIG_CRYPTO=m, it is possible to enable KEXEC_FILE but then the purgatory code is silently left out.
Move this into the common Kconfig.kexec file in a way that is correct everywhere, using the dependency on CRYPTO_SHA256=y only when the purgatory code is available. This requires reversing the dependency between ARCH_SUPPORTS_KEXEC_PURGATORY and KEXEC_FILE, but the effect remains the same, other than making riscv behave like the other ones.
On s390, there is an additional dependency on CRYPTO_SHA256_S390, which should technically not be required but gives better performance. Remove this dependency here, noting that it was not present in the initial Kconfig code but was brought in without an explanation in commit 71406883fd357 ("s390/kexec_file: Add kexec_file_load system call").
[arnd@arndb.de: fix riscv build] Link: https://lkml.kernel.org/r/67ddd260-d424-4229-a815-e3fcfb864a77@app.fastmail.... Link: https://lkml.kernel.org/r/20231023110308.1202042-1-arnd@kernel.org Fixes: 6af5138083005 ("x86/kexec: refactor for kernel/Kconfig.kexec") Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Eric DeVolder eric_devolder@yahoo.com Tested-by: Eric DeVolder eric_devolder@yahoo.com Cc: Albert Ou aou@eecs.berkeley.edu Cc: Alexander Gordeev agordeev@linux.ibm.com Cc: Ard Biesheuvel ardb@kernel.org Cc: Borislav Petkov bp@alien8.de Cc: Christian Borntraeger borntraeger@linux.ibm.com Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: Conor Dooley conor@kernel.org Cc: Dave Hansen dave.hansen@linux.intel.com Cc: David S. Miller davem@davemloft.net Cc: Heiko Carstens hca@linux.ibm.com Cc: Herbert Xu herbert@gondor.apana.org.au Cc: "H. Peter Anvin" hpa@zytor.com Cc: Ingo Molnar mingo@redhat.com Cc: Nicholas Piggin npiggin@gmail.com Cc: Palmer Dabbelt palmer@dabbelt.com Cc: Paul Walmsley paul.walmsley@sifive.com Cc: Peter Zijlstra peterz@infradead.org Cc: Sven Schnelle svens@linux.ibm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/Kconfig | 4 ++-- arch/riscv/Kconfig | 4 +--- arch/s390/Kconfig | 4 ++-- arch/x86/Kconfig | 4 ++-- kernel/Kconfig.kexec | 1 + 5 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index d5d5388973ac7..4640cee33f123 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -607,10 +607,10 @@ config ARCH_SUPPORTS_KEXEC def_bool PPC_BOOK3S || PPC_E500 || (44x && !SMP)
config ARCH_SUPPORTS_KEXEC_FILE - def_bool PPC64 && CRYPTO=y && CRYPTO_SHA256=y + def_bool PPC64
config ARCH_SUPPORTS_KEXEC_PURGATORY - def_bool KEXEC_FILE + def_bool y
config ARCH_SELECTS_KEXEC_FILE def_bool y diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 6688cbbed0b42..9e6d442773eea 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -686,9 +686,7 @@ config ARCH_SELECTS_KEXEC_FILE select KEXEC_ELF
config ARCH_SUPPORTS_KEXEC_PURGATORY - def_bool KEXEC_FILE - depends on CRYPTO=y - depends on CRYPTO_SHA256=y + def_bool ARCH_SUPPORTS_KEXEC_FILE
config ARCH_SUPPORTS_CRASH_DUMP def_bool y diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index ae29e4392664a..bd4782f23f66d 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -252,13 +252,13 @@ config ARCH_SUPPORTS_KEXEC def_bool y
config ARCH_SUPPORTS_KEXEC_FILE - def_bool CRYPTO && CRYPTO_SHA256 && CRYPTO_SHA256_S390 + def_bool y
config ARCH_SUPPORTS_KEXEC_SIG def_bool MODULE_SIG_FORMAT
config ARCH_SUPPORTS_KEXEC_PURGATORY - def_bool KEXEC_FILE + def_bool y
config ARCH_SUPPORTS_CRASH_DUMP def_bool y diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 66bfabae88149..fe3292e310d48 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2034,7 +2034,7 @@ config ARCH_SUPPORTS_KEXEC def_bool y
config ARCH_SUPPORTS_KEXEC_FILE - def_bool X86_64 && CRYPTO && CRYPTO_SHA256 + def_bool X86_64
config ARCH_SELECTS_KEXEC_FILE def_bool y @@ -2042,7 +2042,7 @@ config ARCH_SELECTS_KEXEC_FILE select HAVE_IMA_KEXEC if IMA
config ARCH_SUPPORTS_KEXEC_PURGATORY - def_bool KEXEC_FILE + def_bool y
config ARCH_SUPPORTS_KEXEC_SIG def_bool y diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec index f9619ac6b71d9..d3b8a2b1b5732 100644 --- a/kernel/Kconfig.kexec +++ b/kernel/Kconfig.kexec @@ -36,6 +36,7 @@ config KEXEC config KEXEC_FILE bool "Enable kexec file based system call" depends on ARCH_SUPPORTS_KEXEC_FILE + depends on CRYPTO_SHA256=y || !ARCH_SUPPORTS_KEXEC_PURGATORY select KEXEC_CORE help This is new version of kexec system call. This system call is
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit e63bde3d9417f8318d6dd0d0fafa35ebf307aabd ]
All other users of crypto code use 'select' instead of 'depends on', so do the same thing with KEXEC_FILE for consistency.
In practice this makes very little difference as kernels with kexec support are very likely to also include some other feature that already selects both crypto and crypto_sha256, but being consistent here helps for usability as well as to avoid potential circular dependencies.
This reverts the dependency back to what it was originally before commit 74ca317c26a3f ("kexec: create a new config option CONFIG_KEXEC_FILE for new syscall"), which changed changed it with the comment "This should be safer as "select" is not recursive", but that appears to have been done in error, as "select" is indeed recursive, and there are no other dependencies that prevent CRYPTO_SHA256 from being selected here.
Link: https://lkml.kernel.org/r/20231023110308.1202042-2-arnd@kernel.org Fixes: 74ca317c26a3f ("kexec: create a new config option CONFIG_KEXEC_FILE for new syscall") Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Eric DeVolder eric_devolder@yahoo.com Tested-by: Eric DeVolder eric_devolder@yahoo.com Acked-by: Baoquan He bhe@redhat.com Cc: Herbert Xu herbert@gondor.apana.org.au Cc: "David S. Miller" davem@davemloft.net Cc: Albert Ou aou@eecs.berkeley.edu Cc: Alexander Gordeev agordeev@linux.ibm.com Cc: Ard Biesheuvel ardb@kernel.org Cc: Borislav Petkov bp@alien8.de Cc: Christian Borntraeger borntraeger@linux.ibm.com Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: Conor Dooley conor@kernel.org Cc: Dave Hansen dave.hansen@linux.intel.com Cc: Heiko Carstens hca@linux.ibm.com Cc: "H. Peter Anvin" hpa@zytor.com Cc: Ingo Molnar mingo@redhat.com Cc: Nicholas Piggin npiggin@gmail.com Cc: Palmer Dabbelt palmer@dabbelt.com Cc: Paul Walmsley paul.walmsley@sifive.com Cc: Peter Zijlstra peterz@infradead.org Cc: Sven Schnelle svens@linux.ibm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/Kconfig.kexec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec index d3b8a2b1b5732..37e488d5b4fc0 100644 --- a/kernel/Kconfig.kexec +++ b/kernel/Kconfig.kexec @@ -36,7 +36,8 @@ config KEXEC config KEXEC_FILE bool "Enable kexec file based system call" depends on ARCH_SUPPORTS_KEXEC_FILE - depends on CRYPTO_SHA256=y || !ARCH_SUPPORTS_KEXEC_PURGATORY + select CRYPTO + select CRYPTO_SHA256 select KEXEC_CORE help This is new version of kexec system call. This system call is
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller deller@gmx.de
[ Upstream commit f6847807c22f6944c71c981b630b9fff30801e73 ]
An alignment of 4 bytes is wrong for 64-bit platforms which don't define CONFIG_HAVE_ARCH_PREL32_RELOCATIONS (which then store 64-bit pointers). Fix their alignment to 8 bytes.
Fixes: ddb5cdbafaaa ("kbuild: generate KSYMTAB entries by modpost") Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/export-internal.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/linux/export-internal.h b/include/linux/export-internal.h index 45fca09b23194..b842aeecef791 100644 --- a/include/linux/export-internal.h +++ b/include/linux/export-internal.h @@ -16,10 +16,13 @@ * and eliminates the need for absolute relocations that require runtime * processing on relocatable kernels. */ +#define __KSYM_ALIGN ".balign 4" #define __KSYM_REF(sym) ".long " #sym "- ." #elif defined(CONFIG_64BIT) +#define __KSYM_ALIGN ".balign 8" #define __KSYM_REF(sym) ".quad " #sym #else +#define __KSYM_ALIGN ".balign 4" #define __KSYM_REF(sym) ".long " #sym #endif
@@ -42,7 +45,7 @@ " .asciz "" ns """ "\n" \ " .previous" "\n" \ " .section "___ksymtab" sec "+" #name "", "a"" "\n" \ - " .balign 4" "\n" \ + __KSYM_ALIGN "\n" \ "__ksymtab_" #name ":" "\n" \ __KSYM_REF(sym) "\n" \ __KSYM_REF(__kstrtab_ ##name) "\n" \
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller deller@gmx.de
[ Upstream commit 753547de0daecbdbd1af3618987ddade325d9aaa ]
The ___kcrctab section holds an array of 32-bit CRC values. Add a .balign 4 to tell the linker the correct memory alignment.
Fixes: f3304ecd7f06 ("linux/export: use inline assembler to populate symbol CRCs") Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/export-internal.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/linux/export-internal.h b/include/linux/export-internal.h index b842aeecef791..5280194777340 100644 --- a/include/linux/export-internal.h +++ b/include/linux/export-internal.h @@ -66,6 +66,7 @@
#define SYMBOL_CRC(sym, crc, sec) \ asm(".section "___kcrctab" sec "+" #sym "","a"" "\n" \ + ".balign 4" "\n" \ "__crc_" #sym ":" "\n" \ ".long " #crc "\n" \ ".previous" "\n")
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni pabeni@redhat.com
[ Upstream commit 8005184fd1ca6aeb3fea36f4eb9463fc1b90c114 ]
The MPTCP protocol account for the data enqueued on all the subflows to the main socket send buffer, while the send buffer auto-tuning algorithm set the main socket send buffer size as the max size among the subflows.
That causes bad performances when at least one subflow is sndbuf limited, e.g. due to very high latency, as the MPTCP scheduler can't even fill such buffer.
Change the send-buffer auto-tuning algorithm to compute the main socket send buffer size as the sum of all the subflows buffer size.
Reviewed-by: Mat Martineau martineau@kernel.org Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Mat Martineau martineau@kernel.org Link: https://lore.kernel.org/r/20231023-send-net-next-20231023-2-v1-9-9dc60939d37... Signed-off-by: Jakub Kicinski kuba@kernel.org Stable-dep-of: 4fd19a307016 ("mptcp: fix inconsistent state on fastopen race") Signed-off-by: Sasha Levin sashal@kernel.org --- net/mptcp/protocol.c | 18 +++++++++++++-- net/mptcp/protocol.h | 54 ++++++++++++++++++++++++++++++++++++++++---- net/mptcp/sockopt.c | 5 +++- net/mptcp/subflow.c | 3 +-- 4 files changed, 70 insertions(+), 10 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index c1527f520dce3..44499e49d76e6 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -893,6 +893,7 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk) mptcp_sockopt_sync_locked(msk, ssk); mptcp_subflow_joined(msk, ssk); mptcp_stop_tout_timer(sk); + __mptcp_propagate_sndbuf(sk, ssk); return true; }
@@ -1079,15 +1080,16 @@ static void mptcp_enter_memory_pressure(struct sock *sk) struct mptcp_sock *msk = mptcp_sk(sk); bool first = true;
- sk_stream_moderate_sndbuf(sk); mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
if (first) tcp_enter_memory_pressure(ssk); sk_stream_moderate_sndbuf(ssk); + first = false; } + __mptcp_sync_sndbuf(sk); }
/* ensure we get enough memory for the frag hdr, beyond some minimal amount of @@ -2452,6 +2454,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, WRITE_ONCE(msk->first, NULL);
out: + __mptcp_sync_sndbuf(sk); if (need_push) __mptcp_push_pending(sk, 0);
@@ -3223,7 +3226,7 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk, * uses the correct data */ mptcp_copy_inaddrs(nsk, ssk); - mptcp_propagate_sndbuf(nsk, ssk); + __mptcp_propagate_sndbuf(nsk, ssk);
mptcp_rcv_space_init(msk, ssk); bh_unlock_sock(nsk); @@ -3401,6 +3404,8 @@ static void mptcp_release_cb(struct sock *sk) __mptcp_set_connected(sk); if (__test_and_clear_bit(MPTCP_ERROR_REPORT, &msk->cb_flags)) __mptcp_error_report(sk); + if (__test_and_clear_bit(MPTCP_SYNC_SNDBUF, &msk->cb_flags)) + __mptcp_sync_sndbuf(sk); }
__mptcp_update_rmem(sk); @@ -3445,6 +3450,14 @@ void mptcp_subflow_process_delegated(struct sock *ssk, long status) __set_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->cb_flags); mptcp_data_unlock(sk); } + if (status & BIT(MPTCP_DELEGATE_SNDBUF)) { + mptcp_data_lock(sk); + if (!sock_owned_by_user(sk)) + __mptcp_sync_sndbuf(sk); + else + __set_bit(MPTCP_SYNC_SNDBUF, &mptcp_sk(sk)->cb_flags); + mptcp_data_unlock(sk); + } if (status & BIT(MPTCP_DELEGATE_ACK)) schedule_3rdack_retransmission(ssk); } @@ -3529,6 +3542,7 @@ bool mptcp_finish_join(struct sock *ssk) /* active subflow, already present inside the conn_list */ if (!list_empty(&subflow->node)) { mptcp_subflow_joined(msk, ssk); + mptcp_propagate_sndbuf(parent, ssk); return true; }
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 3612545fa62e0..40866acd91ad5 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -123,6 +123,7 @@ #define MPTCP_RETRANSMIT 4 #define MPTCP_FLUSH_JOIN_LIST 5 #define MPTCP_CONNECTED 6 +#define MPTCP_SYNC_SNDBUF 7
struct mptcp_skb_cb { u64 map_seq; @@ -447,6 +448,7 @@ DECLARE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions); #define MPTCP_DELEGATE_SCHEDULED 0 #define MPTCP_DELEGATE_SEND 1 #define MPTCP_DELEGATE_ACK 2 +#define MPTCP_DELEGATE_SNDBUF 3
#define MPTCP_DELEGATE_ACTIONS_MASK (~BIT(MPTCP_DELEGATE_SCHEDULED)) /* MPTCP subflow context */ @@ -520,6 +522,9 @@ struct mptcp_subflow_context {
u32 setsockopt_seq; u32 stale_rcv_tstamp; + int cached_sndbuf; /* sndbuf size when last synced with the msk sndbuf, + * protected by the msk socket lock + */
struct sock *tcp_sock; /* tcp sk backpointer */ struct sock *conn; /* parent mptcp_sock */ @@ -762,13 +767,52 @@ static inline bool mptcp_data_fin_enabled(const struct mptcp_sock *msk) READ_ONCE(msk->write_seq) == READ_ONCE(msk->snd_nxt); }
-static inline bool mptcp_propagate_sndbuf(struct sock *sk, struct sock *ssk) +static inline void __mptcp_sync_sndbuf(struct sock *sk) { - if ((sk->sk_userlocks & SOCK_SNDBUF_LOCK) || ssk->sk_sndbuf <= READ_ONCE(sk->sk_sndbuf)) - return false; + struct mptcp_subflow_context *subflow; + int ssk_sndbuf, new_sndbuf; + + if (sk->sk_userlocks & SOCK_SNDBUF_LOCK) + return; + + new_sndbuf = sock_net(sk)->ipv4.sysctl_tcp_wmem[0]; + mptcp_for_each_subflow(mptcp_sk(sk), subflow) { + ssk_sndbuf = READ_ONCE(mptcp_subflow_tcp_sock(subflow)->sk_sndbuf); + + subflow->cached_sndbuf = ssk_sndbuf; + new_sndbuf += ssk_sndbuf; + } + + /* the msk max wmem limit is <nr_subflows> * tcp wmem[2] */ + WRITE_ONCE(sk->sk_sndbuf, new_sndbuf); +} + +/* The called held both the msk socket and the subflow socket locks, + * possibly under BH + */ +static inline void __mptcp_propagate_sndbuf(struct sock *sk, struct sock *ssk) +{ + struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); + + if (READ_ONCE(ssk->sk_sndbuf) != subflow->cached_sndbuf) + __mptcp_sync_sndbuf(sk); +} + +/* the caller held only the subflow socket lock, either in process or + * BH context. Additionally this can be called under the msk data lock, + * so we can't acquire such lock here: let the delegate action acquires + * the needed locks in suitable order. + */ +static inline void mptcp_propagate_sndbuf(struct sock *sk, struct sock *ssk) +{ + struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); + + if (likely(READ_ONCE(ssk->sk_sndbuf) == subflow->cached_sndbuf)) + return;
- WRITE_ONCE(sk->sk_sndbuf, ssk->sk_sndbuf); - return true; + local_bh_disable(); + mptcp_subflow_delegate(subflow, MPTCP_DELEGATE_SNDBUF); + local_bh_enable(); }
static inline void mptcp_write_space(struct sock *sk) diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 7539b9c8c2fb4..116e3008231bd 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -95,6 +95,7 @@ static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, in case SO_SNDBUFFORCE: ssk->sk_userlocks |= SOCK_SNDBUF_LOCK; WRITE_ONCE(ssk->sk_sndbuf, sk->sk_sndbuf); + mptcp_subflow_ctx(ssk)->cached_sndbuf = sk->sk_sndbuf; break; case SO_RCVBUF: case SO_RCVBUFFORCE: @@ -1418,8 +1419,10 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)
if (sk->sk_userlocks & tx_rx_locks) { ssk->sk_userlocks |= sk->sk_userlocks & tx_rx_locks; - if (sk->sk_userlocks & SOCK_SNDBUF_LOCK) + if (sk->sk_userlocks & SOCK_SNDBUF_LOCK) { WRITE_ONCE(ssk->sk_sndbuf, sk->sk_sndbuf); + mptcp_subflow_ctx(ssk)->cached_sndbuf = sk->sk_sndbuf; + } if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf); } diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 9c1f8d1d63d24..d8827427ffc84 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -421,6 +421,7 @@ static bool subflow_use_different_dport(struct mptcp_sock *msk, const struct soc
void __mptcp_set_connected(struct sock *sk) { + __mptcp_propagate_sndbuf(sk, mptcp_sk(sk)->first); if (sk->sk_state == TCP_SYN_SENT) { inet_sk_state_store(sk, TCP_ESTABLISHED); sk->sk_state_change(sk); @@ -472,7 +473,6 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) return;
msk = mptcp_sk(parent); - mptcp_propagate_sndbuf(parent, sk); subflow->rel_write_seq = 1; subflow->conn_finished = 1; subflow->ssn_offset = TCP_SKB_CB(skb)->seq; @@ -1728,7 +1728,6 @@ static void subflow_state_change(struct sock *sk)
msk = mptcp_sk(parent); if (subflow_simultaneous_connect(sk)) { - mptcp_propagate_sndbuf(parent, sk); mptcp_do_fallback(sk); mptcp_rcv_space_init(msk, sk); pr_fallback(msk);
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni pabeni@redhat.com
[ Upstream commit d109a7767273d1706b541c22b83a0323823dfde4 ]
After the blamed commit below, the MPTCP release callback can dereference the first subflow pointer via __mptcp_set_connected() and send buffer auto-tuning. Such pointer is always expected to be valid, except at socket destruction time, when the first subflow is deleted and the pointer zeroed.
If the connect event is handled by the release callback while the msk socket is finally released, MPTCP hits the following splat:
general protection fault, probably for non-canonical address 0xdffffc00000000f2: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000790-0x0000000000000797] CPU: 1 PID: 26719 Comm: syz-executor.2 Not tainted 6.6.0-syzkaller-10102-gff269e2cd5ad #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/09/2023 RIP: 0010:mptcp_subflow_ctx net/mptcp/protocol.h:542 [inline] RIP: 0010:__mptcp_propagate_sndbuf net/mptcp/protocol.h:813 [inline] RIP: 0010:__mptcp_set_connected+0x57/0x3e0 net/mptcp/subflow.c:424 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff8a62323c RDX: 00000000000000f2 RSI: ffffffff8a630116 RDI: 0000000000000790 RBP: ffff88803334b100 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000034 R12: ffff88803334b198 R13: ffff888054f0b018 R14: 0000000000000000 R15: ffff88803334b100 FS: 0000000000000000(0000) GS:ffff8880b9900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fbcb4f75198 CR3: 000000006afb5000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> mptcp_release_cb+0xa2c/0xc40 net/mptcp/protocol.c:3405 release_sock+0xba/0x1f0 net/core/sock.c:3537 mptcp_close+0x32/0xf0 net/mptcp/protocol.c:3084 inet_release+0x132/0x270 net/ipv4/af_inet.c:433 inet6_release+0x4f/0x70 net/ipv6/af_inet6.c:485 __sock_release+0xae/0x260 net/socket.c:659 sock_close+0x1c/0x20 net/socket.c:1419 __fput+0x270/0xbb0 fs/file_table.c:394 task_work_run+0x14d/0x240 kernel/task_work.c:180 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xa92/0x2a20 kernel/exit.c:876 do_group_exit+0xd4/0x2a0 kernel/exit.c:1026 get_signal+0x23ba/0x2790 kernel/signal.c:2900 arch_do_signal_or_restart+0x90/0x7f0 arch/x86/kernel/signal.c:309 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x11f/0x240 kernel/entry/common.c:204 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x60 kernel/entry/common.c:296 do_syscall_64+0x4b/0x110 arch/x86/entry/common.c:88 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7fb515e7cae9 Code: Unable to access opcode bytes at 0x7fb515e7cabf. RSP: 002b:00007fb516c560c8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: 000000000000003c RBX: 00007fb515f9c120 RCX: 00007fb515e7cae9 RDX: 0000000000000000 RSI: 0000000020000140 RDI: 0000000000000006 RBP: 00007fb515ec847a R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000006e R14: 00007fb515f9c120 R15: 00007ffc631eb968 </TASK>
To avoid sparkling unneeded conditionals, address the issue explicitly checking msk->first only in the critical place.
Fixes: 8005184fd1ca ("mptcp: refactor sndbuf auto-tuning") Cc: stable@vger.kernel.org Reported-by: syzbot+9dfbaedb6e6baca57a32@syzkaller.appspotmail.com Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/454 Reported-by: Eric Dumazet edumazet@google.com Closes: https://lore.kernel.org/netdev/CANn89iLZUA6S2a=K8GObnS62KK6Jt4B7PsAs7meMFooM... Signed-off-by: Paolo Abeni pabeni@redhat.com Reviewed-by: Eric Dumazet edumazet@google.com Reviewed-by: Mat Martineau martineau@kernel.org Signed-off-by: Matthieu Baerts matttbe@kernel.org Link: https://lore.kernel.org/r/20231114-upstream-net-20231113-mptcp-misc-fixes-6-... Signed-off-by: Jakub Kicinski kuba@kernel.org Stable-dep-of: 4fd19a307016 ("mptcp: fix inconsistent state on fastopen race") Signed-off-by: Sasha Levin sashal@kernel.org --- net/mptcp/protocol.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 44499e49d76e6..dc030551cac13 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -3397,10 +3397,11 @@ static void mptcp_release_cb(struct sock *sk) if (__test_and_clear_bit(MPTCP_CLEAN_UNA, &msk->cb_flags)) __mptcp_clean_una_wakeup(sk); if (unlikely(msk->cb_flags)) { - /* be sure to set the current sk state before tacking actions - * depending on sk_state, that is processing MPTCP_ERROR_REPORT + /* be sure to set the current sk state before taking actions + * depending on sk_state (MPTCP_ERROR_REPORT) + * On sk release avoid actions depending on the first subflow */ - if (__test_and_clear_bit(MPTCP_CONNECTED, &msk->cb_flags)) + if (__test_and_clear_bit(MPTCP_CONNECTED, &msk->cb_flags) && msk->first) __mptcp_set_connected(sk); if (__test_and_clear_bit(MPTCP_ERROR_REPORT, &msk->cb_flags)) __mptcp_error_report(sk);
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni pabeni@redhat.com
[ Upstream commit 4fd19a30701659af5839b7bd19d1f05f05933ebe ]
The netlink PM can race with fastopen self-connect attempts, shutting down the first subflow via:
MPTCP_PM_CMD_DEL_ADDR -> mptcp_nl_remove_id_zero_address -> mptcp_pm_nl_rm_subflow_received -> mptcp_close_ssk
and transitioning such subflow to FIN_WAIT1 status before the syn-ack packet is processed. The MPTCP code does not react to such state change, leaving the connection in not-fallback status and the subflow handshake uncompleted, triggering the following splat:
WARNING: CPU: 0 PID: 10630 at net/mptcp/subflow.c:1405 subflow_data_ready+0x39f/0x690 net/mptcp/subflow.c:1405 Modules linked in: CPU: 0 PID: 10630 Comm: kworker/u4:11 Not tainted 6.6.0-syzkaller-14500-g1c41041124bd #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/09/2023 Workqueue: bat_events batadv_nc_worker RIP: 0010:subflow_data_ready+0x39f/0x690 net/mptcp/subflow.c:1405 Code: 18 89 ee e8 e3 d2 21 f7 40 84 ed 75 1f e8 a9 d7 21 f7 44 89 fe bf 07 00 00 00 e8 0c d3 21 f7 41 83 ff 07 74 07 e8 91 d7 21 f7 <0f> 0b e8 8a d7 21 f7 48 89 df e8 d2 b2 ff ff 31 ff 89 c5 89 c6 e8 RSP: 0018:ffffc90000007448 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff888031efc700 RCX: ffffffff8a65baf4 RDX: ffff888043222140 RSI: ffffffff8a65baff RDI: 0000000000000005 RBP: 0000000000000000 R08: 0000000000000005 R09: 0000000000000007 R10: 000000000000000b R11: 0000000000000000 R12: 1ffff92000000e89 R13: ffff88807a534d80 R14: ffff888021c11a00 R15: 000000000000000b FS: 0000000000000000(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fa19a0ffc81 CR3: 000000007a2db000 CR4: 00000000003506f0 DR0: 000000000000d8dd DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Call Trace: <IRQ> tcp_data_ready+0x14c/0x5b0 net/ipv4/tcp_input.c:5128 tcp_data_queue+0x19c3/0x5190 net/ipv4/tcp_input.c:5208 tcp_rcv_state_process+0x11ef/0x4e10 net/ipv4/tcp_input.c:6844 tcp_v4_do_rcv+0x369/0xa10 net/ipv4/tcp_ipv4.c:1929 tcp_v4_rcv+0x3888/0x3b30 net/ipv4/tcp_ipv4.c:2329 ip_protocol_deliver_rcu+0x9f/0x480 net/ipv4/ip_input.c:205 ip_local_deliver_finish+0x2e4/0x510 net/ipv4/ip_input.c:233 NF_HOOK include/linux/netfilter.h:314 [inline] NF_HOOK include/linux/netfilter.h:308 [inline] ip_local_deliver+0x1b6/0x550 net/ipv4/ip_input.c:254 dst_input include/net/dst.h:461 [inline] ip_rcv_finish+0x1c4/0x2e0 net/ipv4/ip_input.c:449 NF_HOOK include/linux/netfilter.h:314 [inline] NF_HOOK include/linux/netfilter.h:308 [inline] ip_rcv+0xce/0x440 net/ipv4/ip_input.c:569 __netif_receive_skb_one_core+0x115/0x180 net/core/dev.c:5527 __netif_receive_skb+0x1f/0x1b0 net/core/dev.c:5641 process_backlog+0x101/0x6b0 net/core/dev.c:5969 __napi_poll.constprop.0+0xb4/0x540 net/core/dev.c:6531 napi_poll net/core/dev.c:6600 [inline] net_rx_action+0x956/0xe90 net/core/dev.c:6733 __do_softirq+0x21a/0x968 kernel/softirq.c:553 do_softirq kernel/softirq.c:454 [inline] do_softirq+0xaa/0xe0 kernel/softirq.c:441 </IRQ> <TASK> __local_bh_enable_ip+0xf8/0x120 kernel/softirq.c:381 spin_unlock_bh include/linux/spinlock.h:396 [inline] batadv_nc_purge_paths+0x1ce/0x3c0 net/batman-adv/network-coding.c:471 batadv_nc_worker+0x9b1/0x10e0 net/batman-adv/network-coding.c:722 process_one_work+0x884/0x15c0 kernel/workqueue.c:2630 process_scheduled_works kernel/workqueue.c:2703 [inline] worker_thread+0x8b9/0x1290 kernel/workqueue.c:2784 kthread+0x33c/0x440 kernel/kthread.c:388 ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:242 </TASK>
To address the issue, catch the racing subflow state change and use it to cause the MPTCP fallback. Such fallback is also used to cause the first subflow state propagation to the msk socket via mptcp_set_connected(). After this change, the first subflow can additionally propagate the TCP_FIN_WAIT1 state, so rename the helper accordingly.
Finally, if the state propagation is delayed to the msk release callback, the first subflow can change to a different state in between. Cache the relevant target state in a new msk-level field and use such value to update the msk state at release time.
Fixes: 1e777f39b4d7 ("mptcp: add MSG_FASTOPEN sendmsg flag support") Cc: stable@vger.kernel.org Reported-by: syzbot+c53d4d3ddb327e80bc51@syzkaller.appspotmail.com Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/458 Signed-off-by: Paolo Abeni pabeni@redhat.com Reviewed-by: Mat Martineau martineau@kernel.org Signed-off-by: Matthieu Baerts matttbe@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/mptcp/protocol.c | 6 +++--- net/mptcp/protocol.h | 9 ++++++--- net/mptcp/subflow.c | 28 +++++++++++++++++----------- 3 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index dc030551cac13..5c003a0f0fe5b 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -3397,12 +3397,12 @@ static void mptcp_release_cb(struct sock *sk) if (__test_and_clear_bit(MPTCP_CLEAN_UNA, &msk->cb_flags)) __mptcp_clean_una_wakeup(sk); if (unlikely(msk->cb_flags)) { - /* be sure to set the current sk state before taking actions + /* be sure to sync the msk state before taking actions * depending on sk_state (MPTCP_ERROR_REPORT) * On sk release avoid actions depending on the first subflow */ - if (__test_and_clear_bit(MPTCP_CONNECTED, &msk->cb_flags) && msk->first) - __mptcp_set_connected(sk); + if (__test_and_clear_bit(MPTCP_SYNC_STATE, &msk->cb_flags) && msk->first) + __mptcp_sync_state(sk, msk->pending_state); if (__test_and_clear_bit(MPTCP_ERROR_REPORT, &msk->cb_flags)) __mptcp_error_report(sk); if (__test_and_clear_bit(MPTCP_SYNC_SNDBUF, &msk->cb_flags)) diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 40866acd91ad5..07c5ac37d092b 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -122,7 +122,7 @@ #define MPTCP_ERROR_REPORT 3 #define MPTCP_RETRANSMIT 4 #define MPTCP_FLUSH_JOIN_LIST 5 -#define MPTCP_CONNECTED 6 +#define MPTCP_SYNC_STATE 6 #define MPTCP_SYNC_SNDBUF 7
struct mptcp_skb_cb { @@ -293,6 +293,9 @@ struct mptcp_sock { bool use_64bit_ack; /* Set when we received a 64-bit DSN */ bool csum_enabled; bool allow_infinite_fallback; + u8 pending_state; /* A subflow asked to set this sk_state, + * protected by the msk data lock + */ u8 mpc_endpoint_id; u8 recvmsg_inq:1, cork:1, @@ -711,7 +714,7 @@ void mptcp_get_options(const struct sk_buff *skb, struct mptcp_options_received *mp_opt);
void mptcp_finish_connect(struct sock *sk); -void __mptcp_set_connected(struct sock *sk); +void __mptcp_sync_state(struct sock *sk, int state); void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout);
static inline void mptcp_stop_tout_timer(struct sock *sk) @@ -1101,7 +1104,7 @@ static inline bool subflow_simultaneous_connect(struct sock *sk) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
- return sk->sk_state == TCP_ESTABLISHED && + return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_FIN_WAIT1) && is_active_ssk(subflow) && !subflow->conn_finished; } diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index d8827427ffc84..f3a1e4aa0e5eb 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -419,22 +419,28 @@ static bool subflow_use_different_dport(struct mptcp_sock *msk, const struct soc return inet_sk(sk)->inet_dport != inet_sk((struct sock *)msk)->inet_dport; }
-void __mptcp_set_connected(struct sock *sk) +void __mptcp_sync_state(struct sock *sk, int state) { - __mptcp_propagate_sndbuf(sk, mptcp_sk(sk)->first); + struct mptcp_sock *msk = mptcp_sk(sk); + + __mptcp_propagate_sndbuf(sk, msk->first); if (sk->sk_state == TCP_SYN_SENT) { - inet_sk_state_store(sk, TCP_ESTABLISHED); + inet_sk_state_store(sk, state); sk->sk_state_change(sk); } }
-static void mptcp_set_connected(struct sock *sk) +static void mptcp_propagate_state(struct sock *sk, struct sock *ssk) { + struct mptcp_sock *msk = mptcp_sk(sk); + mptcp_data_lock(sk); - if (!sock_owned_by_user(sk)) - __mptcp_set_connected(sk); - else - __set_bit(MPTCP_CONNECTED, &mptcp_sk(sk)->cb_flags); + if (!sock_owned_by_user(sk)) { + __mptcp_sync_state(sk, ssk->sk_state); + } else { + msk->pending_state = ssk->sk_state; + __set_bit(MPTCP_SYNC_STATE, &msk->cb_flags); + } mptcp_data_unlock(sk); }
@@ -496,7 +502,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) subflow_set_remote_key(msk, subflow, &mp_opt); MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEACK); mptcp_finish_connect(sk); - mptcp_set_connected(parent); + mptcp_propagate_state(parent, sk); } else if (subflow->request_join) { u8 hmac[SHA256_DIGEST_SIZE];
@@ -540,7 +546,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) } else if (mptcp_check_fallback(sk)) { fallback: mptcp_rcv_space_init(msk, sk); - mptcp_set_connected(parent); + mptcp_propagate_state(parent, sk); } return;
@@ -1732,7 +1738,7 @@ static void subflow_state_change(struct sock *sk) mptcp_rcv_space_init(msk, sk); pr_fallback(msk); subflow->conn_finished = 1; - mptcp_set_connected(parent); + mptcp_propagate_state(parent, sk); }
/* as recvmsg() does not acquire the subflow socket for ssk selection
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig hch@lst.de
[ Upstream commit 02d374f3418df577c850f0cd45c3da9245ead547 ]
For the QUEUE_FLAG_HW_WC to actually work, it needs to have a separate number from QUEUE_FLAG_FUA, doh.
Fixes: 43c9835b144c ("block: don't allow enabling a cache on devices that don't support it") Signed-off-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20231226081524.180289-1-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/blkdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index eef450f259828..f59fcd5b499a5 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -538,7 +538,7 @@ struct request_queue { #define QUEUE_FLAG_ADD_RANDOM 10 /* Contributes to random pool */ #define QUEUE_FLAG_SYNCHRONOUS 11 /* always completes in submit context */ #define QUEUE_FLAG_SAME_FORCE 12 /* force complete on same CPU */ -#define QUEUE_FLAG_HW_WC 18 /* Write back caching supported */ +#define QUEUE_FLAG_HW_WC 13 /* Write back caching supported */ #define QUEUE_FLAG_INIT_DONE 14 /* queue is initialized */ #define QUEUE_FLAG_STABLE_WRITES 15 /* don't modify blks until WB is done */ #define QUEUE_FLAG_POLL 16 /* IO polling enabled if set */
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David E. Box david.e.box@linux.intel.com
[ Upstream commit 7c13f365aee68b01e7e68ee293a71fdc7571c111 ]
Add a suspend callback to struct pmc for performing platform specific tasks before device suspend. This is needed in order to perform GBE LTR ignore on certain platforms at suspend-time instead of at probe-time and replace the GBE LTR ignore removal that was done in order to fix a bug introduced by commit 804951203aa5 ("platform/x86:intel/pmc: Combine core_init() and core_configure()").
Fixes: 804951203aa5 ("platform/x86:intel/pmc: Combine core_init() and core_configure()") Signed-off-by: "David E. Box" david.e.box@linux.intel.com Link: https://lore.kernel.org/r/20231223032548.1680738-4-david.e.box@linux.intel.c... Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/intel/pmc/core.c | 3 +++ drivers/platform/x86/intel/pmc/core.h | 2 ++ 2 files changed, 5 insertions(+)
diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c index e95d3011b9997..5ab470d87ad7e 100644 --- a/drivers/platform/x86/intel/pmc/core.c +++ b/drivers/platform/x86/intel/pmc/core.c @@ -1279,6 +1279,9 @@ static __maybe_unused int pmc_core_suspend(struct device *dev) struct pmc_dev *pmcdev = dev_get_drvdata(dev); struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
+ if (pmcdev->suspend) + pmcdev->suspend(pmcdev); + /* Check if the syspend will actually use S0ix */ if (pm_suspend_via_firmware()) return 0; diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h index 0729f593c6a75..38d888e3afa63 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -363,6 +363,7 @@ struct pmc { * @s0ix_counter: S0ix residency (step adjusted) * @num_lpm_modes: Count of enabled modes * @lpm_en_modes: Array of enabled modes from lowest to highest priority + * @suspend: Function to perform platform specific suspend * @resume: Function to perform platform specific resume * * pmc_dev contains info about power management controller device. @@ -379,6 +380,7 @@ struct pmc_dev { u64 s0ix_counter; int num_lpm_modes; int lpm_en_modes[LPM_MAX_NUM_MODES]; + void (*suspend)(struct pmc_dev *pmcdev); int (*resume)(struct pmc_dev *pmcdev);
bool has_die_c6;
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David E. Box david.e.box@linux.intel.com
[ Upstream commit 6f9cc5c1f94daa98846b2073733d03ced709704b ]
Commit 804951203aa5 ("platform/x86:intel/pmc: Combine core_init() and core_configure()") caused a network performance regression due to the GBE LTR ignore that it added during probe. The fix will move the ignore to occur at suspend-time (so as to not affect suspend power). This will require the ability to enable the LTR again on resume. Modify pmc_core_send_ltr_ignore() to allow enabling an LTR.
Fixes: 804951203aa5 ("platform/x86:intel/pmc: Combine core_init() and core_configure()") Signed-off-by: "David E. Box" david.e.box@linux.intel.com Link: https://lore.kernel.org/r/20231223032548.1680738-5-david.e.box@linux.intel.c... Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/intel/pmc/adl.c | 2 +- drivers/platform/x86/intel/pmc/cnp.c | 2 +- drivers/platform/x86/intel/pmc/core.c | 9 ++++++--- drivers/platform/x86/intel/pmc/core.h | 2 +- drivers/platform/x86/intel/pmc/mtl.c | 2 +- drivers/platform/x86/intel/pmc/tgl.c | 2 +- 6 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/adl.c b/drivers/platform/x86/intel/pmc/adl.c index 5006008e01bea..a887c388cf16d 100644 --- a/drivers/platform/x86/intel/pmc/adl.c +++ b/drivers/platform/x86/intel/pmc/adl.c @@ -323,7 +323,7 @@ int adl_core_init(struct pmc_dev *pmcdev) * when a cable is attached. Tell the PMC to ignore it. */ dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n"); - pmc_core_send_ltr_ignore(pmcdev, 3); + pmc_core_send_ltr_ignore(pmcdev, 3, 1);
return 0; } diff --git a/drivers/platform/x86/intel/pmc/cnp.c b/drivers/platform/x86/intel/pmc/cnp.c index 420aaa1d7c769..10498204962cd 100644 --- a/drivers/platform/x86/intel/pmc/cnp.c +++ b/drivers/platform/x86/intel/pmc/cnp.c @@ -218,7 +218,7 @@ int cnp_core_init(struct pmc_dev *pmcdev) * when a cable is attached. Tell the PMC to ignore it. */ dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n"); - pmc_core_send_ltr_ignore(pmcdev, 3); + pmc_core_send_ltr_ignore(pmcdev, 3, 1);
return 0; } diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c index 5ab470d87ad7e..022afb97d531c 100644 --- a/drivers/platform/x86/intel/pmc/core.c +++ b/drivers/platform/x86/intel/pmc/core.c @@ -460,7 +460,7 @@ static int pmc_core_pll_show(struct seq_file *s, void *unused) } DEFINE_SHOW_ATTRIBUTE(pmc_core_pll);
-int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value) +int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value, int ignore) { struct pmc *pmc; const struct pmc_reg_map *map; @@ -498,7 +498,10 @@ int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value) mutex_lock(&pmcdev->lock);
reg = pmc_core_reg_read(pmc, map->ltr_ignore_offset); - reg |= BIT(ltr_index); + if (ignore) + reg |= BIT(ltr_index); + else + reg &= ~BIT(ltr_index); pmc_core_reg_write(pmc, map->ltr_ignore_offset, reg);
mutex_unlock(&pmcdev->lock); @@ -521,7 +524,7 @@ static ssize_t pmc_core_ltr_ignore_write(struct file *file, if (err) return err;
- err = pmc_core_send_ltr_ignore(pmcdev, value); + err = pmc_core_send_ltr_ignore(pmcdev, value, 1);
return err == 0 ? count : err; } diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h index 38d888e3afa63..71ba7d691d691 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -488,7 +488,7 @@ extern const struct pmc_bit_map *mtl_ioem_lpm_maps[]; extern const struct pmc_reg_map mtl_ioem_reg_map;
extern void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev); -extern int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value); +int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value, int ignore);
int pmc_core_resume_common(struct pmc_dev *pmcdev); int get_primary_reg_base(struct pmc *pmc); diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c index 2204bc666980e..71dc11811e112 100644 --- a/drivers/platform/x86/intel/pmc/mtl.c +++ b/drivers/platform/x86/intel/pmc/mtl.c @@ -1006,7 +1006,7 @@ int mtl_core_init(struct pmc_dev *pmcdev) * when a cable is attached. Tell the PMC to ignore it. */ dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n"); - pmc_core_send_ltr_ignore(pmcdev, 3); + pmc_core_send_ltr_ignore(pmcdev, 3, 1);
return 0; } diff --git a/drivers/platform/x86/intel/pmc/tgl.c b/drivers/platform/x86/intel/pmc/tgl.c index 2449940102db4..078263db24c7a 100644 --- a/drivers/platform/x86/intel/pmc/tgl.c +++ b/drivers/platform/x86/intel/pmc/tgl.c @@ -268,7 +268,7 @@ int tgl_core_init(struct pmc_dev *pmcdev) * when a cable is attached. Tell the PMC to ignore it. */ dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n"); - pmc_core_send_ltr_ignore(pmcdev, 3); + pmc_core_send_ltr_ignore(pmcdev, 3, 1);
return 0; }
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David E. Box david.e.box@linux.intel.com
[ Upstream commit 70681aa0746ae61d7668b9f651221fad5e30c71e ]
Commit 804951203aa5 ("platform/x86:intel/pmc: Combine core_init() and core_configure()") caused a network performance regression due to the GBE LTR ignore that it added at probe. This was needed in order to allow the SoC to enter the deepest Package C state. To fix the regression and at least support PC10 during suspend, move the LTR ignore from probe to the suspend callback, and enable it again on resume. This solution will allow PC10 during suspend but restrict Package C entry at runtime to no deeper than PC8/9 while a network cable it attach to the PCH LAN.
Fixes: 804951203aa5 ("platform/x86:intel/pmc: Combine core_init() and core_configure()") Signed-off-by: "David E. Box" david.e.box@linux.intel.com Link: https://lore.kernel.org/r/20231223032548.1680738-6-david.e.box@linux.intel.c... Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/intel/pmc/adl.c | 9 +++------ drivers/platform/x86/intel/pmc/cnp.c | 26 ++++++++++++++++++++------ drivers/platform/x86/intel/pmc/core.h | 3 +++ drivers/platform/x86/intel/pmc/mtl.c | 9 +++------ drivers/platform/x86/intel/pmc/tgl.c | 9 ++++----- 5 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/drivers/platform/x86/intel/pmc/adl.c b/drivers/platform/x86/intel/pmc/adl.c index a887c388cf16d..606f7678bcb0a 100644 --- a/drivers/platform/x86/intel/pmc/adl.c +++ b/drivers/platform/x86/intel/pmc/adl.c @@ -314,16 +314,13 @@ int adl_core_init(struct pmc_dev *pmcdev) struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; int ret;
+ pmcdev->suspend = cnl_suspend; + pmcdev->resume = cnl_resume; + pmc->map = &adl_reg_map; ret = get_primary_reg_base(pmc); if (ret) return ret;
- /* Due to a hardware limitation, the GBE LTR blocks PC10 - * when a cable is attached. Tell the PMC to ignore it. - */ - dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n"); - pmc_core_send_ltr_ignore(pmcdev, 3, 1); - return 0; } diff --git a/drivers/platform/x86/intel/pmc/cnp.c b/drivers/platform/x86/intel/pmc/cnp.c index 10498204962cd..98b36651201a0 100644 --- a/drivers/platform/x86/intel/pmc/cnp.c +++ b/drivers/platform/x86/intel/pmc/cnp.c @@ -204,21 +204,35 @@ const struct pmc_reg_map cnp_reg_map = { .etr3_offset = ETR3_OFFSET, };
+void cnl_suspend(struct pmc_dev *pmcdev) +{ + /* + * Due to a hardware limitation, the GBE LTR blocks PC10 + * when a cable is attached. To unblock PC10 during suspend, + * tell the PMC to ignore it. + */ + pmc_core_send_ltr_ignore(pmcdev, 3, 1); +} + +int cnl_resume(struct pmc_dev *pmcdev) +{ + pmc_core_send_ltr_ignore(pmcdev, 3, 0); + + return pmc_core_resume_common(pmcdev); +} + int cnp_core_init(struct pmc_dev *pmcdev) { struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; int ret;
+ pmcdev->suspend = cnl_suspend; + pmcdev->resume = cnl_resume; + pmc->map = &cnp_reg_map; ret = get_primary_reg_base(pmc); if (ret) return ret;
- /* Due to a hardware limitation, the GBE LTR blocks PC10 - * when a cable is attached. Tell the PMC to ignore it. - */ - dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n"); - pmc_core_send_ltr_ignore(pmcdev, 3, 1); - return 0; } diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h index 71ba7d691d691..b66dacbfb94bf 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -502,6 +502,9 @@ int tgl_core_init(struct pmc_dev *pmcdev); int adl_core_init(struct pmc_dev *pmcdev); int mtl_core_init(struct pmc_dev *pmcdev);
+void cnl_suspend(struct pmc_dev *pmcdev); +int cnl_resume(struct pmc_dev *pmcdev); + #define pmc_for_each_mode(i, mode, pmcdev) \ for (i = 0, mode = pmcdev->lpm_en_modes[i]; \ i < pmcdev->num_lpm_modes; \ diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c index 71dc11811e112..504e3e273c323 100644 --- a/drivers/platform/x86/intel/pmc/mtl.c +++ b/drivers/platform/x86/intel/pmc/mtl.c @@ -979,6 +979,8 @@ static void mtl_d3_fixup(void) static int mtl_resume(struct pmc_dev *pmcdev) { mtl_d3_fixup(); + pmc_core_send_ltr_ignore(pmcdev, 3, 0); + return pmc_core_resume_common(pmcdev); }
@@ -989,6 +991,7 @@ int mtl_core_init(struct pmc_dev *pmcdev)
mtl_d3_fixup();
+ pmcdev->suspend = cnl_suspend; pmcdev->resume = mtl_resume;
pmcdev->regmap_list = mtl_pmc_info_list; @@ -1002,11 +1005,5 @@ int mtl_core_init(struct pmc_dev *pmcdev) return ret; }
- /* Due to a hardware limitation, the GBE LTR blocks PC10 - * when a cable is attached. Tell the PMC to ignore it. - */ - dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n"); - pmc_core_send_ltr_ignore(pmcdev, 3, 1); - return 0; } diff --git a/drivers/platform/x86/intel/pmc/tgl.c b/drivers/platform/x86/intel/pmc/tgl.c index 078263db24c7a..e88d3d00c8539 100644 --- a/drivers/platform/x86/intel/pmc/tgl.c +++ b/drivers/platform/x86/intel/pmc/tgl.c @@ -259,16 +259,15 @@ int tgl_core_init(struct pmc_dev *pmcdev) int ret;
pmc->map = &tgl_reg_map; + + pmcdev->suspend = cnl_suspend; + pmcdev->resume = cnl_resume; + ret = get_primary_reg_base(pmc); if (ret) return ret;
pmc_core_get_tgl_lpm_reqs(pmcdev->pdev); - /* Due to a hardware limitation, the GBE LTR blocks PC10 - * when a cable is attached. Tell the PMC to ignore it. - */ - dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n"); - pmc_core_send_ltr_ignore(pmcdev, 3, 1);
return 0; }
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
commit d10c77873ba1e9e6b91905018e29e196fd5f863d upstream.
If ->NameOffset/Length is bigger than ->CreateContextsOffset/Length, ksmbd_check_message doesn't validate request buffer it correctly. So slab-out-of-bounds warning from calling smb_strndup_from_utf16() in smb2_open() could happen. If ->NameLength is non-zero, Set the larger of the two sums (Name and CreateContext size) as the offset and length of the data area.
Reported-by: Yang Chaoming lometsj@live.com Cc: stable@vger.kernel.org Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/smb/server/smb2misc.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
--- a/fs/smb/server/smb2misc.c +++ b/fs/smb/server/smb2misc.c @@ -106,16 +106,25 @@ static int smb2_get_data_area_len(unsign break; case SMB2_CREATE: { + unsigned short int name_off = + le16_to_cpu(((struct smb2_create_req *)hdr)->NameOffset); + unsigned short int name_len = + le16_to_cpu(((struct smb2_create_req *)hdr)->NameLength); + if (((struct smb2_create_req *)hdr)->CreateContextsLength) { *off = le32_to_cpu(((struct smb2_create_req *) hdr)->CreateContextsOffset); *len = le32_to_cpu(((struct smb2_create_req *) hdr)->CreateContextsLength); - break; + if (!name_len) + break; + + if (name_off + name_len < (u64)*off + *len) + break; }
- *off = le16_to_cpu(((struct smb2_create_req *)hdr)->NameOffset); - *len = le16_to_cpu(((struct smb2_create_req *)hdr)->NameLength); + *off = name_off; + *len = name_len; break; } case SMB2_QUERY_INFO:
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com
commit b28ff7a7c3245d7f62acc20f15b4361292fe4117 upstream.
p2sb_bar() unhides P2SB device to get resources from the device. It guards the operation by locking pci_rescan_remove_lock so that parallel rescans do not find the P2SB device. However, this lock causes deadlock when PCI bus rescan is triggered by /sys/bus/pci/rescan. The rescan locks pci_rescan_remove_lock and probes PCI devices. When PCI devices call p2sb_bar() during probe, it locks pci_rescan_remove_lock again. Hence the deadlock.
To avoid the deadlock, do not lock pci_rescan_remove_lock in p2sb_bar(). Instead, do the lock at fs_initcall. Introduce p2sb_cache_resources() for fs_initcall which gets and caches the P2SB resources. At p2sb_bar(), refer the cache and return to the caller.
Suggested-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Fixes: 9745fb07474f ("platform/x86/intel: Add Primary to Sideband (P2SB) bridge support") Cc: stable@vger.kernel.org Signed-off-by: Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Link: https://lore.kernel.org/linux-pci/6xb24fjmptxxn5js2fjrrddjae6twex5bjaftwqsua... Link: https://lore.kernel.org/r/20231229063912.2517922-2-shinichiro.kawasaki@wdc.c... Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/platform/x86/p2sb.c | 172 +++++++++++++++++++++++++++++++++----------- 1 file changed, 131 insertions(+), 41 deletions(-)
--- a/drivers/platform/x86/p2sb.c +++ b/drivers/platform/x86/p2sb.c @@ -26,6 +26,21 @@ static const struct x86_cpu_id p2sb_cpu_ {} };
+/* + * Cache BAR0 of P2SB device functions 0 to 7. + * TODO: The constant 8 is the number of functions that PCI specification + * defines. Same definitions exist tree-wide. Unify this definition and + * the other definitions then move to include/uapi/linux/pci.h. + */ +#define NR_P2SB_RES_CACHE 8 + +struct p2sb_res_cache { + u32 bus_dev_id; + struct resource res; +}; + +static struct p2sb_res_cache p2sb_resources[NR_P2SB_RES_CACHE]; + static int p2sb_get_devfn(unsigned int *devfn) { unsigned int fn = P2SB_DEVFN_DEFAULT; @@ -39,8 +54,16 @@ static int p2sb_get_devfn(unsigned int * return 0; }
+static bool p2sb_valid_resource(struct resource *res) +{ + if (res->flags) + return true; + + return false; +} + /* Copy resource from the first BAR of the device in question */ -static int p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem) +static void p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem) { struct resource *bar0 = &pdev->resource[0];
@@ -56,47 +79,64 @@ static int p2sb_read_bar0(struct pci_dev mem->end = bar0->end; mem->flags = bar0->flags; mem->desc = bar0->desc; - - return 0; }
-static int p2sb_scan_and_read(struct pci_bus *bus, unsigned int devfn, struct resource *mem) +static void p2sb_scan_and_cache_devfn(struct pci_bus *bus, unsigned int devfn) { + struct p2sb_res_cache *cache = &p2sb_resources[PCI_FUNC(devfn)]; struct pci_dev *pdev; - int ret;
pdev = pci_scan_single_device(bus, devfn); if (!pdev) - return -ENODEV; + return;
- ret = p2sb_read_bar0(pdev, mem); + p2sb_read_bar0(pdev, &cache->res); + cache->bus_dev_id = bus->dev.id;
pci_stop_and_remove_bus_device(pdev); - return ret; + return; }
-/** - * p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR - * @bus: PCI bus to communicate with - * @devfn: PCI slot and function to communicate with - * @mem: memory resource to be filled in - * - * The BIOS prevents the P2SB device from being enumerated by the PCI - * subsystem, so we need to unhide and hide it back to lookup the BAR. - * - * if @bus is NULL, the bus 0 in domain 0 will be used. - * If @devfn is 0, it will be replaced by devfn of the P2SB device. - * - * Caller must provide a valid pointer to @mem. - * - * Locking is handled by pci_rescan_remove_lock mutex. - * - * Return: - * 0 on success or appropriate errno value on error. - */ -int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem) +static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn) { - struct pci_dev *pdev_p2sb; + unsigned int slot, fn; + + if (PCI_FUNC(devfn) == 0) { + /* + * When function number of the P2SB device is zero, scan it and + * other function numbers, and if devices are available, cache + * their BAR0s. + */ + slot = PCI_SLOT(devfn); + for (fn = 0; fn < NR_P2SB_RES_CACHE; fn++) + p2sb_scan_and_cache_devfn(bus, PCI_DEVFN(slot, fn)); + } else { + /* Scan the P2SB device and cache its BAR0 */ + p2sb_scan_and_cache_devfn(bus, devfn); + } + + if (!p2sb_valid_resource(&p2sb_resources[PCI_FUNC(devfn)].res)) + return -ENOENT; + + return 0; +} + +static struct pci_bus *p2sb_get_bus(struct pci_bus *bus) +{ + static struct pci_bus *p2sb_bus; + + bus = bus ?: p2sb_bus; + if (bus) + return bus; + + /* Assume P2SB is on the bus 0 in domain 0 */ + p2sb_bus = pci_find_bus(0, 0); + return p2sb_bus; +} + +static int p2sb_cache_resources(void) +{ + struct pci_bus *bus; unsigned int devfn_p2sb; u32 value = P2SBC_HIDE; int ret; @@ -106,8 +146,9 @@ int p2sb_bar(struct pci_bus *bus, unsign if (ret) return ret;
- /* if @bus is NULL, use bus 0 in domain 0 */ - bus = bus ?: pci_find_bus(0, 0); + bus = p2sb_get_bus(NULL); + if (!bus) + return -ENODEV;
/* * Prevent concurrent PCI bus scan from seeing the P2SB device and @@ -115,17 +156,16 @@ int p2sb_bar(struct pci_bus *bus, unsign */ pci_lock_rescan_remove();
- /* Unhide the P2SB device, if needed */ + /* + * The BIOS prevents the P2SB device from being enumerated by the PCI + * subsystem, so we need to unhide and hide it back to lookup the BAR. + * Unhide the P2SB device here, if needed. + */ pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value); if (value & P2SBC_HIDE) pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0);
- pdev_p2sb = pci_scan_single_device(bus, devfn_p2sb); - if (devfn) - ret = p2sb_scan_and_read(bus, devfn, mem); - else - ret = p2sb_read_bar0(pdev_p2sb, mem); - pci_stop_and_remove_bus_device(pdev_p2sb); + ret = p2sb_scan_and_cache(bus, devfn_p2sb);
/* Hide the P2SB device, if it was hidden */ if (value & P2SBC_HIDE) @@ -133,12 +173,62 @@ int p2sb_bar(struct pci_bus *bus, unsign
pci_unlock_rescan_remove();
- if (ret) - return ret; + return ret; +}
- if (mem->flags == 0) +/** + * p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR + * @bus: PCI bus to communicate with + * @devfn: PCI slot and function to communicate with + * @mem: memory resource to be filled in + * + * If @bus is NULL, the bus 0 in domain 0 will be used. + * If @devfn is 0, it will be replaced by devfn of the P2SB device. + * + * Caller must provide a valid pointer to @mem. + * + * Return: + * 0 on success or appropriate errno value on error. + */ +int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem) +{ + struct p2sb_res_cache *cache; + int ret; + + bus = p2sb_get_bus(bus); + if (!bus) + return -ENODEV; + + if (!devfn) { + ret = p2sb_get_devfn(&devfn); + if (ret) + return ret; + } + + cache = &p2sb_resources[PCI_FUNC(devfn)]; + if (cache->bus_dev_id != bus->dev.id) return -ENODEV;
+ if (!p2sb_valid_resource(&cache->res)) + return -ENOENT; + + memcpy(mem, &cache->res, sizeof(*mem)); return 0; } EXPORT_SYMBOL_GPL(p2sb_bar); + +static int __init p2sb_fs_init(void) +{ + p2sb_cache_resources(); + return 0; +} + +/* + * pci_rescan_remove_lock to avoid access to unhidden P2SB devices can + * not be locked in sysfs pci bus rescan path because of deadlock. To + * avoid the deadlock, access to P2SB devices with the lock at an early + * step in kernel initialization and cache required resources. This + * should happen after subsys_initcall which initializes PCI subsystem + * and before device_initcall which requires P2SB resources. + */ +fs_initcall(p2sb_fs_init);
On Jan 03, 2024 / 17:55, Greg Kroah-Hartman wrote:
6.6-stable review patch. If anyone has any objections, please let me know.
From: Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com
commit b28ff7a7c3245d7f62acc20f15b4361292fe4117 upstream.
p2sb_bar() unhides P2SB device to get resources from the device. It guards the operation by locking pci_rescan_remove_lock so that parallel rescans do not find the P2SB device. However, this lock causes deadlock when PCI bus rescan is triggered by /sys/bus/pci/rescan. The rescan locks pci_rescan_remove_lock and probes PCI devices. When PCI devices call p2sb_bar() during probe, it locks pci_rescan_remove_lock again. Hence the deadlock.
To avoid the deadlock, do not lock pci_rescan_remove_lock in p2sb_bar(). Instead, do the lock at fs_initcall. Introduce p2sb_cache_resources() for fs_initcall which gets and caches the P2SB resources. At p2sb_bar(), refer the cache and return to the caller.
Suggested-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Fixes: 9745fb07474f ("platform/x86/intel: Add Primary to Sideband (P2SB) bridge support") Cc: stable@vger.kernel.org Signed-off-by: Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Link: https://lore.kernel.org/linux-pci/6xb24fjmptxxn5js2fjrrddjae6twex5bjaftwqsua... Link: https://lore.kernel.org/r/20231229063912.2517922-2-shinichiro.kawasaki@wdc.c... Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
In same manner as I requested for 6.1-stable, please drop this patch from 6.6-stable due to the new bug report [*].
[*] https://lore.kernel.org/platform-driver-x86/CABq1_vjfyp_B-f4LAL6pg394bP6nDFy...
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sidhartha Kumar sidhartha.kumar@oracle.com
commit 4249f13c11be8b8b7bf93204185e150c3bdc968d upstream.
mas_preallocate() defaults to requesting 1 node for preallocation and then ,depending on the type of store, will update the request variable. There isn't a check for a slot store type, so slot stores are preallocating the default 1 node. Slot stores do not require any additional nodes, so add a check for the slot store case that will bypass node_count_gfp(). Update the tests to reflect that slot stores do not require allocations.
User visible effects of this bug include increased memory usage from the unneeded node that was allocated.
Link: https://lkml.kernel.org/r/20231213205058.386589-1-sidhartha.kumar@oracle.com Fixes: 0b8bb544b1a7 ("maple_tree: update mas_preallocate() testing") Signed-off-by: Sidhartha Kumar sidhartha.kumar@oracle.com Cc: Liam R. Howlett Liam.Howlett@oracle.com Cc: Matthew Wilcox (Oracle) willy@infradead.org Cc: Peng Zhang zhangpeng.00@bytedance.com Cc: stable@vger.kernel.org [6.6+] Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- lib/maple_tree.c | 11 +++++++++++ tools/testing/radix-tree/maple.c | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/lib/maple_tree.c b/lib/maple_tree.c index bb24d84a4922..684689457d77 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -5501,6 +5501,17 @@ int mas_preallocate(struct ma_state *mas, void *entry, gfp_t gfp)
mas_wr_end_piv(&wr_mas); node_size = mas_wr_new_end(&wr_mas); + + /* Slot store, does not require additional nodes */ + if (node_size == wr_mas.node_end) { + /* reuse node */ + if (!mt_in_rcu(mas->tree)) + return 0; + /* shifting boundary */ + if (wr_mas.offset_end - mas->offset == 1) + return 0; + } + if (node_size >= mt_slots[wr_mas.type]) { /* Split, worst case for now. */ request = 1 + mas_mt_height(mas) * 2; diff --git a/tools/testing/radix-tree/maple.c b/tools/testing/radix-tree/maple.c index e5da1cad70ba..76a8990bb14e 100644 --- a/tools/testing/radix-tree/maple.c +++ b/tools/testing/radix-tree/maple.c @@ -35538,7 +35538,7 @@ static noinline void __init check_prealloc(struct maple_tree *mt) MT_BUG_ON(mt, mas_preallocate(&mas, ptr, GFP_KERNEL) != 0); allocated = mas_allocated(&mas); height = mas_mt_height(&mas); - MT_BUG_ON(mt, allocated != 1); + MT_BUG_ON(mt, allocated != 0); mas_store_prealloc(&mas, ptr); MT_BUG_ON(mt, mas_allocated(&mas) != 0);
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Usama Anjum usama.anjum@collabora.com
commit 0aac13add26d546ac74c89d2883b3a5f0fbea039 upstream.
The "locked-in-memory size" limit per process can be non-multiple of page_size. The mmap() fails if we try to allocate locked-in-memory with same size as the allowed limit if it isn't multiple of the page_size because mmap() rounds off the memory size to be allocated to next multiple of page_size.
Fix this by flooring the length to be allocated with mmap() to the previous multiple of the page_size.
This was getting triggered on KernelCI regularly because of different ulimit settings which wasn't multiple of the page_size. Find logs here: https://linux.kernelci.org/test/plan/id/657654bd8e81e654fae13532/ The bug in was present from the time test was first added.
Link: https://lkml.kernel.org/r/20231214101931.1155586-1-usama.anjum@collabora.com Fixes: 76fe17ef588a ("secretmem: test: add basic selftest for memfd_secret(2)") Signed-off-by: Muhammad Usama Anjum usama.anjum@collabora.com Reported-by: "kernelci.org bot" bot@kernelci.org Closes: https://linux.kernelci.org/test/plan/id/657654bd8e81e654fae13532/ Cc: "James E.J. Bottomley" James.Bottomley@HansenPartnership.com Cc: Mike Rapoport (IBM) rppt@kernel.org Cc: Shuah Khan shuah@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/mm/memfd_secret.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/tools/testing/selftests/mm/memfd_secret.c +++ b/tools/testing/selftests/mm/memfd_secret.c @@ -62,6 +62,9 @@ static void test_mlock_limit(int fd) char *mem;
len = mlock_limit_cur; + if (len % page_size != 0) + len = (len/page_size) * page_size; + mem = mmap(NULL, len, prot, mode, fd, 0); if (mem == MAP_FAILED) { fail("unable to mmap secret memory\n");
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li libaokun1@huawei.com
commit e2c27b803bb664748e090d99042ac128b3f88d92 upstream.
The following concurrency may cause the data read to be inconsistent with the data on disk:
cpu1 cpu2 ------------------------------|------------------------------ // Buffered write 2048 from 0 ext4_buffered_write_iter generic_perform_write copy_page_from_iter_atomic ext4_da_write_end ext4_da_do_write_end block_write_end __block_commit_write folio_mark_uptodate // Buffered read 4096 from 0 smp_wmb() ext4_file_read_iter set_bit(PG_uptodate, folio_flags) generic_file_read_iter i_size_write // 2048 filemap_read unlock_page(page) filemap_get_pages filemap_get_read_batch folio_test_uptodate(folio) ret = test_bit(PG_uptodate, folio_flags) if (ret) smp_rmb(); // Ensure that the data in page 0-2048 is up-to-date.
// New buffered write 2048 from 2048 ext4_buffered_write_iter generic_perform_write copy_page_from_iter_atomic ext4_da_write_end ext4_da_do_write_end block_write_end __block_commit_write folio_mark_uptodate smp_wmb() set_bit(PG_uptodate, folio_flags) i_size_write // 4096 unlock_page(page)
isize = i_size_read(inode) // 4096 // Read the latest isize 4096, but without smp_rmb(), there may be // Load-Load disorder resulting in the data in the 2048-4096 range // in the page is not up-to-date. copy_page_to_iter // copyout 4096
In the concurrency above, we read the updated i_size, but there is no read barrier to ensure that the data in the page is the same as the i_size at this point, so we may copy the unsynchronized page out. Hence adding the missing read memory barrier to fix this.
This is a Load-Load reordering issue, which only occurs on some weak mem-ordering architectures (e.g. ARM64, ALPHA), but not on strong mem-ordering architectures (e.g. X86). And theoretically the problem doesn't only happen on ext4, filesystems that call filemap_read() but don't hold inode lock (e.g. btrfs, f2fs, ubifs ...) will have this problem, while filesystems with inode lock (e.g. xfs, nfs) won't have this problem.
Link: https://lkml.kernel.org/r/20231213062324.739009-1-libaokun1@huawei.com Signed-off-by: Baokun Li libaokun1@huawei.com Reviewed-by: Jan Kara jack@suse.cz Cc: Andreas Dilger adilger.kernel@dilger.ca Cc: Christoph Hellwig hch@infradead.org Cc: Dave Chinner david@fromorbit.com Cc: Matthew Wilcox (Oracle) willy@infradead.org Cc: Ritesh Harjani (IBM) ritesh.list@gmail.com Cc: Theodore Ts'o tytso@mit.edu Cc: yangerkun yangerkun@huawei.com Cc: Yu Kuai yukuai3@huawei.com Cc: Zhang Yi yi.zhang@huawei.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/filemap.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/mm/filemap.c +++ b/mm/filemap.c @@ -2667,6 +2667,15 @@ ssize_t filemap_read(struct kiocb *iocb, end_offset = min_t(loff_t, isize, iocb->ki_pos + iter->count);
/* + * Pairs with a barrier in + * block_write_end()->mark_buffer_dirty() or other page + * dirtying routines like iomap_write_end() to ensure + * changes to page contents are visible before we see + * increased inode size. + */ + smp_rmb(); + + /* * Once we start copying data, we don't want to be touching any * cachelines that might be contended: */
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charan Teja Kalla quic_charante@quicinc.com
commit fc346d0a70a13d52fe1c4bc49516d83a42cd7c4c upstream.
Large folios occupy N consecutive entries in the swap cache instead of using multi-index entries like the page cache. However, if a large folio is re-added to the LRU list, it can be migrated. The migration code was not aware of the difference between the swap cache and the page cache and assumed that a single xas_store() would be sufficient.
This leaves potentially many stale pointers to the now-migrated folio in the swap cache, which can lead to almost arbitrary data corruption in the future. This can also manifest as infinite loops with the RCU read lock held.
[willy@infradead.org: modifications to the changelog & tweaked the fix] Fixes: 3417013e0d18 ("mm/migrate: Add folio_migrate_mapping()") Link: https://lkml.kernel.org/r/20231214045841.961776-1-willy@infradead.org Signed-off-by: Charan Teja Kalla quic_charante@quicinc.com Signed-off-by: Matthew Wilcox (Oracle) willy@infradead.org Reported-by: Charan Teja Kalla quic_charante@quicinc.com Closes: https://lkml.kernel.org/r/1700569840-17327-1-git-send-email-quic_charante@qu... Cc: David Hildenbrand david@redhat.com Cc: Johannes Weiner hannes@cmpxchg.org Cc: Kirill A. Shutemov kirill.shutemov@linux.intel.com Cc: Naoya Horiguchi n-horiguchi@ah.jp.nec.com Cc: Shakeel Butt shakeelb@google.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/migrate.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/mm/migrate.c +++ b/mm/migrate.c @@ -405,6 +405,7 @@ int folio_migrate_mapping(struct address int dirty; int expected_count = folio_expected_refs(mapping, folio) + extra_count; long nr = folio_nr_pages(folio); + long entries, i;
if (!mapping) { /* Anonymous page without mapping */ @@ -442,8 +443,10 @@ int folio_migrate_mapping(struct address folio_set_swapcache(newfolio); newfolio->private = folio_get_private(folio); } + entries = nr; } else { VM_BUG_ON_FOLIO(folio_test_swapcache(folio), folio); + entries = 1; }
/* Move dirty while page refs frozen and newpage not yet exposed */ @@ -453,7 +456,11 @@ int folio_migrate_mapping(struct address folio_set_dirty(newfolio); }
- xas_store(&xas, newfolio); + /* Swap cache still stores N entries instead of a high-order entry */ + for (i = 0; i < entries; i++) { + xas_store(&xas, newfolio); + xas_next(&xas); + }
/* * Drop cache reference from old page by unfreezing
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Wilcox (Oracle) willy@infradead.org
commit 39ebd6dce62d8cfe3864e16148927a139f11bc9a upstream.
On 32-bit systems, we'll lose the top bits of index because arithmetic will be performed in unsigned long instead of unsigned long long. This affects files over 4GB in size.
Link: https://lkml.kernel.org/r/20231218135837.3310403-4-willy@infradead.org Fixes: 6100e34b2526 ("mm, memory_failure: Teach memory_failure() about dev_pagemap pages") Signed-off-by: Matthew Wilcox (Oracle) willy@infradead.org Cc: Dan Williams dan.j.williams@intel.com Cc: Naoya Horiguchi n-horiguchi@ah.jp.nec.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/memory-failure.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1705,7 +1705,7 @@ static void unmap_and_kill(struct list_h * mapping being torn down is communicated in siginfo, see * kill_proc() */ - loff_t start = (index << PAGE_SHIFT) & ~(size - 1); + loff_t start = ((loff_t)index << PAGE_SHIFT) & ~(size - 1);
unmap_mapping_range(mapping, start, size, 0); }
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Wilcox (Oracle) willy@infradead.org
commit c79c5a0a00a9457718056b588f312baadf44e471 upstream.
A process may map only some of the pages in a folio, and might be missed if it maps the poisoned page but not the head page. Or it might be unnecessarily hit if it maps the head page, but not the poisoned page.
Link: https://lkml.kernel.org/r/20231218135837.3310403-3-willy@infradead.org Fixes: 7af446a841a2 ("HWPOISON, hugetlb: enable error handling path for hugepage") Signed-off-by: Matthew Wilcox (Oracle) willy@infradead.org Cc: Dan Williams dan.j.williams@intel.com Cc: Naoya Horiguchi n-horiguchi@ah.jp.nec.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/memory-failure.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1571,7 +1571,7 @@ static bool hwpoison_user_mappings(struc * This check implies we don't kill processes if their pages * are in the swap cache early. Those are always late kills. */ - if (!page_mapped(hpage)) + if (!page_mapped(p)) return true;
if (PageSwapCache(p)) { @@ -1622,10 +1622,10 @@ static bool hwpoison_user_mappings(struc try_to_unmap(folio, ttu); }
- unmap_success = !page_mapped(hpage); + unmap_success = !page_mapped(p); if (!unmap_success) pr_err("%#lx: failed to unmap page (mapcount=%d)\n", - pfn, page_mapcount(hpage)); + pfn, page_mapcount(p));
/* * try_to_unmap() might put mlocked page in lru cache, so call
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Keith Busch kbusch@kernel.org
commit d3e8b1858734bf46cda495be4165787b9a3981a6 upstream.
The commit was identified to might sleep in invalid context and is blocking regression testing.
This reverts commit ee6fdc5055e916b1dd497f11260d4901c4c1e55e.
Link: https://lore.kernel.org/linux-nvme/hkhl56n665uvc6t5d6h3wtx7utkcorw4xlwi7d2t2... Link: https://lists.infradead.org/pipermail/linux-nvme/2023-December/043756.html Reported-by: Daniel Wagner dwagner@suse.de Reported-by: Maurizio Lombardi mlombard@redhat.com Cc: Michael Liang mliang@purestorage.com Tested-by: Daniel Wagner dwagner@suse.de Reviewed-by: Daniel Wagner dwagner@suse.de Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Keith Busch kbusch@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvme/host/fc.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-)
--- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -2548,24 +2548,17 @@ nvme_fc_error_recovery(struct nvme_fc_ct * the controller. Abort any ios on the association and let the * create_association error path resolve things. */ - enum nvme_ctrl_state state; - unsigned long flags; - - spin_lock_irqsave(&ctrl->lock, flags); - state = ctrl->ctrl.state; - if (state == NVME_CTRL_CONNECTING) { - set_bit(ASSOC_FAILED, &ctrl->flags); - spin_unlock_irqrestore(&ctrl->lock, flags); + if (ctrl->ctrl.state == NVME_CTRL_CONNECTING) { __nvme_fc_abort_outstanding_ios(ctrl, true); + set_bit(ASSOC_FAILED, &ctrl->flags); dev_warn(ctrl->ctrl.device, "NVME-FC{%d}: transport error during (re)connect\n", ctrl->cnum); return; } - spin_unlock_irqrestore(&ctrl->lock, flags);
/* Otherwise, only proceed if in LIVE state - e.g. on first error */ - if (state != NVME_CTRL_LIVE) + if (ctrl->ctrl.state != NVME_CTRL_LIVE) return;
dev_warn(ctrl->ctrl.device, @@ -3179,16 +3172,12 @@ nvme_fc_create_association(struct nvme_f else ret = nvme_fc_recreate_io_queues(ctrl); } - - spin_lock_irqsave(&ctrl->lock, flags); if (!ret && test_bit(ASSOC_FAILED, &ctrl->flags)) ret = -EIO; - if (ret) { - spin_unlock_irqrestore(&ctrl->lock, flags); + if (ret) goto out_term_aen_ops; - } + changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE); - spin_unlock_irqrestore(&ctrl->lock, flags);
ctrl->ctrl.nr_reconnects = 0;
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (Google) rostedt@goodmis.org
commit 623b1f896fa8a669a277ee5a258307a16c7377a3 upstream.
The tracefs file "buffer_percent" is to allow user space to set a water-mark on how much of the tracing ring buffer needs to be filled in order to wake up a blocked reader.
0 - is to wait until any data is in the buffer 1 - is to wait for 1% of the sub buffers to be filled 50 - would be half of the sub buffers are filled with data 100 - is not to wake the waiter until the ring buffer is completely full
Unfortunately the test for being full was:
dirty = ring_buffer_nr_dirty_pages(buffer, cpu); return (dirty * 100) > (full * nr_pages);
Where "full" is the value for "buffer_percent".
There is two issues with the above when full == 100.
1. dirty * 100 > 100 * nr_pages will never be true That is, the above is basically saying that if the user sets buffer_percent to 100, more pages need to be dirty than exist in the ring buffer!
2. The page that the writer is on is never considered dirty, as dirty pages are only those that are full. When the writer goes to a new sub-buffer, it clears the contents of that sub-buffer.
That is, even if the check was ">=" it would still not be equal as the most pages that can be considered "dirty" is nr_pages - 1.
To fix this, add one to dirty and use ">=" in the compare.
Link: https://lore.kernel.org/linux-trace-kernel/20231226125902.4a057f1d@gandalf.l...
Cc: stable@vger.kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Mathieu Desnoyers mathieu.desnoyers@efficios.com Acked-by: Masami Hiramatsu (Google) mhiramat@kernel.org Fixes: 03329f9939781 ("tracing: Add tracefs file buffer_percentage") Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ring_buffer.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -881,9 +881,14 @@ static __always_inline bool full_hit(str if (!nr_pages || !full) return true;
- dirty = ring_buffer_nr_dirty_pages(buffer, cpu); + /* + * Add one as dirty will never equal nr_pages, as the sub-buffer + * that the writer is on is not counted as dirty. + * This is needed if "buffer_percent" is set to 100. + */ + dirty = ring_buffer_nr_dirty_pages(buffer, cpu) + 1;
- return (dirty * 100) > (full * nr_pages); + return (dirty * 100) >= (full * nr_pages); }
/*
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (Google) rostedt@goodmis.org
commit d05cb470663a2a1879277e544f69e660208f08f2 upstream.
Masami Hiramatsu reported a memory leak in register_ftrace_direct() where if the number of new entries are added is large enough to cause two allocations in the loop:
for (i = 0; i < size; i++) { hlist_for_each_entry(entry, &hash->buckets[i], hlist) { new = ftrace_add_rec_direct(entry->ip, addr, &free_hash); if (!new) goto out_remove; entry->direct = addr; } }
Where ftrace_add_rec_direct() has:
if (ftrace_hash_empty(direct_functions) || direct_functions->count > 2 * (1 << direct_functions->size_bits)) { struct ftrace_hash *new_hash; int size = ftrace_hash_empty(direct_functions) ? 0 : direct_functions->count + 1;
if (size < 32) size = 32;
new_hash = dup_hash(direct_functions, size); if (!new_hash) return NULL;
*free_hash = direct_functions; direct_functions = new_hash; }
The "*free_hash = direct_functions;" can happen twice, losing the previous allocation of direct_functions.
But this also exposed a more serious bug.
The modification of direct_functions above is not safe. As direct_functions can be referenced at any time to find what direct caller it should call, the time between:
new_hash = dup_hash(direct_functions, size); and direct_functions = new_hash;
can have a race with another CPU (or even this one if it gets interrupted), and the entries being moved to the new hash are not referenced.
That's because the "dup_hash()" is really misnamed and is really a "move_hash()". It moves the entries from the old hash to the new one.
Now even if that was changed, this code is not proper as direct_functions should not be updated until the end. That is the best way to handle function reference changes, and is the way other parts of ftrace handles this.
The following is done:
1. Change add_hash_entry() to return the entry it created and inserted into the hash, and not just return success or not.
2. Replace ftrace_add_rec_direct() with add_hash_entry(), and remove the former.
3. Allocate a "new_hash" at the start that is made for holding both the new hash entries as well as the existing entries in direct_functions.
4. Copy (not move) the direct_function entries over to the new_hash.
5. Copy the entries of the added hash to the new_hash.
6. If everything succeeds, then use rcu_pointer_assign() to update the direct_functions with the new_hash.
This simplifies the code and fixes both the memory leak as well as the race condition mentioned above.
Link: https://lore.kernel.org/all/170368070504.42064.8960569647118388081.stgit@dev... Link: https://lore.kernel.org/linux-trace-kernel/20231229115134.08dd5174@gandalf.l...
Cc: stable@vger.kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Mathieu Desnoyers mathieu.desnoyers@efficios.com Cc: Jiri Olsa jolsa@kernel.org Cc: Alexei Starovoitov ast@kernel.org Cc: Daniel Borkmann daniel@iogearbox.net Acked-by: Masami Hiramatsu (Google) mhiramat@kernel.org Fixes: 763e34e74bb7d ("ftrace: Add register_ftrace_direct()") Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ftrace.c | 100 +++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 53 deletions(-)
--- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1183,18 +1183,19 @@ static void __add_hash_entry(struct ftra hash->count++; }
-static int add_hash_entry(struct ftrace_hash *hash, unsigned long ip) +static struct ftrace_func_entry * +add_hash_entry(struct ftrace_hash *hash, unsigned long ip) { struct ftrace_func_entry *entry;
entry = kmalloc(sizeof(*entry), GFP_KERNEL); if (!entry) - return -ENOMEM; + return NULL;
entry->ip = ip; __add_hash_entry(hash, entry);
- return 0; + return entry; }
static void @@ -1349,7 +1350,6 @@ alloc_and_copy_ftrace_hash(int size_bits struct ftrace_func_entry *entry; struct ftrace_hash *new_hash; int size; - int ret; int i;
new_hash = alloc_ftrace_hash(size_bits); @@ -1366,8 +1366,7 @@ alloc_and_copy_ftrace_hash(int size_bits size = 1 << hash->size_bits; for (i = 0; i < size; i++) { hlist_for_each_entry(entry, &hash->buckets[i], hlist) { - ret = add_hash_entry(new_hash, entry->ip); - if (ret < 0) + if (add_hash_entry(new_hash, entry->ip) == NULL) goto free_hash; } } @@ -2536,7 +2535,7 @@ ftrace_find_unique_ops(struct dyn_ftrace
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS /* Protected by rcu_tasks for reading, and direct_mutex for writing */ -static struct ftrace_hash *direct_functions = EMPTY_HASH; +static struct ftrace_hash __rcu *direct_functions = EMPTY_HASH; static DEFINE_MUTEX(direct_mutex); int ftrace_direct_func_count;
@@ -2555,39 +2554,6 @@ unsigned long ftrace_find_rec_direct(uns return entry->direct; }
-static struct ftrace_func_entry* -ftrace_add_rec_direct(unsigned long ip, unsigned long addr, - struct ftrace_hash **free_hash) -{ - struct ftrace_func_entry *entry; - - if (ftrace_hash_empty(direct_functions) || - direct_functions->count > 2 * (1 << direct_functions->size_bits)) { - struct ftrace_hash *new_hash; - int size = ftrace_hash_empty(direct_functions) ? 0 : - direct_functions->count + 1; - - if (size < 32) - size = 32; - - new_hash = dup_hash(direct_functions, size); - if (!new_hash) - return NULL; - - *free_hash = direct_functions; - direct_functions = new_hash; - } - - entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - return NULL; - - entry->ip = ip; - entry->direct = addr; - __add_hash_entry(direct_functions, entry); - return entry; -} - static void call_direct_funcs(unsigned long ip, unsigned long pip, struct ftrace_ops *ops, struct ftrace_regs *fregs) { @@ -4223,8 +4189,8 @@ enter_record(struct ftrace_hash *hash, s /* Do nothing if it exists */ if (entry) return 0; - - ret = add_hash_entry(hash, rec->ip); + if (add_hash_entry(hash, rec->ip) == NULL) + ret = -ENOMEM; } return ret; } @@ -5266,7 +5232,8 @@ __ftrace_match_addr(struct ftrace_hash * return 0; }
- return add_hash_entry(hash, ip); + entry = add_hash_entry(hash, ip); + return entry ? 0 : -ENOMEM; }
static int @@ -5410,7 +5377,7 @@ static void remove_direct_functions_hash */ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr) { - struct ftrace_hash *hash, *free_hash = NULL; + struct ftrace_hash *hash, *new_hash = NULL, *free_hash = NULL; struct ftrace_func_entry *entry, *new; int err = -EBUSY, size, i;
@@ -5436,17 +5403,44 @@ int register_ftrace_direct(struct ftrace } }
- /* ... and insert them to direct_functions hash. */ err = -ENOMEM; + + /* Make a copy hash to place the new and the old entries in */ + size = hash->count + direct_functions->count; + if (size > 32) + size = 32; + new_hash = alloc_ftrace_hash(fls(size)); + if (!new_hash) + goto out_unlock; + + /* Now copy over the existing direct entries */ + size = 1 << direct_functions->size_bits; + for (i = 0; i < size; i++) { + hlist_for_each_entry(entry, &direct_functions->buckets[i], hlist) { + new = add_hash_entry(new_hash, entry->ip); + if (!new) + goto out_unlock; + new->direct = entry->direct; + } + } + + /* ... and add the new entries */ + size = 1 << hash->size_bits; for (i = 0; i < size; i++) { hlist_for_each_entry(entry, &hash->buckets[i], hlist) { - new = ftrace_add_rec_direct(entry->ip, addr, &free_hash); + new = add_hash_entry(new_hash, entry->ip); if (!new) - goto out_remove; + goto out_unlock; + /* Update both the copy and the hash entry */ + new->direct = addr; entry->direct = addr; } }
+ free_hash = direct_functions; + rcu_assign_pointer(direct_functions, new_hash); + new_hash = NULL; + ops->func = call_direct_funcs; ops->flags = MULTI_FLAGS; ops->trampoline = FTRACE_REGS_ADDR; @@ -5454,17 +5448,17 @@ int register_ftrace_direct(struct ftrace
err = register_ftrace_function_nolock(ops);
- out_remove: - if (err) - remove_direct_functions_hash(hash, addr); - out_unlock: mutex_unlock(&direct_mutex);
- if (free_hash) { + if (free_hash && free_hash != EMPTY_HASH) { synchronize_rcu_tasks(); free_ftrace_hash(free_hash); } + + if (new_hash) + free_ftrace_hash(new_hash); + return err; } EXPORT_SYMBOL_GPL(register_ftrace_direct); @@ -6309,7 +6303,7 @@ ftrace_graph_set_hash(struct ftrace_hash
if (entry) continue; - if (add_hash_entry(hash, rec->ip) < 0) + if (add_hash_entry(hash, rec->ip) == NULL) goto out; } else { if (entry) {
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (Google) rostedt@goodmis.org
commit 39a7dc23a1ed0fe81141792a09449d124c5953bd upstream.
If an application blocks on the snapshot or snapshot_raw files, expecting to be woken up when a snapshot occurs, it will not happen. Or it may happen with an unexpected result.
That result is that the application will be reading the main buffer instead of the snapshot buffer. That is because when the snapshot occurs, the main and snapshot buffers are swapped. But the reader has a descriptor still pointing to the buffer that it originally connected to.
This is fine for the main buffer readers, as they may be blocked waiting for a watermark to be hit, and when a snapshot occurs, the data that the main readers want is now on the snapshot buffer.
But for waiters of the snapshot buffer, they are waiting for an event to occur that will trigger the snapshot and they can then consume it quickly to save the snapshot before the next snapshot occurs. But to do this, they need to read the new snapshot buffer, not the old one that is now receiving new data.
Also, it does not make sense to have a watermark "buffer_percent" on the snapshot buffer, as the snapshot buffer is static and does not receive new data except all at once.
Link: https://lore.kernel.org/linux-trace-kernel/20231228095149.77f5b45d@gandalf.l...
Cc: stable@vger.kernel.org Cc: Mathieu Desnoyers mathieu.desnoyers@efficios.com Cc: Mark Rutland mark.rutland@arm.com Acked-by: Masami Hiramatsu (Google) mhiramat@kernel.org Fixes: debdd57f5145f ("tracing: Make a snapshot feature available from userspace") Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ring_buffer.c | 3 ++- kernel/trace/trace.c | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-)
--- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -949,7 +949,8 @@ void ring_buffer_wake_waiters(struct tra /* make sure the waiters see the new index */ smp_wmb();
- rb_wake_up_waiters(&rbwork->work); + /* This can be called in any context */ + irq_work_queue(&rbwork->work); }
/** --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1893,6 +1893,9 @@ update_max_tr(struct trace_array *tr, st __update_max_tr(tr, tsk, cpu);
arch_spin_unlock(&tr->max_lock); + + /* Any waiters on the old snapshot buffer need to wake up */ + ring_buffer_wake_waiters(tr->array_buffer.buffer, RING_BUFFER_ALL_CPUS); }
/** @@ -1944,12 +1947,23 @@ update_max_tr_single(struct trace_array
static int wait_on_pipe(struct trace_iterator *iter, int full) { + int ret; + /* Iterators are static, they should be filled or empty */ if (trace_buffer_iter(iter, iter->cpu_file)) return 0;
- return ring_buffer_wait(iter->array_buffer->buffer, iter->cpu_file, - full); + ret = ring_buffer_wait(iter->array_buffer->buffer, iter->cpu_file, full); + +#ifdef CONFIG_TRACER_MAX_TRACE + /* + * Make sure this is still the snapshot buffer, as if a snapshot were + * to happen, this would now be the main buffer. + */ + if (iter->snapshot) + iter->array_buffer = &iter->tr->max_buffer; +#endif + return ret; }
#ifdef CONFIG_FTRACE_STARTUP_TEST @@ -8514,7 +8528,7 @@ tracing_buffers_splice_read(struct file
wait_index = READ_ONCE(iter->wait_index);
- ret = wait_on_pipe(iter, iter->tr->buffer_percent); + ret = wait_on_pipe(iter, iter->snapshot ? 0 : iter->tr->buffer_percent); if (ret) goto out;
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg johannes.berg@intel.com
commit 7e7efdda6adb385fbdfd6f819d76bc68c923c394 upstream.
[note: this is commit 4a7e92551618f3737b305f62451353ee05662f57 reapplied; that commit had been reverted in 6.6.6 because it caused regressions, see https://lore.kernel.org/stable/2023121450-habitual-transpose-68a1@gregkh/ for details]
My prior race fix here broke CQM when ranges aren't used, as the reporting worker now requires the cqm_config to be set in the wdev, but isn't set when there's no range configured.
Rather than continuing to special-case the range version, set the cqm_config always and configure accordingly, also tracking if range was used or not to be able to clear the configuration appropriately with the same API, which was actually not right if both were implemented by a driver for some reason, as is the case with mac80211 (though there the implementations are equivalent so it doesn't matter.)
Also, the original multiple-RSSI commit lost checking for the callback, so might have potentially crashed if a driver had neither implementation, and userspace tried to use it despite not being advertised as supported.
Cc: stable@vger.kernel.org Fixes: 4a4b8169501b ("cfg80211: Accept multiple RSSI thresholds for CQM") Fixes: 37c20b2effe9 ("wifi: cfg80211: fix cqm_config access race") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: "L�o Lam" leo@leolam.fr Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/wireless/core.h | 1 net/wireless/nl80211.c | 50 ++++++++++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 19 deletions(-)
--- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -299,6 +299,7 @@ struct cfg80211_cqm_config { u32 rssi_hyst; s32 last_rssi_event_value; enum nl80211_cqm_rssi_threshold_event last_rssi_event_type; + bool use_range_api; int n_rssi_thresholds; s32 rssi_thresholds[] __counted_by(n_rssi_thresholds); }; --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -12824,10 +12824,6 @@ static int cfg80211_cqm_rssi_update(stru int i, n, low_index; int err;
- /* RSSI reporting disabled? */ - if (!cqm_config) - return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0); - /* * Obtain current RSSI value if possible, if not and no RSSI threshold * event has been received yet, we should receive an event after a @@ -12902,18 +12898,6 @@ static int nl80211_set_cqm_rssi(struct g wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) return -EOPNOTSUPP;
- if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) { - if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */ - return rdev_set_cqm_rssi_config(rdev, dev, 0, 0); - - return rdev_set_cqm_rssi_config(rdev, dev, - thresholds[0], hysteresis); - } - - if (!wiphy_ext_feature_isset(&rdev->wiphy, - NL80211_EXT_FEATURE_CQM_RSSI_LIST)) - return -EOPNOTSUPP; - if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */ n_thresholds = 0;
@@ -12921,6 +12905,20 @@ static int nl80211_set_cqm_rssi(struct g old = rcu_dereference_protected(wdev->cqm_config, lockdep_is_held(&wdev->mtx));
+ /* if already disabled just succeed */ + if (!n_thresholds && !old) + return 0; + + if (n_thresholds > 1) { + if (!wiphy_ext_feature_isset(&rdev->wiphy, + NL80211_EXT_FEATURE_CQM_RSSI_LIST) || + !rdev->ops->set_cqm_rssi_range_config) + return -EOPNOTSUPP; + } else { + if (!rdev->ops->set_cqm_rssi_config) + return -EOPNOTSUPP; + } + if (n_thresholds) { cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds, n_thresholds), @@ -12935,13 +12933,26 @@ static int nl80211_set_cqm_rssi(struct g memcpy(cqm_config->rssi_thresholds, thresholds, flex_array_size(cqm_config, rssi_thresholds, n_thresholds)); + cqm_config->use_range_api = n_thresholds > 1 || + !rdev->ops->set_cqm_rssi_config;
rcu_assign_pointer(wdev->cqm_config, cqm_config); + + if (cqm_config->use_range_api) + err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config); + else + err = rdev_set_cqm_rssi_config(rdev, dev, + thresholds[0], + hysteresis); } else { RCU_INIT_POINTER(wdev->cqm_config, NULL); + /* if enabled as range also disable via range */ + if (old->use_range_api) + err = rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0); + else + err = rdev_set_cqm_rssi_config(rdev, dev, 0, 0); }
- err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config); if (err) { rcu_assign_pointer(wdev->cqm_config, old); kfree_rcu(cqm_config, rcu_head); @@ -19131,10 +19142,11 @@ void cfg80211_cqm_rssi_notify_work(struc wdev_lock(wdev); cqm_config = rcu_dereference_protected(wdev->cqm_config, lockdep_is_held(&wdev->mtx)); - if (!wdev->cqm_config) + if (!cqm_config) goto unlock;
- cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config); + if (cqm_config->use_range_api) + cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config);
rssi_level = cqm_config->last_rssi_event_value; rssi_event = cqm_config->last_rssi_event_type;
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: "L�o Lam" leo@leolam.fr
Commit 008afb9f3d57 ("wifi: cfg80211: fix CQM for non-range use" backported to 6.6.x) causes nl80211_set_cqm_rssi not to release the wdev lock in some of the error paths.
Of course, the ensuing deadlock causes userland network managers to break pretty badly, and on typical systems this also causes lockups on on suspend, poweroff and reboot. See [1], [2], [3] for example reports.
The upstream commit 7e7efdda6adb ("wifi: cfg80211: fix CQM for non-range use"), committed in November 2023, is completely fine because there was another commit in August 2023 that removed the wdev lock: see commit 076fc8775daf ("wifi: cfg80211: remove wdev mutex").
The reason things broke in 6.6.5 is that commit 4338058f6009 was applied without also applying 076fc8775daf.
Commit 076fc8775daf ("wifi: cfg80211: remove wdev mutex") is a rather large commit; adjusting the error handling (which is what this commit does) yields a much simpler patch and was tested to work properly.
Fix the deadlock by releasing the lock before returning.
[1] https://bugzilla.kernel.org/show_bug.cgi?id=218247 [2] https://bbs.archlinux.org/viewtopic.php?id=290976 [3] https://lore.kernel.org/all/87sf4belmm.fsf@turtle.gmx.de/
Link: https://lore.kernel.org/stable/e374bb16-5b13-44cc-b11a-2f4eefb1ecf5@manjaro.... Fixes: 008afb9f3d57 ("wifi: cfg80211: fix CQM for non-range use") Tested-by: "L�o Lam" leo@leolam.fr Tested-by: Philip Müller philm@manjaro.org Cc: stable@vger.kernel.org Cc: Johannes Berg johannes.berg@intel.com Signed-off-by: "L�o Lam" leo@leolam.fr Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/wireless/nl80211.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
--- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -12906,17 +12906,23 @@ static int nl80211_set_cqm_rssi(struct g lockdep_is_held(&wdev->mtx));
/* if already disabled just succeed */ - if (!n_thresholds && !old) - return 0; + if (!n_thresholds && !old) { + err = 0; + goto unlock; + }
if (n_thresholds > 1) { if (!wiphy_ext_feature_isset(&rdev->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST) || - !rdev->ops->set_cqm_rssi_range_config) - return -EOPNOTSUPP; + !rdev->ops->set_cqm_rssi_range_config) { + err = -EOPNOTSUPP; + goto unlock; + } } else { - if (!rdev->ops->set_cqm_rssi_config) - return -EOPNOTSUPP; + if (!rdev->ops->set_cqm_rssi_config) { + err = -EOPNOTSUPP; + goto unlock; + } }
if (n_thresholds) {
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso pablo@netfilter.org
commit 7315dc1e122c85ffdfc8defffbb8f8b616c2eb1a upstream.
NFT_MSG_DELSET deactivates all elements in the set, skip set->ops->commit() to avoid the unnecessary clone (for the pipapo case) as well as the sync GC cycle, which could deactivate again expired elements in such set.
Fixes: 5f68718b34a5 ("netfilter: nf_tables: GC transaction API to avoid race with control plane") Reported-by: Kevin Rich kevinrich1337@gmail.com Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netfilter/nf_tables_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -9849,7 +9849,7 @@ static void nft_set_commit_update(struct list_for_each_entry_safe(set, next, set_update_list, pending_update) { list_del_init(&set->pending_update);
- if (!set->ops->commit) + if (!set->ops->commit || set->dead) continue;
set->ops->commit(set);
On Wed, 3 Jan 2024 17:55:20 +0100 Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
Works for my Visionfive2 board (riscv64):
Tested-by: Nam Cao namcao@linutronix.de
Best regards, Nam
Hello,
On Wed, 3 Jan 2024 17:55:20 +0100 Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
This rc kernel passes DAMON functionality test[1] on my test machine. Attaching the test results summary below. Please note that I retrieved the kernel from linux-stable-rc tree[2].
Tested-by: SeongJae Park sj@kernel.org
[1] https://github.com/awslabs/damon-tests/tree/next/corr [2] 5fd1c89851c4 ("Linux 6.6.10-rc1")
Thanks, SJ
[...]
---
ok 1 selftests: damon: debugfs_attrs.sh ok 2 selftests: damon: debugfs_schemes.sh ok 3 selftests: damon: debugfs_target_ids.sh ok 4 selftests: damon: debugfs_empty_targets.sh ok 5 selftests: damon: debugfs_huge_count_read_write.sh ok 6 selftests: damon: debugfs_duplicate_context_creation.sh ok 7 selftests: damon: debugfs_rm_non_contexts.sh ok 8 selftests: damon: sysfs.sh ok 9 selftests: damon: sysfs_update_removed_scheme_dir.sh ok 10 selftests: damon: reclaim.sh ok 11 selftests: damon: lru_sort.sh ok 1 selftests: damon-tests: kunit.sh ok 2 selftests: damon-tests: huge_count_read_write.sh ok 3 selftests: damon-tests: buffer_overflow.sh ok 4 selftests: damon-tests: rm_contexts.sh ok 5 selftests: damon-tests: record_null_deref.sh ok 6 selftests: damon-tests: dbgfs_target_ids_read_before_terminate_race.sh ok 7 selftests: damon-tests: dbgfs_target_ids_pid_leak.sh ok 8 selftests: damon-tests: damo_tests.sh ok 9 selftests: damon-tests: masim-record.sh ok 10 selftests: damon-tests: build_i386.sh ok 11 selftests: damon-tests: build_arm64.sh ok 12 selftests: damon-tests: build_i386_idle_flag.sh ok 13 selftests: damon-tests: build_i386_highpte.sh ok 14 selftests: damon-tests: build_nomemcg.sh [33m [92mPASS [39m
On 1/3/24 08:55, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Tested-by: Florian Fainelli florian.fainelli@broadcom.com
On Wed, Jan 03, 2024 at 05:55:20PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
No regressions found on WSL (x86 and arm64).
Built, booted, and reviewed dmesg.
Thank you.
Tested-by: Kelsey Steele kelseysteele@linux.microsoft.com
On 1/3/24 09:55, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Tested-by: Shuah Khan skhan@linuxfoundation.org
thanks, -- Shuah
Hi Greg
On Thu, Jan 4, 2024 at 2:13 AM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
6.6.10-rc1 tested.
Build successfully completed. Boot successfully completed. No dmesg regressions. Video output normal. Sound output normal.
Lenovo ThinkPad X1 Carbon Gen10(Intel i7-1260P(x86_64) arch linux)
[ 0.000000] Linux version 6.6.10-rc1rv (takeshi@ThinkPadX1Gen10J0764) (gcc (GCC) 13.2.1 20230801, GNU ld (GNU Binutils) 2.41.0) #1 SMP PREEMPT_DYNAMIC Thu Jan 4 11:03:04 JST 2024
Thanks
Tested-by: Takeshi Ogasawara takeshi.ogasawara@futuring-girl.com
Hello!
On 03/01/24 10:55 a. m., Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
We're seeing a build regression with x86/GCC-8 and allmodconfig:
-----8<----- In file included from /builds/linux/include/linux/string.h:294, from /builds/linux/include/linux/bitmap.h:11, from /builds/linux/include/linux/cpumask.h:12, from /builds/linux/arch/x86/include/asm/paravirt.h:17, from /builds/linux/arch/x86/include/asm/cpuid.h:62, from /builds/linux/arch/x86/include/asm/processor.h:19, from /builds/linux/arch/x86/include/asm/cpufeature.h:5, from /builds/linux/arch/x86/include/asm/thread_info.h:53, from /builds/linux/include/linux/thread_info.h:60, from /builds/linux/include/linux/uio.h:9, from /builds/linux/include/linux/socket.h:8, from /builds/linux/include/uapi/linux/if.h:25, from /builds/linux/net/wireless/nl80211.c:11: In function 'nl80211_set_cqm_rssi.isra.44', inlined from 'nl80211_set_cqm' at /builds/linux/net/wireless/nl80211.c:13000:10: /builds/linux/include/linux/fortify-string.h:57:29: error: '__builtin_memcpy' pointer overflow between offset 36 and size [-1, 9223372036854775807] [-Werror=array-bounds] #define __underlying_memcpy __builtin_memcpy ^ /builds/linux/include/linux/fortify-string.h:648:2: note: in expansion of macro '__underlying_memcpy' __underlying_##op(p, q, __fortify_size); \ ^~~~~~~~~~~~~ /builds/linux/include/linux/fortify-string.h:693:26: note: in expansion of macro '__fortify_memcpy_chk' #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ ^~~~~~~~~~~~~~~~~~~~ /builds/linux/net/wireless/nl80211.c:12939:3: note: in expansion of macro 'memcpy' memcpy(cqm_config->rssi_thresholds, thresholds, ^~~~~~ cc1: all warnings being treated as errors make[5]: *** [/builds/linux/scripts/Makefile.build:243: net/wireless/nl80211.o] Error 1 ----->8-----
This is currently being bisected, so there is more to follow.
Reported-by: Linux Kernel Functional Testing lkft@linaro.org
Greetings!
Daniel Díaz daniel.diaz@linaro.org
Hello!
On 03/01/24 10:10 p. m., Daniel Díaz wrote:
Hello!
On 03/01/24 10:55 a. m., Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
We're seeing a build regression with x86/GCC-8 and allmodconfig:
-----8<----- In file included from /builds/linux/include/linux/string.h:294, from /builds/linux/include/linux/bitmap.h:11, from /builds/linux/include/linux/cpumask.h:12, from /builds/linux/arch/x86/include/asm/paravirt.h:17, from /builds/linux/arch/x86/include/asm/cpuid.h:62, from /builds/linux/arch/x86/include/asm/processor.h:19, from /builds/linux/arch/x86/include/asm/cpufeature.h:5, from /builds/linux/arch/x86/include/asm/thread_info.h:53, from /builds/linux/include/linux/thread_info.h:60, from /builds/linux/include/linux/uio.h:9, from /builds/linux/include/linux/socket.h:8, from /builds/linux/include/uapi/linux/if.h:25, from /builds/linux/net/wireless/nl80211.c:11: In function 'nl80211_set_cqm_rssi.isra.44', inlined from 'nl80211_set_cqm' at /builds/linux/net/wireless/nl80211.c:13000:10: /builds/linux/include/linux/fortify-string.h:57:29: error: '__builtin_memcpy' pointer overflow between offset 36 and size [-1, 9223372036854775807] [-Werror=array-bounds] #define __underlying_memcpy __builtin_memcpy ^ /builds/linux/include/linux/fortify-string.h:648:2: note: in expansion of macro '__underlying_memcpy' __underlying_##op(p, q, __fortify_size); \ ^~~~~~~~~~~~~ /builds/linux/include/linux/fortify-string.h:693:26: note: in expansion of macro '__fortify_memcpy_chk' #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ ^~~~~~~~~~~~~~~~~~~~ /builds/linux/net/wireless/nl80211.c:12939:3: note: in expansion of macro 'memcpy' memcpy(cqm_config->rssi_thresholds, thresholds, ^~~~~~ cc1: all warnings being treated as errors make[5]: *** [/builds/linux/scripts/Makefile.build:243: net/wireless/nl80211.o] Error 1 ----->8-----
This is currently being bisected, so there is more to follow.
Bisection pointed to:
commit 92045aab1bd9bfd73d816e907ea07739c4550b41 Author: Johannes Berg johannes.berg@intel.com Date: Sat Dec 16 05:47:15 2023 +0000
wifi: cfg80211: fix CQM for non-range use
commit 7e7efdda6adb385fbdfd6f819d76bc68c923c394 upstream.
Reverting that was not possible, so I reverted 47f3694a4259 first ("wifi: nl80211: fix deadlock in nl80211_set_cqm_rssi (6.6.x)"), but that was not enough. After reverting both 47f3694a4259 and 92045aab1bd9, the build passed again.
Reproducer:
tuxmake --runtime podman --target-arch x86_64 --toolchain gcc-8 --kconfig allmodconfig
Greetings!
Daniel Díaz daniel.diaz@linaro.org
On Thu, Jan 04, 2024 at 01:15:45AM -0600, Daniel Díaz wrote:
Hello!
On 03/01/24 10:10 p. m., Daniel Díaz wrote:
Hello!
On 03/01/24 10:55 a. m., Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
We're seeing a build regression with x86/GCC-8 and allmodconfig:
-----8<----- In file included from /builds/linux/include/linux/string.h:294, from /builds/linux/include/linux/bitmap.h:11, from /builds/linux/include/linux/cpumask.h:12, from /builds/linux/arch/x86/include/asm/paravirt.h:17, from /builds/linux/arch/x86/include/asm/cpuid.h:62, from /builds/linux/arch/x86/include/asm/processor.h:19, from /builds/linux/arch/x86/include/asm/cpufeature.h:5, from /builds/linux/arch/x86/include/asm/thread_info.h:53, from /builds/linux/include/linux/thread_info.h:60, from /builds/linux/include/linux/uio.h:9, from /builds/linux/include/linux/socket.h:8, from /builds/linux/include/uapi/linux/if.h:25, from /builds/linux/net/wireless/nl80211.c:11: In function 'nl80211_set_cqm_rssi.isra.44', inlined from 'nl80211_set_cqm' at /builds/linux/net/wireless/nl80211.c:13000:10: /builds/linux/include/linux/fortify-string.h:57:29: error: '__builtin_memcpy' pointer overflow between offset 36 and size [-1, 9223372036854775807] [-Werror=array-bounds] #define __underlying_memcpy __builtin_memcpy ^ /builds/linux/include/linux/fortify-string.h:648:2: note: in expansion of macro '__underlying_memcpy' __underlying_##op(p, q, __fortify_size); \ ^~~~~~~~~~~~~ /builds/linux/include/linux/fortify-string.h:693:26: note: in expansion of macro '__fortify_memcpy_chk' #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ ^~~~~~~~~~~~~~~~~~~~ /builds/linux/net/wireless/nl80211.c:12939:3: note: in expansion of macro 'memcpy' memcpy(cqm_config->rssi_thresholds, thresholds, ^~~~~~ cc1: all warnings being treated as errors make[5]: *** [/builds/linux/scripts/Makefile.build:243: net/wireless/nl80211.o] Error 1 ----->8-----
This is currently being bisected, so there is more to follow.
Bisection pointed to:
commit 92045aab1bd9bfd73d816e907ea07739c4550b41 Author: Johannes Berg johannes.berg@intel.com Date: Sat Dec 16 05:47:15 2023 +0000
wifi: cfg80211: fix CQM for non-range use commit 7e7efdda6adb385fbdfd6f819d76bc68c923c394 upstream.
Reverting that was not possible, so I reverted 47f3694a4259 first ("wifi: nl80211: fix deadlock in nl80211_set_cqm_rssi (6.6.x)"), but that was not enough. After reverting both 47f3694a4259 and 92045aab1bd9, the build passed again.
Reproducer:
tuxmake --runtime podman --target-arch x86_64 --toolchain gcc-8 --kconfig allmodconfig
Very odd, 6.1 works fine with this same compiler? These changes were in the 6.1.70 release (and the 6.1.66 release) before.
It was also in 6.6.5, before being reverted in 6.6.6, so why is this causing a problem now?
confused,
greg k-h
On Thu, 2024-01-04 at 08:58 +0100, Greg Kroah-Hartman wrote:
We're seeing a build regression with x86/GCC-8 and allmodconfig:
-----8<----- In file included from /builds/linux/include/linux/string.h:294, from /builds/linux/include/linux/bitmap.h:11, from /builds/linux/include/linux/cpumask.h:12, from /builds/linux/arch/x86/include/asm/paravirt.h:17, from /builds/linux/arch/x86/include/asm/cpuid.h:62, from /builds/linux/arch/x86/include/asm/processor.h:19, from /builds/linux/arch/x86/include/asm/cpufeature.h:5, from /builds/linux/arch/x86/include/asm/thread_info.h:53, from /builds/linux/include/linux/thread_info.h:60, from /builds/linux/include/linux/uio.h:9, from /builds/linux/include/linux/socket.h:8, from /builds/linux/include/uapi/linux/if.h:25, from /builds/linux/net/wireless/nl80211.c:11: In function 'nl80211_set_cqm_rssi.isra.44', inlined from 'nl80211_set_cqm' at /builds/linux/net/wireless/nl80211.c:13000:10: /builds/linux/include/linux/fortify-string.h:57:29: error: '__builtin_memcpy' pointer overflow between offset 36 and size [-1, 9223372036854775807] [-Werror=array-bounds]
This partially showed up upstream as well, but it was pretty hard to see, so I think config and this very specific compiler version may be affecting it as well.
Very odd, 6.1 works fine with this same compiler? These changes were in the 6.1.70 release (and the 6.1.66 release) before.
It was also in 6.6.5, before being reverted in 6.6.6, so why is this causing a problem now?
Yeah, it's all a bit weird.
Kees ended up fixing it upstream with commit 172db56d90d2 ("netlink: Return unsigned value for nla_len()") (in net-next), but I cannot actually say that I understand all what's going on here.
johannes
On Thu, 4 Jan 2024 at 13:29, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Thu, Jan 04, 2024 at 01:15:45AM -0600, Daniel Díaz wrote:
Hello!
On 03/01/24 10:10 p. m., Daniel Díaz wrote:
Hello!
On 03/01/24 10:55 a. m., Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
We're seeing a build regression with x86/GCC-8 and allmodconfig:
-----8<----- In file included from /builds/linux/include/linux/string.h:294, from /builds/linux/include/linux/bitmap.h:11, from /builds/linux/include/linux/cpumask.h:12, from /builds/linux/arch/x86/include/asm/paravirt.h:17, from /builds/linux/arch/x86/include/asm/cpuid.h:62, from /builds/linux/arch/x86/include/asm/processor.h:19, from /builds/linux/arch/x86/include/asm/cpufeature.h:5, from /builds/linux/arch/x86/include/asm/thread_info.h:53, from /builds/linux/include/linux/thread_info.h:60, from /builds/linux/include/linux/uio.h:9, from /builds/linux/include/linux/socket.h:8, from /builds/linux/include/uapi/linux/if.h:25, from /builds/linux/net/wireless/nl80211.c:11: In function 'nl80211_set_cqm_rssi.isra.44', inlined from 'nl80211_set_cqm' at /builds/linux/net/wireless/nl80211.c:13000:10: /builds/linux/include/linux/fortify-string.h:57:29: error: '__builtin_memcpy' pointer overflow between offset 36 and size [-1, 9223372036854775807] [-Werror=array-bounds] #define __underlying_memcpy __builtin_memcpy ^ /builds/linux/include/linux/fortify-string.h:648:2: note: in expansion of macro '__underlying_memcpy' __underlying_##op(p, q, __fortify_size); \ ^~~~~~~~~~~~~ /builds/linux/include/linux/fortify-string.h:693:26: note: in expansion of macro '__fortify_memcpy_chk' #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ ^~~~~~~~~~~~~~~~~~~~ /builds/linux/net/wireless/nl80211.c:12939:3: note: in expansion of macro 'memcpy' memcpy(cqm_config->rssi_thresholds, thresholds, ^~~~~~ cc1: all warnings being treated as errors make[5]: *** [/builds/linux/scripts/Makefile.build:243: net/wireless/nl80211.o] Error 1 ----->8-----
This is currently being bisected, so there is more to follow.
Bisection pointed to:
commit 92045aab1bd9bfd73d816e907ea07739c4550b41 Author: Johannes Berg johannes.berg@intel.com Date: Sat Dec 16 05:47:15 2023 +0000
wifi: cfg80211: fix CQM for non-range use commit 7e7efdda6adb385fbdfd6f819d76bc68c923c394 upstream.
Reverting that was not possible, so I reverted 47f3694a4259 first ("wifi: nl80211: fix deadlock in nl80211_set_cqm_rssi (6.6.x)"), but that was not enough. After reverting both 47f3694a4259 and 92045aab1bd9, the build passed again.
Reproducer:
tuxmake --runtime podman --target-arch x86_64 --toolchain gcc-8 --kconfig allmodconfig
Very odd, 6.1 works fine with this same compiler?
It works on 6.1 with the same compiler.
These changes were in the 6.1.70 release (and the 6.1.66 release) before.
It was also in 6.6.5, before being reverted in 6.6.6, so why is this causing a problem now?
It was also noticed on 6.6.5-rc1 git_describe: v6.6.4-135-gb0b05ccdd77d
I have already reported this on a stable mailing list [1] on 6.6.5-rc1.
Please find more details and comments from Arnd [2] and Kees [3].
[1] https://lore.kernel.org/stable/CA+G9fYuL_-Q67t+Y7ST5taYv1XkkoJegH2zBvw_ZUOhF... [2] https://lore.kernel.org/stable/ce99918f-eb6a-4ad7-aa44-9d27c27b6b00@app.fast... [3] https://lore.kernel.org/all/202311301016.84D0010@keescook/
Test results comparison, https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.6.y/build/v6.6.9-...
- Naresh
On Thu, Jan 04, 2024 at 06:09:53PM +0530, Naresh Kamboju wrote:
On Thu, 4 Jan 2024 at 13:29, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Thu, Jan 04, 2024 at 01:15:45AM -0600, Daniel Díaz wrote:
Hello!
On 03/01/24 10:10 p. m., Daniel Díaz wrote:
Hello!
On 03/01/24 10:55 a. m., Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
We're seeing a build regression with x86/GCC-8 and allmodconfig:
-----8<----- In file included from /builds/linux/include/linux/string.h:294, from /builds/linux/include/linux/bitmap.h:11, from /builds/linux/include/linux/cpumask.h:12, from /builds/linux/arch/x86/include/asm/paravirt.h:17, from /builds/linux/arch/x86/include/asm/cpuid.h:62, from /builds/linux/arch/x86/include/asm/processor.h:19, from /builds/linux/arch/x86/include/asm/cpufeature.h:5, from /builds/linux/arch/x86/include/asm/thread_info.h:53, from /builds/linux/include/linux/thread_info.h:60, from /builds/linux/include/linux/uio.h:9, from /builds/linux/include/linux/socket.h:8, from /builds/linux/include/uapi/linux/if.h:25, from /builds/linux/net/wireless/nl80211.c:11: In function 'nl80211_set_cqm_rssi.isra.44', inlined from 'nl80211_set_cqm' at /builds/linux/net/wireless/nl80211.c:13000:10: /builds/linux/include/linux/fortify-string.h:57:29: error: '__builtin_memcpy' pointer overflow between offset 36 and size [-1, 9223372036854775807] [-Werror=array-bounds] #define __underlying_memcpy __builtin_memcpy ^ /builds/linux/include/linux/fortify-string.h:648:2: note: in expansion of macro '__underlying_memcpy' __underlying_##op(p, q, __fortify_size); \ ^~~~~~~~~~~~~ /builds/linux/include/linux/fortify-string.h:693:26: note: in expansion of macro '__fortify_memcpy_chk' #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ ^~~~~~~~~~~~~~~~~~~~ /builds/linux/net/wireless/nl80211.c:12939:3: note: in expansion of macro 'memcpy' memcpy(cqm_config->rssi_thresholds, thresholds, ^~~~~~ cc1: all warnings being treated as errors make[5]: *** [/builds/linux/scripts/Makefile.build:243: net/wireless/nl80211.o] Error 1 ----->8-----
This is currently being bisected, so there is more to follow.
Bisection pointed to:
commit 92045aab1bd9bfd73d816e907ea07739c4550b41 Author: Johannes Berg johannes.berg@intel.com Date: Sat Dec 16 05:47:15 2023 +0000
wifi: cfg80211: fix CQM for non-range use commit 7e7efdda6adb385fbdfd6f819d76bc68c923c394 upstream.
Reverting that was not possible, so I reverted 47f3694a4259 first ("wifi: nl80211: fix deadlock in nl80211_set_cqm_rssi (6.6.x)"), but that was not enough. After reverting both 47f3694a4259 and 92045aab1bd9, the build passed again.
Reproducer:
tuxmake --runtime podman --target-arch x86_64 --toolchain gcc-8 --kconfig allmodconfig
Very odd, 6.1 works fine with this same compiler?
It works on 6.1 with the same compiler.
These changes were in the 6.1.70 release (and the 6.1.66 release) before.
It was also in 6.6.5, before being reverted in 6.6.6, so why is this causing a problem now?
It was also noticed on 6.6.5-rc1 git_describe: v6.6.4-135-gb0b05ccdd77d
I have already reported this on a stable mailing list [1] on 6.6.5-rc1.
Please find more details and comments from Arnd [2] and Kees [3].
[1] https://lore.kernel.org/stable/CA+G9fYuL_-Q67t+Y7ST5taYv1XkkoJegH2zBvw_ZUOhF... [2] https://lore.kernel.org/stable/ce99918f-eb6a-4ad7-aa44-9d27c27b6b00@app.fast... [3] https://lore.kernel.org/all/202311301016.84D0010@keescook/
Test results comparison, https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.6.y/build/v6.6.9-...
Ah, ok, thanks, I forgot about that. All should be good then,
greg k-h
On Wed, Jan 03, 2024 at 05:55:20PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Successfully compiled and installed the kernel on my computer (Acer Aspire E15, Intel Core i3 Haswell). No noticeable regressions.
Tested-by: Bagas Sanjaya bagasdotme@gmail.com
Tried to follow this guide: https://wiki.archlinux.org/title/Kernel/Traditional_compilation to compile it on Crystal Linux based on Arch Linux on a Dell Latitude 7390 laptop with a Intel i5-8350U and did not get it to boot but the same process worked for the stable 6.6.9 kernel, so guess i will just wait for the stable 6.6.10 and try when thats out
Den ons 3 jan. 2024 kl 17:13 skrev Greg Kroah-Hartman gregkh@linuxfoundation.org:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 6.6.10-rc1
Pablo Neira Ayuso pablo@netfilter.org netfilter: nf_tables: skip set commit for deleted/destroyed sets
Léo Lam leo@leolam.fr wifi: nl80211: fix deadlock in nl80211_set_cqm_rssi (6.6.x)
Johannes Berg johannes.berg@intel.com wifi: cfg80211: fix CQM for non-range use
Steven Rostedt (Google) rostedt@goodmis.org tracing: Fix blocked reader of snapshot buffer
Steven Rostedt (Google) rostedt@goodmis.org ftrace: Fix modification of direct_function hash while in use
Steven Rostedt (Google) rostedt@goodmis.org ring-buffer: Fix wake ups when buffer_percent is set to 100
Keith Busch kbusch@kernel.org Revert "nvme-fc: fix race between error recovery and creating association"
Matthew Wilcox (Oracle) willy@infradead.org mm/memory-failure: check the mapcount of the precise page
Matthew Wilcox (Oracle) willy@infradead.org mm/memory-failure: cast index to loff_t before shifting it
Charan Teja Kalla quic_charante@quicinc.com mm: migrate high-order folios in swap cache correctly
Baokun Li libaokun1@huawei.com mm/filemap: avoid buffered read/write race to read inconsistent data
Muhammad Usama Anjum usama.anjum@collabora.com selftests: secretmem: floor the memory size to the multiple of page_size
Sidhartha Kumar sidhartha.kumar@oracle.com maple_tree: do not preallocate nodes for slot stores
Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe
Namjae Jeon linkinjeon@kernel.org ksmbd: fix slab-out-of-bounds in smb_strndup_from_utf16()
David E. Box david.e.box@linux.intel.com platform/x86/intel/pmc: Move GBE LTR ignore to suspend callback
David E. Box david.e.box@linux.intel.com platform/x86/intel/pmc: Allow reenabling LTRs
David E. Box david.e.box@linux.intel.com platform/x86/intel/pmc: Add suspend callback
Christoph Hellwig hch@lst.de block: renumber QUEUE_FLAG_HW_WC
Paolo Abeni pabeni@redhat.com mptcp: fix inconsistent state on fastopen race
Paolo Abeni pabeni@redhat.com mptcp: fix possible NULL pointer dereference on close
Paolo Abeni pabeni@redhat.com mptcp: refactor sndbuf auto-tuning
Helge Deller deller@gmx.de linux/export: Ensure natural alignment of kcrctab array
Helge Deller deller@gmx.de linux/export: Fix alignment for 64-bit ksymtab entries
Arnd Bergmann arnd@arndb.de kexec: select CRYPTO from KEXEC_FILE instead of depending on it
Arnd Bergmann arnd@arndb.de kexec: fix KEXEC_FILE dependencies
Xuan Zhuo xuanzhuo@linux.alibaba.com virtio_ring: fix syncs DMA memory with different direction
Zizhi Wo wozizhi@huawei.com fs: cifs: Fix atime update check
Jeff Layton jlayton@kernel.org client: convert to new timestamp accessors
Jeff Layton jlayton@kernel.org fs: new accessor methods for atime and mtime
Namjae Jeon linkinjeon@kernel.org ksmbd: avoid duplicate opinfo_put() call on error of smb21_lease_break_ack()
Namjae Jeon linkinjeon@kernel.org ksmbd: lazy v2 lease break on smb2_write()
Namjae Jeon linkinjeon@kernel.org ksmbd: send v2 lease break notification for directory
Namjae Jeon linkinjeon@kernel.org ksmbd: downgrade RWH lease caching state to RH for directory
Namjae Jeon linkinjeon@kernel.org ksmbd: set v2 lease capability
Namjae Jeon linkinjeon@kernel.org ksmbd: set epoch in create context v2 lease
Namjae Jeon linkinjeon@kernel.org ksmbd: don't update ->op_state as OPLOCK_STATE_NONE on error
Namjae Jeon linkinjeon@kernel.org ksmbd: move setting SMB2_FLAGS_ASYNC_COMMAND and AsyncId
Namjae Jeon linkinjeon@kernel.org ksmbd: release interim response after sending status pending response
Namjae Jeon linkinjeon@kernel.org ksmbd: move oplock handling after unlock parent dir
Namjae Jeon linkinjeon@kernel.org ksmbd: separately allocate ci per dentry
Zongmin Zhou zhouzongmin@kylinos.cn ksmbd: prevent memory leak on error return
Namjae Jeon linkinjeon@kernel.org ksmbd: fix kernel-doc comment of ksmbd_vfs_kern_path_locked()
Namjae Jeon linkinjeon@kernel.org ksmbd: no need to wait for binded connection termination at logoff
Namjae Jeon linkinjeon@kernel.org ksmbd: add support for surrogate pair conversion
Kangjing Huang huangkangjing@gmail.com ksmbd: fix missing RDMA-capable flag for IPoIB device in ksmbd_rdma_capable_netdev()
Namjae Jeon linkinjeon@kernel.org ksmbd: fix kernel-doc comment of ksmbd_vfs_setxattr()
Namjae Jeon linkinjeon@kernel.org ksmbd: reorganize ksmbd_iov_pin_rsp()
Cheng-Han Wu hank20010209@gmail.com ksmbd: Remove unused field in ksmbd_user struct
Diffstat:
Makefile | 4 +- arch/powerpc/Kconfig | 4 +- arch/riscv/Kconfig | 4 +- arch/s390/Kconfig | 4 +- arch/x86/Kconfig | 4 +- drivers/nvme/host/fc.c | 21 +-- drivers/platform/x86/intel/pmc/adl.c | 9 +- drivers/platform/x86/intel/pmc/cnp.c | 26 ++- drivers/platform/x86/intel/pmc/core.c | 12 +- drivers/platform/x86/intel/pmc/core.h | 7 +- drivers/platform/x86/intel/pmc/mtl.c | 9 +- drivers/platform/x86/intel/pmc/tgl.c | 9 +- drivers/platform/x86/p2sb.c | 178 ++++++++++++++++----- drivers/virtio/virtio_ring.c | 6 +- fs/libfs.c | 41 +++-- fs/smb/client/file.c | 18 ++- fs/smb/client/fscache.h | 6 +- fs/smb/client/inode.c | 17 +- fs/smb/client/smb2ops.c | 6 +- fs/smb/common/smb2pdu.h | 1 + fs/smb/server/connection.c | 16 -- fs/smb/server/ksmbd_work.c | 51 +++--- fs/smb/server/mgmt/user_config.h | 1 - fs/smb/server/oplock.c | 118 ++++++++++++-- fs/smb/server/oplock.h | 8 +- fs/smb/server/smb2misc.c | 15 +- fs/smb/server/smb2ops.c | 9 +- fs/smb/server/smb2pdu.c | 258 ++++++++++++++++-------------- fs/smb/server/transport_rdma.c | 40 +++-- fs/smb/server/unicode.c | 187 ++++++++++++++++------ fs/smb/server/vfs.c | 14 +- fs/smb/server/vfs_cache.c | 30 ++-- fs/smb/server/vfs_cache.h | 9 +- include/linux/blkdev.h | 2 +- include/linux/export-internal.h | 6 +- include/linux/fs.h | 85 ++++++++-- kernel/Kconfig.kexec | 2 + kernel/trace/ftrace.c | 100 ++++++------ kernel/trace/ring_buffer.c | 12 +- kernel/trace/trace.c | 20 ++- lib/maple_tree.c | 11 ++ mm/filemap.c | 9 ++ mm/memory-failure.c | 8 +- mm/migrate.c | 9 +- net/mptcp/protocol.c | 27 +++- net/mptcp/protocol.h | 63 +++++++- net/mptcp/sockopt.c | 5 +- net/mptcp/subflow.c | 29 ++-- net/netfilter/nf_tables_api.c | 2 +- net/wireless/core.h | 1 + net/wireless/nl80211.c | 56 ++++--- tools/testing/radix-tree/maple.c | 2 +- tools/testing/selftests/mm/memfd_secret.c | 3 + 53 files changed, 1070 insertions(+), 524 deletions(-)
On Thu, Jan 04, 2024 at 07:55:02AM +0000, Luna Jernberg wrote:
Tried to follow this guide: https://wiki.archlinux.org/title/Kernel/Traditional_compilation to compile it on Crystal Linux based on Arch Linux on a Dell Latitude 7390 laptop with a Intel i5-8350U and did not get it to boot but the same process worked for the stable 6.6.9 kernel, so guess i will just wait for the stable 6.6.10 and try when thats out
Can you use 'git bisect' to find the offending commit?
thanks,
greg k-h
On 1/3/24 8:55 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Tested-by: Ron Economos re@w6rz.net
Hi Greg,
On 03/01/24 10:25 pm, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
Built and boot tested on x86_64 and aarch64.
Tested-by: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
Thanks, Harshit
thanks,
greg k-h
On Wed, 03 Jan 2024 17:55:20 +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.6: 10 builds: 10 pass, 0 fail 26 boots: 26 pass, 0 fail 106 tests: 106 pass, 0 fail
Linux version: 6.6.10-rc1-g5fd1c89851c4 Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000, tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000, tegra20-ventana, tegra210-p2371-2180, tegra210-p3450-0000, tegra30-cardhu-a04
Tested-by: Jon Hunter jonathanh@nvidia.com
Jon
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my x86_64 and ARM64 test systems. No errors or regressions.
Tested-by: Allen Pais apais@linux.microsoft.com
Thanks.
On Wed, Jan 03, 2024 at 05:55:20PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
Build results: total: 157 pass: 157 fail: 0 Qemu test results: total: 545 pass: 545 fail: 0
Tested-by: Guenter Roeck linux@roeck-us.net
Guenter
2024-01-04 1:55 GMT+09:00, Greg Kroah-Hartman gregkh@linuxfoundation.org:
This is the start of the stable review cycle for the 6.6.10 release. There are 49 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 05 Jan 2024 16:47:49 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.10-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.6.y and the diffstat can be found below.
thanks,
greg k-h
I have tested smbtorture and tests through windows client against ksmbd.
Tested-by: Namjae Jeon linkinjeon@kernel.org
Thanks!
linux-stable-mirror@lists.linaro.org