5.10.259-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainerPATCH 271/342 dm-thin: fix metadata refcount underflow
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
[ Upstream commit 09a65adc7d8bbfce06392cb6d375468e2728ead5 ]
There's a bug in dm-thin in the function rebalance_children. If the internal btree node has one entry, the code tries to copy all btree entries from the node's child to the node itself and then decrement the child's reference count.
If the child node is shared (it has reference count > 1), we won't free it, so there would be two pointers to each of the grandchildren nodes. But the reference counts of the grandchildren is not increased, thus the reference count doesn't match the number of pointers that point to the grandchildren. This results in "device mapper: space map common: unable to decrement block" errors.
Fix this bug by incrementing reference counts on the grandchildren if the btree node is shared.
--- drivers/md/persistent-data/dm-btree-remove.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/md/persistent-data/dm-btree-remove.c +8 -0
@@ -415,12 +415,20 @@ static int rebalance_children(struct shaif (le32_to_cpu (n->header.nr_entries) ==1 ) {struct dm_block *child; +int is_shared;dm_block_t b =value64 (n,0 ); + r =dm_tm_block_is_shared (info->tm, b, &is_shared); +if (r) +return r; + r =dm_tm_read_lock (info->tm, b, &btree_node_validator, &child);if (r)return r; +if (is_shared) +inc_children (info->tm,dm_block_data (child), vt); +memcpy (n,dm_block_data (child),dm_bm_block_size (dm_tm_get_bm (info->tm)));
Greg Kroah-Hartman
maintainerPATCH 272/342 btrfs: fix missing last_unlink_trans update when removing a directory
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 999757231c49376cd1a37308d2c8c4c9932571e1 ]
When removing a directory we are not updating its last_unlink_trans field, which can result in incorrect fsync behaviour in case some one fsyncs the directory after it was removed because it's holding a file descriptor on it.
Example scenario:
mkdir /mnt/dir1
mkdir /mnt/dir1/dir2
mkdir /mnt/dir3
sync -f /mnt
# Do some change to the directory and fsync it. chmod 700 /mnt/dir1
xfs_io -c fsync /mnt/dir1
# Move dir2 out of dir1 so that dir1 becomes empty. mv /mnt/dir1/dir2 /mnt/dir3/
open fd on /mnt/dir1
call rmdir(2) on path "/mnt/dir1"
fsync fd
<trigger power failure>
When attempting to mount the filesystem, the log replay will fail with an -EIO error and dmesg/syslog has the following:
[445771.626482] BTRFS info (device dm-0): first mount of filesystem 0368bbea-6c5e-44b5-b409-09abe496e650 [445771.626486] BTRFS info (device dm-0): using crc32c checksum algorithm [445771.627912] BTRFS info (device dm-0): start tree-log replay [445771.628335] page: refcount:2 mapcount:0 mapping:0000000061443ddc index:0x1d00 pfn:0x7072a5 [445771.629453] memcg:ffff89f400351b00 [445771.629892] aops:btree_aops [btrfs] ino:1 [445771.630737] flags: 0x17fffc00000402a(uptodate|lru|private|writeback|node=0|zone=2|lastcpupid=0x1ffff) [445771.632359] raw: 017fffc00000402a fffff47284d950c8 fffff472907b7c08 ffff89f458e412b8 [445771.633713] raw: 0000000000001d00 ffff89f6c51d1a90 00000002ffffffff ffff89f400351b00 [445771.635029] page dumped because: eb page dump [445771.635825] BTRFS critical (device dm-0): corrupt leaf: root=5 block=30408704 slot=10 ino=258, invalid nlink: has 2 expect no more than 1 for dir [445771.638088] BTRFS info (device dm-0): leaf 30408704 gen 10 total ptrs 17 free space 14878 owner 5 [445771.638091] BTRFS info (device dm-0): refs 4 lock_owner 0 current 3581087 [445771.638094] item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160 [445771.638097] inode generation 3 transid 9 size 16 nbytes 16384 [445771.638098] block group 0 mode 40755 links 1 uid 0 gid 0 [445771.638100] rdev 0 sequence 2 flags 0x0 [445771.638102] atime 1775744884.0 [445771.660056] ctime 1775744885.645502983 [445771.660058] mtime 1775744885.645502983 [445771.660060] otime 1775744884.0 [445771.660062] item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12 [445771.660064] index 0 name_len 2 [445771.660066] item 2 key (256 DIR_ITEM 1843588421) itemoff 16077 itemsize 34 [445771.660068] location key (259 1 0) type 2 [445771.660070] transid 9 data_len 0 name_len 4 [445771.660075] item 3 key (256 DIR_ITEM 2363071922) itemoff 16043 itemsize 34 [445771.660076] location key (257 1 0) type 2 [445771.660077] transid 9 data_len 0 name_len 4 [445771.660078] item 4 key (256 DIR_INDEX 2) itemoff 16009 itemsize 34 [445771.660079] location key (257 1 0) type 2 [445771.660080] transid 9 data_len 0 name_len 4 [445771.660081] item 5 key (256 DIR_INDEX 3) itemoff 15975 itemsize 34 [445771.660082] location key (259 1 0) type 2 [445771.660083] transid 9 data_len 0 name_len 4 [445771.660084] item 6 key (257 INODE_ITEM 0) itemoff 15815 itemsize 160 [445771.660086] inode generation 9 transid 9 size 8 nbytes 0 [445771.660087] block group 0 mode 40777 links 1 uid 0 gid 0 [445771.660088] rdev 0 sequence 2 flags 0x0 [445771.660089] atime 1775744885.641174097 [445771.660090] ctime 1775744885.645502983 [445771.660091] mtime 1775744885.645502983 [445771.660105] otime 1775744885.641174097 [445771.660106] item 7 key (257 INODE_REF 256) itemoff 15801 itemsize 14 [445771.660107] index 2 name_len 4 [445771.660108] item 8 key (257 DIR_ITEM 2676584006) itemoff 15767 itemsize 34 [445771.660109] location key (258 1 0) type 2 [445771.660110] transid 9 data_len 0 name_len 4 [445771.660111] item 9 key (257 DIR_INDEX 2) itemoff 15733 itemsize 34 [445771.660112] location key (258 1 0) type 2 [445771.660113] transid 9 data_len 0 name_len 4 [445771.660114] item 10 key (258 INODE_ITEM 0) itemoff 15573 itemsize 160 [445771.660115] inode generation 9 transid 10 size 0 nbytes 0 [445771.660116] block group 0 mode 40755 links 2 uid 0 gid 0 [445771.660117] rdev 0 sequence 0 flags 0x0 [445771.660118] atime 1775744885.645502983 [445771.660119] ctime 1775744885.645502983 [445771.660120] mtime 1775744885.645502983 [445771.660121] otime 1775744885.645502983 [445771.660122] item 11 key (258 INODE_REF 257) itemoff 15559 itemsize 14 [445771.660123] index 2 name_len 4 [445771.660124] item 12 key (258 INODE_REF 259) itemoff 15545 itemsize 14 [445771.660125] index 2 name_len 4 [445771.660126] item 13 key (259 INODE_ITEM 0) itemoff 15385 itemsize 160 [445771.660127] inode generation 9 transid 10 size 8 nbytes 0 [445771.660128] block group 0 mode 40755 links 1 uid 0 gid 0 [445771.660129] rdev 0 sequence 1 flags 0x0 [445771.660130] atime 1775744885.645502983 [445771.660130] ctime 1775744885.645502983 [445771.660131] mtime 1775744885.645502983 [445771.660132] otime 1775744885.645502983 [445771.660133] item 14 key (259 INODE_REF 256) itemoff 15371 itemsize 14 [445771.660134] index 3 name_len 4 [445771.660135] item 15 key (259 DIR_ITEM 2676584006) itemoff 15337 itemsize 34 [445771.660136] location key (258 1 0) type 2 [445771.660137] transid 10 data_len 0 name_len 4 [445771.660138] item 16 key (259 DIR_INDEX 2) itemoff 15303 itemsize 34 [445771.660139] location key (258 1 0) type 2 [445771.660140] transid 10 data_len 0 name_len 4 [445771.660144] BTRFS error (device dm-0): block=30408704 write time tree block corruption detected [445771.661650] ------------[ cut here ]------------ [445771.662358] WARNING: fs/btrfs/disk-io.c:326 at btree_csum_one_bio+0x217/0x230 [btrfs], CPU#8: mount/3581087 [445771.663588] Modules linked in: btrfs f2fs xfs (...) [445771.671229] CPU: 8 UID: 0 PID: 3581087 Comm: mount Tainted: G W 7.0.0-rc6-btrfs-next-230+ #2 PREEMPT(full) [445771.672575] Tainted: [W]=WARN [445771.672987] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014 [445771.674460] RIP: 0010:btree_csum_one_bio+0x217/0x230 [btrfs] [445771.675222] Code: 89 44 24 (...) [445771.677364] RSP: 0018:ffffd23882247660 EFLAGS: 00010246 [445771.678029] RAX: 0000000000000000 RBX: ffff89f6c51d1a90 RCX: 0000000000000000 [445771.678975] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff89f406020000 [445771.679983] RBP: ffff89f821204000 R08: 0000000000000000 R09: 00000000ffefffff [445771.680905] R10: ffffd23882247448 R11: 0000000000000003 R12: ffffd23882247668 [445771.681978] R13: ffff89f458e40fc0 R14: ffff89f737f4f500 R15: ffff89f737f4f500 [445771.682912] FS: 00007f0447a98840(0000) GS:ffff89fb9771d000(0000) knlGS:0000000000000000 [445771.684393] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [445771.685230] CR2: 00007f0447bf1330 CR3: 000000017cb02002 CR4: 0000000000370ef0 [445771.686273] Call Trace: [445771.686646] <TASK> [445771.686969] btrfs_submit_bbio+0x83f/0x860 [btrfs] [445771.687750] ? write_one_eb+0x28f/0x340 [btrfs] [445771.688428] btree_writepages+0x2e3/0x550 [btrfs] [445771.689180] ? kmem_cache_alloc_noprof+0x12a/0x490 [445771.689963] ? alloc_extent_state+0x19/0x120 [btrfs] [445771.690801] ? kmem_cache_free+0x135/0x380 [445771.691328] ? preempt_count_add+0x69/0xa0 [445771.691831] ? set_extent_bit+0x252/0x8e0 [btrfs] [445771.692468] ? xas_load+0x9/0xc0 [445771.692873] ? xas_find+0x14d/0x1a0 [445771.693304] do_writepages+0xc6/0x160 [445771.693756] filemap_writeback+0xb8/0xe0 [445771.694274] btrfs_write_marked_extents+0x61/0x170 [btrfs] [445771.694999] btrfs_write_and_wait_transaction+0x4e/0xc0 [btrfs] [445771.695818] btrfs_commit_transaction+0x5c8/0xd10 [btrfs] [445771.696530] ? kmem_cache_free+0x135/0x380 [445771.697120] ? release_extent_buffer+0x34/0x160 [btrfs] [445771.697786] btrfs_recover_log_trees+0x7be/0x7e0 [btrfs] [445771.698525] ? __pfx_replay_one_buffer+0x10/0x10 [btrfs] [445771.699206] open_ctree+0x11e5/0x1810 [btrfs] [445771.699776] btrfs_get_tree.cold+0xb/0x162 [btrfs] [445771.700463] ? fscontext_read+0x165/0x180 [445771.701146] ? rw_verify_area+0x50/0x180 [445771.701866] vfs_get_tree+0x25/0xd0 [445771.702491] vfs_cmd_create+0x59/0xe0 [445771.703125] __do_sys_fsconfig+0x303/0x610 [445771.703603] do_syscall_64+0xe9/0xf20 [445771.703974] entry_SYSCALL_64_after_hwframe+0x76/0x7e [445771.704700] RIP: 0033:0x7f0447cbd4aa [445771.705108] Code: 73 01 c3 (...) [445771.707263] RSP: 002b:00007ffc4e528318 EFLAGS: 00000246 ORIG_RAX: 00000000000001af [445771.708107] RAX: ffffffffffffffda RBX: 00005561585d8c20 RCX: 00007f0447cbd4aa [445771.708931] RDX: 0000000000000000 RSI: 0000000000000006 RDI: 0000000000000003 [445771.709744] RBP: 00005561585d9120 R08: 0000000000000000 R09: 0000000000000000 [445771.710674] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 [445771.711477] R13: 00007f0447e4f580 R14: 00007f0447e5126c R15: 00007f0447e36a23 [445771.712277] </TASK> [445771.712541] ---[ end trace 0000000000000000 ]--- [445771.713382] BTRFS error (device dm-0): error while writing out transaction: -5 [445771.714679] BTRFS warning (device dm-0): Skipping commit of aborted transaction. [445771.715562] BTRFS error (device dm-0 state A): Transaction aborted (error -5) [445771.716459] BTRFS: error (device dm-0 state A) in cleanup_transaction:2068: errno=-5 IO failure [445771.717936] BTRFS error (device dm-0 state EA): failed to recover log trees with error: -5 [445771.719681] BTRFS error (device dm-0 state EA): open_ctree failed: -5
The problem is that such a fsync should have result in a fallback to a transaction commit, but that did not happen because through the btrfs_rmdir() we never update the directory's last_unlink_trans field. Any inode that had a link removed must have its last_unlink_trans updated to the ID of transaction used for the operation, otherwise fsync and log replay will not work correctly.
btrfs_rmdir() calls btrfs_unlink_inode() and through that call chain we never call btrfs_record_unlink_dir() in order to update last_unlink_trans. However btrfs_unlink(), which is used for unlinking regular files, calls btrfs_record_unlink_dir() and then calls btrfs_unlink_inode(). So fix this by moving the call to btrfs_record_unlink_dir() from btrfs_unlink() to btrfs_unlink_inode().
A test case for fstests will follow soon.
--- fs/btrfs/inode.c | 2 ++ 1 file changed, 2 insertions(+)
fs/btrfs/inode.c +2 -0
@@ -4178,6 +4178,8 @@ static int btrfs_rmdir(struct inode *dirif (err) goto out; +btrfs_record_unlink_dir (trans,BTRFS_I (dir),BTRFS_I (inode), false); +/* now the directory is empty */ err = btrfs_unlink_inode(trans, root, BTRFS_I(dir), BTRFS_I(d_inode(dentry)), dentry->d_name.name,
Greg Kroah-Hartman
maintainerPATCH 273/342 smb: client: Use FullSessionKey for AES-256 encryption key derivation
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Piyush Sachdeva <[email protected]>
[ Upstream commit 5be7a0cef3229fb3b63a07c0d289daf752545424 ]
When Kerberos authentication is used with AES-256 encryption (AES-256-CCM or AES-256-GCM), the SMB3 encryption and decryption keys must be derived using the full session key (Session.FullSessionKey) rather than just the first 16 bytes (Session.SessionKey).
Per MS-SMB2 section 3.2.5.3.1, when Connection.Dialect is "3.1.1" and Connection.CipherId is AES-256-CCM or AES-256-GCM, Session.FullSessionKey must be set to the full cryptographic key from the GSS authentication context. The encryption and decryption key derivation (SMBC2SCipherKey, SMBS2CCipherKey) must use this FullSessionKey as the KDF input. The signing key derivation continues to use Session.SessionKey (first 16 bytes) in all cases.
Previously, generate_key() hardcoded SMB2_NTLMV2_SESSKEY_SIZE (16) as the HMAC-SHA256 key input length for all derivations. When Kerberos with AES-256 provides a 32-byte session key, the KDF for encryption/decryption was using only the first 16 bytes, producing keys that did not match the server's, causing mount failures with sec=krb5 and require_gcm_256=1.
Add a full_key_size parameter to generate_key() and pass the appropriate size from generate_smb3signingkey():
- Signing: always SMB2_NTLMV2_SESSKEY_SIZE (16 bytes)
- Encryption/Decryption: ses->auth_key.len when AES-256, otherwise 16
Also fix cifs_dump_full_key() to report the actual session key length for AES-256 instead of hardcoded CIFS_SESS_KEY_SIZE, so that userspace tools like Wireshark receive the correct key for decryption.
--- fs/cifs/smb2transport.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-)
fs/cifs/smb2transport.c +26 -10
@@ -305,7 +305,8 @@ out: }static int generate_key (struct cifs_ses *ses,struct kvec label, -struct kvec context,__u8 *key,unsigned int key_size) +struct kvec context,__u8 *key,unsigned int key_size, +unsigned int full_key_size) {unsigned char zero =0x0 ;__u8 i[4 ] = {0 ,0 ,0 ,1 };
@@ -326,7 +327,7 @@ static int generate_key(struct cifs_ses } rc =crypto_shash_setkey (server->secmech.hmacsha256, - ses->auth_key.response,SMB2_NTLMV2_SESSKEY_SIZE ); + ses->auth_key.response, full_key_size);if (rc) {cifs_server_dbg (VFS ,"%s: Could not set with session key\n" , __func__); goto smb3signkey_ret;
@@ -407,10 +408,9 @@ static int generate_smb3signingkey(struct cifs_ses *ses, const struct derivation_triplet *ptriplet) { - int rc; -#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS + unsigned int full_key_size = SMB2_NTLMV2_SESSKEY_SIZE;struct TCP_Server_Info *server = ses->server; -#endif +int rc;/* * All channels use the same encryption/decryption keys but
@@ -426,30 +426,46 @@ generate_smb3signingkey(struct cifs_ses rc =generate_key (ses, ptriplet->signing.label, ptriplet->signing.context,cifs_ses_binding_channel (ses)->signkey, -SMB3_SIGN_KEY_SIZE ); +SMB3_SIGN_KEY_SIZE , +SMB2_NTLMV2_SESSKEY_SIZE );if (rc)return rc; }else { rc =generate_key (ses, ptriplet->signing.label, ptriplet->signing.context, ses->smb3signingkey, -SMB3_SIGN_KEY_SIZE ); +SMB3_SIGN_KEY_SIZE , +SMB2_NTLMV2_SESSKEY_SIZE );if (rc)return rc; +/* +* Per MS-SMB2 3.2.5.3.1, signing key always uses Session.SessionKey +* (first 16 bytes). Encryption/decryption keys use +* Session.FullSessionKey when dialect is 3.1.1 and cipher is +* AES-256-CCM or AES-256-GCM, otherwise Session.SessionKey. +*/ + +if (server->dialect ==SMB311_PROT_ID && + (server->cipher_type ==SMB2_ENCRYPTION_AES256_CCM || + server->cipher_type ==SMB2_ENCRYPTION_AES256_GCM )) + full_key_size = ses->auth_key.len; +memcpy (ses->chans[0 ].signkey, ses->smb3signingkey,SMB3_SIGN_KEY_SIZE ); rc =generate_key (ses, ptriplet->encryption.label, ptriplet->encryption.context, ses->smb3encryptionkey, -SMB3_ENC_DEC_KEY_SIZE ); +SMB3_ENC_DEC_KEY_SIZE , + full_key_size);if (rc)return rc; rc =generate_key (ses, ptriplet->decryption.label, ptriplet->decryption.context, ses->smb3decryptionkey, -SMB3_ENC_DEC_KEY_SIZE ); +SMB3_ENC_DEC_KEY_SIZE , + full_key_size);if (rc)return rc; }
@@ -464,7 +480,7 @@ generate_smb3signingkey(struct cifs_ses &ses->Suid);cifs_dbg (VFS ,"Cipher type %d\n" , server->cipher_type);cifs_dbg (VFS ,"Session Key %*ph\n" , -SMB2_NTLMV2_SESSKEY_SIZE , ses->auth_key.response); + (int )ses->auth_key.len, ses->auth_key.response);cifs_dbg (VFS ,"Signing Key %*ph\n" ,SMB3_SIGN_KEY_SIZE , ses->smb3signingkey); if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
Greg Kroah-Hartman
maintainerPATCH 274/342 mptcp: pm: ADD_ADDR rtx: fix potential data-race
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Matthieu Baerts (NGI0)" <[email protected]>
[ Upstream commit 5cd6e0ad79d2615264f63929f8b457ad97ae550d ]
This mptcp_pm_add_timer() helper is executed as a timer callback in softirq context. To avoid any data races, the socket lock needs to be held with bh_lock_sock().
If the socket is in use, retry again soon after, similar to what is done with the keepalive timer.
--- net/mptcp/pm_netlink.c | 8 ++++++++ 1 file changed, 8 insertions(+)
net/mptcp/pm_netlink.c +8 -0
@@ -226,6 +226,13 @@ static void mptcp_pm_add_timer(struct tiif (!entry->addr.id)return ; +bh_lock_sock (sk); +if (sock_owned_by_user (sk)) { +/* Try again later. */ +sk_reset_timer (sk, timer, jiffies +HZ /20 ); + goto out; + } +if (mptcp_pm_should_add_signal (msk)) {sk_reset_timer (sk, timer, jiffies +TCP_RTO_MAX /8 ); goto out;
@@ -245,6 +252,7 @@ static void mptcp_pm_add_timer(struct tispin_unlock_bh (&msk->pm.lock); out: +bh_unlock_sock (sk);__sock_put (sk); }
Greg Kroah-Hartman
maintainerPATCH 275/342 f2fs: fix incorrect file address mapping when inline inode is unwritten
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongpeng Yang <[email protected]>
[ Upstream commit 68a0178981a0f493295afa29f8880246e561494c ]
When fileinfo->fi_flags does not have the FIEMAP_FLAG_SYNC bit set and inline data has not been persisted yet, the physical address of the extent is calculated incorrectly for unwritten inline inodes.
root@vm:/mnt/f2fs# dd if=/dev/zero of=data.3k bs=3k count=1 root@vm:/mnt/f2fs# f2fs_io fiemap 0 100 data.3k Fiemap: offset = 0 len = 100 logical addr. physical addr. length flags 0 0000000000000000 00000ffffffff16c 0000000000000c00 00000301
This patch fixes the issue by checking if the inode's address is valid. If the inline inode is unwritten, set the physical address to 0 and mark the extent with FIEMAP_EXTENT_UNKNOWN | FIEMAP_EXTENT_DELALLOC flags.
--- fs/f2fs/inline.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
fs/f2fs/inline.c +9 -4
@@ -761,7 +761,7 @@ int f2fs_read_inline_dir(struct file *fiint f2fs_inline_data_fiemap (struct inode *inode,struct fiemap_extent_info *fieinfo,__u64 start,__u64 len) { -__u64 byteaddr, ilen; +__u64 byteaddr =0 , ilen;__u32 flags =FIEMAP_EXTENT_DATA_INLINE |FIEMAP_EXTENT_NOT_ALIGNED |FIEMAP_EXTENT_LAST ;struct node_info ni;
@@ -794,9 +794,14 @@ int f2fs_inline_data_fiemap(struct inodeif (err) goto out; - byteaddr = (__u64 )ni.blk_addr << inode->i_sb->s_blocksize_bits; - byteaddr += (char *)inline_data_addr (inode, ipage) - - (char *)F2FS_INODE (ipage); +if (__is_valid_data_blkaddr (ni.blk_addr)) { + byteaddr = (__u64 )ni.blk_addr << inode->i_sb->s_blocksize_bits; + byteaddr += (char *)inline_data_addr (inode, ipage) - + (char *)F2FS_INODE (ipage); + }else { +f2fs_bug_on (F2FS_I_SB (inode), ni.blk_addr !=NEW_ADDR ); + flags |=FIEMAP_EXTENT_DELALLOC |FIEMAP_EXTENT_UNKNOWN ; + } err =fiemap_fill_next_extent (fieinfo, start, byteaddr, ilen, flags);trace_f2fs_fiemap (inode, start, byteaddr, ilen, flags, err); out:
Greg Kroah-Hartman
maintainerPATCH 276/342 spi: st-ssc4: fix controller deregistration
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit 19857374010d06ca6a2f7c2c53464122eb804df0 ]
Make sure to deregister the controller before disabling underlying resources like clocks during driver unbind.
--- drivers/spi/spi-st-ssc4.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/spi/spi-st-ssc4.c +7 -1
@@ -372,7 +372,7 @@ static int spi_st_probe(struct platform_platform_set_drvdata (pdev, master); - ret =devm_spi_register_master (&pdev->dev, master); + ret =spi_register_master (master);if (ret) {dev_err (&pdev->dev,"Failed to register master\n" ); goto rpm_disable;
@@ -394,10 +394,16 @@ static int spi_st_remove(struct platformstruct spi_master *master =platform_get_drvdata (pdev);struct spi_st *spi_st =spi_master_get_devdata (master); +spi_master_get (master); + +spi_unregister_master (master); +pm_runtime_disable (&pdev->dev);clk_disable_unprepare (spi_st->clk); +spi_master_put (master); +pinctrl_pm_select_sleep_state (&pdev->dev);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 277/342 spi: lantiq-ssc: fix controller deregistration
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit b99206710d032c16b7f8b75e4bc18414d8e4b9f4 ]
Make sure to deregister the controller before releasing underlying resources like clocks during driver unbind.
--- drivers/spi/spi-lantiq-ssc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/spi/spi-lantiq-ssc.c +7 -1
@@ -1003,7 +1003,7 @@ static int lantiq_ssc_probe(struct platf"Lantiq SSC SPI controller (Rev %i, TXFS %u, RXFS %u, DMA %u)\n" , revision, spi->tx_fifo_size, spi->rx_fifo_size, supports_dma); - err =devm_spi_register_master (dev, master); + err =spi_register_master (master);if (err) {dev_err (dev,"failed to register spi_master\n" ); goto err_wq_destroy;
@@ -1027,6 +1027,10 @@ static int lantiq_ssc_remove(struct plat {struct lantiq_ssc_spi *spi =platform_get_drvdata (pdev); +spi_master_get (spi->master); + +spi_unregister_master (spi->master); +lantiq_ssc_writel (spi,0 ,LTQ_SPI_IRNEN );lantiq_ssc_writel (spi,0 ,LTQ_SPI_CLC );rx_fifo_flush (spi);
@@ -1037,6 +1041,8 @@ static int lantiq_ssc_remove(struct platclk_disable_unprepare (spi->spi_clk);clk_put (spi->fpi_clk); +spi_master_put (spi->master); +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 278/342 Bluetooth: fix UAF in l2cap_sock_cleanup_listen() vs l2cap_conn_del()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Safa Karakuş <[email protected]>
[ Upstream commit ab1513597c6cf17cd1ad2a21e3b045421b48e022 ]
bt_accept_dequeue() unlinks a not-yet-accepted child from the parent accept queue and release_sock()s it before returning, so the returned sk has no caller reference and is unlocked.
l2cap_sock_cleanup_listen() walks these children on listening-socket close. A concurrent HCI disconnect drives hci_rx_work -> l2cap_conn_del() which runs l2cap_chan_del() + l2cap_sock_kill() and frees the child sk and its l2cap_chan; cleanup_listen() then uses both:
BUG: KASAN: slab-use-after-free in l2cap_sock_kill
l2cap_sock_kill / l2cap_sock_cleanup_listen / __x64_sys_close
Freed by: l2cap_conn_del -> l2cap_sock_close_cb -> l2cap_sock_killThis is distinct from the two fixes already in this area: commit e83f5e24da741 ("Bluetooth: serialize accept_q access") serialises the accept_q list/poll and takes temporary refs inside bt_accept_dequeue(), and CVE-2025-39860 serialises the userspace close()/accept() race by calling cleanup_listen() under lock_sock() in l2cap_sock_release(). Neither covers l2cap_conn_del() running from hci_rx_work, so this UAF still reproduces on current bluetooth/master.
Take the reference at the source: bt_accept_dequeue() does sock_hold() while sk is still locked, before release_sock(); callers sock_put(). cleanup_listen() pins the chan with l2cap_chan_hold_unless_zero() under a brief child sk lock (serialising vs l2cap_sock_teardown_cb()), drops it before l2cap_chan_lock(), and skips a duplicate l2cap_sock_kill() on SOCK_DEAD. conn->lock is not taken here: cleanup_listen() runs under the parent sk lock and that would invertconn->lock -> chan->lock -> sk_lock (lockdep).
KASAN/SMP: an unprivileged listen/close vs HCI-disconnect race produced 12 use-after-free reports per run before this change; 0, and no lockdep report, over 1600+ raced iterations after it on bluetooth/master.
--- net/bluetooth/af_bluetooth.c | 10 ++++++++ net/bluetooth/l2cap_sock.c | 51 +++++++++++++++++++++++++++++++++++++------ net/bluetooth/rfcomm/sock.c | 9 ++++++- net/bluetooth/sco.c | 9 ++++++- 4 files changed, 70 insertions(+), 9 deletions(-)
net/bluetooth/af_bluetooth.c +10 -0
@@ -237,6 +237,16 @@ restart:if (newsock)sock_graft (sk, newsock); +/* Hand the caller a reference taken while sk is +* still locked. bt_accept_unlink() just dropped +* the accept-queue reference; without this hold a +* concurrent teardown (e.g. l2cap_conn_del() -> +* l2cap_sock_kill()) could free sk between +* release_sock() and the caller using it. Every +* caller drops this with sock_put() when done. +*/ +sock_hold (sk); +release_sock (sk);return sk; }
net/bluetooth/l2cap_sock.c +44 -7
74 lines not on this page · raw message
net/bluetooth/rfcomm/sock.c +8 -1
@@ -190,6 +190,8 @@ static void rfcomm_sock_cleanup_listen(swhile ((sk =bt_accept_dequeue (parent,NULL ))) {rfcomm_sock_close (sk);rfcomm_sock_kill (sk); +/* Drop the reference handed back by bt_accept_dequeue(). */ +sock_put (sk); } parent->sk_state =BT_CLOSED ;
@@ -508,8 +510,13 @@ static int rfcomm_sock_accept(struct soc } nsk =bt_accept_dequeue (sk, newsock); -if (nsk) +if (nsk) { +/* Drop the bridging ref from bt_accept_dequeue(); +* the grafted socket keeps nsk alive from here. +*/ +sock_put (nsk);break ; + }if (!timeo) { err = -EAGAIN ;
net/bluetooth/sco.c +8 -1
@@ -384,6 +384,8 @@ static void sco_sock_cleanup_listen(struwhile ((sk =bt_accept_dequeue (parent,NULL ))) {sco_sock_close (sk);sco_sock_kill (sk); +/* Drop the reference handed back by bt_accept_dequeue(). */ +sock_put (sk); } parent->sk_state =BT_CLOSED ;
@@ -677,8 +679,13 @@ static int sco_sock_accept(struct socket } ch =bt_accept_dequeue (sk, newsock); -if (ch) +if (ch) { +/* Drop the bridging ref from bt_accept_dequeue(); +* the grafted socket keeps ch alive from here. +*/ +sock_put (ch);break ; + }if (!timeo) { err = -EAGAIN ;
Greg Kroah-Hartman
maintainerPATCH 279/342 Bluetooth: hci_qca: Convert timeout from jiffies to ms
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuai Zhang <[email protected]>
[ Upstream commit 375ba7484132662a4a8c7547d088fb6275c00282 ]
Since the timer uses jiffies as its unit rather than ms, the timeout value must be converted from ms to jiffies when configuring the timer. Otherwise, the intended 8s timeout is incorrectly set to approximately 33s.
To improve readability, embed msecs_to_jiffies() directly in the macro definitions and drop the _MS suffix from macros that now yield jiffies
values: MEMDUMP_TIMEOUT, FW_DOWNLOAD_TIMEOUT, IBS_DISABLE_SSR_TIMEOUT, CMD_TRANS_TIMEOUT, and IBS_BTSOC_TX_IDLE_TIMEOUT.
IBS_WAKE_RETRANS_TIMEOUT_MS and IBS_HOST_TX_IDLE_TIMEOUT_MS are intentionally left unchanged. Their values are stored in the struct fields wake_retrans and tx_idle_delay, which hold ms values at runtime and can be modified via debugfs. The msecs_to_jiffies() conversion happens at each call site against the field value, so it cannot be embedded in the macro.
Wake timer depends on commit c347ca17d62a
--- drivers/bluetooth/hci_qca.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-)
drivers/bluetooth/hci_qca.c +16 -17
@@ -46,13 +46,12 @@#define HCI_MAX_IBS_SIZE 10#define IBS_WAKE_RETRANS_TIMEOUT_MS 100 -#define IBS_BTSOC_TX_IDLE_TIMEOUT_MS 200 +#define IBS_BTSOC_TX_IDLE_TIMEOUT msecs_to_jiffies(200)#define IBS_HOST_TX_IDLE_TIMEOUT_MS 2000 -#define CMD_TRANS_TIMEOUT_MS 100 -#define MEMDUMP_TIMEOUT_MS 8000 -#define IBS_DISABLE_SSR_TIMEOUT_MS \ - (MEMDUMP_TIMEOUT_MS + FW_DOWNLOAD_TIMEOUT_MS) -#define FW_DOWNLOAD_TIMEOUT_MS 3000 +#define CMD_TRANS_TIMEOUT msecs_to_jiffies(100) +#define MEMDUMP_TIMEOUT msecs_to_jiffies(8000) +#define FW_DOWNLOAD_TIMEOUT msecs_to_jiffies(3000) +#define IBS_DISABLE_SSR_TIMEOUT (MEMDUMP_TIMEOUT + FW_DOWNLOAD_TIMEOUT)/* susclk rate */ #define SUSCLK_RATE_32KHZ 32768
@@ -1041,7 +1040,7 @@ static void qca_controller_memdump(struc dump_size);queue_delayed_work (qca->workqueue, &qca->ctrl_memdump_timeout, -msecs_to_jiffies (MEMDUMP_TIMEOUT_MS ) +MEMDUMP_TIMEOUT );skb_pull (skb,sizeof (dump_size));
@@ -1309,7 +1308,7 @@ static int qca_set_baudrate(struct hci_dif (hu->serdev)serdev_device_wait_until_sent (hu->serdev, -msecs_to_jiffies (CMD_TRANS_TIMEOUT_MS )); +CMD_TRANS_TIMEOUT );/* Give the controller time to process the request */ if (qca_is_wcn399x (qca_soc_type (hu)))
@@ -1330,8 +1329,8 @@ static inline void host_set_baudrate(strstatic int qca_send_power_pulse (struct hci_uart *hu,bool on) { +int timeout =CMD_TRANS_TIMEOUT ;int ret; -int timeout =msecs_to_jiffies (CMD_TRANS_TIMEOUT_MS );u8 cmd = on ?QCA_WCN3990_POWERON_PULSE :QCA_WCN3990_POWEROFF_PULSE ;/* These power pulses are single byte command which are sent
@@ -1490,7 +1489,7 @@ static void qca_wait_for_dump_collectionstruct qca_data *qca = hu->priv;wait_on_bit_timeout (&qca->flags,QCA_MEMDUMP_COLLECTION , -TASK_UNINTERRUPTIBLE ,MEMDUMP_TIMEOUT_MS ); +TASK_UNINTERRUPTIBLE ,MEMDUMP_TIMEOUT );clear_bit (QCA_MEMDUMP_COLLECTION , &qca->flags); }
@@ -2071,7 +2070,7 @@ static void qca_serdev_remove(struct serstatic void qca_serdev_shutdown (struct device *dev) {int ret; -int timeout =msecs_to_jiffies (CMD_TRANS_TIMEOUT_MS ); +int timeout =CMD_TRANS_TIMEOUT ;struct serdev_device *serdev =to_serdev_device (dev);struct qca_serdev *qcadev =serdev_device_get_drvdata (serdev);struct hci_uart *hu = &qcadev->serdev_hu;
@@ -2129,7 +2128,7 @@ static int __maybe_unused qca_suspend(stbool tx_pending = false;int ret =0 ;u8 cmd; -u32 wait_timeout =0 ; +unsigned long wait_timeout =0 ;set_bit (QCA_SUSPENDING , &qca->flags);
@@ -2150,15 +2149,15 @@ static int __maybe_unused qca_suspend(stif (test_bit (QCA_IBS_DISABLED , &qca->flags) ||test_bit (QCA_SSR_TRIGGERED , &qca->flags)) { wait_timeout =test_bit (QCA_SSR_TRIGGERED , &qca->flags) ? -IBS_DISABLE_SSR_TIMEOUT_MS : -FW_DOWNLOAD_TIMEOUT_MS ; +IBS_DISABLE_SSR_TIMEOUT : +FW_DOWNLOAD_TIMEOUT ;/* QCA_IBS_DISABLED flag is set to true, During FW download * and during memory dump collection. It is reset to false, * After FW download complete. */ wait_on_bit_timeout (&qca->flags,QCA_IBS_DISABLED , -TASK_UNINTERRUPTIBLE ,msecs_to_jiffies (wait_timeout)); +TASK_UNINTERRUPTIBLE , wait_timeout);if (test_bit (QCA_IBS_DISABLED , &qca->flags)) {bt_dev_err (hu->hdev,"SSR or FW download time out" );
@@ -2210,7 +2209,7 @@ static int __maybe_unused qca_suspend(stif (tx_pending) {serdev_device_wait_until_sent (hu->serdev, -msecs_to_jiffies (CMD_TRANS_TIMEOUT_MS )); +CMD_TRANS_TIMEOUT );serial_clock_vote (HCI_IBS_TX_VOTE_CLOCK_OFF , hu); }
@@ -2219,7 +2218,7 @@ static int __maybe_unused qca_suspend(st*/ ret =wait_event_interruptible_timeout (qca->suspend_wait_q, qca->rx_ibs_state ==HCI_IBS_RX_ASLEEP , -msecs_to_jiffies (IBS_BTSOC_TX_IDLE_TIMEOUT_MS )); +IBS_BTSOC_TX_IDLE_TIMEOUT );if (ret ==0 ) { ret = -ETIMEDOUT ; goto error;
Greg Kroah-Hartman
maintainerPATCH 280/342 qed: Use the bitmap API to simplify some functions
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit 5e6c7ccd3ea4b25dd6b4b0363859913f315deacb ]
'cid_map' is a bitmap. So use 'bitmap_zalloc()' to simplify code, improve the semantic and avoid some open-coded arithmetic in allocator arguments.
Also change the corresponding 'kfree()' into 'bitmap_free()' to keep consistency.
Also change some 'memset()' into 'bitmap_zero()' to keep consistency. This is also much less verbose.
Stable-dep-of: 2bccfb8476ca ("qed: fix double free in qed_cxt_tables_alloc()")
--- drivers/net/ethernet/qlogic/qed/qed_cxt.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-)
drivers/net/ethernet/qlogic/qed/qed_cxt.c +5 -19
@@ -1037,12 +1037,12 @@ static void qed_cid_map_free(struct qed_u32 type, vf;for (type =0 ; type <MAX_CONN_TYPES ; type++) { -kfree (p_mngr->acquired[type].cid_map); +bitmap_free (p_mngr->acquired[type].cid_map); p_mngr->acquired[type].max_count =0 ; p_mngr->acquired[type].start_cid =0 ;for (vf =0 ; vf <MAX_NUM_VFS ; vf++) { -kfree (p_mngr->acquired_vf[type][vf].cid_map); +bitmap_free (p_mngr->acquired_vf[type][vf].cid_map); p_mngr->acquired_vf[type][vf].max_count =0 ; p_mngr->acquired_vf[type][vf].start_cid =0 ; }
@@ -1055,15 +1055,10 @@ qed_cid_map_alloc_single(struct qed_hwfnu32 cid_start, u32 cid_count, struct qed_cid_acquired_map *p_map) { - u32 size; - if (!cid_count) return 0; - size =DIV_ROUND_UP (cid_count, -sizeof (unsigned long ) *BITS_PER_BYTE ) * -sizeof (unsigned long ); - p_map->cid_map =kzalloc (size,GFP_KERNEL ); + p_map->cid_map = bitmap_zalloc(cid_count, GFP_KERNEL);if (!p_map->cid_map)return -ENOMEM ;
@@ -1217,7 +1212,6 @@ void qed_cxt_mngr_setup(struct qed_hwfnstruct qed_cid_acquired_map *p_map;struct qed_conn_type_cfg *p_cfg;int type; -u32 len;/* Reset acquired cids */ for (type =0 ; type <MAX_CONN_TYPES ; type++) {
@@ -1226,11 +1220,7 @@ void qed_cxt_mngr_setup(struct qed_hwfn p_cfg = &p_mngr->conn_cfg[type];if (p_cfg->cid_count) { p_map = &p_mngr->acquired[type]; - len =DIV_ROUND_UP (p_map->max_count, -sizeof (unsigned long ) * -BITS_PER_BYTE ) * -sizeof (unsigned long ); -memset (p_map->cid_map,0 , len); +bitmap_zero (p_map->cid_map, p_map->max_count); }if (!p_cfg->cids_per_vf)
@@ -1238,11 +1228,7 @@ void qed_cxt_mngr_setup(struct qed_hwfnfor (vf =0 ; vf <MAX_NUM_VFS ; vf++) { p_map = &p_mngr->acquired_vf[type][vf]; - len =DIV_ROUND_UP (p_map->max_count, -sizeof (unsigned long ) * -BITS_PER_BYTE ) * -sizeof (unsigned long ); -memset (p_map->cid_map,0 , len); +bitmap_zero (p_map->cid_map, p_map->max_count); } } }
Greg Kroah-Hartman
maintainerPATCH 281/342 qed: fix double free in qed_cxt_tables_alloc()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dawei Feng <[email protected]>
[ Upstream commit 2bccfb8476ca5f3548afbd623dc7a6980d4e77de ]
If one of the later PF or VF CID bitmap allocations fails, qed_cid_map_alloc() jumps to cid_map_fail and frees the previously allocated CID bitmaps before returning an error. qed_cxt_tables_alloc() then calls qed_cxt_mngr_free(), which invokes qed_cid_map_free() again.
Fix this by setting each CID bitmap pointer to NULL after bitmap_free() to avoid double free.
The bug was first flagged by an experimental analysis tool we are developing for kernel memory-management bugs while analyzing v6.13-rc1. The tool is still under development and is not yet publicly available. Manual inspection confirms that the bug is still present in v7.1-rc3.
Runtime reproduction was not attempted because exercising the failing allocation path requires device-specific setup.
--- drivers/net/ethernet/qlogic/qed/qed_cxt.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/qlogic/qed/qed_cxt.c +2 -0
@@ -1038,11 +1038,13 @@ static void qed_cid_map_free(struct qed_for (type =0 ; type <MAX_CONN_TYPES ; type++) {bitmap_free (p_mngr->acquired[type].cid_map); + p_mngr->acquired[type].cid_map =NULL ; p_mngr->acquired[type].max_count =0 ; p_mngr->acquired[type].start_cid =0 ;for (vf =0 ; vf <MAX_NUM_VFS ; vf++) {bitmap_free (p_mngr->acquired_vf[type][vf].cid_map); + p_mngr->acquired_vf[type][vf].cid_map =NULL ; p_mngr->acquired_vf[type][vf].max_count =0 ; p_mngr->acquired_vf[type][vf].start_cid =0 ; }
Greg Kroah-Hartman
maintainerPATCH 282/342 net: Remove redundant if statements
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yajun Deng <[email protected]>
[ Upstream commit 1160dfa178eb848327e9dec39960a735f4dc1685 ]
The 'if (dev)' statement already move into dev_{put , hold}, so remove redundant if statements.
Stable-dep-of: e196115ec330 ("netfilter: nf_queue: hold bridge skb->dev while queued")
--- net/batman-adv/bridge_loop_avoidance.c | 6 ++---- net/batman-adv/distributed-arp-table.c | 3 +-- net/batman-adv/gateway_client.c | 3 +-- net/batman-adv/multicast.c | 9 +++------ net/batman-adv/originator.c | 12 ++++-------- net/batman-adv/translation-table.c | 9 +++------ net/can/raw.c | 8 ++------ net/core/dev.c | 6 ++---- net/core/drop_monitor.c | 6 ++---- net/core/dst.c | 6 ++---- net/core/neighbour.c | 15 +++++---------- net/ethtool/netlink.c | 6 ++---- net/ieee802154/nl-phy.c | 3 +-- net/ieee802154/nl802154.c | 3 +-- net/ieee802154/socket.c | 3 +-- net/ipv4/fib_semantics.c | 4 +--- net/ipv4/route.c | 3 +-- net/ipv6/addrconf.c | 6 ++---- net/ipv6/ip6mr.c | 3 +-- net/ipv6/route.c | 3 +-- net/netfilter/nf_queue.c | 24 ++++++++---------------- net/netlabel/netlabel_unlabeled.c | 6 ++---- net/netrom/nr_loopback.c | 3 +-- net/netrom/nr_route.c | 3 +-- net/packet/af_packet.c | 15 +++++---------- net/phonet/af_phonet.c | 3 +-- net/phonet/pn_dev.c | 6 ++---- net/phonet/socket.c | 3 +-- net/sched/act_mirred.c | 6 ++---- net/smc/smc_pnet.c | 3 +-- net/wireless/nl80211.c | 16 +++++----------- net/wireless/scan.c | 3 +-- 32 files changed, 68 insertions(+), 140 deletions(-)
net/batman-adv/bridge_loop_avoidance.c +2 -4
@@ -2402,8 +2402,7 @@ out:if (primary_if)batadv_hardif_put (primary_if); -if (soft_iface) -dev_put (soft_iface); +dev_put (soft_iface);return ret; }
@@ -2640,8 +2639,7 @@ out:if (primary_if)batadv_hardif_put (primary_if); -if (soft_iface) -dev_put (soft_iface); +dev_put (soft_iface);return ret; }
net/batman-adv/distributed-arp-table.c +1 -2
@@ -1045,8 +1045,7 @@ out:if (primary_if)batadv_hardif_put (primary_if); -if (soft_iface) -dev_put (soft_iface); +dev_put (soft_iface);return ret; }
net/batman-adv/gateway_client.c +1 -2
@@ -590,8 +590,7 @@ int batadv_gw_dump(struct sk_buff *msg, out:if (primary_if)batadv_hardif_put (primary_if); -if (soft_iface) -dev_put (soft_iface); +dev_put (soft_iface);return ret; }
net/batman-adv/multicast.c +3 -6
@@ -92,8 +92,7 @@ static struct net_device *batadv_mcast_g upper =netdev_master_upper_dev_get_rcu (upper); }while (upper && !(upper->priv_flags &IFF_EBRIDGE )); -if (upper) -dev_hold (upper); +dev_hold (upper);rcu_read_unlock ();return upper;
@@ -541,8 +540,7 @@ batadv_mcast_mla_softif_get(struct net_d } out: -if (bridge) -dev_put (bridge); +dev_put (bridge);return ret4 + ret6; }
@@ -2386,8 +2384,7 @@ batadv_mcast_netlink_get_primary(struct } out: -if (soft_iface) -dev_put (soft_iface); +dev_put (soft_iface);if (!ret && primary_if) *primary_if = hard_iface;
net/batman-adv/originator.c +4 -8
@@ -823,12 +823,10 @@ int batadv_hardif_neigh_dump(struct sk_b out:if (hardif)batadv_hardif_put (hardif); -if (hard_iface) -dev_put (hard_iface); +dev_put (hard_iface);if (primary_if)batadv_hardif_put (primary_if); -if (soft_iface) -dev_put (soft_iface); +dev_put (soft_iface);return ret; }
@@ -1502,12 +1500,10 @@ int batadv_orig_dump(struct sk_buff *msg out:if (hardif)batadv_hardif_put (hardif); -if (hard_iface) -dev_put (hard_iface); +dev_put (hard_iface);if (primary_if)batadv_hardif_put (primary_if); -if (soft_iface) -dev_put (soft_iface); +dev_put (soft_iface);return ret; }
net/batman-adv/translation-table.c +3 -6
@@ -815,8 +815,7 @@ check_roaming: out:if (in_hardif)batadv_hardif_put (in_hardif); -if (in_dev) -dev_put (in_dev); +dev_put (in_dev);if (tt_local)batadv_tt_local_entry_put (tt_local);if (tt_global)
@@ -1331,8 +1330,7 @@ int batadv_tt_local_dump(struct sk_buff out:if (primary_if)batadv_hardif_put (primary_if); -if (soft_iface) -dev_put (soft_iface); +dev_put (soft_iface); cb->args[0 ] = bucket; cb->args[1 ] = idx;
@@ -2252,8 +2250,7 @@ int batadv_tt_global_dump(struct sk_buff out:if (primary_if)batadv_hardif_put (primary_if); -if (soft_iface) -dev_put (soft_iface); +dev_put (soft_iface); cb->args[0 ] = bucket; cb->args[1 ] = idx;
net/can/raw.c +2 -6
@@ -601,9 +601,7 @@ static int raw_setsockopt(struct socket ro->count = count; out_fil: -if (dev) -dev_put (dev); - +dev_put (dev);release_sock (sk);rtnl_unlock ();
@@ -647,9 +645,7 @@ static int raw_setsockopt(struct socket ro->err_mask = err_mask; out_err: -if (dev) -dev_put (dev); - +dev_put (dev);release_sock (sk);rtnl_unlock ();
net/core/dev.c +2 -4
@@ -906,8 +906,7 @@ struct net_device *dev_get_by_name(strucrcu_read_lock (); dev =dev_get_by_name_rcu (net, name); -if (dev) -dev_hold (dev); +dev_hold (dev);rcu_read_unlock ();return dev; }
@@ -980,8 +979,7 @@ struct net_device *dev_get_by_index(strurcu_read_lock (); dev =dev_get_by_index_rcu (net, ifindex); -if (dev) -dev_hold (dev); +dev_hold (dev);rcu_read_unlock ();return dev; }
net/core/drop_monitor.c +2 -4
@@ -854,8 +854,7 @@ net_dm_hw_metadata_copy(const struct dev } hw_metadata->input_dev = metadata->input_dev; -if (hw_metadata->input_dev) -dev_hold (hw_metadata->input_dev); +dev_hold (hw_metadata->input_dev);return hw_metadata;
@@ -871,8 +870,7 @@ free_hw_metadata:static void net_dm_hw_metadata_free (const struct devlink_trap_metadata *hw_metadata) { -if (hw_metadata->input_dev) -dev_put (hw_metadata->input_dev); +dev_put (hw_metadata->input_dev);kfree (hw_metadata->fa_cookie);kfree (hw_metadata->trap_name);kfree (hw_metadata->trap_group_name);
net/core/dst.c +2 -4
@@ -49,8 +49,7 @@ void dst_init(struct dst_entry *dst, str unsigned short flags) { dst->dev = dev; -if (dev) -dev_hold (dev); +dev_hold (dev); dst->ops = ops;dst_init_metrics (dst, dst_default_metrics.metrics, true); dst->expires =0UL ;
@@ -111,8 +110,7 @@ struct dst_entry *dst_destroy(struct dst#endif if (dst->ops->destroy) dst->ops->destroy (dst); -if (dst->dev) -dev_put (dst->dev); +dev_put (dst->dev);lwtstate_put (dst->lwtstate);
net/core/neighbour.c +5 -10
@@ -743,12 +743,10 @@ struct pneigh_entry * pneigh_lookup(struwrite_pnet (&n->net, net);memcpy (n->key, pkey, key_len); n->dev = dev; -if (dev) -dev_hold (dev); +dev_hold (dev);if (tbl->pconstructor && tbl->pconstructor (n)) { -if (dev) -dev_put (dev); +dev_put (dev);kfree (n); n =NULL ; goto out;
@@ -780,8 +778,7 @@ int pneigh_delete(struct neigh_table *tbwrite_unlock_bh (&tbl->lock);if (tbl->pdestructor) tbl->pdestructor (n); -if (n->dev) -dev_put (n->dev); +dev_put (n->dev);kfree (n);return 0 ; }
@@ -814,8 +811,7 @@ static int pneigh_ifdown_and_unlock(stru n->next =NULL ;if (tbl->pdestructor) tbl->pdestructor (n); -if (n->dev) -dev_put (n->dev); +dev_put (n->dev);kfree (n); }return -ENOENT ;
@@ -1677,8 +1673,7 @@ void neigh_parms_release(struct neigh_talist_del (&parms->list); parms->dead =1 ;write_unlock_bh (&tbl->lock); -if (parms->dev) -dev_put (parms->dev); +dev_put (parms->dev);call_rcu (&parms->rcu_head, neigh_rcu_free_parms); }EXPORT_SYMBOL (neigh_parms_release);
net/ethtool/netlink.c +2 -4
@@ -356,8 +356,7 @@ static int ethnl_default_doit(struct sk_ ops->cleanup_data (reply_data);genlmsg_end (rskb, reply_payload); -if (req_info->dev) -dev_put (req_info->dev); +dev_put (req_info->dev);kfree (reply_data);kfree (req_info);return genlmsg_reply (rskb, info);
@@ -369,8 +368,7 @@ err_cleanup:if (ops->cleanup_data) ops->cleanup_data (reply_data); err_dev: -if (req_info->dev) -dev_put (req_info->dev); +dev_put (req_info->dev);kfree (reply_data);kfree (req_info);return ret;
net/ieee802154/nl-phy.c +1 -2
@@ -340,8 +340,7 @@ nla_put_failure: out_dev:wpan_phy_put (phy); out: -if (dev) -dev_put (dev); +dev_put (dev);return rc; }
net/ieee802154/nl802154.c +1 -2
@@ -2230,8 +2230,7 @@ static void nl802154_post_doit(const strif (ops->internal_flags &NL802154_FLAG_NEED_WPAN_DEV ) {struct wpan_dev *wpan_dev = info->user_ptr[1 ]; -if (wpan_dev->netdev) -dev_put (wpan_dev->netdev); +dev_put (wpan_dev->netdev); }else {dev_put (info->user_ptr[1 ]); }
net/ieee802154/socket.c +1 -2
@@ -41,8 +41,7 @@ ieee802154_get_dev(struct net *net, consieee802154_devaddr_to_raw (hwaddr, addr->extended_addr);rcu_read_lock (); dev =dev_getbyhwaddr_rcu (net,ARPHRD_IEEE802154 , hwaddr); -if (dev) -dev_hold (dev); +dev_hold (dev);rcu_read_unlock ();break ;case IEEE802154_ADDR_SHORT :
net/ipv4/fib_semantics.c +1 -3
@@ -210,9 +210,7 @@ static void rt_fibinfo_free_cpus(structvoid fib_nh_common_release (struct fib_nh_common *nhc) { -if (nhc->nhc_dev) -dev_put (nhc->nhc_dev); - +dev_put (nhc->nhc_dev);lwtstate_put (nhc->nhc_lwtstate);rt_fibinfo_free_cpus (nhc->nhc_pcpu_rth_output);rt_fibinfo_free (&nhc->nhc_rth_input);
net/ipv4/route.c +1 -2
@@ -2782,8 +2782,7 @@ struct dst_entry *ipv4_blackhole_route(s new->output = dst_discard_out; new->dev = net->loopback_dev; -if (new->dev) -dev_hold (new->dev); +dev_hold (new->dev); rt->rt_is_input = ort->rt_is_input; rt->rt_iif = ort->rt_iif;
net/ipv6/addrconf.c +2 -4
@@ -693,8 +693,7 @@ static int inet6_netconf_get_devconf(str errout:if (in6_dev)in6_dev_put (in6_dev); -if (dev) -dev_put (dev); +dev_put (dev);return err; }
@@ -5469,8 +5468,7 @@ static int inet6_rtm_getaddr(struct sk_b errout_ifa:in6_ifa_put (ifa); errout: -if (dev) -dev_put (dev); +dev_put (dev);if (fillargs.netnsid >=0 )put_net (tgt_net);
net/ipv6/ip6mr.c +1 -2
@@ -561,8 +561,7 @@ static int pim6_rcv(struct sk_buff *skb)read_lock (&mrt_lock);if (reg_vif_num >=0 ) reg_dev = mrt->vif_table[reg_vif_num].dev; -if (reg_dev) -dev_hold (reg_dev); +dev_hold (reg_dev);read_unlock (&mrt_lock);if (!reg_dev)
net/ipv6/route.c +1 -2
@@ -3521,8 +3521,7 @@ out:fib_nh_common_release (&fib6_nh->nh_common); fib6_nh->nh_common.nhc_pcpu_rth_output =NULL ; fib6_nh->fib_nh_lws =NULL ; -if (dev) -dev_put (dev); +dev_put (dev); }return err;
net/netfilter/nf_queue.c +8 -16
@@ -60,18 +60,14 @@ static void nf_queue_entry_release_refs(struct nf_hook_state *state = &entry->state;/* Release those devices we held, or Alexey will kill me. */ -if (state->in) -dev_put (state->in); -if (state->out) -dev_put (state->out); +dev_put (state->in); +dev_put (state->out);if (state->sk)nf_queue_sock_put (state->sk);#if IS_ENABLED (CONFIG_BRIDGE_NETFILTER ) -if (entry->physin) -dev_put (entry->physin); -if (entry->physout) -dev_put (entry->physout); +dev_put (entry->physin); +dev_put (entry->physout);#endif }
@@ -107,16 +103,12 @@ bool nf_queue_entry_get_refs(struct nf_qif (state->sk && !refcount_inc_not_zero (&state->sk->sk_refcnt))return false; -if (state->in) -dev_hold (state->in); -if (state->out) -dev_hold (state->out); +dev_hold (state->in); +dev_hold (state->out);#if IS_ENABLED (CONFIG_BRIDGE_NETFILTER ) -if (entry->physin) -dev_hold (entry->physin); -if (entry->physout) -dev_hold (entry->physout); +dev_hold (entry->physin); +dev_hold (entry->physout);#endif return true; }
net/netlabel/netlabel_unlabeled.c +2 -4
@@ -492,8 +492,7 @@ static int netlbl_unlhsh_remove_addr4(stnetlbl_af4list_audit_addr (audit_buf,1 , (dev !=NULL ? dev->name :NULL ), addr->s_addr, mask->s_addr); -if (dev !=NULL ) -dev_put (dev); +dev_put (dev);if (entry !=NULL &&security_secid_to_secctx (entry->secid, &secctx, &secctx_len) ==0 ) {
@@ -553,8 +552,7 @@ static int netlbl_unlhsh_remove_addr6(stnetlbl_af6list_audit_addr (audit_buf,1 , (dev !=NULL ? dev->name :NULL ), addr, mask); -if (dev !=NULL ) -dev_put (dev); +dev_put (dev);if (entry !=NULL &&security_secid_to_secctx (entry->secid, &secctx, &secctx_len) ==0 ) {
net/netrom/nr_loopback.c +1 -2
@@ -59,8 +59,7 @@ static void nr_loopback_timer(struct timif (dev ==NULL ||nr_rx_frame (skb, dev) ==0 )kfree_skb (skb); -if (dev !=NULL ) -dev_put (dev); +dev_put (dev);if (!skb_queue_empty (&loopback_queue) && !nr_loopback_running ())mod_timer (&loopback_timer, jiffies +10 );
net/netrom/nr_route.c +1 -2
@@ -573,8 +573,7 @@ struct net_device *nr_dev_first(void)if (first ==NULL ||strncmp (dev->name, first->name,3 ) <0 ) first = dev; } -if (first) -dev_hold (first); +dev_hold (first);rcu_read_unlock ();return first;
net/packet/af_packet.c +5 -10
@@ -249,8 +249,7 @@ static struct net_device *packet_cached_rcu_read_lock (); dev =rcu_dereference (po->cached_dev); -if (likely (dev)) -dev_hold (dev); +dev_hold (dev);rcu_read_unlock ();return dev;
@@ -3103,8 +3102,7 @@ static int packet_snd(struct socket *soc out_free:kfree_skb (skb); out_unlock: -if (dev) -dev_put (dev); +dev_put (dev); out:return err; }
@@ -3241,8 +3239,7 @@ static int packet_do_bind(struct sock *s } } -if (dev) -dev_hold (dev); +dev_hold (dev); proto_curr = po->prot_hook.type; dev_curr = po->prot_hook.dev;
@@ -3279,8 +3276,7 @@ static int packet_do_bind(struct sock *spacket_cached_dev_assign (po, dev); } } -if (dev_curr) -dev_put (dev_curr); +dev_put (dev_curr);if (proto ==0 || !need_rehook) goto out_unlock;
@@ -4216,8 +4212,7 @@ static int packet_notifier(struct notifiif (msg ==NETDEV_UNREGISTER ) {packet_cached_dev_reset (po);WRITE_ONCE (po->ifindex,-1 ); -if (po->prot_hook.dev) -dev_put (po->prot_hook.dev); +dev_put (po->prot_hook.dev); po->prot_hook.dev =NULL ; }spin_unlock (&po->bind_lock);
net/phonet/af_phonet.c +1 -2
@@ -275,8 +275,7 @@ int pn_skb_send(struct sock *sk, struct drop:kfree_skb (skb); -if (dev) -dev_put (dev); +dev_put (dev);return err; }EXPORT_SYMBOL (pn_skb_send);
net/phonet/pn_dev.c +2 -4
@@ -122,8 +122,7 @@ struct net_device *phonet_device_get(strbreak ; dev =NULL ; } -if (dev) -dev_hold (dev); +dev_hold (dev);rcu_read_unlock ();return dev; }
@@ -411,8 +410,7 @@ struct net_device *phonet_route_output(s daddr >>=2 ;rcu_read_lock (); dev =rcu_dereference (routes->table[daddr]); -if (dev) -dev_hold (dev); +dev_hold (dev);rcu_read_unlock ();if (!dev)
net/phonet/socket.c +1 -2
@@ -379,8 +379,7 @@ static int pn_socket_ioctl(struct socket saddr =PN_NO_ADDR ;release_sock (sk); -if (dev) -dev_put (dev); +dev_put (dev);if (saddr ==PN_NO_ADDR )return -EHOSTUNREACH ;
net/sched/act_mirred.c +2 -4
@@ -79,8 +79,7 @@ static void tcf_mirred_release(struct tc/* last reference to action, no need to lock */ dev =rcu_dereference_protected (m->tcfm_dev,1 ); -if (dev) -dev_put (dev); +dev_put (dev); }static const struct nla_policy mirred_policy[TCA_MIRRED_MAX +1 ] = {
@@ -181,8 +180,7 @@ static int tcf_mirred_init(struct net *n mac_header_xmit =dev_is_mac_header_xmit (dev); dev =rcu_replace_pointer (m->tcfm_dev, dev,lockdep_is_held (&m->tcf_lock)); -if (dev) -dev_put (dev); +dev_put (dev); m->tcfm_mac_header_xmit = mac_header_xmit; } goto_ch =tcf_action_set_ctrlact (*a, parm->action, goto_ch);
net/smc/smc_pnet.c +1 -2
@@ -395,8 +395,7 @@ static int smc_pnet_add_eth(struct smc_preturn 0 ; out_put: -if (ndev) -dev_put (ndev); +dev_put (ndev);return rc; }
net/wireless/nl80211.c +5 -11
@@ -6356,8 +6356,7 @@ static int nl80211_set_station(struct sk err =rdev_change_station (rdev, dev, mac_addr, ¶ms); out_put_vlan: -if (params.vlan) -dev_put (params.vlan); +dev_put (params.vlan);return err; }
@@ -6592,8 +6591,7 @@ static int nl80211_new_station(struct sk err =rdev_add_station (rdev, dev, mac_addr, ¶ms); -if (params.vlan) -dev_put (params.vlan); +dev_put (params.vlan);return err; }
@@ -8308,8 +8306,7 @@ static int nl80211_trigger_scan(struct s goto out_free;nl80211_send_scan_start (rdev, wdev); -if (wdev->netdev) -dev_hold (wdev->netdev); +dev_hold (wdev->netdev);return 0 ;
@@ -14661,9 +14658,7 @@ static int nl80211_pre_doit(const structreturn -ENETDOWN ; } -if (dev) -dev_hold (dev); - +dev_hold (dev); info->user_ptr[0 ] = rdev; }
@@ -14677,8 +14672,7 @@ static void nl80211_post_doit(const struif (ops->internal_flags &NL80211_FLAG_NEED_WDEV ) {struct wireless_dev *wdev = info->user_ptr[1 ]; -if (wdev->netdev) -dev_put (wdev->netdev); +dev_put (wdev->netdev); }else {dev_put (info->user_ptr[1 ]); }
net/wireless/scan.c +1 -2
@@ -1057,8 +1057,7 @@ void ___cfg80211_scan_done(struct cfg802 }#endif -if (wdev->netdev) -dev_put (wdev->netdev); +dev_put (wdev->netdev);kfree (rdev->int_scan_req); rdev->int_scan_req =NULL ;
Greg Kroah-Hartman
maintainerPATCH 283/342 netfilter: nf_queue: hold bridge skb->dev while queued
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoze Xie <[email protected]>
[ Upstream commit e196115ec330a18de415bdb9f5071aa9f08e53ce ]
br_pass_frame_up() rewrites skb->dev from the ingress port to the bridge master before queueing bridge LOCAL_IN packets. NFQUEUE only holds references on state.in/out and bridge physdevs, so a queued bridge packet can retain a freed bridge master in skb->dev until reinjection.
When the verdict is reinjected later, br_netif_receive_skb() re-enters the receive path with skb->dev still pointing at the freed bridge master, triggering a use-after-free.
Store skb->dev in the queue entry, hold a reference on it for the queue lifetime, and use the saved device when dropping queued packets during NETDEV_DOWN handling.
--- include/net/netfilter/nf_queue.h | 1 + net/netfilter/nf_queue.c | 4 +++- net/netfilter/nfnetlink_queue.c | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-)
include/net/netfilter/nf_queue.h +1 -0
@@ -12,6 +12,7 @@struct nf_queue_entry {struct list_head list;struct sk_buff *skb; +struct net_device *skb_dev;unsigned int id;unsigned int hook_index;/* index in hook_entries->hook[] */ #if IS_ENABLED (CONFIG_BRIDGE_NETFILTER )
net/netfilter/nf_queue.c +3 -1
@@ -60,6 +60,7 @@ static void nf_queue_entry_release_refs(struct nf_hook_state *state = &entry->state;/* Release those devices we held, or Alexey will kill me. */ +dev_put (entry->skb_dev);dev_put (state->in);dev_put (state->out);if (state->sk)
@@ -103,6 +104,7 @@ bool nf_queue_entry_get_refs(struct nf_qif (state->sk && !refcount_inc_not_zero (&state->sk->sk_refcnt))return false; +dev_hold (entry->skb_dev);dev_hold (state->in);dev_hold (state->out);
@@ -204,11 +206,11 @@ static int __nf_queue(struct sk_buff *sk *entry = (struct nf_queue_entry ) { .skb = skb, + .skb_dev = skb->dev, .state = *state, .hook_index = index, .size =sizeof (*entry) + route_key_size, }; -__nf_queue_entry_init_physdevs (entry);if (!nf_queue_entry_get_refs (entry)) {
net/netfilter/nfnetlink_queue.c +2 -0
@@ -911,6 +911,8 @@ dev_cmp(struct nf_queue_entry *entry, unif (physinif == ifindex || physoutif == ifindex)return 1 ;#endif +if (entry->skb_dev && entry->skb_dev->ifindex == ifindex) +return 1 ;if (entry->state.in)if (entry->state.in->ifindex == ifindex)return 1 ;
Greg Kroah-Hartman
maintainerPATCH 284/342 Bluetooth: Consolidate code around sk_alloc into a helper function
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 6bfa273e533d7b25eee3d74e28a7fe8e6a8e7a93 ]
This consolidates code around sk_alloc into bt_sock_alloc which does take care of common initialization.
Stable-dep-of: e83f5e24da74 ("Bluetooth: serialize accept_q access")
--- include/net/bluetooth/bluetooth.h | 2 ++ net/bluetooth/af_bluetooth.c | 21 +++++++++++++++++++++ net/bluetooth/bnep/sock.c | 10 +--------- net/bluetooth/hci_sock.c | 10 ++-------- net/bluetooth/l2cap_sock.c | 10 +--------- net/bluetooth/rfcomm/sock.c | 13 +++---------- net/bluetooth/sco.c | 10 +--------- 7 files changed, 31 insertions(+), 45 deletions(-)
include/net/bluetooth/bluetooth.h +2 -0
@@ -314,6 +314,8 @@ int bt_sock_register(int proto, const svoid bt_sock_unregister (int proto);void bt_sock_link (struct bt_sock_list *l,struct sock *s);void bt_sock_unlink (struct bt_sock_list *l,struct sock *s); +struct sock *bt_sock_alloc (struct net *net,struct socket *sock, +struct proto *prot,int proto,gfp_t prio,int kern);int bt_sock_recvmsg (struct socket *sock,struct msghdr *msg,size_t len,int flags); int bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg,
net/bluetooth/af_bluetooth.c +21 -0
@@ -138,6 +138,27 @@ static int bt_sock_create(struct net *nereturn err; } +struct sock *bt_sock_alloc (struct net *net,struct socket *sock, +struct proto *prot,int proto,gfp_t prio,int kern) +{ +struct sock *sk; + + sk =sk_alloc (net,PF_BLUETOOTH , prio, prot, kern); +if (!sk) +return NULL ; + +sock_init_data (sock, sk); +INIT_LIST_HEAD (&bt_sk (sk)->accept_q); + +sock_reset_flag (sk,SOCK_ZAPPED ); + + sk->sk_protocol = proto; + sk->sk_state =BT_OPEN ; + +return sk; +} +EXPORT_SYMBOL (bt_sock_alloc); +void bt_sock_link (struct bt_sock_list *l,struct sock *sk) {write_lock (&l->lock);
net/bluetooth/bnep/sock.c +1 -9
@@ -204,21 +204,13 @@ static int bnep_sock_create(struct net *if (sock->type !=SOCK_RAW )return -ESOCKTNOSUPPORT ; - sk =sk_alloc (net,PF_BLUETOOTH ,GFP_ATOMIC , &bnep_proto, kern); + sk =bt_sock_alloc (net, sock, &bnep_proto, protocol,GFP_ATOMIC , kern);if (!sk)return -ENOMEM ; -sock_init_data (sock, sk); - sock->ops = &bnep_sock_ops; - sock->state =SS_UNCONNECTED ; -sock_reset_flag (sk,SOCK_ZAPPED ); - - sk->sk_protocol = protocol; - sk->sk_state =BT_OPEN ; -bt_sock_link (&bnep_sk_list, sk);return 0 ; }
net/bluetooth/hci_sock.c +2 -8
@@ -2091,18 +2091,12 @@ static int hci_sock_create(struct net *n sock->ops = &hci_sock_ops; - sk =sk_alloc (net,PF_BLUETOOTH ,GFP_ATOMIC , &hci_sk_proto, kern); + sk =bt_sock_alloc (net, sock, &hci_sk_proto, protocol,GFP_ATOMIC , + kern);if (!sk)return -ENOMEM ; -sock_init_data (sock, sk); - -sock_reset_flag (sk,SOCK_ZAPPED ); - - sk->sk_protocol = protocol; - sock->state =SS_UNCONNECTED ; - sk->sk_state =BT_OPEN ; sk->sk_destruct = hci_sock_destruct;bt_sock_link (&hci_sk_list, sk);
net/bluetooth/l2cap_sock.c +1 -9
@@ -1901,21 +1901,13 @@ static struct sock *l2cap_sock_alloc(strstruct sock *sk;struct l2cap_chan *chan; - sk =sk_alloc (net,PF_BLUETOOTH , prio, &l2cap_proto, kern); + sk =bt_sock_alloc (net, sock, &l2cap_proto, proto, prio, kern);if (!sk)return NULL ; -sock_init_data (sock, sk); -INIT_LIST_HEAD (&bt_sk (sk)->accept_q); - sk->sk_destruct = l2cap_sock_destruct; sk->sk_sndtimeo =L2CAP_CONN_TIMEOUT ; -sock_reset_flag (sk,SOCK_ZAPPED ); - - sk->sk_protocol = proto; - sk->sk_state =BT_OPEN ; - chan =l2cap_chan_create ();if (!chan) {sk_free (sk);
net/bluetooth/rfcomm/sock.c +3 -10
@@ -280,18 +280,16 @@ static struct proto rfcomm_proto = { .obj_size = sizeof(struct rfcomm_pinfo) }; -static struct sock *rfcomm_sock_alloc (struct net *net,struct socket *sock,int proto,gfp_t prio,int kern) +static struct sock *rfcomm_sock_alloc (struct net *net,struct socket *sock, +int proto,gfp_t prio,int kern) {struct rfcomm_dlc *d;struct sock *sk; - sk =sk_alloc (net,PF_BLUETOOTH , prio, &rfcomm_proto, kern); + sk =bt_sock_alloc (net, sock, &rfcomm_proto, proto, prio, kern);if (!sk)return NULL ; -sock_init_data (sock, sk); -INIT_LIST_HEAD (&bt_sk (sk)->accept_q); - d =rfcomm_dlc_alloc (prio);if (!d) {sk_free (sk);
@@ -310,11 +308,6 @@ static struct sock *rfcomm_sock_alloc(st sk->sk_sndbuf =RFCOMM_MAX_CREDITS *RFCOMM_DEFAULT_MTU *10 ; sk->sk_rcvbuf =RFCOMM_MAX_CREDITS *RFCOMM_DEFAULT_MTU *10 ; -sock_reset_flag (sk,SOCK_ZAPPED ); - - sk->sk_protocol = proto; - sk->sk_state =BT_OPEN ; -bt_sock_link (&rfcomm_sk_list, sk);BT_DBG ("sk %p" , sk);
net/bluetooth/sco.c +1 -9
@@ -491,21 +491,13 @@ static struct sock *sco_sock_alloc(struc {struct sock *sk; - sk =sk_alloc (net,PF_BLUETOOTH , prio, &sco_proto, kern); + sk =bt_sock_alloc (net, sock, &sco_proto, proto, prio, kern);if (!sk)return NULL ; -sock_init_data (sock, sk); -INIT_LIST_HEAD (&bt_sk (sk)->accept_q); - sk->sk_destruct = sco_sock_destruct; sk->sk_sndtimeo =SCO_CONN_TIMEOUT ; -sock_reset_flag (sk,SOCK_ZAPPED ); - - sk->sk_protocol = proto; - sk->sk_state =BT_OPEN ; -sco_pi (sk)->setting =BT_VOICE_CVSD_16BIT ;bt_sock_link (&sco_sk_list, sk);
Greg Kroah-Hartman
maintainerPATCH 285/342 Bluetooth: Init sk_peer_* on bt_sock_alloc
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 464c702fb9374ff8f3f816f24fb7ac719dd20e1e ]
This makes sure peer information is always available via sock when using bt_sock_alloc.
Stable-dep-of: e83f5e24da74 ("Bluetooth: serialize accept_q access")
--- net/bluetooth/af_bluetooth.c | 24 ++++++++++++++++++++++++ net/bluetooth/hidp/sock.c | 10 +--------- net/bluetooth/l2cap_sock.c | 19 ------------------- 3 files changed, 25 insertions(+), 28 deletions(-)
net/bluetooth/af_bluetooth.c +24 -0
@@ -155,6 +155,14 @@ struct sock *bt_sock_alloc(struct net *n sk->sk_protocol = proto; sk->sk_state =BT_OPEN ; +/* Init peer information so it can be properly monitored */ +if (!kern) { +spin_lock (&sk->sk_peer_lock); + sk->sk_peer_pid =get_pid (task_tgid (current)); + sk->sk_peer_cred =get_current_cred (); +spin_unlock (&sk->sk_peer_lock); + } +return sk; }EXPORT_SYMBOL (bt_sock_alloc);
@@ -177,6 +185,9 @@ EXPORT_SYMBOL(bt_sock_unlink);void bt_accept_enqueue (struct sock *parent,struct sock *sk,bool bh) { +const struct cred *old_cred; +struct pid *old_pid; +BT_DBG ("parent %p, sk %p" , parent, sk);sock_hold (sk);
@@ -189,6 +200,19 @@ void bt_accept_enqueue(struct sock *parelist_add_tail (&bt_sk (sk)->accept_q, &bt_sk (parent)->accept_q);bt_sk (sk)->parent = parent; +/* Copy credentials from parent since for incoming connections the +* socket is allocated by the kernel. +*/ +spin_lock (&sk->sk_peer_lock); + old_pid = sk->sk_peer_pid; + old_cred = sk->sk_peer_cred; + sk->sk_peer_pid =get_pid (parent->sk_peer_pid); + sk->sk_peer_cred =get_cred (parent->sk_peer_cred); +spin_unlock (&sk->sk_peer_lock); + +put_pid (old_pid); +put_cred (old_cred); +if (bh)bh_unlock_sock (sk);else
net/bluetooth/hidp/sock.c +1 -9
@@ -255,21 +255,13 @@ static int hidp_sock_create(struct net *if (sock->type !=SOCK_RAW )return -ESOCKTNOSUPPORT ; - sk =sk_alloc (net,PF_BLUETOOTH ,GFP_ATOMIC , &hidp_proto, kern); + sk =bt_sock_alloc (net, sock, &hidp_proto, protocol,GFP_ATOMIC , kern);if (!sk)return -ENOMEM ; -sock_init_data (sock, sk); - sock->ops = &hidp_sock_ops; - sock->state =SS_UNCONNECTED ; -sock_reset_flag (sk,SOCK_ZAPPED ); - - sk->sk_protocol = protocol; - sk->sk_state =BT_OPEN ; -bt_sock_link (&hidp_sk_list, sk);return 0 ;
net/bluetooth/l2cap_sock.c +0 -19
@@ -177,21 +177,6 @@ done:return err; } -static void l2cap_sock_init_pid (struct sock *sk) -{ -struct l2cap_chan *chan =l2cap_pi (sk)->chan; - -/* Only L2CAP_MODE_EXT_FLOWCTL ever need to access the PID in order to -* group the channels being requested. -*/ -if (chan->mode !=L2CAP_MODE_EXT_FLOWCTL ) -return ; - -spin_lock (&sk->sk_peer_lock); - sk->sk_peer_pid =get_pid (task_tgid (current)); -spin_unlock (&sk->sk_peer_lock); -} -static int l2cap_sock_connect (struct socket *sock,struct sockaddr *addr,int alen,int flags) {
@@ -267,8 +252,6 @@ static int l2cap_sock_connect(struct soc chan->mode != L2CAP_MODE_EXT_FLOWCTL) chan->mode =L2CAP_MODE_LE_FLOWCTL ; -l2cap_sock_init_pid (sk); - err =l2cap_chan_connect (chan, la.l2_psm,__le16_to_cpu (la.l2_cid), &la.l2_bdaddr, la.l2_bdaddr_type);if (err)
@@ -324,8 +307,6 @@ static int l2cap_sock_listen(struct sock goto done; } -l2cap_sock_init_pid (sk); - sk->sk_max_ack_backlog = backlog; sk->sk_ack_backlog =0 ;
Greg Kroah-Hartman
maintainerPATCH 286/342 Bluetooth: serialize accept_q access
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiexun Wang <[email protected]>
[ Upstream commit e83f5e24da741fa9405aeeff00b08c5ee7c37b88 ]
bt_sock_poll() walks the accept queue without synchronization, while child teardown can unlink the same socket and drop its last reference. The unsynchronized accept queue walk has existed since the initial Bluetooth import.
Protect accept_q with a dedicated lock for queue updates and polling. Also rework bt_accept_dequeue() to take temporary child references under the queue lock before dropping it and locking the child socket.
--- include/net/bluetooth/bluetooth.h | 1 net/bluetooth/af_bluetooth.c | 87 ++++++++++++++++++++++++++++---------- 2 files changed, 66 insertions(+), 22 deletions(-)
include/net/bluetooth/bluetooth.h +1 -0
@@ -291,6 +291,7 @@ void baswap(bdaddr_t *dst, const bdaddr_struct bt_sock {struct sock sk;struct list_head accept_q; +spinlock_t accept_q_lock;/* protects accept_q */ struct sock *parent;unsigned long flags;void (*skb_msg_name)(struct sk_buff *,void *,int *);
net/bluetooth/af_bluetooth.c +65 -22
163 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 287/342 net: hsr: defer node table free until after RCU readers
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
[ Upstream commit aaec7096f9961eb223b5b149abe9495525c205d9 ]
HSR node-list and node-status generic-netlink operations run under rcu_read_lock(). They walk hsr->node_db through hsr_get_next_node() and hsr_get_node_data(), but RTM_DELLINK teardown removes the same node table with plain list_del() and frees each node immediately.
That lets a generic-netlink reader hold a struct hsr_node pointer across hsr_dellink(). In a KASAN build, widening the reader window after hsr_get_next_node() obtains the node reproduces a slab-use-after-free when the reader copies node->macaddress_A; the freeing stack is hsr_del_nodes() from hsr_dellink().
Use list_del_rcu() and defer the free through the existing hsr_free_node_rcu() callback. This matches the lifetime rule used by the HSR prune paths, which already delete nodes with list_del_rcu() and call_rcu().
--- net/hsr/hsr_framereg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/hsr/hsr_framereg.c +4 -2
@@ -123,8 +123,10 @@ void hsr_del_nodes(struct list_head *nodstruct hsr_node *node;struct hsr_node *tmp; -list_for_each_entry_safe (node, tmp, node_db, mac_list) -kfree (node); +list_for_each_entry_safe (node, tmp, node_db, mac_list) { +list_del_rcu (&node->mac_list); +kfree_rcu (node, rcu_head); + } } void prp_handle_san_frame(bool san, enum hsr_port_type port,
Greg Kroah-Hartman
maintainerPATCH 288/342 ice: fix VF queue configuration with low MTU values
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jose Ignacio Tornos Martinez <[email protected]>
[ Upstream commit 3ba4dd024d26372733d1c02e13e076c6016e3320 ]
The ice driver's VF queue configuration validation rejects databuffer_size values below 1024 bytes, which prevents VFs from using MTU values below 871 bytes.
The iavf driver calculates databuffer_size based on the MTU using:
databuffer_size = ALIGN(MTU + LIBETH_RX_LL_LEN, 128)
where LIBETH_RX_LL_LEN = 26 (ETH_HLEN + 2*VLAN_HLEN + ETH_FCS_LEN).
For MTU values below 871:
MTU 870: 870 + 26 = 896, aligned to 128 = 896 (< 1024, rejected) MTU 871: 871 + 26 = 897, aligned to 128 = 1024 (>= 1024, accepted)
The 1024-byte minimum seems unnecessarily restrictive, because the hardware supports databuffer_size as low as 128 bytes (the alignment boundary), which should allow MTU values down to the standard minimum of 68 bytes.
I haven't found the reason why the limit was configured in the commit 9c7dd7566d18 ("ice: add validation in OP_CONFIG_VSI_QUEUES VF message"), so with no more information and since it is working, change the minimum databuffer_size validation from 1024 to 128 bytes to allow standard low MTU values while still preventing invalid configurations.
--- drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +1 -1
@@ -2990,7 +2990,7 @@ static int ice_vc_cfg_qs_msg(struct ice_if (qpi->rxq.databuffer_size !=0 && (qpi->rxq.databuffer_size > ((16 *1024 ) -128 ) || - qpi->rxq.databuffer_size <1024 )) { + qpi->rxq.databuffer_size <128 )) { v_ret =VIRTCHNL_STATUS_ERR_PARAM ; goto error_param; }
Greg Kroah-Hartman
maintainerPATCH 289/342 use less confusing names for iov_iter direction initializers
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
[ Upstream commit de4eda9de2d957ef2d6a8365a01e26a435e958cb ]
READ/WRITE proved to be actively confusing - the meanings are "data destination, as used with read(2)" and "data source, as used with write(2)", but people keep interpreting those as "we read data from it" and "we write data to it", i.e. exactly the wrong way.
Call them ITER_DEST and ITER_SOURCE - at least that is harder to misinterpret...
Stable-dep-of: a4f0b001782b ("vsock/virtio: reset connection on receiving queue overflow")
--- arch/x86/kernel/cpu/microcode/intel.c | 2 +- crypto/testmgr.c | 4 ++-- drivers/block/drbd/drbd_main.c | 2 +- drivers/block/drbd/drbd_receiver.c | 2 +- drivers/block/loop.c | 14 +++++++------- drivers/block/nbd.c | 10 +++++----- drivers/char/random.c | 4 ++-- drivers/fsi/fsi-sbefifo.c | 6 +++--- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 2 +- drivers/isdn/mISDN/l1oip_core.c | 2 +- drivers/misc/vmw_vmci/vmci_queue_pair.c | 6 +++--- drivers/net/ppp/ppp_generic.c | 2 +- drivers/nvme/host/tcp.c | 4 ++-- drivers/nvme/target/io-cmd-file.c | 4 ++-- drivers/nvme/target/tcp.c | 2 +- drivers/scsi/sg.c | 2 +- drivers/target/iscsi/iscsi_target_util.c | 4 ++-- drivers/target/target_core_file.c | 2 +- drivers/usb/usbip/usbip_common.c | 2 +- drivers/vhost/net.c | 6 +++--- drivers/vhost/scsi.c | 10 +++++----- drivers/vhost/vhost.c | 6 +++--- drivers/vhost/vringh.c | 4 ++-- drivers/vhost/vsock.c | 4 ++-- drivers/xen/pvcalls-back.c | 8 ++++---- fs/9p/vfs_addr.c | 4 ++-- fs/9p/vfs_dir.c | 2 +- fs/9p/xattr.c | 4 ++-- fs/afs/cmservice.c | 2 +- fs/afs/internal.h | 4 ++-- fs/afs/rxrpc.c | 12 ++++++------ fs/aio.c | 4 ++-- fs/ceph/file.c | 4 ++-- fs/cifs/connect.c | 6 +++--- fs/cifs/file.c | 4 ++-- fs/cifs/smb2ops.c | 4 ++-- fs/cifs/transport.c | 6 +++--- fs/nfsd/vfs.c | 4 ++-- fs/ocfs2/cluster/tcp.c | 2 +- fs/orangefs/inode.c | 6 +++--- fs/read_write.c | 12 ++++++------ fs/seq_file.c | 2 +- fs/splice.c | 10 +++++----- include/linux/uio.h | 3 +++ mm/madvise.c | 2 +- mm/page_io.c | 2 +- mm/process_vm_access.c | 2 +- net/9p/client.c | 2 +- net/bluetooth/6lowpan.c | 2 +- net/bluetooth/a2mp.c | 2 +- net/bluetooth/smp.c | 2 +- net/ipv4/tcp.c | 2 +- net/netfilter/ipvs/ip_vs_sync.c | 2 +- net/smc/smc_clc.c | 6 +++--- net/socket.c | 12 ++++++------ net/sunrpc/socklib.c | 6 +++--- net/sunrpc/svcsock.c | 4 ++-- net/sunrpc/xprtsock.c | 6 +++--- net/tipc/topsrv.c | 2 +- net/tls/tls_device.c | 4 ++-- net/xfrm/espintcp.c | 2 +- security/keys/keyctl.c | 4 ++-- 62 files changed, 138 insertions(+), 135 deletions(-)
arch/x86/kernel/cpu/microcode/intel.c +1 -1
@@ -940,7 +940,7 @@ static enum ucode_state request_microcod kvec.iov_base = (void *)firmware->data; kvec.iov_len = firmware->size; -iov_iter_kvec (&iter,WRITE , &kvec,1 , firmware->size); +iov_iter_kvec (&iter,ITER_SOURCE , &kvec,1 , firmware->size); ret =generic_load_microcode (cpu, &iter);release_firmware (firmware);
crypto/testmgr.c +2 -2
@@ -747,7 +747,7 @@ static int build_cipher_test_sglists(strstruct iov_iter input;int err; -iov_iter_kvec (&input,WRITE , inputs, nr_inputs, src_total_len); +iov_iter_kvec (&input,ITER_SOURCE , inputs, nr_inputs, src_total_len); err = build_test_sglist(&tsgls->src, cfg->src_divs, alignmask, cfg->inplace ? max(dst_total_len, src_total_len) :
@@ -1130,7 +1130,7 @@ static int build_hash_sglist(struct test kv.iov_base = (void *)vec->plaintext; kv.iov_len = vec->psize; -iov_iter_kvec (&input,WRITE , &kv,1 , vec->psize); +iov_iter_kvec (&input,ITER_SOURCE , &kv,1 , vec->psize);return build_test_sglist (tsgl, cfg->src_divs, alignmask, vec->psize, &input, divs); }
drivers/block/drbd/drbd_main.c +1 -1
@@ -1857,7 +1857,7 @@ int drbd_send(struct drbd_connection *co/* THINK if (signal_pending) return ... ? */ -iov_iter_kvec (&msg.msg_iter,WRITE , &iov,1 , size); +iov_iter_kvec (&msg.msg_iter,ITER_SOURCE , &iov,1 , size);if (sock == connection->data.socket) {rcu_read_lock ();
drivers/block/drbd/drbd_receiver.c +1 -1
@@ -505,7 +505,7 @@ static int drbd_recv_short(struct socketstruct msghdr msg = { .msg_flags = (flags ? flags :MSG_WAITALL |MSG_NOSIGNAL ) }; -iov_iter_kvec (&msg.msg_iter,READ , &iov,1 , size); +iov_iter_kvec (&msg.msg_iter,ITER_DEST , &iov,1 , size);return sock_recvmsg (sock, &msg, msg.msg_flags); }
drivers/block/loop.c +7 -7
@@ -265,7 +265,7 @@ static int lo_write_bvec(struct file *fistruct iov_iter i;ssize_t bw; -iov_iter_bvec (&i,WRITE , bvec,1 , bvec->bv_len); +iov_iter_bvec (&i,ITER_SOURCE , bvec,1 , bvec->bv_len);file_start_write (file); bw =vfs_iter_write (file, &i, ppos,0 );
@@ -343,7 +343,7 @@ static int lo_read_simple(struct loop_dessize_t len;rq_for_each_segment (bvec, rq, iter) { -iov_iter_bvec (&i,READ , &bvec,1 , bvec.bv_len); +iov_iter_bvec (&i,ITER_DEST , &bvec,1 , bvec.bv_len); len =vfs_iter_read (lo->lo_backing_file, &i, &pos,0 );if (len <0 )return len;
@@ -384,7 +384,7 @@ static int lo_read_transfer(struct loop_ b.bv_offset =0 ; b.bv_len = bvec.bv_len; -iov_iter_bvec (&i,READ , &b,1 , b.bv_len); +iov_iter_bvec (&i,ITER_DEST , &b,1 , b.bv_len); len =vfs_iter_read (lo->lo_backing_file, &i, &pos,0 );if (len <0 ) { ret = len;
@@ -508,7 +508,7 @@ static void lo_rw_aio_complete(struct ki }static int lo_rw_aio (struct loop_device *lo,struct loop_cmd *cmd, -loff_t pos,bool rw) +loff_t pos,int rw) {struct iov_iter iter;struct req_iterator rq_iter;
@@ -566,7 +566,7 @@ static int lo_rw_aio(struct loop_deviceif (cmd->css)kthread_associate_blkcg (cmd->css); -if (rw ==WRITE ) +if (rw ==ITER_SOURCE ) ret =call_write_iter (file, &cmd->iocb, &iter);else ret =call_read_iter (file, &cmd->iocb, &iter);
@@ -611,14 +611,14 @@ static int do_req_filebacked(struct loopif (lo->transfer)return lo_write_transfer (lo, rq, pos);else if (cmd->use_aio) -return lo_rw_aio (lo, cmd, pos,WRITE ); +return lo_rw_aio (lo, cmd, pos,ITER_SOURCE );else return lo_write_simple (lo, rq, pos);case REQ_OP_READ :if (lo->transfer)return lo_read_transfer (lo, rq, pos);else if (cmd->use_aio) -return lo_rw_aio (lo, cmd, pos,READ ); +return lo_rw_aio (lo, cmd, pos,ITER_DEST );else return lo_read_simple (lo, rq, pos);default :
drivers/block/nbd.c +5 -5
@@ -543,7 +543,7 @@ static int nbd_send_cmd(struct nbd_devicu32 nbd_cmd_flags =0 ;int sent = nsock->sent, skip =0 ; -iov_iter_kvec (&from,WRITE , &iov,1 ,sizeof (request)); +iov_iter_kvec (&from,ITER_SOURCE , &iov,1 ,sizeof (request)); type =req_to_nbd_cmd_type (req);if (type ==U32_MAX )
@@ -629,7 +629,7 @@ send_pages:dev_dbg (nbd_to_dev (nbd),"request %p: sending %d bytes data\n" , req, bvec.bv_len); -iov_iter_bvec (&from,WRITE , &bvec,1 , bvec.bv_len); +iov_iter_bvec (&from,ITER_SOURCE , &bvec,1 , bvec.bv_len);if (skip) {if (skip >=iov_iter_count (&from)) { skip -=iov_iter_count (&from);
@@ -681,7 +681,7 @@ static int nbd_read_reply(struct nbd_devint result; reply->magic =0 ; -iov_iter_kvec (&to,READ , &iov,1 ,sizeof (*reply)); +iov_iter_kvec (&to,ITER_DEST , &iov,1 ,sizeof (*reply)); result =sock_xmit (nbd, index,0 , &to,MSG_WAITALL ,NULL );if (result <0 ) {if (!nbd_disconnected (nbd->config))
@@ -758,7 +758,7 @@ static struct nbd_cmd *nbd_handle_reply(struct iov_iter to;rq_for_each_segment (bvec, req, iter) { -iov_iter_bvec (&to,READ , &bvec,1 , bvec.bv_len); +iov_iter_bvec (&to,ITER_DEST , &bvec,1 , bvec.bv_len); result =sock_xmit (nbd, index,0 , &to,MSG_WAITALL ,NULL );if (result <0 ) { dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n",
@@ -1206,7 +1206,7 @@ static void send_disconnects(struct nbd_for (i =0 ; i < config->num_connections; i++) {struct nbd_sock *nsock = config->socks[i]; -iov_iter_kvec (&from,WRITE , &iov,1 ,sizeof (request)); +iov_iter_kvec (&from,ITER_SOURCE , &iov,1 ,sizeof (request));mutex_lock (&nsock->tx_lock); ret =sock_xmit (nbd, i,1 , &from,0 ,NULL );if (ret <0 )
drivers/char/random.c +2 -2
@@ -1237,7 +1237,7 @@ SYSCALL_DEFINE3(getrandom, char __user *return ret; } - ret =import_single_range (READ , ubuf, len, &iov, &iter); + ret =import_single_range (ITER_DEST , ubuf, len, &iov, &iter);if (unlikely (ret))return ret;return get_random_bytes_user (&iter);
@@ -1348,7 +1348,7 @@ static long random_ioctl(struct file *f,return -EINVAL ;if (get_user (len, p++))return -EFAULT ; - ret =import_single_range (WRITE , p, len, &iov, &iter); + ret =import_single_range (ITER_SOURCE , p, len, &iov, &iter);if (unlikely (ret))return ret; ret =write_pool_user (&iter);
drivers/fsi/fsi-sbefifo.c +3 -3
@@ -640,7 +640,7 @@ static void sbefifo_collect_async_ffdc(s } ffdc_iov.iov_base = ffdc; ffdc_iov.iov_len =SBEFIFO_MAX_FFDC_SIZE ; -iov_iter_kvec (&ffdc_iter,READ , &ffdc_iov,1 ,SBEFIFO_MAX_FFDC_SIZE ); +iov_iter_kvec (&ffdc_iter,ITER_DEST , &ffdc_iov,1 ,SBEFIFO_MAX_FFDC_SIZE ); cmd[0 ] =cpu_to_be32 (2 ); cmd[1 ] =cpu_to_be32 (SBEFIFO_CMD_GET_SBE_FFDC ); rc =sbefifo_do_command (sbefifo, cmd,2 , &ffdc_iter);
@@ -737,7 +737,7 @@ int sbefifo_submit(struct device *dev, c rbytes = (*resp_len) *sizeof (__be32); resp_iov.iov_base = response; resp_iov.iov_len = rbytes; -iov_iter_kvec (&resp_iter,READ , &resp_iov,1 , rbytes); +iov_iter_kvec (&resp_iter,ITER_DEST , &resp_iov,1 , rbytes);/* Perform the command */ mutex_lock (&sbefifo->lock);
@@ -817,7 +817,7 @@ static ssize_t sbefifo_user_read(struct/* Prepare iov iterator */ resp_iov.iov_base = buf; resp_iov.iov_len = len; -iov_iter_init (&resp_iter,READ , &resp_iov,1 , len); +iov_iter_init (&resp_iter,ITER_DEST , &resp_iov,1 , len);/* Perform the command */ mutex_lock (&sbefifo->lock);
drivers/infiniband/ulp/rtrs/rtrs-clt.c +1 -1
@@ -902,7 +902,7 @@ static void rtrs_clt_init_req(struct rtr req->need_inv_comp = false; req->inv_errno =0 ; -iov_iter_kvec (&iter,WRITE , vec,1 , usr_len); +iov_iter_kvec (&iter,ITER_SOURCE , vec,1 , usr_len); len =_copy_from_iter (req->iu->buf, usr_len, &iter);WARN_ON (len != usr_len);
drivers/isdn/mISDN/l1oip_core.c +1 -1
@@ -706,7 +706,7 @@ l1oip_socket_thread(void *data)printk (KERN_DEBUG "%s: socket created and open\n" , __func__);while (!signal_pending (current)) { -iov_iter_kvec (&msg.msg_iter,READ , &iov,1 , recvbuf_size); +iov_iter_kvec (&msg.msg_iter,ITER_DEST , &iov,1 , recvbuf_size); recvlen =sock_recvmsg (socket, &msg,0 );if (recvlen >0 ) {l1oip_socket_parse (hc, &sin_rx, recvbuf, recvlen);
drivers/misc/vmw_vmci/vmci_queue_pair.c +3 -3
@@ -3028,7 +3028,7 @@ ssize_t vmci_qpair_enqueue(struct vmci_qif (!qpair || !buf)return VMCI_ERROR_INVALID_ARGS ; -iov_iter_kvec (&from,WRITE , &v,1 , buf_size); +iov_iter_kvec (&from,ITER_SOURCE , &v,1 , buf_size);qp_lock (qpair);
@@ -3072,7 +3072,7 @@ ssize_t vmci_qpair_dequeue(struct vmci_qif (!qpair || !buf)return VMCI_ERROR_INVALID_ARGS ; -iov_iter_kvec (&to,READ , &v,1 , buf_size); +iov_iter_kvec (&to,ITER_DEST , &v,1 , buf_size);qp_lock (qpair);
@@ -3117,7 +3117,7 @@ ssize_t vmci_qpair_peek(struct vmci_qp *if (!qpair || !buf)return VMCI_ERROR_INVALID_ARGS ; -iov_iter_kvec (&to,READ , &v,1 , buf_size); +iov_iter_kvec (&to,ITER_DEST , &v,1 , buf_size);qp_lock (qpair);
drivers/net/ppp/ppp_generic.c +1 -1
@@ -490,7 +490,7 @@ static ssize_t ppp_read(struct file *fil ret = -EFAULT ; iov.iov_base = buf; iov.iov_len = count; -iov_iter_init (&to,READ , &iov,1 , count); +iov_iter_init (&to,ITER_DEST , &iov,1 , count);if (skb_copy_datagram_iter (skb,0 , &to, skb->len)) goto outf; ret = skb->len;
drivers/nvme/host/tcp.c +2 -2
@@ -296,7 +296,7 @@ static inline void nvme_tcp_advance_req(if (!iov_iter_count (&req->iter) && req->data_sent < req->data_len) { req->curr_bio = req->curr_bio->bi_next; -nvme_tcp_init_iter (req,WRITE ); +nvme_tcp_init_iter (req,ITER_SOURCE ); } }
@@ -766,7 +766,7 @@ static int nvme_tcp_recv_data(struct nvmnvme_tcp_init_recv_ctx (queue);return -EIO ; } -nvme_tcp_init_iter (req,READ ); +nvme_tcp_init_iter (req,ITER_DEST ); }/* we can read only from what is left in this bio */
drivers/nvme/target/io-cmd-file.c +2 -2
@@ -111,10 +111,10 @@ static ssize_t nvmet_file_submit_bvec(stif (req->cmd->rw.control &cpu_to_le16 (NVME_RW_FUA )) ki_flags |=IOCB_DSYNC ; call_iter = req->ns->file->f_op->write_iter; - rw =WRITE ; + rw =ITER_SOURCE ; }else { call_iter = req->ns->file->f_op->read_iter; - rw =READ ; + rw =ITER_DEST ; }iov_iter_bvec (&iter, rw, req->f.bvec, nr_segs, count);
drivers/nvme/target/tcp.c +1 -1
@@ -339,7 +339,7 @@ static void nvmet_tcp_build_pdu_iovec(st sg_offset =0 ; } -iov_iter_bvec (&cmd->recv_msg.msg_iter,READ , cmd->iov, +iov_iter_bvec (&cmd->recv_msg.msg_iter,ITER_DEST , cmd->iov, nr_pages, cmd->pdu_len); }
drivers/scsi/sg.c +1 -1
@@ -1753,7 +1753,7 @@ sg_start_req(Sg_request *srp, unsigned cSg_scatter_hold *rsv_schp = &sfp->reserve;struct request_queue *q = sfp->parentdp->device->request_queue;struct rq_map_data *md, map_data; -int rw = hp->dxfer_direction ==SG_DXFER_TO_DEV ?WRITE :READ ; +int rw = hp->dxfer_direction ==SG_DXFER_TO_DEV ?ITER_SOURCE :ITER_DEST ;unsigned char *long_cmdp =NULL ; SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp,
drivers/target/iscsi/iscsi_target_util.c +2 -2
@@ -1247,7 +1247,7 @@ int rx_data(return -1 ;memset (&msg,0 ,sizeof (struct msghdr )); -iov_iter_kvec (&msg.msg_iter,READ , iov, iov_count, data); +iov_iter_kvec (&msg.msg_iter,ITER_DEST , iov, iov_count, data);while (msg_data_left (&msg)) { rx_loop =sock_recvmsg (conn->sock, &msg,MSG_WAITALL );
@@ -1283,7 +1283,7 @@ int tx_data(memset (&msg,0 ,sizeof (struct msghdr )); -iov_iter_kvec (&msg.msg_iter,WRITE , iov, iov_count, data); +iov_iter_kvec (&msg.msg_iter,ITER_SOURCE , iov, iov_count, data);while (msg_data_left (&msg)) {int tx_loop =sock_sendmsg (conn->sock, &msg);
drivers/target/target_core_file.c +1 -1
@@ -480,7 +480,7 @@ fd_execute_write_same(struct se_cmd *cmd len += se_dev->dev_attrib.block_size; } -iov_iter_bvec (&iter,WRITE , bvec, nolb, len); +iov_iter_bvec (&iter,ITER_SOURCE , bvec, nolb, len); ret =vfs_iter_write (fd_dev->fd_file, &iter, &pos,0 );kfree (bvec);
drivers/usb/usbip/usbip_common.c +1 -1
@@ -309,7 +309,7 @@ int usbip_recv(struct socket *sock, voidif (!sock || !buf || !size)return -EINVAL ; -iov_iter_kvec (&msg.msg_iter,READ , &iov,1 , size); +iov_iter_kvec (&msg.msg_iter,ITER_DEST , &iov,1 , size);usbip_dbg_xmit ("enter\n" );
drivers/vhost/net.c +3 -3
@@ -614,7 +614,7 @@ static size_t init_iov_iter(struct vhost/* Skip header. TODO: support TSO. */ size_t len =iov_length (vq->iov, out); -iov_iter_init (iter,WRITE , vq->iov, out, len); +iov_iter_init (iter,ITER_SOURCE , vq->iov, out, len);iov_iter_advance (iter, hdr_size);return iov_iter_count (iter);
@@ -1188,14 +1188,14 @@ static void handle_rx(struct vhost_net * msg.msg_control =vhost_net_buf_consume (&nvq->rxq);/* On overrun, truncate and discard */ if (unlikely (headcount >UIO_MAXIOV )) { -iov_iter_init (&msg.msg_iter,READ , vq->iov,1 ,1 ); +iov_iter_init (&msg.msg_iter,ITER_DEST , vq->iov,1 ,1 ); err = sock->ops->recvmsg (sock, &msg,1 ,MSG_DONTWAIT |MSG_TRUNC );pr_debug ("Discarded rx packet: len %zd\n" , sock_len);continue ; }/* We don't need to be notified again. */ -iov_iter_init (&msg.msg_iter,READ , vq->iov, in, vhost_len); +iov_iter_init (&msg.msg_iter,ITER_DEST , vq->iov, in, vhost_len); fixup = msg.msg_iter;if (unlikely ((vhost_hlen))) {/* We will supply the header ourselves
drivers/vhost/scsi.c +5 -5
@@ -574,7 +574,7 @@ static void vhost_scsi_complete_cmd_workmemcpy (v_rsp.sense, cmd->tvc_sense_buf, se_cmd->scsi_sense_length); -iov_iter_init (&iov_iter,READ , &cmd->tvc_resp_iov, +iov_iter_init (&iov_iter,ITER_DEST , &cmd->tvc_resp_iov, cmd->tvc_in_iovs,sizeof (v_rsp)); ret =copy_to_iter (&v_rsp,sizeof (v_rsp), &iov_iter);if (likely (ret ==sizeof (v_rsp))) {
@@ -883,7 +883,7 @@ vhost_scsi_get_desc(struct vhost_scsi *v* point at the start of the outgoing WRITE payload, if * DMA_TO_DEVICE is set. */ -iov_iter_init (&vc->out_iter,WRITE , vq->iov, vc->out, vc->out_size); +iov_iter_init (&vc->out_iter,ITER_SOURCE , vq->iov, vc->out, vc->out_size); ret =0 ; done:
@@ -1036,7 +1036,7 @@ vhost_scsi_handle_vq(struct vhost_scsi * data_direction =DMA_FROM_DEVICE ; exp_data_len = vc.in_size - vc.rsp_size; -iov_iter_init (&in_iter,READ , &vq->iov[vc.out], vc.in, +iov_iter_init (&in_iter,ITER_DEST , &vq->iov[vc.out], vc.in, vc.rsp_size + exp_data_len);iov_iter_advance (&in_iter, vc.rsp_size); data_iter = in_iter;
@@ -1173,7 +1173,7 @@ vhost_scsi_send_tmf_resp(struct vhost_scmemset (&rsp,0 ,sizeof (rsp)); rsp.response = tmf_resp_code; -iov_iter_init (&iov_iter,READ , resp_iov, in_iovs,sizeof (rsp)); +iov_iter_init (&iov_iter,ITER_DEST , resp_iov, in_iovs,sizeof (rsp)); ret =copy_to_iter (&rsp,sizeof (rsp), &iov_iter);if (likely (ret ==sizeof (rsp)))
@@ -1268,7 +1268,7 @@ vhost_scsi_send_an_resp(struct vhost_scsmemset (&rsp,0 ,sizeof (rsp));/* event_actual = 0 */ rsp.response =VIRTIO_SCSI_S_OK ; -iov_iter_init (&iov_iter,READ , &vq->iov[vc->out], vc->in,sizeof (rsp)); +iov_iter_init (&iov_iter,ITER_DEST , &vq->iov[vc->out], vc->in,sizeof (rsp)); ret =copy_to_iter (&rsp,sizeof (rsp), &iov_iter);if (likely (ret ==sizeof (rsp)))
drivers/vhost/vhost.c +3 -3
@@ -841,7 +841,7 @@ static int vhost_copy_to_user(struct vho VHOST_ACCESS_WO);if (ret <0 ) goto out; -iov_iter_init (&t,WRITE , vq->iotlb_iov, ret, size); +iov_iter_init (&t,ITER_SOURCE , vq->iotlb_iov, ret, size); ret =copy_to_iter (from, size, &t);if (ret == size) ret =0 ;
@@ -880,7 +880,7 @@ static int vhost_copy_from_user(struct v (unsigned long long) size); goto out; } -iov_iter_init (&f,READ , vq->iotlb_iov, ret, size); +iov_iter_init (&f,ITER_DEST , vq->iotlb_iov, ret, size); ret =copy_from_iter (to, size, &f);if (ret == size) ret =0 ;
@@ -2132,7 +2132,7 @@ static int get_indirect(struct vhost_virvq_err (vq,"Translation failure %d in indirect.\n" , ret);return ret; } -iov_iter_init (&from,READ , vq->indirect, ret, len); +iov_iter_init (&from,ITER_DEST , vq->indirect, ret, len); count = len /sizeof desc;/* Buffers are chained via a 16 bit next field, so * we can have at most 2^16 of these. */
drivers/vhost/vringh.c +2 -2
@@ -1122,7 +1122,7 @@ static inline int copy_from_iotlb(constif (ret <0 )return ret; -iov_iter_bvec (&iter,READ , iov, ret, len); +iov_iter_bvec (&iter,ITER_DEST , iov, ret, len); ret =copy_from_iter (dst, len, &iter);
@@ -1141,7 +1141,7 @@ static inline int copy_to_iotlb(const stif (ret <0 )return ret; -iov_iter_bvec (&iter,WRITE , iov, ret, len); +iov_iter_bvec (&iter,ITER_SOURCE , iov, ret, len);return copy_to_iter (src, len, &iter); }
drivers/vhost/vsock.c +2 -2
@@ -155,7 +155,7 @@ vhost_transport_do_send_pkt(struct vhostbreak ; } -iov_iter_init (&iov_iter,READ , &vq->iov[out], in, iov_len); +iov_iter_init (&iov_iter,ITER_DEST , &vq->iov[out], in, iov_len); payload_len = pkt->len - pkt->off;/* If the packet is greater than the space available in the
@@ -337,7 +337,7 @@ vhost_vsock_alloc_pkt(struct vhost_virtqreturn NULL ; len =iov_length (vq->iov, out); -iov_iter_init (&iov_iter,WRITE , vq->iov, out, len); +iov_iter_init (&iov_iter,ITER_SOURCE , vq->iov, out, len); nbytes =copy_from_iter (&pkt->hdr,sizeof (pkt->hdr), &iov_iter);if (nbytes !=sizeof (pkt->hdr)) {
drivers/xen/pvcalls-back.c +4 -4
@@ -129,13 +129,13 @@ static bool pvcalls_conn_back_read(voidif (masked_prod < masked_cons) { vec[0 ].iov_base = data->in + masked_prod; vec[0 ].iov_len = wanted; -iov_iter_kvec (&msg.msg_iter,READ , vec,1 , wanted); +iov_iter_kvec (&msg.msg_iter,ITER_DEST , vec,1 , wanted); }else { vec[0 ].iov_base = data->in + masked_prod; vec[0 ].iov_len = array_size - masked_prod; vec[1 ].iov_base = data->in; vec[1 ].iov_len = wanted - vec[0 ].iov_len; -iov_iter_kvec (&msg.msg_iter,READ , vec,2 , wanted); +iov_iter_kvec (&msg.msg_iter,ITER_DEST , vec,2 , wanted); }atomic_set (&map->read,0 );
@@ -188,13 +188,13 @@ static bool pvcalls_conn_back_write(struif (pvcalls_mask (prod, array_size) >pvcalls_mask (cons, array_size)) { vec[0 ].iov_base = data->out +pvcalls_mask (cons, array_size); vec[0 ].iov_len = size; -iov_iter_kvec (&msg.msg_iter,WRITE , vec,1 , size); +iov_iter_kvec (&msg.msg_iter,ITER_SOURCE , vec,1 , size); }else { vec[0 ].iov_base = data->out +pvcalls_mask (cons, array_size); vec[0 ].iov_len = array_size -pvcalls_mask (cons, array_size); vec[1 ].iov_base = data->out; vec[1 ].iov_len = size - vec[0 ].iov_len; -iov_iter_kvec (&msg.msg_iter,WRITE , vec,2 , size); +iov_iter_kvec (&msg.msg_iter,ITER_SOURCE , vec,2 , size); }atomic_set (&map->write,0 );
fs/9p/vfs_addr.c +2 -2
@@ -51,7 +51,7 @@ static int v9fs_fid_readpage(void *data,if (retval ==0 )return retval; -iov_iter_bvec (&to,READ , &bvec,1 ,PAGE_SIZE ); +iov_iter_bvec (&to,ITER_DEST , &bvec,1 ,PAGE_SIZE ); retval =p9_client_read (fid,page_offset (page), &to, &err);if (err) {
@@ -162,7 +162,7 @@ static int v9fs_vfs_writepage_locked(str bvec.bv_page = page; bvec.bv_offset =0 ; bvec.bv_len = len; -iov_iter_bvec (&from,WRITE , &bvec,1 , len); +iov_iter_bvec (&from,ITER_SOURCE , &bvec,1 , len);/* We should have writeback_fid always set */ BUG_ON (!v9inode->writeback_fid);
fs/9p/vfs_dir.c +1 -1
@@ -108,7 +108,7 @@ static int v9fs_dir_readdir(struct fileif (rdir->tail == rdir->head) {struct iov_iter to;int n; -iov_iter_kvec (&to,READ , &kvec,1 , buflen); +iov_iter_kvec (&to,ITER_DEST , &kvec,1 , buflen); n =p9_client_read (file->private_data, ctx->pos, &to, &err);if (err)
fs/9p/xattr.c +2 -2
@@ -32,7 +32,7 @@ ssize_t v9fs_fid_xattr_get(struct p9_fidstruct iov_iter to;int err; -iov_iter_kvec (&to,READ , &kvec,1 , buffer_size); +iov_iter_kvec (&to,ITER_DEST , &kvec,1 , buffer_size); attr_fid =p9_client_xattrwalk (fid, name, &attr_size);if (IS_ERR (attr_fid)) {
@@ -107,7 +107,7 @@ int v9fs_fid_xattr_set(struct p9_fid *fistruct iov_iter from;int retval, err; -iov_iter_kvec (&from,WRITE , &kvec,1 , value_len); +iov_iter_kvec (&from,ITER_SOURCE , &kvec,1 , value_len);p9_debug (P9_DEBUG_VFS ,"name = %s value_len = %zu flags = %d\n" , name, value_len, flags);
fs/afs/cmservice.c +1 -1
@@ -298,7 +298,7 @@ static int afs_deliver_cb_callback(strucif (call->count2 != call->count && call->count2 !=0 )return afs_protocol_error (call, afs_eproto_cb_count); call->iter = &call->def_iter; -iov_iter_discard (&call->def_iter,READ , call->count2 *3 *4 ); +iov_iter_discard (&call->def_iter,ITER_DEST , call->count2 *3 *4 ); call->unmarshall++; fallthrough;
fs/afs/internal.h +2 -2
@@ -1273,7 +1273,7 @@ static inline void afs_extract_begin(str { call->kvec[0 ].iov_base = buf; call->kvec[0 ].iov_len = size; -iov_iter_kvec (&call->def_iter,READ , call->kvec,1 , size); +iov_iter_kvec (&call->def_iter,ITER_DEST , call->kvec,1 , size); }static inline void afs_extract_to_tmp (struct afs_call *call)
@@ -1288,7 +1288,7 @@ static inline void afs_extract_to_tmp64(static inline void afs_extract_discard (struct afs_call *call,size_t size) { -iov_iter_discard (&call->def_iter,READ , size); +iov_iter_discard (&call->def_iter,ITER_DEST , size); }static inline void afs_extract_to_buf (struct afs_call *call,size_t size)
fs/afs/rxrpc.c +6 -6
@@ -302,7 +302,7 @@ static void afs_load_bvec(struct afs_cal offset =0 ; } -iov_iter_bvec (&msg->msg_iter,WRITE , bv, nr, bytes); +iov_iter_bvec (&msg->msg_iter,ITER_SOURCE , bv, nr, bytes); }/*
@@ -437,7 +437,7 @@ void afs_make_call(struct afs_addr_curso msg.msg_name =NULL ; msg.msg_namelen =0 ; -iov_iter_kvec (&msg.msg_iter,WRITE , iov,1 , call->request_size); +iov_iter_kvec (&msg.msg_iter,ITER_SOURCE , iov,1 , call->request_size); msg.msg_control =NULL ; msg.msg_controllen =0 ; msg.msg_flags =MSG_WAITALL | (call->send_pages ?MSG_MORE :0 );
@@ -467,7 +467,7 @@ error_do_abort:rxrpc_kernel_abort_call (call->net->socket, rxcall,RX_USER_ABORT , ret,"KSD" ); }else { -iov_iter_kvec (&msg.msg_iter,READ ,NULL ,0 ,0 ); +iov_iter_kvec (&msg.msg_iter,ITER_DEST ,NULL ,0 ,0 );rxrpc_kernel_recv_data (call->net->socket, rxcall, &msg.msg_iter, false, &call->abort_code, &call->service_id);
@@ -517,7 +517,7 @@ static void afs_deliver_to_call(struct a state == AFS_CALL_SV_AWAIT_ACK ) {if (state ==AFS_CALL_SV_AWAIT_ACK ) { -iov_iter_kvec (&call->def_iter,READ ,NULL ,0 ,0 ); +iov_iter_kvec (&call->def_iter,ITER_DEST ,NULL ,0 ,0 ); ret = rxrpc_kernel_recv_data(call->net->socket, call->rxcall, &call->def_iter, false, &remote_abort,
@@ -854,7 +854,7 @@ void afs_send_empty_reply(struct afs_cal msg.msg_name =NULL ; msg.msg_namelen =0 ; -iov_iter_kvec (&msg.msg_iter,WRITE ,NULL ,0 ,0 ); +iov_iter_kvec (&msg.msg_iter,ITER_SOURCE ,NULL ,0 ,0 ); msg.msg_control =NULL ; msg.msg_controllen =0 ; msg.msg_flags =0 ;
@@ -894,7 +894,7 @@ void afs_send_simple_reply(struct afs_ca iov[0 ].iov_len = len; msg.msg_name =NULL ; msg.msg_namelen =0 ; -iov_iter_kvec (&msg.msg_iter,WRITE , iov,1 , len); +iov_iter_kvec (&msg.msg_iter,ITER_SOURCE , iov,1 , len); msg.msg_control =NULL ; msg.msg_controllen =0 ; msg.msg_flags =0 ;
fs/aio.c +2 -2
@@ -1547,7 +1547,7 @@ static int aio_read(struct kiocb *req, cif (unlikely (!file->f_op->read_iter))return -EINVAL ; - ret =aio_setup_rw (READ , iocb, &iovec, vectored, compat, &iter); + ret =aio_setup_rw (ITER_DEST , iocb, &iovec, vectored, compat, &iter);if (ret <0 )return ret; ret =rw_verify_area (READ , file, &req->ki_pos,iov_iter_count (&iter));
@@ -1575,7 +1575,7 @@ static int aio_write(struct kiocb *req,if (unlikely (!file->f_op->write_iter))return -EINVAL ; - ret =aio_setup_rw (WRITE , iocb, &iovec, vectored, compat, &iter); + ret =aio_setup_rw (ITER_SOURCE , iocb, &iovec, vectored, compat, &iter);if (ret <0 )return ret; ret =rw_verify_area (WRITE , file, &req->ki_pos,iov_iter_count (&iter));
fs/ceph/file.c +2 -2
@@ -1115,7 +1115,7 @@ static void ceph_aio_complete_req(struct aio_req->total_len = rc + zlen; } -iov_iter_bvec (&i,READ , osd_data->bvec_pos.bvecs, +iov_iter_bvec (&i,ITER_DEST , osd_data->bvec_pos.bvecs, osd_data->num_bvecs, osd_data->bvec_pos.iter.bi_size);iov_iter_advance (&i, rc);
@@ -1342,7 +1342,7 @@ ceph_direct_read_write(struct kiocb *iocint zlen =min_t (size_t, len - ret, size - pos - ret); -iov_iter_bvec (&i,READ , bvecs, num_pages, len); +iov_iter_bvec (&i,ITER_DEST , bvecs, num_pages, len);iov_iter_advance (&i, ret);iov_iter_zero (zlen, &i); ret += zlen;
fs/cifs/connect.c +3 -3
@@ -747,7 +747,7 @@ cifs_read_from_socket(struct TCP_Server_ {struct msghdr smb_msg = {};struct kvec iov = {.iov_base = buf, .iov_len = to_read}; -iov_iter_kvec (&smb_msg.msg_iter,READ , &iov,1 , to_read); +iov_iter_kvec (&smb_msg.msg_iter,ITER_DEST , &iov,1 , to_read);return cifs_readv_from_socket (server, &smb_msg); }
@@ -762,7 +762,7 @@ cifs_discard_from_socket(struct TCP_Serv* and cifs_readv_from_socket sets msg_control and msg_controllen * so little to initialize in struct msghdr */ -iov_iter_discard (&smb_msg.msg_iter,READ , to_read); +iov_iter_discard (&smb_msg.msg_iter,ITER_DEST , to_read);return cifs_readv_from_socket (server, &smb_msg); }
@@ -774,7 +774,7 @@ cifs_read_page_from_socket(struct TCP_Sestruct msghdr smb_msg = {};struct bio_vec bv = { .bv_page = page, .bv_len = to_read, .bv_offset = page_offset}; -iov_iter_bvec (&smb_msg.msg_iter,READ , &bv,1 , to_read); +iov_iter_bvec (&smb_msg.msg_iter,ITER_DEST , &bv,1 , to_read);return cifs_readv_from_socket (server, &smb_msg); }
fs/cifs/file.c +2 -2
@@ -3180,7 +3180,7 @@ static ssize_t __cifs_writev( ctx->iter = *from; ctx->len = len; }else { - rc =setup_aio_ctx_iter (ctx, from,WRITE ); + rc =setup_aio_ctx_iter (ctx, from,ITER_SOURCE );if (rc) {kref_put (&ctx->refcount, cifs_aio_ctx_release);return rc;
@@ -3920,7 +3920,7 @@ static ssize_t __cifs_readv( ctx->iter = *to; ctx->len = len; }else { - rc =setup_aio_ctx_iter (ctx, to,READ ); + rc =setup_aio_ctx_iter (ctx, to,ITER_DEST );if (rc) {kref_put (&ctx->refcount, cifs_aio_ctx_release);return rc;
fs/cifs/smb2ops.c +2 -2
@@ -4720,13 +4720,13 @@ handle_read_data(struct TCP_Server_Inforeturn 0 ; } -iov_iter_bvec (&iter,WRITE , bvec, npages, data_len); +iov_iter_bvec (&iter,ITER_SOURCE , bvec, npages, data_len); }else if (buf_len >= data_offset + data_len) {/* read response payload is in buf */ WARN_ONCE (npages >0 ,"read data can be either in buf or in pages" ); iov.iov_base = buf + data_offset; iov.iov_len = data_len; -iov_iter_kvec (&iter,WRITE , &iov,1 , data_len); +iov_iter_kvec (&iter,ITER_SOURCE , &iov,1 , data_len); }else {/* read response payload cannot be in both buf and pages */ WARN_ONCE (1 ,"buf can not contain only a part of read data" );
fs/cifs/transport.c +3 -3
@@ -362,7 +362,7 @@ __smb_send_rqst(struct TCP_Server_Info * .iov_base = &rfc1002_marker, .iov_len = 4 }; -iov_iter_kvec (&smb_msg.msg_iter,WRITE , &hiov,1 ,4 ); +iov_iter_kvec (&smb_msg.msg_iter,ITER_SOURCE , &hiov,1 ,4 ); rc =smb_send_kvec (server, &smb_msg, &sent);if (rc <0 ) goto unmask;
@@ -383,7 +383,7 @@ __smb_send_rqst(struct TCP_Server_Info * size += iov[i].iov_len; } -iov_iter_kvec (&smb_msg.msg_iter,WRITE , iov, n_vec, size); +iov_iter_kvec (&smb_msg.msg_iter,ITER_SOURCE , iov, n_vec, size); rc =smb_send_kvec (server, &smb_msg, &sent);if (rc <0 )
@@ -399,7 +399,7 @@ __smb_send_rqst(struct TCP_Server_Info *rqst_page_get_length (&rqst[j], i, &bvec.bv_len, &bvec.bv_offset); -iov_iter_bvec (&smb_msg.msg_iter,WRITE , +iov_iter_bvec (&smb_msg.msg_iter,ITER_SOURCE , &bvec,1 , bvec.bv_len); rc =smb_send_kvec (server, &smb_msg, &sent);if (rc <0 )
fs/nfsd/vfs.c +2 -2
@@ -1043,7 +1043,7 @@ __be32 nfsd_readv(struct svc_rqst *rqstpssize_t host_err;trace_nfsd_read_vector (rqstp, fhp, offset, *count); -iov_iter_kvec (&iter,READ , vec, vlen, *count); +iov_iter_kvec (&iter,ITER_DEST , vec, vlen, *count); host_err =vfs_iter_read (file, &iter, &ppos,0 );return nfsd_finish_read (rqstp, fhp, file, offset, count, eof, host_err); }
@@ -1133,7 +1133,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, sif (stable && !use_wgather) flags |=RWF_SYNC ; -iov_iter_kvec (&iter,WRITE , vec, vlen, *cnt); +iov_iter_kvec (&iter,ITER_SOURCE , vec, vlen, *cnt); since =READ_ONCE (file->f_wb_err);if (verf)nfsd_copy_write_verifier (verf, nn);
fs/ocfs2/cluster/tcp.c +1 -1
@@ -902,7 +902,7 @@ static int o2net_recv_tcp_msg(struct soc {struct kvec vec = { .iov_len = len, .iov_base = data, };struct msghdr msg = { .msg_flags =MSG_DONTWAIT , }; -iov_iter_kvec (&msg.msg_iter,READ , &vec,1 , len); +iov_iter_kvec (&msg.msg_iter,ITER_DEST , &vec,1 , len);return sock_recvmsg (sock, &msg,MSG_DONTWAIT ); }
fs/orangefs/inode.c +3 -3
@@ -52,7 +52,7 @@ static int orangefs_writepage_locked(str bv.bv_len = wlen; bv.bv_offset = off %PAGE_SIZE ;WARN_ON (wlen ==0 ); -iov_iter_bvec (&iter,WRITE , &bv,1 , wlen); +iov_iter_bvec (&iter,ITER_SOURCE , &bv,1 , wlen); ret =wait_for_direct_io (ORANGEFS_IO_WRITE , inode, &off, &iter, wlen, len, wr,NULL ,NULL );
@@ -110,7 +110,7 @@ static int orangefs_writepages_work(struelse ow->bv[i].bv_offset =0 ; } -iov_iter_bvec (&iter,WRITE , ow->bv, ow->npages, ow->len); +iov_iter_bvec (&iter,ITER_SOURCE , ow->bv, ow->npages, ow->len);WARN_ON (ow->off >= len);if (ow->off + ow->len > len)
@@ -275,7 +275,7 @@ static int orangefs_readpage(struct file bv.bv_page = page; bv.bv_len =PAGE_SIZE ; bv.bv_offset =0 ; -iov_iter_bvec (&iter,READ , &bv,1 ,PAGE_SIZE ); +iov_iter_bvec (&iter,ITER_DEST , &bv,1 ,PAGE_SIZE ); ret =wait_for_direct_io (ORANGEFS_IO_READ , inode, &off, &iter, read_size, inode->i_size,NULL , &buffer_index, file);
fs/read_write.c +6 -6
@@ -410,7 +410,7 @@ static ssize_t new_sync_read(struct fileinit_sync_kiocb (&kiocb, filp); kiocb.ki_pos = (ppos ? *ppos :0 ); -iov_iter_init (&iter,READ , &iov,1 , len); +iov_iter_init (&iter,ITER_DEST , &iov,1 , len); ret =call_read_iter (filp, &kiocb, &iter);BUG_ON (ret == -EIOCBQUEUED );
@@ -450,7 +450,7 @@ ssize_t __kernel_read(struct file *file,init_sync_kiocb (&kiocb, file); kiocb.ki_pos = pos ? *pos :0 ; -iov_iter_kvec (&iter,READ , &iov,1 , iov.iov_len); +iov_iter_kvec (&iter,ITER_DEST , &iov,1 , iov.iov_len); ret = file->f_op->read_iter (&kiocb, &iter);if (ret >0 ) {if (pos)
@@ -513,7 +513,7 @@ static ssize_t new_sync_write(struct filinit_sync_kiocb (&kiocb, filp); kiocb.ki_pos = (ppos ? *ppos :0 ); -iov_iter_init (&iter,WRITE , &iov,1 , len); +iov_iter_init (&iter,ITER_SOURCE , &iov,1 , len); ret =call_write_iter (filp, &kiocb, &iter);BUG_ON (ret == -EIOCBQUEUED );
@@ -546,7 +546,7 @@ ssize_t __kernel_write(struct file *fileinit_sync_kiocb (&kiocb, file); kiocb.ki_pos = pos ? *pos :0 ; -iov_iter_kvec (&iter,WRITE , &iov,1 , iov.iov_len); +iov_iter_kvec (&iter,ITER_SOURCE , &iov,1 , iov.iov_len); ret = file->f_op->write_iter (&kiocb, &iter);if (ret >0 ) {if (pos)
@@ -916,7 +916,7 @@ static ssize_t vfs_readv(struct file *fistruct iov_iter iter;ssize_t ret; - ret =import_iovec (READ , vec, vlen,ARRAY_SIZE (iovstack), &iov, &iter); + ret =import_iovec (ITER_DEST , vec, vlen,ARRAY_SIZE (iovstack), &iov, &iter);if (ret >=0 ) { ret =do_iter_read (file, &iter, pos, flags);kfree (iov);
@@ -933,7 +933,7 @@ static ssize_t vfs_writev(struct file *fstruct iov_iter iter;ssize_t ret; - ret =import_iovec (WRITE , vec, vlen,ARRAY_SIZE (iovstack), &iov, &iter); + ret =import_iovec (ITER_SOURCE , vec, vlen,ARRAY_SIZE (iovstack), &iov, &iter);if (ret >=0 ) {file_start_write (file); ret =do_iter_write (file, &iter, pos, flags);
fs/seq_file.c +1 -1
@@ -156,7 +156,7 @@ ssize_t seq_read(struct file *file, charssize_t ret;init_sync_kiocb (&kiocb, file); -iov_iter_init (&iter,READ , &iov,1 , size); +iov_iter_init (&iter,ITER_DEST , &iov,1 , size); kiocb.ki_pos = *ppos; ret =seq_read_iter (&kiocb, &iter);
fs/splice.c +5 -5
@@ -304,7 +304,7 @@ ssize_t generic_file_splice_read(structunsigned int i_head;int ret; -iov_iter_pipe (&to,READ , pipe, len); +iov_iter_pipe (&to,ITER_DEST , pipe, len); i_head = to.head;init_sync_kiocb (&kiocb, in); kiocb.ki_pos = *ppos;
@@ -685,7 +685,7 @@ iter_file_splice_write(struct pipe_inode n++; } -iov_iter_bvec (&from,WRITE , array, n, sd.total_len - left); +iov_iter_bvec (&from,ITER_SOURCE , array, n, sd.total_len - left); ret =vfs_iter_write (out, &from, &sd.pos,0 );if (ret <=0 )break ;
@@ -1263,9 +1263,9 @@ static int vmsplice_type(struct fd f, inif (!f.file)return -EBADF ;if (f.file->f_mode &FMODE_WRITE ) { - *type =WRITE ; + *type =ITER_SOURCE ; }else if (f.file->f_mode &FMODE_READ ) { - *type =READ ; + *type =ITER_DEST ; }else {fdput (f);return -EBADF ;
@@ -1314,7 +1314,7 @@ SYSCALL_DEFINE4(vmsplice, int, fd, constif (!iov_iter_count (&iter)) error =0 ; -else if (iov_iter_rw (&iter) ==WRITE ) +else if (type ==ITER_SOURCE ) error =vmsplice_to_pipe (f.file, &iter, flags);else error =vmsplice_to_user (f.file, &iter, flags);
include/linux/uio.h +3 -0
@@ -26,6 +26,9 @@ enum iter_type { ITER_DISCARD = 64, }; +#define ITER_SOURCE 1 // == WRITE +#define ITER_DEST 0 // == READ +struct iov_iter_state {size_t iov_offset;size_t count;
mm/madvise.c +1 -1
@@ -1184,7 +1184,7 @@ SYSCALL_DEFINE5(process_madvise, int, pi goto out; } - ret =import_iovec (READ , vec, vlen,ARRAY_SIZE (iovstack), &iov, &iter); + ret =import_iovec (ITER_DEST , vec, vlen,ARRAY_SIZE (iovstack), &iov, &iter);if (ret <0 ) goto out;
mm/page_io.c +1 -1
@@ -269,7 +269,7 @@ int __swap_writepage(struct page *page, };struct iov_iter from; -iov_iter_bvec (&from,WRITE , &bv,1 ,PAGE_SIZE ); +iov_iter_bvec (&from,ITER_SOURCE , &bv,1 ,PAGE_SIZE );init_sync_kiocb (&kiocb, swap_file); kiocb.ki_pos =page_file_offset (page);
mm/process_vm_access.c +1 -1
@@ -264,7 +264,7 @@ static ssize_t process_vm_rw(pid_t pid,struct iovec *iov_r = iovstack_r;struct iov_iter iter;ssize_t rc; -int dir = vm_write ?WRITE :READ ; +int dir = vm_write ?ITER_SOURCE :ITER_DEST ;if (flags !=0 )return -EINVAL ;
net/9p/client.c +1 -1
@@ -2095,7 +2095,7 @@ int p9_client_readdir(struct p9_fid *fidstruct kvec kv = {.iov_base = data, .iov_len = count};struct iov_iter to; -iov_iter_kvec (&to,READ , &kv,1 , count); +iov_iter_kvec (&to,ITER_DEST , &kv,1 , count);p9_debug (P9_DEBUG_9P ,">>> TREADDIR fid %d offset %llu count %d\n" , fid->fid, (unsigned long long ) offset, count);
net/bluetooth/6lowpan.c +1 -1
@@ -478,7 +478,7 @@ static int send_pkt(struct l2cap_chan *c iv.iov_len = skb->len;memset (&msg,0 ,sizeof (msg)); -iov_iter_kvec (&msg.msg_iter,WRITE , &iv,1 , skb->len); +iov_iter_kvec (&msg.msg_iter,ITER_SOURCE , &iv,1 , skb->len); err =l2cap_chan_send (chan, &msg, skb->len);if (err >0 ) {
net/bluetooth/a2mp.c +1 -1
@@ -56,7 +56,7 @@ static void a2mp_send(struct amp_mgr *mgmemset (&msg,0 ,sizeof (msg)); -iov_iter_kvec (&msg.msg_iter,WRITE , &iv,1 , total_len); +iov_iter_kvec (&msg.msg_iter,ITER_SOURCE , &iv,1 , total_len);l2cap_chan_send (chan, &msg, total_len);
net/bluetooth/smp.c +1 -1
@@ -606,7 +606,7 @@ static void smp_send_cmd(struct l2cap_comemset (&msg,0 ,sizeof (msg)); -iov_iter_kvec (&msg.msg_iter,WRITE , iv,2 ,1 + len); +iov_iter_kvec (&msg.msg_iter,ITER_SOURCE , iv,2 ,1 + len);l2cap_chan_send (chan, &msg,1 + len);
net/ipv4/tcp.c +1 -1
@@ -1812,7 +1812,7 @@ static int tcp_copy_straggler_data(strucif (copy_address != zc->copybuf_address)return -EINVAL ; - err =import_single_range (READ , (void __user *)copy_address, + err =import_single_range (ITER_DEST , (void __user *)copy_address, copylen, &iov, &msg.msg_iter);if (err)return err;
net/netfilter/ipvs/ip_vs_sync.c +1 -1
@@ -1617,7 +1617,7 @@ ip_vs_receive(struct socket *sock, charEnterFunction (7 );/* Receive a packet */ -iov_iter_kvec (&msg.msg_iter,READ , &iov,1 , buflen); +iov_iter_kvec (&msg.msg_iter,ITER_DEST , &iov,1 , buflen); len =sock_recvmsg (sock, &msg,MSG_DONTWAIT );if (len <0 )return len;
net/smc/smc_clc.c +3 -3
@@ -361,7 +361,7 @@ int smc_clc_wait_msg(struct smc_sock *sm*/ krflags =MSG_PEEK |MSG_WAITALL ; clc_sk->sk_rcvtimeo = timeout; -iov_iter_kvec (&msg.msg_iter,READ , &vec,1 , +iov_iter_kvec (&msg.msg_iter,ITER_DEST , &vec,1 ,sizeof (struct smc_clc_msg_hdr )); len =sock_recvmsg (smc->clcsock, &msg, krflags);if (signal_pending (current)) {
@@ -408,7 +408,7 @@ int smc_clc_wait_msg(struct smc_sock *sm }else { recvlen = datlen; } -iov_iter_kvec (&msg.msg_iter,READ , &vec,1 , recvlen); +iov_iter_kvec (&msg.msg_iter,ITER_DEST , &vec,1 , recvlen); krflags =MSG_WAITALL ; len =sock_recvmsg (smc->clcsock, &msg, krflags);if (len < recvlen || !smc_clc_msg_hdr_valid (clcm, check_trl)) {
@@ -425,7 +425,7 @@ int smc_clc_wait_msg(struct smc_sock *sm/* receive remaining proposal message */ recvlen = datlen >SMC_CLC_RECV_BUF_LEN ?SMC_CLC_RECV_BUF_LEN : datlen; -iov_iter_kvec (&msg.msg_iter,READ , &vec,1 , recvlen); +iov_iter_kvec (&msg.msg_iter,ITER_DEST , &vec,1 , recvlen); len =sock_recvmsg (smc->clcsock, &msg, krflags);if (len < recvlen) { smc->sk.sk_err =EPROTO ;
net/socket.c +6 -6
@@ -706,7 +706,7 @@ EXPORT_SYMBOL(sock_sendmsg);int kernel_sendmsg (struct socket *sock,struct msghdr *msg,struct kvec *vec,size_t num,size_t size) { -iov_iter_kvec (&msg->msg_iter,WRITE , vec, num, size); +iov_iter_kvec (&msg->msg_iter,ITER_SOURCE , vec, num, size);return sock_sendmsg (sock, msg); }EXPORT_SYMBOL (kernel_sendmsg);
@@ -732,7 +732,7 @@ int kernel_sendmsg_locked(struct sock *sif (!sock->ops->sendmsg_locked)return sock_no_sendmsg_locked (sk, msg, size); -iov_iter_kvec (&msg->msg_iter,WRITE , vec, num, size); +iov_iter_kvec (&msg->msg_iter,ITER_SOURCE , vec, num, size);return sock->ops->sendmsg_locked (sk, msg,msg_data_left (msg)); }
@@ -944,7 +944,7 @@ int kernel_recvmsg(struct socket *sock, struct kvec *vec, size_t num, size_t size, int flags) { msg->msg_control_is_user = false; -iov_iter_kvec (&msg->msg_iter,READ , vec, num, size); +iov_iter_kvec (&msg->msg_iter,ITER_DEST , vec, num, size);return sock_recvmsg (sock, msg, flags); }EXPORT_SYMBOL (kernel_recvmsg);
@@ -1982,7 +1982,7 @@ int __sys_sendto(int fd, void __user *bustruct iovec iov;int fput_needed; - err =import_single_range (WRITE , buff, len, &iov, &msg.msg_iter); + err =import_single_range (ITER_SOURCE , buff, len, &iov, &msg.msg_iter);if (unlikely (err))return err; sock =sockfd_lookup_light (fd, &err, &fput_needed);
@@ -2043,7 +2043,7 @@ int __sys_recvfrom(int fd, void __user *int err, err2;int fput_needed; - err =import_single_range (READ , ubuf, size, &iov, &msg.msg_iter); + err =import_single_range (ITER_DEST , ubuf, size, &iov, &msg.msg_iter);if (unlikely (err))return err; sock =sockfd_lookup_light (fd, &err, &fput_needed);
@@ -2314,7 +2314,7 @@ static int copy_msghdr_from_user(structif (err)return err; - err =import_iovec (save_addr ?READ :WRITE , + err =import_iovec (save_addr ?ITER_DEST :ITER_SOURCE , msg.msg_iov, msg.msg_iovlen,UIO_FASTIOV , iov, &kmsg->msg_iter);return err <0 ? err :0 ;
net/sunrpc/socklib.c +3 -3
@@ -213,7 +213,7 @@ static inline int xprt_sendmsg(struct sostatic int xprt_send_kvec (struct socket *sock,struct msghdr *msg,struct kvec *vec,size_t seek) { -iov_iter_kvec (&msg->msg_iter,WRITE , vec,1 , vec->iov_len); +iov_iter_kvec (&msg->msg_iter,ITER_SOURCE , vec,1 , vec->iov_len);return xprt_sendmsg (sock, msg, seek); }
@@ -226,7 +226,7 @@ static int xprt_send_pagedata(struct socif (err <0 )return err; -iov_iter_bvec (&msg->msg_iter,WRITE , xdr->bvec,xdr_buf_pagecount (xdr), +iov_iter_bvec (&msg->msg_iter,ITER_SOURCE , xdr->bvec,xdr_buf_pagecount (xdr), xdr->page_len + xdr->page_base);return xprt_sendmsg (sock, msg, base + xdr->page_base); }
@@ -249,7 +249,7 @@ static int xprt_send_rm_and_kvec(struct };size_t len = iov[0 ].iov_len + iov[1 ].iov_len; -iov_iter_kvec (&msg->msg_iter,WRITE , iov,2 , len); +iov_iter_kvec (&msg->msg_iter,ITER_SOURCE , iov,2 , len);return xprt_sendmsg (sock, msg, base); }
net/sunrpc/svcsock.c +2 -2
@@ -271,7 +271,7 @@ static ssize_t svc_tcp_read_msg(struct s rqstp->rq_respages = &rqstp->rq_pages[i]; rqstp->rq_next_page = rqstp->rq_respages +1 ; -iov_iter_bvec (&msg.msg_iter,READ , bvec, i, buflen); +iov_iter_bvec (&msg.msg_iter,ITER_DEST , bvec, i, buflen);if (seek) {iov_iter_advance (&msg.msg_iter, seek); buflen -= seek;
@@ -880,7 +880,7 @@ static ssize_t svc_tcp_read_marker(struc want =sizeof (rpc_fraghdr) - svsk->sk_tcplen; iov.iov_base = ((char *)&svsk->sk_marker) + svsk->sk_tcplen; iov.iov_len = want; -iov_iter_kvec (&msg.msg_iter,READ , &iov,1 , want); +iov_iter_kvec (&msg.msg_iter,ITER_DEST , &iov,1 , want); len =sock_recvmsg (svsk->sk_sock, &msg,MSG_DONTWAIT );if (len <0 )return len;
net/sunrpc/xprtsock.c +3 -3
@@ -358,7 +358,7 @@ static ssize_t xs_read_kvec(struct socket *sock, struct msghdr *msg, int flags, struct kvec *kvec, size_t count, size_t seek) { - iov_iter_kvec(&msg->msg_iter, READ, kvec, 1, count); + iov_iter_kvec(&msg->msg_iter, ITER_DEST, kvec, 1, count);return xs_sock_recvmsg (sock, msg, flags, seek); }
@@ -367,7 +367,7 @@ xs_read_bvec(struct socket *sock, struct struct bio_vec *bvec, unsigned long nr, size_t count, size_t seek) { - iov_iter_bvec(&msg->msg_iter, READ, bvec, nr, count); + iov_iter_bvec(&msg->msg_iter, ITER_DEST, bvec, nr, count);return xs_sock_recvmsg (sock, msg, flags, seek); }
@@ -375,7 +375,7 @@ static ssize_t xs_read_discard(struct socket *sock, struct msghdr *msg, int flags, size_t count) { - iov_iter_discard(&msg->msg_iter, READ, count); + iov_iter_discard(&msg->msg_iter, ITER_DEST, count);return sock_recvmsg (sock, msg, flags); }
net/tipc/topsrv.c +1 -1
@@ -396,7 +396,7 @@ static int tipc_conn_rcv_from_sock(struc iov.iov_base = &s; iov.iov_len =sizeof (s); msg.msg_name =NULL ; -iov_iter_kvec (&msg.msg_iter,READ , &iov,1 , iov.iov_len); +iov_iter_kvec (&msg.msg_iter,ITER_DEST , &iov,1 , iov.iov_len); ret =sock_recvmsg (con->sock, &msg,MSG_DONTWAIT );if (ret == -EWOULDBLOCK )return -EWOULDBLOCK ;
net/tls/tls_device.c +2 -2
@@ -585,7 +585,7 @@ int tls_device_sendpage(struct sock *sk, kaddr =kmap (page); iov.iov_base = kaddr + offset; iov.iov_len = size; -iov_iter_kvec (&msg_iter,WRITE , &iov,1 , size); +iov_iter_kvec (&msg_iter,ITER_SOURCE , &iov,1 , size); rc =tls_push_data (sk, &msg_iter, size, flags,TLS_RECORD_TYPE_DATA );kunmap (page);
@@ -660,7 +660,7 @@ static int tls_device_push_pending_recor {struct iov_iter msg_iter; -iov_iter_kvec (&msg_iter,WRITE ,NULL ,0 ,0 ); +iov_iter_kvec (&msg_iter,ITER_SOURCE ,NULL ,0 ,0 );return tls_push_data (sk, &msg_iter,0 , flags,TLS_RECORD_TYPE_DATA ); }
net/xfrm/espintcp.c +1 -1
@@ -360,7 +360,7 @@ static int espintcp_sendmsg(struct sock *((__be16 *)buf) =cpu_to_be16 (msglen); pfx_iov.iov_base = buf; pfx_iov.iov_len =sizeof (buf); -iov_iter_kvec (&pfx_iter,WRITE , &pfx_iov,1 , pfx_iov.iov_len); +iov_iter_kvec (&pfx_iter,ITER_SOURCE , &pfx_iov,1 , pfx_iov.iov_len); err =sk_msg_memcopy_from_iter (sk, &pfx_iter, &emsg->skmsg, pfx_iov.iov_len);
security/keys/keyctl.c +2 -2
@@ -1256,7 +1256,7 @@ long keyctl_instantiate_key(key_serial_tstruct iov_iter from;int ret; - ret =import_single_range (WRITE , (void __user *)_payload, plen, + ret =import_single_range (ITER_SOURCE , (void __user *)_payload, plen, &iov, &from);if (unlikely (ret))return ret;
@@ -1288,7 +1288,7 @@ long keyctl_instantiate_key_iov(key_seriif (!_payload_iov) ioc =0 ; - ret =import_iovec (WRITE , _payload_iov, ioc, + ret =import_iovec (ITER_SOURCE , _payload_iov, ioc,ARRAY_SIZE (iovstack), &iov, &from);if (ret <0 )return ret;
Greg Kroah-Hartman
maintainerPATCH 290/342 selftests: mptcp: drop nanoseconds width specifier
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Matthieu Baerts (NGI0)" <[email protected]>
[ Upstream commit 01ff78e4b3d98689184c52d97f9575dfbdc3b10f ]
Using the format specifier +%s%3N with GNU date is honoured, and only prints 3 digits of the nanoseconds portion of the seconds since epoch, which corresponds to the milliseconds.
The uutils implementation of date currently does not honour this, and always prints all 9 digits. This is a known issue [1], but can be worked around by adapting this test to use nanoseconds instead of microseconds, and then divide it by 1e6.
This fix is similar to what has been done on systemd side [2], and it is needed to run the selftests on Ubuntu 26.04, containing uutils 0.8.0.
Note that the Fixes tag is there even if this patch doesn't fix an issue in the kernel selftests, but it is useful for those using uutils 0.8.0.
--- tools/testing/selftests/net/mptcp/mptcp_connect.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_connect.sh +3 -3
@@ -421,7 +421,7 @@ do_transfer() wait_local_port_listen "${listener_ns}" "${port}" local start - start=$(date +%s%3N) + start=$(date +%s%N) ip netns exec ${connector_ns} ./mptcp_connect -t $timeout -p $port -s ${cl_proto} $extra_args $connect_addr < "$cin" > "$cout" & local cpid=$!
@@ -431,7 +431,7 @@ do_transfer() local rets=$? local stop - stop=$(date +%s%3N) + stop=$(date +%s%N) if $capture; then sleep 1
@@ -440,7 +440,7 @@ do_transfer() fi local duration - duration=$((stop-start)) + duration=$(((stop-start) / 1000000)) duration=$(printf "(duration %05sms)" $duration) if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then echo "$duration [ FAIL ] client exit code $retc, server $rets" 1>&2
Greg Kroah-Hartman
maintainerPATCH 291/342 mptcp: do not drop partial packets
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shardul Bankar <[email protected]>
[ Upstream commit 50c2d91c5dfa0e465826ec1f8dbad9cdc254bd85 ]
When a packet arrives with map_seq < ack_seq < end_seq, the beginning of the packet has already been acknowledged but the end contains new data. Currently the entire packet is dropped as "old data," forcing the sender to retransmit.
Instead, skip the already-acked bytes by adjusting the skb offset and enqueue only the new portion. Update bytes_received and ack_seq to reflect the new data consumed.
A previous attempt at this fix has been sent by Paolo Abeni [1], but had issues [2]: it also added a zero-window check and changed rcv_wnd_sent initialization, which caused test regressions. This version addresses only the partial packet handling without modifying receive window accounting.
--- net/mptcp/protocol.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
net/mptcp/protocol.c +19 -3
@@ -314,10 +314,26 @@ static bool __mptcp_move_skb(struct mptcreturn false; } -/* old data, keep it simple and drop the whole pkt, sender -* will retransmit as needed, if needed. +/* Completely old data? */ +if (!after64 (MPTCP_SKB_CB (skb)->end_seq, msk->ack_seq)) { +MPTCP_INC_STATS (sock_net (sk),MPTCP_MIB_DUPDATA ); +mptcp_drop (sk, skb); +return false; + } + +/* Partial packet: map_seq < ack_seq < end_seq. +* Skip the already-acked bytes and enqueue the new data. */ -MPTCP_INC_STATS (sock_net (sk),MPTCP_MIB_DUPDATA ); + copy_len =MPTCP_SKB_CB (skb)->end_seq - msk->ack_seq; +MPTCP_SKB_CB (skb)->offset += msk->ack_seq -MPTCP_SKB_CB (skb)->map_seq; +MPTCP_SKB_CB (skb)->map_seq += msk->ack_seq - +MPTCP_SKB_CB (skb)->map_seq; +WRITE_ONCE (msk->ack_seq, msk->ack_seq + copy_len); + +skb_set_owner_r (skb, sk); +__skb_queue_tail (&sk->sk_receive_queue, skb); +return true; + drop:mptcp_drop (sk, skb);return false;
Greg Kroah-Hartman
maintainerPATCH 292/342 octeontx2-pf: avoid double free of pool->stack on AQ init failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dawei Feng <[email protected]>
[ Upstream commit 9b244c242bec48b37e82b89787afd6a4c43457e1 ]
otx2_pool_aq_init() frees pool->stack when mailbox sync or retry allocation fails, but leaves the pointer unchanged. Later, otx2_sq_aura_pool_init() unwinds the partial setup through otx2_aura_pool_free(), which frees pool->stack again. The CN20K-specific cn20k_pool_aq_init() implementation has the same bug in
its corresponding error path.
Set pool->stack to NULL immediately after the local free so the shared cleanup path does not free the same stack again while cleaning up partially initialized pool state.
The bug was first flagged by an experimental analysis tool we are developing for kernel memory-management bugs while analyzing v6.13-rc1. The tool is still under development and is not yet publicly available. Manual inspection confirms that the bug is still present in v7.1-rc3.
Runtime validation was not performed because reproducing this path requires OcteonTX2/CN20K hardware.
--- drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +2 -0
@@ -1194,11 +1194,13 @@ static int otx2_pool_init(struct otx2_ni err =otx2_sync_mbox_msg (&pfvf->mbox);if (err) {qmem_free (pfvf->dev, pool->stack); + pool->stack =NULL ;return err; } aq =otx2_mbox_alloc_msg_npa_aq_enq (&pfvf->mbox);if (!aq) {qmem_free (pfvf->dev, pool->stack); + pool->stack =NULL ;return -ENOMEM ; } }
Greg Kroah-Hartman
maintainerPATCH 293/342 octeontx2-af: Add validation for lmac type
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hariprasad Kelam <[email protected]>
[ Upstream commit cb5edce271764524b88b1a6866b3e626686d9a33 ]
Upon physical link change, firmware reports to the kernel about the change along with the details like speed, lmac_type_id, etc. Kernel derives lmac_type based on lmac_type_id received from firmware.
In a few scenarios, firmware returns an invalid lmac_type_id, which is resulting in below kernel panic. This patch adds the missing validation of the lmac_type_id field.
Internal error: Oops: 96000005 [#1] PREEMPT SMP [ 35.321595] Modules linked in: [ 35.328982] CPU: 0 PID: 31 Comm: kworker/0:1 Not tainted 5.4.210-g2e3169d8e1bc-dirty #17 [ 35.337014] Hardware name: Marvell CN103XX board (DT) [ 35.344297] Workqueue: events work_for_cpu_fn [ 35.352730] pstate: 40400089 (nZcv daIf +PAN -UAO) [ 35.360267] pc : strncpy+0x10/0x30 [ 35.366595] lr : cgx_link_change_handler+0x90/0x180
Stable-dep-of: c0bf0a4f3f1f ("octeontx2-af: CGX: add bounds check to cgx_speed_mbps index")
--- drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 15 +++++++++++---- drivers/net/ethernet/marvell/octeontx2/af/mbox.h | 1 + 2 files changed, 12 insertions(+), 4 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/cgx.c +11 -4
@@ -669,15 +669,22 @@ static inline void link_status_user_formstruct cgx_link_user_info *linfo, struct cgx *cgx, u8 lmac_id) { - char *lmac_string; - linfo->link_up = FIELD_GET(RESP_LINKSTAT_UP, lstat); linfo->full_duplex =FIELD_GET (RESP_LINKSTAT_FDUPLEX , lstat); linfo->speed = cgx_speed_mbps[FIELD_GET (RESP_LINKSTAT_SPEED , lstat)]; + linfo->an =FIELD_GET (RESP_LINKSTAT_AN , lstat); linfo->fec =FIELD_GET (RESP_LINKSTAT_FEC , lstat); linfo->lmac_type_id =cgx_get_lmac_type (cgx, lmac_id); - lmac_string = cgx_lmactype_string[linfo->lmac_type_id]; -strncpy (linfo->lmac_type, lmac_string,LMACTYPE_STR_LEN -1 ); + +if (linfo->lmac_type_id >=LMAC_MODE_MAX ) { +dev_err (&cgx->pdev->dev,"Unknown lmac_type_id %d reported by firmware on cgx port%d:%d" , + linfo->lmac_type_id, cgx->cgx_id, lmac_id); +strncpy (linfo->lmac_type,"Unknown" ,LMACTYPE_STR_LEN -1 ); +return ; + } + +strncpy (linfo->lmac_type, cgx_lmactype_string[linfo->lmac_type_id], +LMACTYPE_STR_LEN -1 ); }/* Hardware event handlers */
drivers/net/ethernet/marvell/octeontx2/af/mbox.h +1 -0
@@ -369,6 +369,7 @@ struct cgx_link_user_info { uint64_t full_duplex:1; uint64_t lmac_type_id:4; uint64_t speed:20; /* speed in Mbps */ + uint64_t an:1; /* AN supported or not */ uint64_t fec:2; /* FEC type if enabled else 0 */#define LMACTYPE_STR_LEN 16char lmac_type[LMACTYPE_STR_LEN ];
Greg Kroah-Hartman
maintainerPATCH 294/342 octeontx2-af: replace deprecated strncpy with strscpy
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Stitt <[email protected]>
[ Upstream commit 473f8f2d1bfe1103f20140fdc80cad406b4d68c0 ]
strncpy is deprecated for use on NUL-terminated destination strings
[1] and as such we should prefer more robust and less ambiguous string interfaces.
We can see that linfo->lmac_type is expected to be NUL-terminated based on the ... - 1's present in the current code. Presumably making room for a NUL-byte at the end of the buffer.
Considering the above, a suitable replacement is strscpy [2] due to the fact that it guarantees NUL-termination on the destination buffer without unnecessarily NUL-padding.
Let's also prefer the more idiomatic strscpy usage of (dest, src, sizeof(dest)) rather than (dest, src, SOME_LEN).
Stable-dep-of: c0bf0a4f3f1f ("octeontx2-af: CGX: add bounds check to cgx_speed_mbps index")
--- drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/cgx.c +3 -3
@@ -679,12 +679,12 @@ static inline void link_status_user_formif (linfo->lmac_type_id >=LMAC_MODE_MAX ) {dev_err (&cgx->pdev->dev,"Unknown lmac_type_id %d reported by firmware on cgx port%d:%d" , linfo->lmac_type_id, cgx->cgx_id, lmac_id); -strncpy (linfo->lmac_type,"Unknown" ,LMACTYPE_STR_LEN -1 ); +strscpy (linfo->lmac_type,"Unknown" ,sizeof (linfo->lmac_type));return ; } -strncpy (linfo->lmac_type, cgx_lmactype_string[linfo->lmac_type_id], -LMACTYPE_STR_LEN -1 ); +strscpy (linfo->lmac_type, cgx_lmactype_string[linfo->lmac_type_id], +sizeof (linfo->lmac_type)); }/* Hardware event handlers */
Greg Kroah-Hartman
maintainerPATCH 295/342 octeontx2-af: CGX: add bounds check to cgx_speed_mbps index
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sam Daly <[email protected]>
[ Upstream commit c0bf0a4f3f1f5f57aa83e1400ba4f56f0abfd542 ]
cgx_speed_mbps has 13 elements but RESP_LINKSTAT_SPEED can yield values 0-15. If it returns a value >= 13, this causes an out-of-bounds array access. Add a bounds check and default to speed 0 if the index is out of range.
--- drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/net/ethernet/marvell/octeontx2/af/cgx.c +6 -1
@@ -669,13 +669,18 @@ static inline void link_status_user_formstruct cgx_link_user_info *linfo, struct cgx *cgx, u8 lmac_id) { + unsigned int speed; + linfo->link_up =FIELD_GET (RESP_LINKSTAT_UP , lstat); linfo->full_duplex =FIELD_GET (RESP_LINKSTAT_FDUPLEX , lstat); - linfo->speed = cgx_speed_mbps[FIELD_GET (RESP_LINKSTAT_SPEED , lstat)]; linfo->an =FIELD_GET (RESP_LINKSTAT_AN , lstat); linfo->fec =FIELD_GET (RESP_LINKSTAT_FEC , lstat); linfo->lmac_type_id =cgx_get_lmac_type (cgx, lmac_id); + speed =FIELD_GET (RESP_LINKSTAT_SPEED , lstat); + linfo->speed = speed <ARRAY_SIZE (cgx_speed_mbps) ? + cgx_speed_mbps[speed] :0 ; +if (linfo->lmac_type_id >=LMAC_MODE_MAX ) {dev_err (&cgx->pdev->dev,"Unknown lmac_type_id %d reported by firmware on cgx port%d:%d" , linfo->lmac_type_id, cgx->cgx_id, lmac_id);
Greg Kroah-Hartman
maintainerPATCH 296/342 spi: qup: switch to use modern name
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yingliang <[email protected]>
[ Upstream commit 597442ff4f6226206b7cc28b86eb2be0ae9c6418 ]
Change legacy name master to modern name host or controller.
No functional changed.
Stable-dep-of: a7e8f3efd50a ("spi: qup: fix error pointer deref after DMA setup failure")
--- drivers/spi/spi-qup.c | 164 +++++++++++++++++++++++++------------------------- 1 file changed, 82 insertions(+), 82 deletions(-)
drivers/spi/spi-qup.c +82 -82
@@ -386,20 +386,20 @@ static void spi_qup_write(struct spi_qup }while (remainder); } -static int spi_qup_prep_sg (struct spi_master *master,struct scatterlist *sgl, +static int spi_qup_prep_sg (struct spi_controller *host,struct scatterlist *sgl,unsigned int nents,enum dma_transfer_direction dir,dma_async_tx_callback callback) { -struct spi_qup *qup =spi_master_get_devdata (master); +struct spi_qup *qup =spi_controller_get_devdata (host);unsigned long flags =DMA_PREP_INTERRUPT |DMA_PREP_FENCE ;struct dma_async_tx_descriptor *desc;struct dma_chan *chan;dma_cookie_t cookie;if (dir ==DMA_MEM_TO_DEV ) - chan = master->dma_tx; + chan = host->dma_tx;else - chan = master->dma_rx; + chan = host->dma_rx; desc =dmaengine_prep_slave_sg (chan, sgl, nents, dir, flags);if (IS_ERR_OR_NULL (desc))
@@ -413,13 +413,13 @@ static int spi_qup_prep_sg(struct spi_mareturn dma_submit_error (cookie); } -static void spi_qup_dma_terminate (struct spi_master *master, +static void spi_qup_dma_terminate (struct spi_controller *host,struct spi_transfer *xfer) {if (xfer->tx_buf) -dmaengine_terminate_all (master->dma_tx); +dmaengine_terminate_all (host->dma_tx);if (xfer->rx_buf) -dmaengine_terminate_all (master->dma_rx); +dmaengine_terminate_all (host->dma_rx); } static u32 spi_qup_sgl_get_nents_len(struct scatterlist *sgl, u32 max,
@@ -446,8 +446,8 @@ static int spi_qup_do_dma(struct spi_dev unsigned long timeout) {dma_async_tx_callback rx_done =NULL , tx_done =NULL ; -struct spi_master *master = spi->master; -struct spi_qup *qup =spi_master_get_devdata (master); +struct spi_controller *host = spi->controller; +struct spi_qup *qup =spi_controller_get_devdata (host);struct scatterlist *tx_sgl, *rx_sgl;int ret;
@@ -482,20 +482,20 @@ static int spi_qup_do_dma(struct spi_devreturn ret; }if (rx_sgl) { - ret =spi_qup_prep_sg (master, rx_sgl, rx_nents, + ret =spi_qup_prep_sg (host, rx_sgl, rx_nents,DMA_DEV_TO_MEM , rx_done);if (ret)return ret; -dma_async_issue_pending (master->dma_rx); +dma_async_issue_pending (host->dma_rx); }if (tx_sgl) { - ret =spi_qup_prep_sg (master, tx_sgl, tx_nents, + ret =spi_qup_prep_sg (host, tx_sgl, tx_nents,DMA_MEM_TO_DEV , tx_done);if (ret)return ret; -dma_async_issue_pending (master->dma_tx); +dma_async_issue_pending (host->dma_tx); }if (!wait_for_completion_timeout (&qup->done, timeout))
@@ -514,8 +514,8 @@ static int spi_qup_do_dma(struct spi_devstatic int spi_qup_do_pio (struct spi_device *spi,struct spi_transfer *xfer,unsigned long timeout) { -struct spi_master *master = spi->master; -struct spi_qup *qup =spi_master_get_devdata (master); +struct spi_controller *host = spi->controller; +struct spi_qup *qup =spi_controller_get_devdata (host);int ret, n_words, iterations, offset =0 ; n_words = qup->n_words;
@@ -660,7 +660,7 @@ static irqreturn_t spi_qup_qup_irq(int i/* set clock freq ... bits per word, determine mode */ static int spi_qup_io_prep (struct spi_device *spi,struct spi_transfer *xfer) { -struct spi_qup *controller =spi_master_get_devdata (spi->master); +struct spi_qup *controller =spi_controller_get_devdata (spi->controller);int ret;if (spi->mode &SPI_LOOP && xfer->len > controller->in_fifo_sz) {
@@ -681,9 +681,9 @@ static int spi_qup_io_prep(struct spi_deif (controller->n_words <= (controller->in_fifo_sz /sizeof (u32))) controller->mode =QUP_IO_M_MODE_FIFO ; -else if (spi->master->can_dma && - spi->master->can_dma (spi->master, spi, xfer) && - spi->master->cur_msg_mapped) +else if (spi->controller->can_dma && + spi->controller->can_dma (spi->controller, spi, xfer) && + spi->controller->cur_msg_mapped) controller->mode =QUP_IO_M_MODE_BAM ;else controller->mode =QUP_IO_M_MODE_BLOCK ;
@@ -694,7 +694,7 @@ static int spi_qup_io_prep(struct spi_de/* prep qup for another spi transaction of specific type */ static int spi_qup_io_config (struct spi_device *spi,struct spi_transfer *xfer) { -struct spi_qup *controller =spi_master_get_devdata (spi->master); +struct spi_qup *controller =spi_controller_get_devdata (spi->controller);u32 config, iomode, control;unsigned long flags;
@@ -842,11 +842,11 @@ static int spi_qup_io_config(struct spi_return 0 ; } -static int spi_qup_transfer_one (struct spi_master *master, +static int spi_qup_transfer_one (struct spi_controller *host,struct spi_device *spi,struct spi_transfer *xfer) { -struct spi_qup *controller =spi_master_get_devdata (master); +struct spi_qup *controller =spi_controller_get_devdata (host);unsigned long timeout, flags;int ret;
@@ -880,21 +880,21 @@ static int spi_qup_transfer_one(struct sspin_unlock_irqrestore (&controller->lock, flags);if (ret &&spi_qup_is_dma_xfer (controller->mode)) -spi_qup_dma_terminate (master, xfer); +spi_qup_dma_terminate (host, xfer);return ret; } -static bool spi_qup_can_dma (struct spi_master *master,struct spi_device *spi, +static bool spi_qup_can_dma (struct spi_controller *host,struct spi_device *spi,struct spi_transfer *xfer) { -struct spi_qup *qup =spi_master_get_devdata (master); +struct spi_qup *qup =spi_controller_get_devdata (host);size_t dma_align =dma_get_cache_alignment ();int n_words;if (xfer->rx_buf) {if (!IS_ALIGNED ((size_t )xfer->rx_buf, dma_align) || -IS_ERR_OR_NULL (master->dma_rx)) +IS_ERR_OR_NULL (host->dma_rx))return false;if (qup->qup_v1 && (xfer->len % qup->in_blk_sz))return false;
@@ -902,7 +902,7 @@ static bool spi_qup_can_dma(struct spi_mif (xfer->tx_buf) {if (!IS_ALIGNED ((size_t )xfer->tx_buf, dma_align) || -IS_ERR_OR_NULL (master->dma_tx)) +IS_ERR_OR_NULL (host->dma_tx))return false;if (qup->qup_v1 && (xfer->len % qup->out_blk_sz))return false;
@@ -915,30 +915,30 @@ static bool spi_qup_can_dma(struct spi_mreturn true; } -static void spi_qup_release_dma (struct spi_master *master) +static void spi_qup_release_dma (struct spi_controller *host) { -if (!IS_ERR_OR_NULL (master->dma_rx)) -dma_release_channel (master->dma_rx); -if (!IS_ERR_OR_NULL (master->dma_tx)) -dma_release_channel (master->dma_tx); +if (!IS_ERR_OR_NULL (host->dma_rx)) +dma_release_channel (host->dma_rx); +if (!IS_ERR_OR_NULL (host->dma_tx)) +dma_release_channel (host->dma_tx); } -static int spi_qup_init_dma (struct spi_master *master,resource_size_t base) +static int spi_qup_init_dma (struct spi_controller *host,resource_size_t base) { -struct spi_qup *spi =spi_master_get_devdata (master); +struct spi_qup *spi =spi_controller_get_devdata (host);struct dma_slave_config *rx_conf = &spi->rx_conf, *tx_conf = &spi->tx_conf;struct device *dev = spi->dev;int ret;/* allocate dma resources, if available */ - master->dma_rx =dma_request_chan (dev,"rx" ); -if (IS_ERR (master->dma_rx)) -return PTR_ERR (master->dma_rx); - - master->dma_tx =dma_request_chan (dev,"tx" ); -if (IS_ERR (master->dma_tx)) { - ret =PTR_ERR (master->dma_tx); + host->dma_rx =dma_request_chan (dev,"rx" ); +if (IS_ERR (host->dma_rx)) +return PTR_ERR (host->dma_rx); + + host->dma_tx =dma_request_chan (dev,"tx" ); +if (IS_ERR (host->dma_tx)) { + ret =PTR_ERR (host->dma_tx); goto err_tx; }
@@ -953,13 +953,13 @@ static int spi_qup_init_dma(struct spi_m tx_conf->dst_addr = base +QUP_OUTPUT_FIFO ; tx_conf->dst_maxburst = spi->out_blk_sz; - ret =dmaengine_slave_config (master->dma_rx, rx_conf); + ret =dmaengine_slave_config (host->dma_rx, rx_conf);if (ret) {dev_err (dev,"failed to configure RX channel\n" ); goto err; } - ret =dmaengine_slave_config (master->dma_tx, tx_conf); + ret =dmaengine_slave_config (host->dma_tx, tx_conf);if (ret) {dev_err (dev,"failed to configure TX channel\n" ); goto err;
@@ -968,9 +968,9 @@ static int spi_qup_init_dma(struct spi_mreturn 0 ; err: -dma_release_channel (master->dma_tx); +dma_release_channel (host->dma_tx); err_tx: -dma_release_channel (master->dma_rx); +dma_release_channel (host->dma_rx);return ret; }
@@ -980,7 +980,7 @@ static void spi_qup_set_cs(struct spi_deu32 spi_ioc;u32 spi_ioc_orig; - controller =spi_master_get_devdata (spi->master); + controller =spi_controller_get_devdata (spi->controller); spi_ioc =readl_relaxed (controller->base +SPI_IO_CONTROL ); spi_ioc_orig = spi_ioc;if (!val)
@@ -994,7 +994,7 @@ static void spi_qup_set_cs(struct spi_destatic int spi_qup_probe (struct platform_device *pdev) { -struct spi_master *master; +struct spi_controller *host;struct clk *iclk, *cclk;struct spi_qup *controller;struct resource *res;
@@ -1030,32 +1030,32 @@ static int spi_qup_probe(struct platformreturn -ENXIO ; } - master =spi_alloc_master (dev,sizeof (struct spi_qup )); -if (!master) { -dev_err (dev,"cannot allocate master\n" ); + host =spi_alloc_master (dev,sizeof (struct spi_qup )); +if (!host) { +dev_err (dev,"cannot allocate host\n" );return -ENOMEM ; }/* use num-cs unless not present or out of range */ if (of_property_read_u32 (dev->of_node,"num-cs" , &num_cs) || num_cs >SPI_NUM_CHIPSELECTS ) - master->num_chipselect =SPI_NUM_CHIPSELECTS ; + host->num_chipselect =SPI_NUM_CHIPSELECTS ;else - master->num_chipselect = num_cs; + host->num_chipselect = num_cs; - master->bus_num = pdev->id; - master->mode_bits =SPI_CPOL |SPI_CPHA |SPI_CS_HIGH |SPI_LOOP ; - master->bits_per_word_mask =SPI_BPW_RANGE_MASK (4 ,32 ); - master->max_speed_hz = max_freq; - master->transfer_one = spi_qup_transfer_one; - master->dev.of_node = pdev->dev.of_node; - master->auto_runtime_pm = true; - master->dma_alignment =dma_get_cache_alignment (); - master->max_dma_len =SPI_MAX_XFER ; + host->bus_num = pdev->id; + host->mode_bits =SPI_CPOL |SPI_CPHA |SPI_CS_HIGH |SPI_LOOP ; + host->bits_per_word_mask =SPI_BPW_RANGE_MASK (4 ,32 ); + host->max_speed_hz = max_freq; + host->transfer_one = spi_qup_transfer_one; + host->dev.of_node = pdev->dev.of_node; + host->auto_runtime_pm = true; + host->dma_alignment =dma_get_cache_alignment (); + host->max_dma_len =SPI_MAX_XFER ; -platform_set_drvdata (pdev, master); +platform_set_drvdata (pdev, host); - controller =spi_master_get_devdata (master); + controller =spi_controller_get_devdata (host); controller->dev = dev; controller->base = base;
@@ -1063,16 +1063,16 @@ static int spi_qup_probe(struct platform controller->cclk = cclk; controller->irq = irq; - ret =spi_qup_init_dma (master, res->start); + ret =spi_qup_init_dma (host, res->start);if (ret == -EPROBE_DEFER ) goto error;else if (!ret) - master->can_dma = spi_qup_can_dma; + host->can_dma = spi_qup_can_dma; controller->qup_v1 = (uintptr_t )of_device_get_match_data (dev);if (!controller->qup_v1) - master->set_cs = spi_qup_set_cs; + host->set_cs = spi_qup_set_cs;spin_lock_init (&controller->lock);init_completion (&controller->done);
@@ -1150,7 +1150,7 @@ static int spi_qup_probe(struct platformpm_runtime_set_active (dev);pm_runtime_enable (dev); - ret =devm_spi_register_master (dev, master); + ret =devm_spi_register_controller (dev, host);if (ret) goto disable_pm;
@@ -1162,17 +1162,17 @@ error_clk:clk_disable_unprepare (cclk);clk_disable_unprepare (iclk); error_dma: -spi_qup_release_dma (master); +spi_qup_release_dma (host); error: -spi_master_put (master); +spi_controller_put (host);return ret; }#ifdef CONFIG_PM static int spi_qup_pm_suspend_runtime (struct device *device) { -struct spi_master *master =dev_get_drvdata (device); -struct spi_qup *controller =spi_master_get_devdata (master); +struct spi_controller *host =dev_get_drvdata (device); +struct spi_qup *controller =spi_controller_get_devdata (host);u32 config;/* Enable clocks auto gaiting */
@@ -1188,8 +1188,8 @@ static int spi_qup_pm_suspend_runtime(ststatic int spi_qup_pm_resume_runtime (struct device *device) { -struct spi_master *master =dev_get_drvdata (device); -struct spi_qup *controller =spi_master_get_devdata (master); +struct spi_controller *host =dev_get_drvdata (device); +struct spi_qup *controller =spi_controller_get_devdata (host);u32 config;int ret;
@@ -1214,8 +1214,8 @@ static int spi_qup_pm_resume_runtime(str#ifdef CONFIG_PM_SLEEP static int spi_qup_suspend (struct device *device) { -struct spi_master *master =dev_get_drvdata (device); -struct spi_qup *controller =spi_master_get_devdata (master); +struct spi_controller *host =dev_get_drvdata (device); +struct spi_qup *controller =spi_controller_get_devdata (host);int ret;if (pm_runtime_suspended (device)) {
@@ -1223,7 +1223,7 @@ static int spi_qup_suspend(struct deviceif (ret)return ret; } - ret =spi_master_suspend (master); + ret =spi_controller_suspend (host);if (ret)return ret;
@@ -1238,8 +1238,8 @@ static int spi_qup_suspend(struct devicestatic int spi_qup_resume (struct device *device) { -struct spi_master *master =dev_get_drvdata (device); -struct spi_qup *controller =spi_master_get_devdata (master); +struct spi_controller *host =dev_get_drvdata (device); +struct spi_qup *controller =spi_controller_get_devdata (host);int ret; ret =clk_prepare_enable (controller->iclk);
@@ -1256,7 +1256,7 @@ static int spi_qup_resume(struct deviceif (ret) goto disable_clk; - ret =spi_master_resume (master); + ret =spi_controller_resume (host);if (ret) goto disable_clk;
@@ -1271,8 +1271,8 @@ disable_clk:static int spi_qup_remove (struct platform_device *pdev) { -struct spi_master *master =dev_get_drvdata (&pdev->dev); -struct spi_qup *controller =spi_master_get_devdata (master); +struct spi_controller *host =dev_get_drvdata (&pdev->dev); +struct spi_qup *controller =spi_controller_get_devdata (host);int ret; ret =pm_runtime_get_sync (&pdev->dev);
@@ -1290,7 +1290,7 @@ static int spi_qup_remove(struct platfor ERR_PTR(ret)); } -spi_qup_release_dma (master); +spi_qup_release_dma (host);pm_runtime_put_noidle (&pdev->dev);pm_runtime_disable (&pdev->dev);
Greg Kroah-Hartman
maintainerPATCH 297/342 spi: qup: fix error pointer deref after DMA setup failure
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit a7e8f3efd50a165ba0189f6dc57f7e51a7d149db ]
The driver falls back to PIO mode if DMA setup fails during probe.
Make sure to the clear the DMA channel pointers on setup failure to avoid dereferencing an error pointer (or attempting to release a channel a second time) on later probe errors or driver unbind.
This issue was flagged by Sashiko when reviewing a devres allocation conversion patch.
--- drivers/spi/spi-qup.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/spi/spi-qup.c +3 -0
@@ -969,8 +969,11 @@ static int spi_qup_init_dma(struct spi_c err:dma_release_channel (host->dma_tx); + host->dma_tx =NULL ; err_tx:dma_release_channel (host->dma_rx); + host->dma_rx =NULL ; +return ret; }
Greg Kroah-Hartman
maintainerPATCH 298/342 arm64: tlb: Flush walk cache when unsharing PMD tables
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zeng Heng <[email protected]>
[ Upstream commit c2ff4764e03e7a8d758352f4aceb8fe1be6ac971 ]
When huge_pmd_unshare() is called to unshare a PMD table, the tlb_unshare_pmd_ptdesc() function sets tlb->unshared_tables=true but the aarch64 tlb_flush() only checked tlb->freed_tables to determine whether to use TLBF_NONE (vae1is, invalidates walk cache) or TLBF_NOWALKCACHE (vale1is, leaf-only).
This caused the stale PMD page table entry to remain in the walk cache after unshare, potentially leading to incorrect page table walks.
Fix by including unshared_tables in the check, so that when unsharing tables, TLBF_NONE is used and the walk cache is properly invalidated.
Here is the detailed distinction between vae1is and vale1is:
| Instruction Combination | Actual Invalidation Scope | | ------------------------ | --------------------------------------------------| | `VAE1IS` + TTL=`0` | All entries at all levels (full invalidation) | | `VAE1IS` + TTL=`2` (L2) | Non-leaf at Level 0/1 + leaf at Level 2 | | `VALE1IS` + TTL=`0` | Leaf entries at all levels (non-leaf not cleared) | | `VALE1IS` + TTL=`2` (L2) | Leaf entry at Level 2 only |
--- arch/arm64/include/asm/tlb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/include/asm/tlb.h +1 -1
@@ -53,7 +53,7 @@ static inline int tlb_get_level(struct mstatic inline void tlb_flush (struct mmu_gather *tlb) {struct vm_area_struct vma =TLB_FLUSH_VMA (tlb->mm,0 ); -bool last_level = !tlb->freed_tables; +bool last_level = !(tlb->freed_tables || tlb->unshared_tables);unsigned long stride =tlb_get_unmap_size (tlb);int tlb_level =tlb_get_level (tlb);
Greg Kroah-Hartman
maintainerPATCH 299/342 phy: tegra: xusb: Disable trk clk when not in use
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wayne Chang <[email protected]>
[ Upstream commit 71d9e899584e11bbd7eaf9934a619c69a15060d8 ]
Pad tracking is a one-time calibration for Tegra186 and Tegra194. Clk should be disabled after calibration.
Disable clk after calibration.
While at it add 100us delay for HW recording the calibration value.
Stable-dep-of: da110228b54f ("phy: tegra: xusb: Fix per-pad high-speed termination calibration")
--- drivers/phy/tegra/xusb-tegra186.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/phy/tegra/xusb-tegra186.c +4 -2
@@ -225,6 +225,10 @@ static void tegra186_utmi_bias_pad_power value &= ~USB2_PD_TRK ;padctl_writel (padctl, value,XUSB_PADCTL_USB2_BIAS_PAD_CTL1 ); +udelay (100 ); + +clk_disable_unprepare (priv->usb2_trk_clk); +mutex_unlock (&padctl->lock); }
@@ -249,8 +253,6 @@ static void tegra186_utmi_bias_pad_power value |=USB2_PD_TRK ;padctl_writel (padctl, value,XUSB_PADCTL_USB2_BIAS_PAD_CTL1 ); -clk_disable_unprepare (priv->usb2_trk_clk); -mutex_unlock (&padctl->lock); }
Greg Kroah-Hartman
maintainerPATCH 300/342 phy: tegra: xusb: Fix per-pad high-speed termination calibration
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wayne Chang <[email protected]>
[ Upstream commit da110228b54f2e2143d97ea7151e0dc22e539d67 ]
The existing code reads a single hs_term_range_adj value from bit field [10:7] of FUSE_SKU_CALIB_0 and applies it to all USB2 pads uniformly. However, on SoCs that support per-pad termination, each pad has its own hs_term_range_adj field: pad 0 in FUSE_SKU_CALIB_0[10:7], and pads 1-3 in FUSE_USB_CALIB_EXT_0 at bit offsets [8:5], [12:9], and [16:13] respectively.
Fix the calibration by reading per-pad values from the appropriate fuse registers. For SoCs that do not support per-pad termination, replicate pad 0's value to all pads to maintain existing behavior.
Add a has_per_pad_term flag to the SoC data to indicate whether per-pad termination values are available in FUSE_USB_CALIB_EXT_0.
--- drivers/phy/tegra/xusb-tegra186.c | 32 +++++++++++++++++++++++++------- drivers/phy/tegra/xusb.h | 1 + 2 files changed, 26 insertions(+), 7 deletions(-)
drivers/phy/tegra/xusb-tegra186.c +25 -7
@@ -20,8 +20,8 @@/* FUSE USB_CALIB registers */ #define HS_CURR_LEVEL_PADX_SHIFT (x) ((x) ? (11 + (x - 1) * 6) : 0)#define HS_CURR_LEVEL_PAD_MASK 0x3f -#define HS_TERM_RANGE_ADJ_SHIFT 7 -#define HS_TERM_RANGE_ADJ_MASK 0xf +#define HS_TERM_RANGE_ADJ_PADX_SHIFT (x) ((x) ? (5 + (x - 1) * 4) : 7) +#define HS_TERM_RANGE_ADJ_PAD_MASK 0xf#define HS_SQUELCH_SHIFT 29#define HS_SQUELCH_MASK 0x7
@@ -127,7 +127,7 @@struct tegra_xusb_fuse_calibration {u32 *hs_curr_level;u32 hs_squelch; -u32 hs_term_range_adj; +u32 *hs_term_range_adj;u32 rpd_ctrl; };
@@ -477,7 +477,7 @@ static int tegra186_utmi_phy_power_on(st value =padctl_readl (padctl,XUSB_PADCTL_USB2_OTG_PADX_CTL1 (index)); value &= ~TERM_RANGE_ADJ (~0 ); - value |=TERM_RANGE_ADJ (priv->calib.hs_term_range_adj); + value |=TERM_RANGE_ADJ (priv->calib.hs_term_range_adj[index]); value &= ~RPD_CTRL (~0 ); value |=RPD_CTRL (priv->calib.rpd_ctrl);padctl_writel (padctl, value,XUSB_PADCTL_USB2_OTG_PADX_CTL1 (index));
@@ -895,17 +895,23 @@ static const char * const tegra186_usb3_static int tegra186_xusb_read_fuse_calibration (struct tegra186_xusb_padctl *padctl) { +const struct tegra_xusb_padctl_soc *soc = padctl->base.soc;struct device *dev = padctl->base.dev;unsigned int i, count;u32 value, *level; +u32 *hs_term_range_adj;int err; - count = padctl->base.soc->ports.usb2.count; + count = soc->ports.usb2.count; level =devm_kcalloc (dev, count,sizeof (u32),GFP_KERNEL );if (!level)return -ENOMEM ; + hs_term_range_adj =devm_kcalloc (dev, count,sizeof (u32),GFP_KERNEL ); +if (!hs_term_range_adj) +return -ENOMEM ; + err =tegra_fuse_readl (TEGRA_FUSE_SKU_CALIB_0 , &value);if (err) {if (err != -EPROBE_DEFER )
@@ -924,8 +930,8 @@ tegra186_xusb_read_fuse_calibration(stru padctl->calib.hs_squelch = (value >>HS_SQUELCH_SHIFT ) &HS_SQUELCH_MASK ; - padctl->calib.hs_term_range_adj = (value >>HS_TERM_RANGE_ADJ_SHIFT ) & -HS_TERM_RANGE_ADJ_MASK ; + hs_term_range_adj[0 ] = (value >>HS_TERM_RANGE_ADJ_PADX_SHIFT (0 )) & +HS_TERM_RANGE_ADJ_PAD_MASK ; err =tegra_fuse_readl (TEGRA_FUSE_USB_CALIB_EXT_0 , &value);if (err) {
@@ -937,6 +943,17 @@ tegra186_xusb_read_fuse_calibration(stru padctl->calib.rpd_ctrl = (value >>RPD_CTRL_SHIFT ) &RPD_CTRL_MASK ; +for (i =1 ; i < count; i++) { +if (soc->has_per_pad_term) + hs_term_range_adj[i] = + (value >>HS_TERM_RANGE_ADJ_PADX_SHIFT (i)) & +HS_TERM_RANGE_ADJ_PAD_MASK ; +else + hs_term_range_adj[i] = hs_term_range_adj[0 ]; + } + + padctl->calib.hs_term_range_adj = hs_term_range_adj; +return 0 ; }
@@ -1095,6 +1112,7 @@ const struct tegra_xusb_padctl_soc tegra .supply_names = tegra194_xusb_padctl_supply_names, .num_supplies = ARRAY_SIZE(tegra194_xusb_padctl_supply_names), .supports_gen2 = true, + .has_per_pad_term = true, };EXPORT_SYMBOL_GPL (tegra194_xusb_padctl_soc);#endif
drivers/phy/tegra/xusb.h +1 -0
@@ -415,6 +415,7 @@ struct tegra_xusb_padctl_soc {unsigned int num_supplies;bool supports_gen2;bool need_fake_usb3_port; +bool has_per_pad_term; };struct tegra_xusb_padctl {
Greg Kroah-Hartman
maintainerPATCH 301/342 scsi: target: iscsi: Bound iscsi_encode_text_output() appends to rsp_buf
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
[ Upstream commit bf33e01f88388c43e285492a63e539df6ffed64c ]
iscsi_encode_text_output() concatenates "key=value\0" records into login->rsp_buf, an 8192-byte kzalloc(MAX_KEY_VALUE_PAIRS) buffer allocated in iscsit_alloc_login_setup_buffer(). The three sprintf() call sites in this function (lines 1398, 1411, 1424 in v7.1-rc2) never check the remaining buffer capacity:
*length += sprintf(output_buf, "%s=%s", er->key, er->value); *length += 1; output_buf = textbuf + *length;
The 8192-byte ceiling at iscsi_target_check_login_request() bounds the *input* Login PDU payload, but a single PDU can carry up to 2048 minimal four-byte "a=b\0" pairs, each unknown key expanding to a 16-byte "a=NotUnderstood\0" output record via iscsi_add_notunderstood_response(). 2048 * 16 = 32 KiB of output into an 8 KiB buffer, producing a ~24 KiB heap overrun in the kmalloc-8k slab.
The fix introduces a static iscsi_encode_text_record() helper that uses snprintf() with a per-call bounds check against the remaining buffer, and threads a u32 textbuf_size parameter through iscsi_encode_text_output(). Both call sites in iscsi_target_handle_csg_zero() (PHASE_SECURITY) and iscsi_target_handle_csg_one() (PHASE_OPERATIONAL) pass MAX_KEY_VALUE_PAIRS. On overflow the encoder logs the condition, calls iscsi_release_extra_responses() to drop queued records, and returns -1; both caller sites now emit ISCSI_STATUS_CLS_INITIATOR_ERR / ISCSI_LOGIN_STATUS_INIT_ERR via iscsit_tx_login_rsp() before returning, so the initiator sees an explicit failed-login response rather than a silent connection drop. (Prior to this patch only the PHASE_OPERATIONAL caller did that; the PHASE_SECURITY caller is converted to the same shape.)
--- drivers/target/iscsi/iscsi_target_nego.c | 7 ++ drivers/target/iscsi/iscsi_target_parameters.c | 62 +++++++++++++++++++------ drivers/target/iscsi/iscsi_target_parameters.h | 2 3 files changed, 55 insertions(+), 16 deletions(-)
drivers/target/iscsi/iscsi_target_nego.c +6 -1
@@ -878,10 +878,14 @@ static int iscsi_target_handle_csg_zero(SENDER_TARGET , login->rsp_buf, &login->rsp_length, +MAX_KEY_VALUE_PAIRS , conn->param_list, conn->tpg->tpg_attrib.login_keys_workaround); -if (ret <0 ) +if (ret <0 ) { +iscsit_tx_login_rsp (conn,ISCSI_STATUS_CLS_INITIATOR_ERR , +ISCSI_LOGIN_STATUS_INIT_ERR );return -1 ; + }if (!iscsi_check_negotiated_keys (conn->param_list)) { if (conn->tpg->tpg_attrib.authentication &&
@@ -949,6 +953,7 @@ static int iscsi_target_handle_csg_one(sSENDER_TARGET , login->rsp_buf, &login->rsp_length, +MAX_KEY_VALUE_PAIRS , conn->param_list, conn->tpg->tpg_attrib.login_keys_workaround);if (ret <0 ) {
drivers/target/iscsi/iscsi_target_parameters.c +48 -14
101 lines not on this page · raw message
drivers/target/iscsi/iscsi_target_parameters.h +1 -1
@@ -46,7 +46,7 @@ extern struct iscsi_param *iscsi_find_paextern int iscsi_extract_key_value (char *,char **,char **);extern int iscsi_update_param_value (struct iscsi_param *,char *);extern int iscsi_decode_text_input (u8 ,u8 ,char *,u32 ,struct iscsi_conn *); -extern int iscsi_encode_text_output (u8 ,u8 ,char *,u32 *, +extern int iscsi_encode_text_output (u8 ,u8 ,char *,u32 *,u32 ,struct iscsi_param_list *,bool );extern int iscsi_check_negotiated_keys (struct iscsi_param_list *); extern void iscsi_set_connection_parameters(struct iscsi_conn_ops *,
Greg Kroah-Hartman
maintainerPATCH 302/342 usb: typec: ucsi: Check if power role change actually happened before handling
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myrrh Periwinkle <[email protected]>
[ Upstream commit b80e7d34c7ea6a564525119d6138fbb577a23dba ]
The CrOS EC may send a connector status change event with the power direction changed flag set even if the power direction hasn't actually changed after initiating a SET_PDR command internally [1]. In practice this happens on every system suspend due to other changes performed by the EC [2][3][4], causing suspend to fail.
Fix this by checking if the power role change actually happened before handling it.
[1]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/subsys/pd_controller/pdc_power_mgmt.c;l=1689;drc=2d5a1cffce4e5ac8a39442cb3b764d2d5e1cf794
[2]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/subsys/pd_controller/pdc_power_mgmt.c;l=3923;drc=2d5a1cffce4e5ac8a39442cb3b764d2d5e1cf794
[3]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/subsys/pd_controller/pdc_power_mgmt.c;l=5094;drc=2d5a1cffce4e5ac8a39442cb3b764d2d5e1cf794
[4]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/subsys/pd_controller/pdc_power_mgmt.c;l=2229;drc=2d5a1cffce4e5ac8a39442cb3b764d2d5e1cf794
--- drivers/usb/typec/ucsi/ucsi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/usb/typec/ucsi/ucsi.c +5 -2
@@ -656,7 +656,7 @@ static void ucsi_handle_connector_changestruct ucsi *ucsi = con->ucsi;struct ucsi_connector_status pre_ack_status;struct ucsi_connector_status post_ack_status; -enum typec_role role; +enum typec_role role, prev_role;u16 inferred_changes;u16 changed_flags;u64 command;
@@ -692,6 +692,8 @@ static void ucsi_handle_connector_change* short transitional changes. */ + prev_role = !!(con->status.flags &UCSI_CONSTAT_PWR_DIR ); +/* 1. First UCSI_GET_CONNECTOR_STATUS */ command =UCSI_GET_CONNECTOR_STATUS |UCSI_CONNECTOR_NUMBER (con->num); ret = ucsi_send_command(ucsi, command, &pre_ack_status,
@@ -769,7 +771,8 @@ static void ucsi_handle_connector_changeucsi_port_psy_changed (con); } -if (con->status.change &UCSI_CONSTAT_POWER_DIR_CHANGE ) { +if ((con->status.change &UCSI_CONSTAT_POWER_DIR_CHANGE ) && + role != prev_role) {typec_set_pwr_role (con->port, role);/* Complete pending power role swap */
Greg Kroah-Hartman
maintainerPATCH 303/342 thunderbolt: property: Cap recursion depth in __tb_property_parse_dir()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
[ Upstream commit 928abe19fbf0127003abcb1ea69cabc1c897d0ab ]
A DIRECTORY entry's value field is used as the dir_offset for a recursive call into __tb_property_parse_dir() with no depth counter. A crafted peer that chains DIRECTORY entries into a back-reference loop drives the parser until the kernel stack is exhausted and the guard page fires. Any untrusted XDomain peer (cable, dock, in-line inspector, adjacent host) that reaches the PROPERTIES_REQUEST control-plane exchange can trigger this without authentication.
Thread a depth counter through tb_property_parse() and __tb_property_parse_dir(), and reject blocks that exceed TB_PROPERTY_MAX_DEPTH = 8. That is comfortably larger than any observed legitimate XDomain layout.
Operators who do not need XDomain host-to-host discovery can disable the path entirely with thunderbolt.xdomain=0 on the kernel command line.
--- drivers/thunderbolt/property.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/thunderbolt/property.c +12 -6
@@ -35,10 +35,11 @@ struct tb_property_dir_entry { };#define TB_PROPERTY_ROOTDIR_MAGIC 0x55584401 +#define TB_PROPERTY_MAX_DEPTH 8static struct tb_property_dir *__tb_property_parse_dir (const u32 *block,size_t block_len,unsigned int dir_offset,size_t dir_len, -bool is_root); +bool is_root,unsigned int depth);static inline void parse_dwdata (void *dst,const void *src,size_t dwords) {
@@ -99,7 +100,8 @@ tb_property_alloc(const char *key, enum }static struct tb_property *tb_property_parse (const u32 *block,size_t block_len, -const struct tb_property_entry *entry) +const struct tb_property_entry *entry, +unsigned int depth) {char key[TB_PROPERTY_KEY_SIZE +1 ];struct tb_property *property;
@@ -120,7 +122,7 @@ static struct tb_property *tb_property_pswitch (property->type) {case TB_PROPERTY_TYPE_DIRECTORY : dir =__tb_property_parse_dir (block, block_len, entry->value, - entry->length, false); + entry->length, false, depth +1 );if (!dir) {kfree (property);return NULL ;
@@ -165,13 +167,17 @@ static struct tb_property *tb_property_p }static struct tb_property_dir *__tb_property_parse_dir (const u32 *block, -size_t block_len,unsigned int dir_offset,size_t dir_len,bool is_root) +size_t block_len,unsigned int dir_offset,size_t dir_len,bool is_root, +unsigned int depth) {const struct tb_property_entry *entries;size_t i, content_len, nentries;unsigned int content_offset;struct tb_property_dir *dir; +if (depth >TB_PROPERTY_MAX_DEPTH ) +return NULL ; + dir =kzalloc (sizeof (*dir),GFP_KERNEL );if (!dir)return NULL ;
@@ -206,7 +212,7 @@ static struct tb_property_dir *__tb_propfor (i =0 ; i < nentries; i++) {struct tb_property *property; - property =tb_property_parse (block, block_len, &entries[i]); + property =tb_property_parse (block, block_len, &entries[i], depth);if (!property) {tb_property_free_dir (dir);return NULL ;
@@ -243,7 +249,7 @@ struct tb_property_dir *tb_property_parsreturn NULL ;return __tb_property_parse_dir (block, block_len,0 , rootdir->length, - true); + true,0 ); }/**
Greg Kroah-Hartman
maintainerPATCH 304/342 tty: serial: qcom-geni-serial: remove unused symbols
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
[ Upstream commit 68c6bd92c86cbc4937834c79963b27c77ee3bf51 ]
Drop all unused symbols from the driver.
Stable-dep-of: ca2584d841b6 ("serial: qcom-geni: fix UART_RX_PAR_EN bit position")
--- drivers/tty/serial/qcom_geni_serial.c | 15 --------------- 1 file changed, 15 deletions(-)
drivers/tty/serial/qcom_geni_serial.c +0 -15
@@ -38,20 +38,11 @@#define UART_TX_PAR_EN BIT(0)#define UART_CTS_MASK BIT(1) -/* SE_UART_TX_WORD_LEN */ -#define TX_WORD_LEN_MSK GENMASK(9, 0) -/* SE_UART_TX_STOP_BIT_LEN */ -#define TX_STOP_BIT_LEN_MSK GENMASK(23, 0)#define TX_STOP_BIT_LEN_1 0 -#define TX_STOP_BIT_LEN_1_5 1#define TX_STOP_BIT_LEN_2 2 -/* SE_UART_TX_TRANS_LEN */ -#define TX_TRANS_LEN_MSK GENMASK(23, 0) -/* SE_UART_RX_TRANS_CFG */ -#define UART_RX_INS_STATUS_BIT BIT(2)#define UART_RX_PAR_EN BIT(3)/* SE_UART_RX_WORD_LEN */
@@ -62,12 +53,9 @@/* SE_UART_TX_PARITY_CFG/RX_PARITY_CFG */ #define PAR_CALC_EN BIT(0) -#define PAR_MODE_MSK GENMASK(2, 1) -#define PAR_MODE_SHFT 1#define PAR_EVEN 0x00#define PAR_ODD 0x01#define PAR_SPACE 0x10 -#define PAR_MARK 0x11/* SE_UART_MANUAL_RFR register fields */ #define UART_MANUAL_RFR_EN BIT(31)
@@ -76,11 +64,8 @@/* UART M_CMD OP codes */ #define UART_START_TX 0x1 -#define UART_START_BREAK 0x4 -#define UART_STOP_BREAK 0x5/* UART S_CMD OP codes */ #define UART_START_READ 0x1 -#define UART_PARAM 0x1#define UART_OVERSAMPLING 32#define STALE_TIMEOUT 16
Greg Kroah-Hartman
maintainerPATCH 305/342 tty: serial: qcom-geni-serial: align #define values
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
[ Upstream commit 6cde11dbf4b65170eeefba48df730c93d75e01a3 ]
Keep the #define symbols aligned for better readability.
Stable-dep-of: ca2584d841b6 ("serial: qcom-geni: fix UART_RX_PAR_EN bit position")
--- drivers/tty/serial/qcom_geni_serial.c | 60 +++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-)
drivers/tty/serial/qcom_geni_serial.c +30 -30
@@ -35,57 +35,57 @@#define SE_UART_MANUAL_RFR 0x2ac/* SE_UART_TRANS_CFG */ -#define UART_TX_PAR_EN BIT(0) -#define UART_CTS_MASK BIT(1) +#define UART_TX_PAR_EN BIT(0) +#define UART_CTS_MASK BIT(1)/* SE_UART_TX_STOP_BIT_LEN */ -#define TX_STOP_BIT_LEN_1 0 -#define TX_STOP_BIT_LEN_2 2 +#define TX_STOP_BIT_LEN_1 0 +#define TX_STOP_BIT_LEN_2 2/* SE_UART_RX_TRANS_CFG */ -#define UART_RX_PAR_EN BIT(3) +#define UART_RX_PAR_EN BIT(3)/* SE_UART_RX_WORD_LEN */ -#define RX_WORD_LEN_MASK GENMASK(9, 0) +#define RX_WORD_LEN_MASK GENMASK(9, 0)/* SE_UART_RX_STALE_CNT */ -#define RX_STALE_CNT GENMASK(23, 0) +#define RX_STALE_CNT GENMASK(23, 0)/* SE_UART_TX_PARITY_CFG/RX_PARITY_CFG */ -#define PAR_CALC_EN BIT(0) -#define PAR_EVEN 0x00 -#define PAR_ODD 0x01 -#define PAR_SPACE 0x10 +#define PAR_CALC_EN BIT(0) +#define PAR_EVEN 0x00 +#define PAR_ODD 0x01 +#define PAR_SPACE 0x10/* SE_UART_MANUAL_RFR register fields */ -#define UART_MANUAL_RFR_EN BIT(31) -#define UART_RFR_NOT_READY BIT(1) -#define UART_RFR_READY BIT(0) +#define UART_MANUAL_RFR_EN BIT(31) +#define UART_RFR_NOT_READY BIT(1) +#define UART_RFR_READY BIT(0)/* UART M_CMD OP codes */ -#define UART_START_TX 0x1 +#define UART_START_TX 0x1/* UART S_CMD OP codes */ -#define UART_START_READ 0x1 +#define UART_START_READ 0x1 -#define UART_OVERSAMPLING 32 -#define STALE_TIMEOUT 16 -#define DEFAULT_BITS_PER_CHAR 10 -#define GENI_UART_CONS_PORTS 1 -#define GENI_UART_PORTS 3 -#define DEF_FIFO_DEPTH_WORDS 16 -#define DEF_TX_WM 2 -#define DEF_FIFO_WIDTH_BITS 32 -#define UART_RX_WM 2 +#define UART_OVERSAMPLING 32 +#define STALE_TIMEOUT 16 +#define DEFAULT_BITS_PER_CHAR 10 +#define GENI_UART_CONS_PORTS 1 +#define GENI_UART_PORTS 3 +#define DEF_FIFO_DEPTH_WORDS 16 +#define DEF_TX_WM 2 +#define DEF_FIFO_WIDTH_BITS 32 +#define UART_RX_WM 2/* SE_UART_LOOPBACK_CFG */ -#define RX_TX_SORTED BIT(0) -#define CTS_RTS_SORTED BIT(1) -#define RX_TX_CTS_RTS_SORTED (RX_TX_SORTED | CTS_RTS_SORTED) +#define RX_TX_SORTED BIT(0) +#define CTS_RTS_SORTED BIT(1) +#define RX_TX_CTS_RTS_SORTED (RX_TX_SORTED | CTS_RTS_SORTED)/* UART pin swap value */ -#define DEFAULT_IO_MACRO_IO0_IO1_MASK GENMASK(3, 0) +#define DEFAULT_IO_MACRO_IO0_IO1_MASK GENMASK(3, 0)#define IO_MACRO_IO0_SEL 0x3 -#define DEFAULT_IO_MACRO_IO2_IO3_MASK GENMASK(15, 4) +#define DEFAULT_IO_MACRO_IO2_IO3_MASK GENMASK(15, 4)#define IO_MACRO_IO2_IO3_SWAP 0x4640/* We always configure 4 bytes per FIFO word */
Greg Kroah-Hartman
maintainerPATCH 306/342 serial: qcom-geni: fix UART_RX_PAR_EN bit position
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prasanna S <[email protected]>
[ Upstream commit ca2584d841b69391ffc4144840563d2e1a0018df ]
UART_RX_PAR_EN is incorrectly defined as bit 3, which triggers false framing errors (S_GP_IRQ_1_EN) and causes received data to be dropped when parity is enabled and the parity bit is 0.
Define UART_RX_PAR_EN as bit 4 of the SE_UART_RX_TRANS_CFG register, as specified in the reference manual.
--- drivers/tty/serial/qcom_geni_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/qcom_geni_serial.c +1 -1
@@ -43,7 +43,7 @@#define TX_STOP_BIT_LEN_2 2/* SE_UART_RX_TRANS_CFG */ -#define UART_RX_PAR_EN BIT(3) +#define UART_RX_PAR_EN BIT(4)/* SE_UART_RX_WORD_LEN */ #define RX_WORD_LEN_MASK GENMASK(9, 0)
Greg Kroah-Hartman
maintainerPATCH 307/342 serial: altera_jtaguart: Use platform_get_irq_optional() to get the interrupt
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lad Prabhakar <[email protected]>
[ Upstream commit 60302276caff50f907bc3391a364691ab4a21b43 ]
platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static allocation of IRQ resources in DT core code, this causes an issue when using hierarchical interrupt domains using "interrupts" property in the node as this bypasses the hierarchical setup and messes up the irq chaining.
In preparation for removal of static setup of IRQ resource from DT core code use platform_get_irq_optional().
Stable-dep-of: ea66be25f0e9 ("serial: altera_jtaguart: handle uart_add_one_port() failures")
--- drivers/tty/serial/altera_jtaguart.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/tty/serial/altera_jtaguart.c +7 -4
@@ -420,8 +420,9 @@ static int altera_jtaguart_probe(structstruct altera_jtaguart_platform_uart *platp =dev_get_platdata (&pdev->dev);struct uart_port *port; -struct resource *res_irq, *res_mem; +struct resource *res_mem;int i = pdev->id; +int irq;/* -1 emphasizes that the platform must have one port, no .N suffix */ if (i ==-1 )
@@ -440,9 +441,11 @@ static int altera_jtaguart_probe(structelse return -ENODEV ; - res_irq =platform_get_resource (pdev,IORESOURCE_IRQ ,0 ); -if (res_irq) - port->irq = res_irq->start; + irq =platform_get_irq_optional (pdev,0 ); +if (irq <0 && irq != -ENXIO ) +return irq; +if (irq >0 ) + port->irq = irq;else if (platp) port->irq = platp->irq;else
Greg Kroah-Hartman
maintainerPATCH 308/342 serial: altera_jtaguart: handle uart_add_one_port() failures
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <[email protected]>
[ Upstream commit ea66be25f0e934f49d24cd0c5845d13cdba3520b ]
altera_jtaguart_probe() maps the register window before registering the UART port, but it ignores failures from uart_add_one_port(). If port registration fails, probe still returns success and the mapping remains live until a later remove path that is not part of probe failure cleanup.
Return the uart_add_one_port() error and unmap the register window on that failure path.
This issue was identified during our ongoing static-analysis research while reviewing kernel code.
--- drivers/tty/serial/altera_jtaguart.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/tty/serial/altera_jtaguart.c +6 -1
@@ -423,6 +423,7 @@ static int altera_jtaguart_probe(structstruct resource *res_mem;int i = pdev->id;int irq; +int ret;/* -1 emphasizes that the platform must have one port, no .N suffix */ if (i ==-1 )
@@ -462,7 +463,11 @@ static int altera_jtaguart_probe(struct port->flags =UPF_BOOT_AUTOCONF ; port->dev = &pdev->dev; -uart_add_one_port (&altera_jtaguart_driver, port); + ret =uart_add_one_port (&altera_jtaguart_driver, port); +if (ret) { +iounmap (port->membase); +return ret; + }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 309/342 scsi: target: iscsi: Fix CRC overread and double-free in iscsit_handle_text_cmd()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
[ Upstream commit 778c2ab142c625a8a8afa570e0f9b7873f445d99 ]
Two latent bugs in the Text-phase handler, both present since the original LIO integration in commit e48354ce078c ("iscsi-target: Add iSCSI fabric support for target v4.1"):
1) DataDigest CRC buffer overread (4 bytes past text_in).
text_in is kzalloc()'d at ALIGN(payload_length, 4). rx_size is then incremented by ISCSI_CRC_LEN to make room for the received DataDigest in the iovec, but the same (now-bumped) rx_size is passed as the buffer length to iscsit_crc_buf():
if (conn->conn_ops->DataDigest) {
...
rx_size += ISCSI_CRC_LEN;
}
...
if (conn->conn_ops->DataDigest) {
data_crc = iscsit_crc_buf(text_in, rx_size, 0, NULL); iscsit_crc_buf() walks rx_size bytes of text_in with crc32c(), so when DataDigest is negotiated it reads 4 bytes past the end of the text_in allocation. KASAN reproduces this directly on the unpatched mainline tree as slab-out-of-bounds in crc32c() called from the Text PDU path. The OOB bytes feed crc32c() and are then compared against the initiator-supplied checksum, so the value does not flow back to the attacker, but the kernel does read past the buffer on every Text PDU with DataDigest=CRC32C.
Fix by passing the actual padded payload length (ALIGN(payload_length, 4)) that was used for the kzalloc().
2) Stale cmd->text_in_ptr re-free (double-free) on ERL>0 bad DataDigest drop.
On DataDigest mismatch with ErrorRecoveryLevel > 0 the handler silently drops the PDU and lets the initiator plug the CmdSN gap:
kfree(text_in);
return 0; cmd->text_in_ptr still points at the freed buffer. The next Text Request on the same ITT re-enters iscsit_setup_text_cmd(), which unconditionally does
kfree(cmd->text_in_ptr);
cmd->text_in_ptr = NULL; freeing the same pointer a second time. Session teardown via iscsit_release_cmd() has the same shape and hits the same double-free if the connection is dropped before a second Text Request arrives.
On an unmodified mainline tree the bug-1 CRC overread fires first on the initial valid Text Request and perturbs the subsequent state, so #4 was isolated by building a kernel with only the bug-1 hunk of this patch applied plus temporary printk() observability around the three relevant kfree() sites. The observability prints are not part of this patch. On that build, a three-PDU Text Request sequence after login produces two back-to-back splats:
BUG: KASAN: double-free in iscsit_setup_text_cmd+0x??
BUG: KASAN: double-free in iscsit_release_cmd+0x?? showing the same pointer freed in the ERL>0 drop path and again in iscsit_setup_text_cmd() (next Text Request on the same ITT) and once more in iscsit_release_cmd() (session teardown). On distro kernels with CONFIG_SLAB_FREELIST_HARDENED=y (default) the double-free becomes a remote kernel BUG(); on non-hardened kernels it corrupts the slab freelist.
Fix by clearing cmd->text_in_ptr after the kfree() in the ERL>0 drop path. With both hunks applied #4 is directly observable on the stock tree without observability printks; fixing bug-1 alone would mask #4 less, not more, so the hunks are submitted together.
Both fixes are one-liners. The Text PDU state machine is unchanged and the wire protocol is unaffected.
--- drivers/target/iscsi/iscsi_target.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/target/iscsi/iscsi_target.c +4 -2
@@ -2294,8 +2294,9 @@ iscsit_handle_text_cmd(struct iscsi_connif (conn->conn_ops->DataDigest) {iscsit_do_crypto_hash_buf (conn->conn_rx_hash, - text_in, rx_size,0 ,NULL , - &data_crc); + text_in, +ALIGN (payload_length,4 ), +0 ,NULL , &data_crc);if (checksum != data_crc) { pr_err("Text data CRC32C DataDigest"
@@ -2315,6 +2316,7 @@ iscsit_handle_text_cmd(struct iscsi_conn" Command CmdSN: 0x%08x due to" " DataCRC error.\n", hdr->cmdsn);kfree (text_in); + cmd->text_in_ptr =NULL ;return 0 ; } }else {
Greg Kroah-Hartman
maintainerPATCH 310/342 usb: typec: ucsi: Dont update power_supply on power role change if not connected
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myrrh Periwinkle <[email protected]>
[ Upstream commit d98d413ca65d0790a8f3695d0a5845538958ab84 ]
We only need to update the power_supply on power role change if the port is connected, because otherwise the online status should be the same for both cases.
--- drivers/usb/typec/ucsi/ucsi.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/usb/typec/ucsi/ucsi.c +6 -0
@@ -775,6 +775,12 @@ static void ucsi_handle_connector_change role != prev_role) {typec_set_pwr_role (con->port, role); +/* Some power_supply properties vary depending on the power direction when +* connected +*/ +if (con->status.flags &UCSI_CONSTAT_CONNECTED ) +ucsi_port_psy_changed (con); +/* Complete pending power role swap */ if (!completion_done (&con->complete))complete (&con->complete);
Re: [PATCH 5.10 310/342] usb: typec: ucsi: Dont update power_supply on power role change if not connected
Quoted 27 lines · Greg Kroah-Hartman
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myrrh Periwinkle <[email protected]>
[ Upstream commit
d98d413ca65d0790a8f3695d0a5845538958ab84]We only need to update the
power_supplyon power role change if the port is connected, because otherwise the online status should be the same for both cases.Cc stable <[email protected]>Fixes 7616f006db07 ("usb: typec: ucsi: Update power_supply on power role change")Signed-off-by Myrrh Periwinkle <[email protected]>Reported-and-tested-by Sergey Senozhatsky <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>Signed-off-by Sasha Levin <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/usb/typec/ucsi/ucsi.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/usb/typec/ucsi/ucsi.c static void ucsi_handle_connector_change · line 783
Quoted 9 lines
drivers/usb/typec/ucsi/ucsi.c +6
-0@@ -775,6 +775,12 @@ static void ucsi_handle_connector_change role != prev_role) {typec_set_pwr_role (con->port, role); +/* Some power_supply properties vary depending on the power direction when +* connected +*/ +if (con->status.flags &UCSI_CONSTAT_CONNECTED ) +ucsi_port_psy_changed (con); +
This should be making a call to ucsi_port_psy_changed() conditional, not adding a call.
I think this went wrong because an earlier backport, commit 7a3f8d1a44db "usb: typec: ucsi: Update power_supply on power role change", put the call to ucsi_port_psy_changed() in the wrong place in this function.
Ben.
Quoted 5 lines
drivers/usb/typec/ucsi/ucsi.c +0
-0/* Complete pending power role swap */ if (!completion_done (&con->complete))complete (&con->complete);
Signature · 5 lines
Ben Hutchings
[W]e found...that it wasn't as easy to get programs right as we had
thought. I realized that a large part of my life from then on was going
to be spent in finding mistakes in my own programs.
- Maurice Wilkes, 1949Greg Kroah-Hartman
maintainerPATCH 311/342 netfilter: nft_fib: fix stale stack leak via the OIFNAME register
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Davide Ornaghi <[email protected]>
[ Upstream commit ab185e0c4fb82dfba6fb86f8271e06f931d9c64c ]
For NFT_FIB_RESULT_OIFNAME the destination register is declared with len = IFNAMSIZ (four 32-bit registers), but on the lookup-fail, RTN_LOCAL and oif-mismatch paths nft_fib{4,6}_eval() only writes one register via "*dest = 0". The remaining three registers are left as whatever was on the stack in nft_do_chain()'s struct nft_regs, and a downstream expression that loads the register span can leak that uninitialised kernel stack to userspace.
The NFTA_FIB_F_PRESENT existence check has the same shape: it is only meaningful for NFT_FIB_RESULT_OIF, yet it was accepted for any result type while the eval stores a single byte via nft_reg_store8(), leaving the rest of the declared span stale.
Fix both:
- replace the bare "*dest = 0" in the eval with nft_fib_store_result(), which strscpy_pad()s the whole IFNAMSIZ for OIFNAME (and is already used on the other early-return path), and
- restrict NFTA_FIB_F_PRESENT to NFT_FIB_RESULT_OIF and declare its destination as a single u8, so the marked span matches the one byte the eval writes.
--- net/ipv4/netfilter/nft_fib_ipv4.c | 2 +- net/ipv6/netfilter/nft_fib_ipv6.c | 2 +- net/netfilter/nft_fib.c | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-)
net/ipv4/netfilter/nft_fib_ipv4.c +1 -1
@@ -118,7 +118,7 @@ void nft_fib4_eval(const struct nft_expr fl4.saddr =get_saddr (iph->daddr); } - *dest =0 ; +nft_fib_store_result (dest, priv,NULL );if (fib_lookup (nft_net (pkt), &fl4, &res,FIB_LOOKUP_IGNORE_LINKSTATE ))return ;
net/ipv6/netfilter/nft_fib_ipv6.c +1 -1
@@ -189,7 +189,7 @@ void nft_fib6_eval(const struct nft_expr } } - *dest =0 ; +nft_fib_store_result (dest, priv,NULL ); rt = (void *)ip6_route_lookup (nft_net (pkt), &fl6, pkt->skb, lookup_flags);if (rt->dst.error)
net/netfilter/nft_fib.c +6 -0
@@ -105,6 +105,12 @@ int nft_fib_init(const struct nft_ctx *creturn -EINVAL ; } +if (priv->flags &NFTA_FIB_F_PRESENT ) { +if (priv->result !=NFT_FIB_RESULT_OIF ) +return -EINVAL ; + len =sizeof (u8); + } + err =nft_parse_register_store (ctx, tb[NFTA_FIB_DREG ], &priv->dreg,NULL ,NFT_DATA_VALUE , len);if (err <0 )
Greg Kroah-Hartman
maintainerPATCH 312/342 hv_netvsc: use kmap_local_page in netvsc_copy_to_send_buf
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anton Leontev <[email protected]>
[ Upstream commit 004e9ecfe6c5384f9e0b2f6f6389d42ec22789af ]
netvsc_copy_to_send_buf() copies page buffer entries into the VMBus send buffer using phys_to_virt() on the entry PFN. Entries for the RNDIS header and the skb linear data come from kmalloc'd memory and are always in the kernel direct map, but entries for skb fragments reference page cache or user pages, which on 32-bit x86 with CONFIG_HIGHMEM=y can live above the LOWMEM boundary. For such a page phys_to_virt() returns an address outside the direct map and the subsequent memcpy() faults on the transmit softirq path, which is fatal.
Map the pages with kmap_local_page() instead, handling two properties of the page buffer entries:
- pb[i].pfn is a Hyper-V PFN at HV_HYP_PAGE_SIZE (4K) granularity, not a native PFN. Reconstruct the physical address first and derive the native page from it, so the mapping stays correct where PAGE_SIZE > HV_HYP_PAGE_SIZE (e.g. arm64 with 64K pages).
- Since commit 41a6328b2c55 ("hv_netvsc: Preserve contiguous PFN grouping in the page buffer array"), an entry describes a full physically contiguous fragment and pb[i].len can exceed PAGE_SIZE, while kmap_local_page() maps a single page. Copy page by page, splitting at native page boundaries.
The copy path only handles packets smaller than the send section size (6144 bytes by default); larger packets take the cp_partial path where only the RNDIS header is copied. So entries here are bounded by the section size and a copy is split at most once on 4K-page systems. On !CONFIG_HIGHMEM configs kmap_local_page() folds to page_address() and no mapping work is added.
--- drivers/net/hyperv/netvsc.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/net/hyperv/netvsc.c +15 -4
@@ -12,6 +12,7 @@#include <linux/sched.h> #include <linux/wait.h> #include <linux/mm.h> +#include <linux/highmem.h> #include <linux/delay.h> #include <linux/io.h> #include <linux/slab.h>
@@ -889,12 +890,22 @@ static void netvsc_copy_to_send_buf(stru }for (i =0 ; i < page_count; i++) { -char *src =phys_to_virt (pb[i].pfn <<HV_HYP_PAGE_SHIFT ); -u32 offset = pb[i].offset; +phys_addr_t paddr = (pb[i].pfn <<HV_HYP_PAGE_SHIFT ) + + pb[i].offset;u32 len = pb[i].len; -memcpy (dest, (src + offset), len); - dest += len; +while (len) { +struct page *page =pfn_to_page (PHYS_PFN (paddr)); +u32 off =offset_in_page (paddr); +u32 chunk =min_t (u32, len,PAGE_SIZE - off); +char *src =kmap_atomic (page); + +memcpy (dest, src + off, chunk); +kunmap_atomic (src); + dest += chunk; + paddr += chunk; + len -= chunk; + } }if (padding)
Greg Kroah-Hartman
maintainerPATCH 313/342 mm/huge_memory: update file PMD counter before folio_put()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yin Tirui <[email protected]>
[ Upstream commit 8d878059924f12c1bc24556a92ec56add74de3c8 ]
__split_huge_pmd_locked() updates the file/shmem RSS counter after dropping the PMD mapping's folio reference. If folio_put() drops the last reference, mm_counter_file() can later read freed folio state via folio_test_swapbacked().
Move the counter update before folio_put().
--- mm/huge_memory.c | 2 ++ 1 file changed, 2 insertions(+)
mm/huge_memory.c +2 -0
@@ -2066,7 +2066,9 @@ static void __split_huge_pmd_locked(struif (!PageReferenced (page) &&pmd_young (old_pmd))SetPageReferenced (page);page_remove_rmap (page, true); +add_mm_counter (mm,mm_counter_file (page), -HPAGE_PMD_NR );put_page (page); +return ; }add_mm_counter (mm,mm_counter_file (page), -HPAGE_PMD_NR );return ;
Greg Kroah-Hartman
maintainerPATCH 314/342 RDMA/umem: fix kernel-doc warnings
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randy Dunlap <[email protected]>
[ Upstream commit ff46d1392750444fab5ae5a0194764ffdc4ac0d2 ]
Add or correct kernel-doc comments to eliminate warnings:
Warning: include/rdma/ib_umem.h:104 function parameter 'biter' not
described in 'rdma_umem_for_each_dma_block'
Warning: include/rdma/ib_umem.h:140 function parameter 'pgsz_bitmap' not
described in 'ib_umem_find_best_pgoff'
Warning: include/rdma/ib_umem.h:141 No description found for return
value of 'ib_umem_find_best_pgoff'
Stable-dep-of: 15fe76e23615 ("RDMA/umem: Fix truncation for block sizes >= 4G")
--- include/rdma/ib_umem.h | 1 + 1 file changed, 1 insertion(+)
include/rdma/ib_umem.h +1 -0
@@ -57,6 +57,7 @@ static inline void __rdma_umem_block_ite/** * rdma_umem_for_each_dma_block - iterate over contiguous DMA blocks of the umem * @umem: umem to iterate over +* @biter: block iterator variable * @pgsz: Page size to split the list into * * pgsz must be <= PAGE_SIZE or computed by ib_umem_find_best_pgsz(). The
Greg Kroah-Hartman
maintainerPATCH 315/342 RDMA: Move DMA block iterator logic into dedicated files
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Romanovsky <[email protected]>
[ Upstream commit 6094ea64c69520ed1e770e7c79c43412de202bfa ]
The DMA iterator logic was mixed into verbs and umem-specific code, forcing all users to include rdma/ib_umem.h. Move the block iterator logic into iter.c and rdma/iter.h so that rdma/ib_umem.h and rdma/ib_verbs.h can be separated in a follow-up patch.
Stable-dep-of: 15fe76e23615 ("RDMA/umem: Fix truncation for block sizes >= 4G")
--- drivers/infiniband/core/Makefile | 2 drivers/infiniband/core/iter.c | 43 ++++++++++++++ drivers/infiniband/core/verbs.c | 37 ------------ drivers/infiniband/hw/bnxt_re/qplib_res.c | 2 drivers/infiniband/hw/cxgb4/mem.c | 2 drivers/infiniband/hw/efa/efa_verbs.c | 2 drivers/infiniband/hw/hns/hns_roce_alloc.c | 2 drivers/infiniband/hw/i40iw/i40iw_verbs.c | 1 drivers/infiniband/hw/mlx4/mr.c | 1 drivers/infiniband/hw/mlx5/mem.c | 1 drivers/infiniband/hw/mthca/mthca_provider.c | 2 drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 2 drivers/infiniband/hw/qedr/verbs.c | 2 drivers/infiniband/hw/vmw_pvrdma/pvrdma.h | 2 include/rdma/ib_umem.h | 24 -------- include/rdma/ib_verbs.h | 47 --------------- include/rdma/iter.h | 80 +++++++++++++++++++++++++++ 17 files changed, 135 insertions(+), 117 deletions(-) create mode 100644 drivers/infiniband/core/iter.c create mode 100644 include/rdma/iter.h
drivers/infiniband/core/Makefile +1 -1
@@ -12,7 +12,7 @@ ib_core-y := packer.o ud_header.o verb roce_gid_mgmt.o mr_pool.o addr.o sa_query.o \ multicast.o mad.o smi.o agent.o mad_rmpp.o \ nldev.o restrack.o counters.o ib_core_uverbs.o \ - trace.o lag.o + trace.o lag.o iter.o ib_core-$(CONFIG_SECURITY_INFINIBAND) += security.o ib_core-$(CONFIG_CGROUP_RDMA) += cgroup.o
drivers/infiniband/core/iter.c new file +43 -0
43 lines not on this page · raw message
drivers/infiniband/core/verbs.c +0 -37
@@ -2896,40 +2896,3 @@ int rdma_init_netdev(struct ib_device *d netdev, params.param); }EXPORT_SYMBOL (rdma_init_netdev); - -void __rdma_block_iter_start (struct ib_block_iter *biter, -struct scatterlist *sglist,unsigned int nents, -unsigned long pgsz) -{ -memset (biter,0 ,sizeof (struct ib_block_iter )); - biter->__sg = sglist; - biter->__sg_nents = nents; - -/* Driver provides best block size to use */ - biter->__pg_bit =__fls (pgsz); -} -EXPORT_SYMBOL (__rdma_block_iter_start); - -bool __rdma_block_iter_next (struct ib_block_iter *biter) -{ -unsigned int block_offset; -unsigned int sg_delta; - -if (!biter->__sg_nents || !biter->__sg) -return false; - - biter->__dma_addr =sg_dma_address (biter->__sg) + biter->__sg_advance; - block_offset = biter->__dma_addr & (BIT_ULL (biter->__pg_bit) -1 ); - sg_delta =BIT_ULL (biter->__pg_bit) - block_offset; - -if (sg_dma_len (biter->__sg) - biter->__sg_advance > sg_delta) { - biter->__sg_advance += sg_delta; - }else { - biter->__sg_advance =0 ; - biter->__sg =sg_next (biter->__sg); - biter->__sg_nents--; - } - -return true; -} -EXPORT_SYMBOL (__rdma_block_iter_next);
drivers/infiniband/hw/bnxt_re/qplib_res.c +1 -1
@@ -46,7 +46,7 @@#include <linux/if_vlan.h> #include <linux/vmalloc.h> #include <rdma/ib_verbs.h> -#include <rdma/ib_umem.h> +#include <rdma/iter.h> #include "roce_hsi.h" #include "qplib_res.h"
drivers/infiniband/hw/cxgb4/mem.c +1 -1
@@ -32,9 +32,9 @@#include <linux/module.h> #include <linux/moduleparam.h> -#include <rdma/ib_umem.h> #include <linux/atomic.h> #include <rdma/ib_user_verbs.h> +#include <rdma/iter.h> #include "iw_cxgb4.h"
drivers/infiniband/hw/efa/efa_verbs.c +1 -1
@@ -7,9 +7,9 @@#include <linux/log2.h> #include <rdma/ib_addr.h> -#include <rdma/ib_umem.h> #include <rdma/ib_user_verbs.h> #include <rdma/ib_verbs.h> +#include <rdma/iter.h> #include <rdma/uverbs_ioctl.h> #include "efa.h"
drivers/infiniband/hw/hns/hns_roce_alloc.c +1 -1
@@ -34,7 +34,7 @@#include <linux/platform_device.h> #include <linux/vmalloc.h> #include "hns_roce_device.h" -#include <rdma/ib_umem.h> +#include <rdma/iter.h> int hns_roce_bitmap_alloc (struct hns_roce_bitmap *bitmap,unsigned long *obj) {
drivers/infiniband/hw/i40iw/i40iw_verbs.c +1 -0
@@ -45,6 +45,7 @@#include <rdma/iw_cm.h> #include <rdma/ib_user_verbs.h> #include <rdma/ib_umem.h> +#include <rdma/iter.h> #include <rdma/uverbs_ioctl.h> #include "i40iw.h"
drivers/infiniband/hw/mlx4/mr.c +1 -0
@@ -33,6 +33,7 @@#include <linux/slab.h> #include <rdma/ib_user_verbs.h> +#include <rdma/iter.h> #include "mlx4_ib.h"
drivers/infiniband/hw/mlx5/mem.c +1 -0
@@ -33,6 +33,7 @@#include <linux/module.h> #include <rdma/ib_umem.h> #include <rdma/ib_umem_odp.h> +#include <rdma/iter.h> #include "mlx5_ib.h" #include <linux/jiffies.h>
drivers/infiniband/hw/mthca/mthca_provider.c +1 -1
@@ -35,8 +35,8 @@*/ #include <rdma/ib_smi.h> -#include <rdma/ib_umem.h> #include <rdma/ib_user_verbs.h> +#include <rdma/iter.h> #include <rdma/uverbs_ioctl.h> #include <linux/sched.h>
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +1 -1
@@ -44,9 +44,9 @@#include <rdma/ib_verbs.h> #include <rdma/ib_user_verbs.h> #include <rdma/iw_cm.h> -#include <rdma/ib_umem.h> #include <rdma/ib_addr.h> #include <rdma/ib_cache.h> +#include <rdma/iter.h> #include <rdma/uverbs_ioctl.h> #include "ocrdma.h"
drivers/infiniband/hw/qedr/verbs.c +1 -1
@@ -39,9 +39,9 @@#include <rdma/ib_verbs.h> #include <rdma/ib_user_verbs.h> #include <rdma/iw_cm.h> -#include <rdma/ib_umem.h> #include <rdma/ib_addr.h> #include <rdma/ib_cache.h> +#include <rdma/iter.h> #include <rdma/uverbs_ioctl.h> #include <linux/qed/common_hsi.h>
drivers/infiniband/hw/vmw_pvrdma/pvrdma.h +1 -1
@@ -53,8 +53,8 @@#include <linux/pci.h> #include <linux/semaphore.h> #include <linux/workqueue.h> -#include <rdma/ib_umem.h> #include <rdma/ib_verbs.h> +#include <rdma/iter.h> #include <rdma/vmw_pvrdma-abi.h> #include "pvrdma_ring.h"
include/rdma/ib_umem.h +0 -24
@@ -46,30 +46,6 @@ static inline size_t ib_umem_num_pages(s {return ib_umem_num_dma_blocks (umem,PAGE_SIZE ); } - -static inline void __rdma_umem_block_iter_start (struct ib_block_iter *biter, -struct ib_umem *umem, -unsigned long pgsz) -{ -__rdma_block_iter_start (biter, umem->sg_head.sgl, umem->nmap, pgsz); -} - -/** -* rdma_umem_for_each_dma_block - iterate over contiguous DMA blocks of the umem -* @umem: umem to iterate over -* @biter: block iterator variable -* @pgsz: Page size to split the list into -* -* pgsz must be <= PAGE_SIZE or computed by ib_umem_find_best_pgsz(). The -* returned DMA blocks will be aligned to pgsz and span the range: -* ALIGN_DOWN(umem->address, pgsz) to ALIGN(umem->address + umem->length, pgsz) -* -* Performs exactly ib_umem_num_dma_blocks() iterations. -*/ -#define rdma_umem_for_each_dma_block (umem, biter, pgsz) \ - for (__rdma_umem_block_iter_start(biter, umem, pgsz); \ - __rdma_block_iter_next(biter);) -#ifdef CONFIG_INFINIBAND_USER_MEM struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr,
include/rdma/ib_verbs.h +0 -47
59 lines not on this page · raw message
include/rdma/iter.h new file +80 -0
80 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 316/342 RDMA/umem: Fix truncation for block sizes >= 4G
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 15fe76e23615f502d051ef0768f86babaf08746c ]
When the iommu is used the linearization of the mapping can give a single block that is very large split across multiple SG entries.
When __rdma_block_iter_next() reassembles the split SG entries it is overflowing the 32 bit stack values and computed the wrong DMA addresses for blocks after the truncation.
Use the right types to hold DMA addresses.
--- drivers/infiniband/core/iter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/core/iter.c +2 -2
@@ -19,8 +19,8 @@ EXPORT_SYMBOL(__rdma_block_iter_start);bool __rdma_block_iter_next (struct ib_block_iter *biter) { -unsigned int block_offset; -unsigned int delta; +dma_addr_t block_offset; +dma_addr_t delta;if (!biter->__sg_nents || !biter->__sg)return false;
Greg Kroah-Hartman
maintainerPATCH 317/342 Bluetooth: L2CAP: use chan timer to close channels in cleanup_listen()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Siwei Zhang <[email protected]>
[ Upstream commit 8c8e620467a7b51562dbcefbd1f09f288d7d710d ]
l2cap_chan_close() removes the channel from conn->chan_l, which must be done under conn->lock. cleanup_listen() runs under the parent sk_lock, so acquiring conn->lock would invert the established conn->lock -> chan->lock -> sk_lock order.
Instead of calling l2cap_chan_close() directly, schedule l2cap_chan_timeout with delay 0 to close the channel asynchronously. The timeout handler already acquires conn->lock and chan->lock in the correct order.
The timer is only armed when chan->conn is still set: if it is already NULL, l2cap_conn_del() has already processed this channel (l2cap_chan_del + l2cap_sock_teardown_cb + l2cap_sock_close_cb), so there is nothing left to do. If l2cap_conn_del() races in after the timer is armed, __clear_chan_timer() inside l2cap_chan_del() cancels it; if the timer has already fired, the handler returns harmlessly because chan->conn was cleared.
--- net/bluetooth/l2cap_sock.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
net/bluetooth/l2cap_sock.c +9 -7
@@ -1437,6 +1437,10 @@ static void l2cap_sock_cleanup_listen(st* pin it (hold_unless_zero() additionally skips a chan already past * its last reference). We then drop the sk lock before taking * chan->lock, so sk and chan locks are never held together. +* +* Since we cannot call l2cap_chan_close() without conn->lock, +* schedule l2cap_chan_timeout to close the channel; it already +* acquires conn->lock -> chan->lock in the correct order. */ while ((sk =bt_accept_dequeue (parent,NULL ))) {struct l2cap_chan *chan;
@@ -1454,14 +1458,12 @@ static void l2cap_sock_cleanup_listen(st state_to_string(chan->state));l2cap_chan_lock (chan); -__clear_chan_timer (chan); -l2cap_chan_close (chan,ECONNRESET ); -/* l2cap_conn_del() may already have killed this socket -* (it sets SOCK_DEAD); skip the duplicate to avoid a -* double sock_put()/l2cap_chan_put(). +/* Since we cannot call l2cap_chan_close() without +* conn->lock, schedule its timer to trigger the close +* and cleanup of this channel. */ -if (!sock_flag (sk,SOCK_DEAD )) -l2cap_sock_kill (sk); +if (chan->conn) +__set_chan_timer (chan,0 );l2cap_chan_unlock (chan);l2cap_chan_put (chan);
Greg Kroah-Hartman
maintainerPATCH 318/342 ALSA: hda/hdmi: Add quirk for TUXEDO IBS14G6
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Erhardt <[email protected]>
commit d649c58bcad8fb9b749e3837136a201632fa109d upstream.
Depending on the timing during boot, the BIOS might report wrong pin capabilities, which can lead to HDMI audio being disabled. Therefore, force HDMI audio connection on TUXEDO InfinityBook S 14 Gen6.
--- sound/pci/hda/patch_hdmi.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_hdmi.c +1 -0
@@ -1973,6 +1973,7 @@ static const struct snd_pci_quirk force_SND_PCI_QUIRK (0x1043 ,0x86ae ,"ASUS" ,1 ),/* Z170 PRO */ SND_PCI_QUIRK (0x1043 ,0x86c7 ,"ASUS" ,1 ),/* Z170M PLUS */ SND_PCI_QUIRK (0x1462 ,0xec94 ,"MS-7C94" ,1 ), +SND_PCI_QUIRK (0x1558 ,0x14a1 ,"TUXEDO InfinityBook S 14 Gen6" ,1 ),SND_PCI_QUIRK (0x8086 ,0x2060 ,"Intel NUC5CPYB" ,1 ), SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", 1), {}
Greg Kroah-Hartman
maintainerPATCH 319/342 iio: adc: npcm: fix unbalanced clk_disable_unprepare()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Carlier <[email protected]>
[ Upstream commit 0d42e2c0bd6ceb89e44c6e065f9bdf9b1df3ef0c ]
The driver acquired the ADC clock with devm_clk_get() and read its rate, but never called clk_prepare_enable(). The probe error path and npcm_adc_remove() both called clk_disable_unprepare() unconditionally, causing the clk framework's enable/prepare counts to underflow on probe failure or module unbind.
The issue went unnoticed because NPCM BMC firmware leaves the ADC clock enabled at boot, so the driver happened to work in practice.
Switch to devm_clk_get_enabled() so the clock is properly enabled during probe and automatically released by the device-managed cleanup, and drop the now-redundant clk_disable_unprepare() from both the probe error path and remove().
While at it, drop the duplicate error message on devm_request_irq() failure since the IRQ core already logs it.
--- drivers/iio/adc/npcm_adc.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-)
drivers/iio/adc/npcm_adc.c +8 -18
@@ -180,7 +180,6 @@ static int npcm_adc_probe(struct platforu32 reg_con;struct npcm_adc *info;struct iio_dev *indio_dev; -struct device *dev = &pdev->dev; indio_dev =devm_iio_device_alloc (&pdev->dev,sizeof (*info));if (!indio_dev)
@@ -197,7 +196,7 @@ static int npcm_adc_probe(struct platforif (IS_ERR (info->reset))return PTR_ERR (info->reset); - info->adc_clk =devm_clk_get (&pdev->dev,NULL ); + info->adc_clk =devm_clk_get_enabled (&pdev->dev,NULL );if (IS_ERR (info->adc_clk)) {dev_warn (&pdev->dev,"ADC clock failed: can't read clk\n" );return PTR_ERR (info->adc_clk);
@@ -210,17 +209,13 @@ static int npcm_adc_probe(struct platfor info->adc_sample_hz =clk_get_rate (info->adc_clk) / ((div +1 ) *2 ); irq =platform_get_irq (pdev,0 ); -if (irq <=0 ) { - ret = -EINVAL ; - goto err_disable_clk; - } +if (irq <=0 ) +return -EINVAL ; ret =devm_request_irq (&pdev->dev, irq, npcm_adc_isr,0 ,"NPCM_ADC" , indio_dev); -if (ret <0 ) { -dev_err (dev,"failed requesting interrupt\n" ); - goto err_disable_clk; - } +if (ret <0 ) +return ret; reg_con =ioread32 (info->regs +NPCM_ADCCON ); info->vref =devm_regulator_get_optional (&pdev->dev,"vref" );
@@ -228,7 +223,7 @@ static int npcm_adc_probe(struct platfor ret =regulator_enable (info->vref);if (ret) {dev_err (&pdev->dev,"Can't enable ADC reference voltage\n" ); - goto err_disable_clk; +return ret; } iowrite32(reg_con & ~NPCM_ADCCON_REFSEL,
@@ -238,10 +233,8 @@ static int npcm_adc_probe(struct platfor* Any error which is not ENODEV indicates the regulator * has been specified and so is a failure case. */ -if (PTR_ERR (info->vref) != -ENODEV ) { - ret =PTR_ERR (info->vref); - goto err_disable_clk; - } +if (PTR_ERR (info->vref) != -ENODEV ) +return PTR_ERR (info->vref);/* Use internal reference */ iowrite32(reg_con | NPCM_ADCCON_REFSEL,
@@ -280,8 +273,6 @@ err_iio_register:iowrite32 (reg_con & ~NPCM_ADCCON_ADC_EN , info->regs +NPCM_ADCCON );if (!IS_ERR (info->vref))regulator_disable (info->vref); -err_disable_clk: -clk_disable_unprepare (info->adc_clk);return ret; }
@@ -298,7 +289,6 @@ static int npcm_adc_remove(struct platfoiowrite32 (regtemp & ~NPCM_ADCCON_ADC_EN , info->regs +NPCM_ADCCON );if (!IS_ERR (info->vref))regulator_disable (info->vref); -clk_disable_unprepare (info->adc_clk);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 320/342 usb: cdns3: gadget: fix request skipping after clearing halt
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongchao Wu <[email protected]>
[ Upstream commit c8778ff817a7047d6848fefba99dcb27b1bf01fe ]
According to the cdns3 datasheet, the EPRST (Endpoint Reset) command causes the DMA engine to reposition its internal pointer to the next Transfer Descriptor (TD) if it was already processing one.
This issue is consistently observed during the ADB identification process on macOS hosts, where the host issues a Clear_Halt. Although commit 4bf2dd65135a ("usb: cdns3: gadget: toggle cycle bit before reset endpoint") attempted to avoid DMA advance by toggling the cycle bit, trace logs show that on certain hosts like macOS, the DMA pointer (EP_TRADDR) still shifts after EPRST:
cdns3_ctrl_req: Clear Endpoint Feature(Halt ep1out)
cdns3_doorbell_epx: ep1out, ep_trbaddr f9c04030 <-- Should be f9c04000
cdns3_gadget_giveback: ep1out: req: ... length: 16384/16384
As shown above, the DMA pointer jumped to the next TD, causing the controller to skip the initial TRBs of the request. This leads to data misalignment and ADB protocol hangs on macOS.
Fix this by manually restoring the EP_TRADDR register to the starting physical address of the current request after the EPRST operation is complete.
--- drivers/usb/cdns3/gadget.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/usb/cdns3/gadget.c +11 -1
@@ -2798,9 +2798,19 @@ int __cdns3_gadget_ep_clear_halt(struct priv_ep->flags &= ~(EP_STALLED |EP_STALL_PENDING );if (request) { -if (trb) +if (trb) { *trb = trb_tmp; +/* +* Per datasheet, EPRST causes DMA to reposition to the next TD. +* Manually reset EP_TRADDR to the current TRB to prevent +* the hardware from skipping the interrupted request. +*/ +writel (EP_TRADDR_TRADDR (priv_ep->trb_pool_dma + + priv_req->start_trb *TRB_SIZE ), + &priv_dev->regs->ep_traddr); + } +cdns3_rearm_transfer (priv_ep,1 ); }
Greg Kroah-Hartman
maintainerPATCH 321/342 iio: chemical: scd30: Use guard(mutex) to allow early returns
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cameron <[email protected]>
[ Upstream commit 5feb5532870fbced5d6f450b8061a33f461b88ca ]
Auto cleanup based release of the lock allows for simpler code flow in a few functions with large multiplexing style switch statements and no common operations following the switch.
Stable-dep-of: 5aba4f94b225 ("iio: chemical: scd30: fix division by zero in write_raw")
--- drivers/iio/chemical/scd30_core.c | 63 ++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 35 deletions(-)
drivers/iio/chemical/scd30_core.c +28 -35
@@ -5,6 +5,7 @@* Copyright (c) 2020 Tomasz Duszynski <[email protected]> */ #include <linux/bits.h> +#include <linux/cleanup.h> #include <linux/completion.h> #include <linux/delay.h> #include <linux/device.h>
@@ -198,112 +199,104 @@ static int scd30_read_raw(struct iio_dev int *val, int *val2, long mask) { struct scd30_state *state = iio_priv(indio_dev); -int ret = -EINVAL ; +int ret;u16 tmp; -mutex_lock (&state->lock); +guard (mutex)(&state->lock);switch (mask) {case IIO_CHAN_INFO_RAW :case IIO_CHAN_INFO_PROCESSED :if (chan->output) { *val = state->pressure_comp; - ret =IIO_VAL_INT ; -break ; +return IIO_VAL_INT ; } ret =iio_device_claim_direct_mode (indio_dev);if (ret) -break ; +return ret; ret =scd30_read (state);if (ret) {iio_device_release_direct_mode (indio_dev); -break ; +return ret; } *val = state->meas[chan->address];iio_device_release_direct_mode (indio_dev); - ret =IIO_VAL_INT ; -break ; +return IIO_VAL_INT ;case IIO_CHAN_INFO_SCALE : *val =0 ; *val2 =1 ; - ret =IIO_VAL_INT_PLUS_MICRO ; -break ; +return IIO_VAL_INT_PLUS_MICRO ;case IIO_CHAN_INFO_SAMP_FREQ : ret =scd30_command_read (state,CMD_MEAS_INTERVAL , &tmp);if (ret) -break ; +return ret; *val =0 ; *val2 =1000000000 / tmp; - ret =IIO_VAL_INT_PLUS_NANO ; -break ; +return IIO_VAL_INT_PLUS_NANO ;case IIO_CHAN_INFO_CALIBBIAS : ret =scd30_command_read (state,CMD_TEMP_OFFSET , &tmp);if (ret) -break ; +return ret; *val = tmp; - ret =IIO_VAL_INT ; -break ; +return IIO_VAL_INT ; +default : +return -EINVAL ; } -mutex_unlock (&state->lock); - -return ret; }static int scd30_write_raw (struct iio_dev *indio_dev,struct iio_chan_spec const *chan,int val,int val2,long mask) {struct scd30_state *state =iio_priv (indio_dev); -int ret = -EINVAL ; +int ret; -mutex_lock (&state->lock); +guard (mutex)(&state->lock);switch (mask) {case IIO_CHAN_INFO_SAMP_FREQ :if (val) -break ; +return -EINVAL ; val =1000000000 / val2;if (val <SCD30_MEAS_INTERVAL_MIN_S || val >SCD30_MEAS_INTERVAL_MAX_S ) -break ; +return -EINVAL ; ret =scd30_command_write (state,CMD_MEAS_INTERVAL , val);if (ret) -break ; +return ret; state->meas_interval = val; -break ; +return 0 ;case IIO_CHAN_INFO_RAW :switch (chan->type) {case IIO_PRESSURE :if (val <SCD30_PRESSURE_COMP_MIN_MBAR || val >SCD30_PRESSURE_COMP_MAX_MBAR ) -break ; +return -EINVAL ; ret =scd30_command_write (state,CMD_START_MEAS , val);if (ret) -break ; +return ret; state->pressure_comp = val; -break ; +return 0 ;default : -break ; +return -EINVAL ; } -break ;case IIO_CHAN_INFO_CALIBBIAS :if (val <0 || val >SCD30_TEMP_OFFSET_MAX ) -break ; +return -EINVAL ;/* * Manufacturer does not explicitly specify min/max sensible * values hence check is omitted for simplicity. */ - ret =scd30_command_write (state,CMD_TEMP_OFFSET /10 , val); +return scd30_command_write (state,CMD_TEMP_OFFSET /10 , val); +default : +return -EINVAL ; } -mutex_unlock (&state->lock); - -return ret; } static int scd30_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
Greg Kroah-Hartman
maintainerPATCH 322/342 iio: chemical: scd30: fix division by zero in write_raw
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antoniu Miclaus <[email protected]>
[ Upstream commit 5aba4f94b225617a55fed442a70329b2ee19c0a5 ]
Add a zero check for val2 before using it as a divisor when setting the sampling frequency. A user writing a zero fractional part to the sampling_frequency sysfs attribute triggers a division by zero in the kernel.
--- drivers/iio/chemical/scd30_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/chemical/scd30_core.c +1 -1
@@ -257,7 +257,7 @@ static int scd30_write_raw(struct iio_deguard (mutex)(&state->lock);switch (mask) {case IIO_CHAN_INFO_SAMP_FREQ : -if (val) +if (val || !val2)return -EINVAL ; val =1000000000 / val2;
Greg Kroah-Hartman
maintainerPATCH 323/342 iio: gyro: adis16260: fix division by zero in write_raw
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antoniu Miclaus <[email protected]>
[ Upstream commit 761e8b489e6cf166c574034b70637f8a7eadd0ee ]
Add a validation check for the sampling frequency value before using it as a divisor. A user writing zero to the sampling_frequency sysfs attribute triggers a division by zero in the kernel.
--- drivers/iio/gyro/adis16260.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/iio/gyro/adis16260.c +3 -0
@@ -293,6 +293,9 @@ static int adis16260_write_raw(struct ii addr = adis16260_addresses[chan->scan_index][1 ];return adis_write_reg_16 (adis, addr, val);case IIO_CHAN_INFO_SAMP_FREQ : +if (val <=0 ) +return -EINVAL ; +mutex_lock (&adis->state_lock);if (spi_get_device_id (adis->spi)->driver_data) t =256 / val;
Greg Kroah-Hartman
maintainerPATCH 324/342 iio: dac: ad5686: fix ref bit initialization for single-channel parts
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rodrigo Alencar <[email protected]>
[ Upstream commit ecae2ae606d493cf11457946436335bd0e726663 ]
The reference bit position was ignored when writing the register at the probe() function (!!val was used). When such bit is 1, internal voltage reference is disabled so that an external one can be used. For multi-channel devices, bit 0 of the Internal Reference Setup command behaves the same way, so AD5686_REF_BIT_MSK is created. The issue exists since support for single-channel devices were first introduced.
--- drivers/iio/dac/ad5686.c | 6 +++--- drivers/iio/dac/ad5686.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-)
drivers/iio/dac/ad5686.c +3 -3
@@ -488,7 +488,7 @@ int ad5686_probe(struct device *dev,break ;case AD5686_REGMAP : cmd =AD5686_CMD_INTERNAL_REFER_SETUP ; - ref_bit_msk =0 ; + ref_bit_msk =AD5686_REF_BIT_MSK ;break ;case AD5693_REGMAP : cmd =AD5686_CMD_CONTROL_REG ;
@@ -500,9 +500,9 @@ int ad5686_probe(struct device *dev, goto error_disable_reg; } - val = (voltage_uv | ref_bit_msk); + val = voltage_uv ? ref_bit_msk :0 ; - ret = st->write (st, cmd,0 , !!val); + ret = st->write (st, cmd,0 , val);if (ret) goto error_disable_reg;
drivers/iio/dac/ad5686.h +1 -0
@@ -44,6 +44,7 @@#define AD5310_REF_BIT_MSK BIT(8)#define AD5683_REF_BIT_MSK BIT(12) +#define AD5686_REF_BIT_MSK BIT(0)#define AD5693_REF_BIT_MSK BIT(12)/**
Greg Kroah-Hartman
maintainerPATCH 325/342 xfrm: input: hold netns during deferred transport reinjection
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhengchuan Liang <[email protected]>
[ Upstream commit c16f74dc1d75d0e2e7670076d5375deda110ebeb ]
Transport-mode reinjection stores a struct net pointer in skb->cb and uses it later from xfrm_trans_reinject(). That pointer must stay valid until the deferred callback runs.
Take a netns reference when queueing deferred reinjection work and drop it after the callback completes. Use maybe_get_net() so the queueing path does not revive a namespace that is already being torn down.
This keeps the existing workqueue design and fixes the netns lifetime handling in one place for all users of xfrm_trans_queue_net().
--- net/xfrm/xfrm_input.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
net/xfrm/xfrm_input.c +12 -4
@@ -777,9 +777,12 @@ static void xfrm_trans_reinject(unsigned__skb_queue_head_init (&queue);skb_queue_splice_init (&trans->queue, &queue); -while ((skb =__skb_dequeue (&queue))) -XFRM_TRANS_SKB_CB (skb)->finish (XFRM_TRANS_SKB_CB (skb)->net, -NULL , skb); +while ((skb =__skb_dequeue (&queue))) { +struct net *net =XFRM_TRANS_SKB_CB (skb)->net; + +XFRM_TRANS_SKB_CB (skb)->finish (net,NULL , skb); +put_net (net); + } } int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
@@ -787,6 +790,7 @@ int xfrm_trans_queue_net(struct net *net struct sk_buff *)) {struct xfrm_trans_tasklet *trans; +struct net *hold_net; trans =this_cpu_ptr (&xfrm_trans_tasklet);
@@ -795,8 +799,12 @@ int xfrm_trans_queue_net(struct net *netBUILD_BUG_ON (sizeof (struct xfrm_trans_cb ) >sizeof (skb->cb)); + hold_net =maybe_get_net (net); +if (!hold_net) +return -ENODEV ; +XFRM_TRANS_SKB_CB (skb)->finish = finish; -XFRM_TRANS_SKB_CB (skb)->net = net; +XFRM_TRANS_SKB_CB (skb)->net = hold_net;__skb_queue_tail (&trans->queue, skb);tasklet_schedule (&trans->tasklet);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 326/342 net: skbuff: fix missing zerocopy reference in pskb_carve helpers
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Minh Nguyen <[email protected]>
[ Upstream commit 98d0912e9f841e5529a5b89a972805f34cb1c69d ]
pskb_carve_inside_header() and pskb_carve_inside_nonlinear() both copy the old skb_shared_info header into a new buffer via memcpy(), which includes the destructor_arg pointer (uarg) for MSG_ZEROCOPY skbs. Neither function calls net_zcopy_get() for the new shinfo, creating an unaccounted holder: every skb_shared_info with destructor_arg set will call skb_zcopy_clear() once when freed, but the corresponding net_zcopy_get() was never called for the new copy. Repeated calls drive uarg->refcnt to zero prematurely, freeing ubuf_info_msgzc while TX skbs still hold live destructor_arg pointers.
KASAN reports use-after-free on a freed ubuf_info_msgzc:
BUG: KASAN: slab-use-after-free in skb_release_data+0x77b/0x810 Read of size 8 at addr ffff88801574d3e8 by task poc/220 Call Trace: skb_release_data+0x77b/0x810 kfree_skb_list_reason+0x13e/0x610 skb_release_data+0x4cd/0x810 sk_skb_reason_drop+0xf3/0x340 skb_queue_purge_reason+0x282/0x440 rds_tcp_inc_free+0x1e/0x30 rds_recvmsg+0x354/0x1780 __sys_recvmsg+0xdf/0x180 Allocated by task 219: msg_zerocopy_realloc+0x157/0x7b0 tcp_sendmsg_locked+0x2892/0x3ba0 Freed by task 219: ip_recv_error+0x74a/0xb10 tcp_recvmsg+0x475/0x530
The skb consuming the late access still referenced the same uarg via shinfo->destructor_arg copied by pskb_carve_inside_nonlinear() without a refcount bump. This has been verified to be reliably exploitable: a working proof-of-concept achieves full root privilege escalation from an unprivileged local user on a default kernel configuration.
The fix follows the pattern of pskb_expand_head() which has the same memcpy/cloned structure. For pskb_carve_inside_header(), net_zcopy_get() is placed after skb_orphan_frags() succeeds, so the orphan error path needs no cleanup. For pskb_carve_inside_nonlinear(), net_zcopy_get() is placed after all failure points and just before skb_release_data(), so no error path needs cleanup at all -- matching pskb_expand_head() more closely and avoiding the need for a balancing net_zcopy_put().
--- net/core/skbuff.c | 4 ++++ 1 file changed, 4 insertions(+)
net/core/skbuff.c +4 -0
@@ -6058,6 +6058,8 @@ static int pskb_carve_inside_header(strukfree (data);return -ENOMEM ; } +if (skb_zcopy (skb)) +refcount_inc (&skb_uarg (skb)->refcnt);for (i =0 ; i <skb_shinfo (skb)->nr_frags; i++)skb_frag_ref (skb, i);if (skb_has_frag_list (skb))
@@ -6210,6 +6212,8 @@ static int pskb_carve_inside_nonlinear(skfree (data);return -ENOMEM ; } +if (skb_zcopy (skb)) +refcount_inc (&skb_uarg (skb)->refcnt);skb_release_data (skb); skb->head = data;
Greg Kroah-Hartman
maintainerPATCH 327/342 serial: samsung_tty: Use port lock wrappers
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
[ Upstream commit 97d7a9aeba1d424c2359f1686d02c75d798ad184 ]
When a serial port is used for kernel console output, then all modifications to the UART registers which are done from other contexts, e.g. getty, termios, are interference points for the kernel console.
So far this has been ignored and the printk output is based on the principle of hope. The rework of the console infrastructure which aims to support threaded and atomic consoles, requires to mark sections which modify the UART registers as unsafe. This allows the atomic write function to make informed decisions and eventually to restore operational state. It also allows to prevent the regular UART code from modifying UART registers while printk output is in progress.
All modifications of UART registers are guarded by the UART port lock, which provides an obvious synchronization point with the console infrastructure.
To avoid adding this functionality to all UART drivers, wrap the spin_[un]lock*() invocations for uart_port::lock into helper functions which just contain the spin_[un]lock*() invocations for now. In a subsequent step these helpers will gain the console synchronization mechanisms.
Converted with coccinelle. No functional change.
Stable-dep-of: a3bb136bff5e ("tty: serial: samsung: Remove redundant port lock acquisition in rx helpers")
--- drivers/tty/serial/samsung_tty.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
drivers/tty/serial/samsung_tty.c +18 -18
@@ -245,7 +245,7 @@ static void s3c24xx_serial_rx_enable(strunsigned int ucon, ufcon;int count =10000 ; -spin_lock_irqsave (&port->lock, flags); +uart_port_lock_irqsave (port, &flags);while (--count && !s3c24xx_serial_txempty_nofifo (port))udelay (100 );
@@ -259,7 +259,7 @@ static void s3c24xx_serial_rx_enable(strwr_regl (port,S3C2410_UCON , ucon); ourport->rx_enabled =1 ; -spin_unlock_irqrestore (&port->lock, flags); +uart_port_unlock_irqrestore (port, flags); }static void s3c24xx_serial_rx_disable (struct uart_port *port)
@@ -268,14 +268,14 @@ static void s3c24xx_serial_rx_disable(stunsigned long flags;unsigned int ucon; -spin_lock_irqsave (&port->lock, flags); +uart_port_lock_irqsave (port, &flags); ucon =rd_regl (port,S3C2410_UCON ); ucon &= ~S3C2410_UCON_RXIRQMODE ;wr_regl (port,S3C2410_UCON , ucon); ourport->rx_enabled =0 ; -spin_unlock_irqrestore (&port->lock, flags); +uart_port_unlock_irqrestore (port, flags); }static void s3c24xx_serial_stop_tx (struct uart_port *port)
@@ -334,7 +334,7 @@ static void s3c24xx_serial_tx_dma_compledma_sync_single_for_cpu (ourport->port.dev, dma->tx_transfer_addr, dma->tx_size,DMA_TO_DEVICE ); -spin_lock_irqsave (&port->lock, flags); +uart_port_lock_irqsave (port, &flags); xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE -1 ); port->icount.tx += count;
@@ -344,7 +344,7 @@ static void s3c24xx_serial_tx_dma_compleuart_write_wakeup (port);s3c24xx_serial_start_next_tx (ourport); -spin_unlock_irqrestore (&port->lock, flags); +uart_port_unlock_irqrestore (port, flags); }static void enable_tx_dma (struct s3c24xx_uart_port *ourport)
@@ -579,7 +579,7 @@ static void s3c24xx_serial_rx_dma_comple received = dma->rx_bytes_requested - state.residue;async_tx_ack (dma->rx_desc); -spin_lock_irqsave (&port->lock, flags); +uart_port_lock_irqsave (port, &flags);if (received)s3c24xx_uart_copy_rx_to_tty (ourport, t, received);
@@ -591,7 +591,7 @@ static void s3c24xx_serial_rx_dma_comples3c64xx_start_rx_dma (ourport); -spin_unlock_irqrestore (&port->lock, flags); +uart_port_unlock_irqrestore (port, flags); }static void s3c64xx_start_rx_dma (struct s3c24xx_uart_port *ourport)
@@ -679,7 +679,7 @@ static irqreturn_t s3c24xx_serial_rx_cha utrstat =rd_regl (port,S3C2410_UTRSTAT );rd_regl (port,S3C2410_UFSTAT ); -spin_lock_irqsave (&port->lock, flags); +uart_port_lock_irqsave (port, &flags);if (!(utrstat &S3C2410_UTRSTAT_TIMEOUT )) {s3c64xx_start_rx_dma (ourport);
@@ -708,7 +708,7 @@ static irqreturn_t s3c24xx_serial_rx_chawr_regl (port,S3C2410_UTRSTAT ,S3C2410_UTRSTAT_TIMEOUT ); finish: -spin_unlock_irqrestore (&port->lock, flags); +uart_port_unlock_irqrestore (port, flags);return IRQ_HANDLED ; }
@@ -806,9 +806,9 @@ static irqreturn_t s3c24xx_serial_rx_chastruct uart_port *port = &ourport->port;unsigned long flags; -spin_lock_irqsave (&port->lock, flags); +uart_port_lock_irqsave (port, &flags);s3c24xx_serial_rx_drain_fifo (ourport); -spin_unlock_irqrestore (&port->lock, flags); +uart_port_unlock_irqrestore (port, flags);return IRQ_HANDLED ; }
@@ -956,7 +956,7 @@ static void s3c24xx_serial_break_ctl(strunsigned long flags;unsigned int ucon; -spin_lock_irqsave (&port->lock, flags); +uart_port_lock_irqsave (port, &flags); ucon =rd_regl (port,S3C2410_UCON );
@@ -967,7 +967,7 @@ static void s3c24xx_serial_break_ctl(strwr_regl (port,S3C2410_UCON , ucon); -spin_unlock_irqrestore (&port->lock, flags); +uart_port_unlock_irqrestore (port, flags); }static int s3c24xx_serial_request_dma (struct s3c24xx_uart_port *p)
@@ -1192,7 +1192,7 @@ static int s3c64xx_serial_startup(struct ourport->tx_enabled =0 ; ourport->tx_claimed =1 ; -spin_lock_irqsave (&port->lock, flags); +uart_port_lock_irqsave (port, &flags); ufcon =rd_regl (port,S3C2410_UFCON ); ufcon |=S3C2410_UFCON_RESETRX |S5PV210_UFCON_RXTRIG8 ;
@@ -1202,7 +1202,7 @@ static int s3c64xx_serial_startup(structenable_rx_pio (ourport); -spin_unlock_irqrestore (&port->lock, flags); +uart_port_unlock_irqrestore (port, flags);/* Enable Rx Interrupt */ s3c24xx_clear_bit (port,S3C64XX_UINTM_RXD ,S3C64XX_UINTM );
@@ -1479,7 +1479,7 @@ static void s3c24xx_serial_set_termios(s ulcon |=S3C2410_LCON_PNONE ; } -spin_lock_irqsave (&port->lock, flags); +uart_port_lock_irqsave (port, &flags); dev_dbg(port->dev, "setting ulcon to %08x, brddiv to %d, udivslot %08x\n",
@@ -1537,7 +1537,7 @@ static void s3c24xx_serial_set_termios(sif ((termios->c_cflag &CREAD ) ==0 ) port->ignore_status_mask |=RXSTAT_DUMMY_READ ; -spin_unlock_irqrestore (&port->lock, flags); +uart_port_unlock_irqrestore (port, flags); }static const char *s3c24xx_serial_type (struct uart_port *port)
Greg Kroah-Hartman
maintainerPATCH 328/342 tty: serial: samsung: use u32 for register interactions
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tudor Ambarus <[email protected]>
[ Upstream commit 032a725c16add79332d774348d7ad7d0d4b86479 ]
All registers of the IP have 32 bits. Use u32 variables when reading or writing from/to the registers. The purpose of those variables becomes clearer.
Stable-dep-of: a3bb136bff5e ("tty: serial: samsung: Remove redundant port lock acquisition in rx helpers")
--- drivers/tty/serial/samsung_tty.c | 67 +++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 33 deletions(-)
drivers/tty/serial/samsung_tty.c +34 -33
@@ -186,7 +186,7 @@ static void wr_reg(struct uart_port *por/* Byte-order aware bit setting/clearing functions. */ static inline void s3c24xx_set_bit (struct uart_port *port,int idx, -unsigned int reg) +u32 reg) {unsigned long flags;u32 val;
@@ -199,7 +199,7 @@ static inline void s3c24xx_set_bit(struc }static inline void s3c24xx_clear_bit (struct uart_port *port,int idx, -unsigned int reg) +u32 reg) {unsigned long flags;u32 val;
@@ -242,8 +242,8 @@ static void s3c24xx_serial_rx_enable(str {struct s3c24xx_uart_port *ourport =to_ourport (port);unsigned long flags; -unsigned int ucon, ufcon;int count =10000 ; +u32 ucon, ufcon;uart_port_lock_irqsave (port, &flags);
@@ -266,7 +266,7 @@ static void s3c24xx_serial_rx_disable(st {struct s3c24xx_uart_port *ourport =to_ourport (port);unsigned long flags; -unsigned int ucon; +u32 ucon;uart_port_lock_irqsave (port, &flags);
@@ -551,7 +551,7 @@ static inline struct s3c2410_uartcfg }static int s3c24xx_serial_rx_fifocnt (struct s3c24xx_uart_port *ourport, -unsigned long ufstat) +u32 ufstat) {struct s3c24xx_uart_info *info = ourport->info;
@@ -623,7 +623,7 @@ static void s3c64xx_start_rx_dma(structstatic void enable_rx_dma (struct s3c24xx_uart_port *ourport) {struct uart_port *port = &ourport->port; -unsigned int ucon; +u32 ucon;/* set Rx mode to DMA mode */ ucon =rd_regl (port,S3C2410_UCON );
@@ -646,7 +646,7 @@ static void enable_rx_dma(struct s3c24xxstatic void enable_rx_pio (struct s3c24xx_uart_port *ourport) {struct uart_port *port = &ourport->port; -unsigned int ucon; +u32 ucon;/* set Rx mode to DMA mode */ ucon =rd_regl (port,S3C2410_UCON );
@@ -667,7 +667,6 @@ static void s3c24xx_serial_rx_drain_fifostatic irqreturn_t s3c24xx_serial_rx_chars_dma (void *dev_id) { -unsigned int utrstat, received;struct s3c24xx_uart_port *ourport = dev_id;struct uart_port *port = &ourport->port;struct s3c24xx_uart_dma *dma = ourport->dma;
@@ -675,6 +674,8 @@ static irqreturn_t s3c24xx_serial_rx_chastruct tty_port *t = &port->state->port;unsigned long flags;struct dma_tx_state state; +unsigned int received; +u32 utrstat; utrstat =rd_regl (port,S3C2410_UTRSTAT );rd_regl (port,S3C2410_UFSTAT );
@@ -716,9 +717,10 @@ finish:static void s3c24xx_serial_rx_drain_fifo (struct s3c24xx_uart_port *ourport) {struct uart_port *port = &ourport->port; -unsigned int ufcon, ch, flag, ufstat, uerstat; +unsigned int ch, flag;unsigned int fifocnt =0 ;int max_count = port->fifosize; +u32 ufcon, ufstat, uerstat;while (max_count-- >0 ) {/*
@@ -898,7 +900,7 @@ static irqreturn_t s3c64xx_serial_handle {struct s3c24xx_uart_port *ourport = id;struct uart_port *port = &ourport->port; -unsigned int pend =rd_regl (port,S3C64XX_UINTP ); +u32 pend =rd_regl (port,S3C64XX_UINTP );irqreturn_t ret =IRQ_HANDLED ;if (pend &S3C64XX_UINTM_RXD_MSK ) {
@@ -915,8 +917,8 @@ static irqreturn_t s3c64xx_serial_handlestatic unsigned int s3c24xx_serial_tx_empty (struct uart_port *port) {struct s3c24xx_uart_info *info =s3c24xx_port_to_info (port); -unsigned long ufstat =rd_regl (port,S3C2410_UFSTAT ); -unsigned long ufcon =rd_regl (port,S3C2410_UFCON ); +u32 ufstat =rd_regl (port,S3C2410_UFSTAT ); +u32 ufcon =rd_regl (port,S3C2410_UFCON );if (ufcon &S3C2410_UFCON_FIFOMODE ) { if ((ufstat & info->tx_fifomask) != 0 ||
@@ -931,7 +933,7 @@ static unsigned int s3c24xx_serial_tx_em/* no modem control lines */ static unsigned int s3c24xx_serial_get_mctrl (struct uart_port *port) { -unsigned int umstat =rd_reg (port,S3C2410_UMSTAT ); +u32 umstat =rd_reg (port,S3C2410_UMSTAT );if (umstat &S3C2410_UMSTAT_CTS )return TIOCM_CAR |TIOCM_DSR |TIOCM_CTS ;
@@ -941,7 +943,7 @@ static unsigned int s3c24xx_serial_get_mstatic void s3c24xx_serial_set_mctrl (struct uart_port *port,unsigned int mctrl) { -unsigned int umcon =rd_regl (port,S3C2410_UMCON ); +u32 umcon =rd_regl (port,S3C2410_UMCON );if (mctrl &TIOCM_RTS ) umcon |=S3C2410_UMCOM_RTS_LOW ;
@@ -954,7 +956,7 @@ static void s3c24xx_serial_set_mctrl(strstatic void s3c24xx_serial_break_ctl (struct uart_port *port,int break_state) {unsigned long flags; -unsigned int ucon; +u32 ucon;uart_port_lock_irqsave (port, &flags);
@@ -1167,7 +1169,7 @@ static int s3c64xx_serial_startup(struct {struct s3c24xx_uart_port *ourport =to_ourport (port);unsigned long flags; -unsigned int ufcon; +u32 ufcon;int ret;wr_regl (port,S3C64XX_UINTM ,0xf );
@@ -1210,6 +1212,7 @@ static int s3c64xx_serial_startup(structreturn ret; } +/* power power management control */ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
@@ -1261,7 +1264,7 @@ static void s3c24xx_serial_pm(struct uarstatic inline int s3c24xx_serial_getsource (struct uart_port *port) {struct s3c24xx_uart_info *info =s3c24xx_port_to_info (port); -unsigned int ucon; +u32 ucon;if (info->num_clks ==1 )return 0 ;
@@ -1275,7 +1278,7 @@ static void s3c24xx_serial_setsource(str unsigned int clk_sel) {struct s3c24xx_uart_info *info =s3c24xx_port_to_info (port); -unsigned int ucon; +u32 ucon;if (info->num_clks ==1 )return ;
@@ -1394,9 +1397,8 @@ static void s3c24xx_serial_set_termios(sstruct clk *clk =ERR_PTR (-EINVAL );unsigned long flags;unsigned int baud, quot, clk_sel =0 ; -unsigned int ulcon; -unsigned int umcon;unsigned int udivslot =0 ; +u32 ulcon, umcon;/* * We don't support modem control lines.
@@ -1712,7 +1714,7 @@ static void s3c24xx_serial_resetport(str struct s3c2410_uartcfg *cfg) {struct s3c24xx_uart_info *info =s3c24xx_port_to_info (port); -unsigned long ucon =rd_regl (port,S3C2410_UCON ); +u32 ucon =rd_regl (port,S3C2410_UCON );unsigned int ucon_mask; ucon_mask = info->clksel_mask;
@@ -2150,7 +2152,7 @@ static int s3c24xx_serial_resume_noirq(sif (port) {/* restore IRQ mask */ if (s3c24xx_serial_has_interrupt_mask (port)) { -unsigned int uintm =0xf ; +u32 uintm =0xf ;if (ourport->tx_enabled) uintm &= ~S3C64XX_UINTM_TXD_MSK ;
@@ -2188,10 +2190,10 @@ static const struct dev_pm_ops s3c24xx_sstatic struct uart_port *cons_uart;static int -s3c24xx_serial_console_txrdy (struct uart_port *port,unsigned int ufcon) +s3c24xx_serial_console_txrdy (struct uart_port *port,u32 ufcon) {struct s3c24xx_uart_info *info =s3c24xx_port_to_info (port); -unsigned long ufstat, utrstat; +u32 ufstat, utrstat;if (ufcon &S3C2410_UFCON_FIFOMODE ) {/* fifo mode - check amount of data in fifo registers... */
@@ -2207,7 +2209,7 @@ s3c24xx_serial_console_txrdy(struct uart }static bool -s3c24xx_port_configured (unsigned int ucon) +s3c24xx_port_configured (u32 ucon) {/* consider the serial port configured if the tx/rx mode set */ return (ucon &0xf ) !=0 ;
@@ -2222,7 +2224,7 @@ s3c24xx_port_configured(unsigned int ucostatic int s3c24xx_serial_get_poll_char (struct uart_port *port) {struct s3c24xx_uart_port *ourport =to_ourport (port); -unsigned int ufstat; +u32 ufstat; ufstat =rd_regl (port,S3C2410_UFSTAT );if (s3c24xx_serial_rx_fifocnt (ourport, ufstat) ==0 )
@@ -2234,8 +2236,8 @@ static int s3c24xx_serial_get_poll_char(static void s3c24xx_serial_put_poll_char (struct uart_port *port,unsigned char c) { -unsigned int ufcon =rd_regl (port,S3C2410_UFCON ); -unsigned int ucon =rd_regl (port,S3C2410_UCON ); +u32 ufcon =rd_regl (port,S3C2410_UFCON ); +u32 ucon =rd_regl (port,S3C2410_UCON );/* not possible to xmit on unconfigured port */ if (!s3c24xx_port_configured (ucon))
@@ -2251,7 +2253,7 @@ static void s3c24xx_serial_put_poll_charstatic void s3c24xx_serial_console_putchar (struct uart_port *port,int ch) { -unsigned int ufcon =rd_regl (port,S3C2410_UFCON ); +u32 ufcon =rd_regl (port,S3C2410_UFCON );while (!s3c24xx_serial_console_txrdy (port, ufcon))cpu_relax ();
@@ -2262,7 +2264,7 @@ static void s3c24xx_serial_console_write(struct console *co, const char *s, unsigned int count) { - unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON); + u32 ucon = rd_regl(cons_uart, S3C2410_UCON);/* not possible to xmit on unconfigured port */ if (!s3c24xx_port_configured (ucon))
@@ -2276,11 +2278,9 @@ s3c24xx_serial_get_options(struct uart_p int *parity, int *bits) { struct clk *clk; -unsigned int ulcon; -unsigned int ucon; -unsigned int ubrdiv;unsigned long rate;unsigned int clk_sel; +u32 ulcon, ucon, ubrdiv;char clk_name[MAX_CLK_NAME_LENGTH ]; ulcon =rd_regl (port,S3C2410_ULCON );
@@ -2677,6 +2677,7 @@ static void samsung_early_write(struct cuart_console_write (&dev->port, s, n, samsung_early_putc); } +static int __init samsung_early_console_setup (struct earlycon_device *device,const char *opt) {
Greg Kroah-Hartman
maintainerPATCH 329/342 tty: serial: samsung: Remove redundant port lock acquisition in rx helpers
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tudor Ambarus <[email protected]>
[ Upstream commit a3bb136bff5e6a5e48cdd813246c9c4686feaaa9 ]
Sashiko identified a deadlock when the console flow is engaged [1].
When console flow control is enabled (UPF_CONS_FLOW), s3c24xx_serial_stop_tx() calls s3c24xx_serial_rx_enable() and s3c24xx_serial_start_tx() calls s3c24xx_serial_rx_disable().
The serial core framework invokes the .stop_tx() and .start_tx() callbacks with the port->lock spinlock already held. Furthermore, all internal driver paths that invoke stop_tx (such as the DMA TX completion handler s3c24xx_serial_tx_dma_complete() or the PIO TX IRQ handler s3c24xx_serial_tx_irq()) also acquire port->lock prior to calling it. (Note that s3c24xx_serial_start_tx() is only invoked by the serial core).
However, s3c24xx_serial_rx_enable() and s3c24xx_serial_rx_disable() unconditionally attempt to acquire port->lock again using uart_port_lock_irqsave(). Since spinlocks are not recursive, this causes a deadlock on the same CPU when console flow control is engaged.
Remove the redundant lock acquisition from both rx helper functions.
--- drivers/tty/serial/samsung_tty.c | 8 -------- 1 file changed, 8 deletions(-)
drivers/tty/serial/samsung_tty.c +0 -8
@@ -241,12 +241,9 @@ static int s3c24xx_serial_has_interrupt_static void s3c24xx_serial_rx_enable (struct uart_port *port) {struct s3c24xx_uart_port *ourport =to_ourport (port); -unsigned long flags;int count =10000 ;u32 ucon, ufcon; -uart_port_lock_irqsave (port, &flags); -while (--count && !s3c24xx_serial_txempty_nofifo (port))udelay (100 );
@@ -259,23 +256,18 @@ static void s3c24xx_serial_rx_enable(strwr_regl (port,S3C2410_UCON , ucon); ourport->rx_enabled =1 ; -uart_port_unlock_irqrestore (port, flags); }static void s3c24xx_serial_rx_disable (struct uart_port *port) {struct s3c24xx_uart_port *ourport =to_ourport (port); -unsigned long flags;u32 ucon; -uart_port_lock_irqsave (port, &flags); - ucon =rd_regl (port,S3C2410_UCON ); ucon &= ~S3C2410_UCON_RXIRQMODE ;wr_regl (port,S3C2410_UCON , ucon); ourport->rx_enabled =0 ; -uart_port_unlock_irqrestore (port, flags); }static void s3c24xx_serial_stop_tx (struct uart_port *port)
Greg Kroah-Hartman
maintainerPATCH 330/342 usb: gadget: f_hid: tidy error handling in hidg_alloc
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Keeping <[email protected]>
[ Upstream commit 944fe915d00d3cb1bacb1e77cabfb6dc82e6f8b8 ]
Unify error handling at the end of the function, reducing the risk of missing something on one of the error paths.
Moving the increment of opts->refcnt later means there is no need to decrement it on the error path and is safe as this is guarded by opts->lock which is held for this entire section.
Stable-dep-of: 4f88d65def6f ("usb: gadget: f_hid: fix device reference leak in hidg_alloc()")
--- drivers/usb/gadget/function/f_hid.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
drivers/usb/gadget/function/f_hid.c +11 -10
@@ -1265,7 +1265,6 @@ static struct usb_function *hidg_alloc(s opts = container_of(fi, struct f_hid_opts, func_inst);mutex_lock (&opts->lock); - ++opts->refcnt;spin_lock_init (&hidg->write_spinlock);spin_lock_init (&hidg->read_spinlock);
@@ -1278,11 +1277,8 @@ static struct usb_function *hidg_alloc(s hidg->dev.class = hidg_class; hidg->dev.devt =MKDEV (major, opts->minor); ret =dev_set_name (&hidg->dev,"hidg%d" , opts->minor); -if (ret) { - --opts->refcnt; -mutex_unlock (&opts->lock); -return ERR_PTR (ret); - } +if (ret) + goto err_unlock; hidg->bInterfaceSubClass = opts->subclass; hidg->bInterfaceProtocol = opts->protocol;
@@ -1293,14 +1289,13 @@ static struct usb_function *hidg_alloc(s opts->report_desc_length, GFP_KERNEL);if (!hidg->report_desc) { -put_device (&hidg->dev); - --opts->refcnt; -mutex_unlock (&opts->lock); -return ERR_PTR (-ENOMEM ); + ret = -ENOMEM ; + goto err_put_device; } } hidg->use_out_ep = !opts->no_out_endpoint; + ++opts->refcnt;mutex_unlock (&opts->lock); hidg->func.name ="hid" ;
@@ -1315,6 +1310,12 @@ static struct usb_function *hidg_alloc(s hidg->qlen =4 ;return &hidg->func; + +err_put_device: +put_device (&hidg->dev); +err_unlock: +mutex_unlock (&opts->lock); +return ERR_PTR (ret); }DECLARE_USB_FUNCTION_INIT (hid, hidg_alloc_inst, hidg_alloc);
Greg Kroah-Hartman
maintainerPATCH 331/342 usb: gadget: f_hid: fix device reference leak in hidg_alloc()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <[email protected]>
[ Upstream commit 4f88d65def6f3c90121601b4f62a4c967f3063a6 ]
hidg_alloc() initializes hidg->dev with device_initialize() before calling dev_set_name(). If dev_set_name() fails, the function currently jumps to err_unlock and returns without calling put_device().
This leaves the device reference unbalanced and prevents hidg_release() from being called. Calling put_device() here is also safe, since hidg_release() only frees resources owned by hidg.
The issue was identified by a static analysis tool I developed and confirmed by manual review.
Route the dev_set_name() failure path through err_put_device so the device reference is dropped properly.
--- drivers/usb/gadget/function/f_hid.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/usb/gadget/function/f_hid.c +1 -2
@@ -1278,7 +1278,7 @@ static struct usb_function *hidg_alloc(s hidg->dev.devt =MKDEV (major, opts->minor); ret =dev_set_name (&hidg->dev,"hidg%d" , opts->minor);if (ret) - goto err_unlock; + goto err_put_device; hidg->bInterfaceSubClass = opts->subclass; hidg->bInterfaceProtocol = opts->protocol;
@@ -1313,7 +1313,6 @@ static struct usb_function *hidg_alloc(s err_put_device:put_device (&hidg->dev); -err_unlock:mutex_unlock (&opts->lock);return ERR_PTR (ret); }
Greg Kroah-Hartman
maintainerPATCH 332/342 lib/crypto: mpi: Fix integer underflow in mpi_read_raw_from_sgl()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner <[email protected]>
commit 8c2f1288250a90a4b5cabed5d888d7e3aeed4035 upstream.
Yiming reports an integer underflow in mpi_read_raw_from_sgl() when subtracting "lzeros" from the unsigned "nbytes".
For this to happen, the scatterlist "sgl" needs to occupy more bytes than the "nbytes" parameter and the first "nbytes + 1" bytes of the scatterlist must be zero. Under these conditions, the while loop iterating over the scatterlist will count more zeroes than "nbytes", subtract the number of zeroes from "nbytes" and cause the underflow.
When commit 2d4d1eea540b ("lib/mpi: Add mpi sgl helpers") originally introduced the bug, it couldn't be triggered because all callers of mpi_read_raw_from_sgl() passed a scatterlist whose length was equal to "nbytes".
However since commit 63ba4d67594a ("KEYS: asymmetric: Use new crypto interface without scatterlists"), the underflow can now actually be triggered. When invoking a KEYCTL_PKEY_ENCRYPT system call with a larger "out_len" than "in_len" and filling the "in" buffer with zeroes, crypto_akcipher_sync_prep() will create an all-zero scatterlist used for both the "src" and "dst" member of struct akcipher_request and thereby fulfil the conditions to trigger the bug:
sys_keyctl()
keyctl_pkey_e_d_s()
asymmetric_key_eds_op()
software_key_eds_op()
crypto_akcipher_sync_encrypt()
crypto_akcipher_sync_prep()
crypto_akcipher_encrypt()
rsa_enc()
mpi_read_raw_from_sgl()To the user this will be visible as a DoS as the kernel spins forever, causing soft lockup splats as a side effect.
Fix it.
--- lib/mpi/mpicoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/mpi/mpicoder.c +1 -1
@@ -453,7 +453,7 @@ MPI mpi_read_raw_from_sgl(struct scatter lzeros =0 ; len =0 ;while (nbytes >0 ) { -while (len && !*buff) { +while (len && !*buff && lzeros < nbytes) { lzeros++; len--; buff++;
Greg Kroah-Hartman
maintainerPATCH 333/342 arm64: Subscribe Microsoft Azure Cobalt 100 to ARM Neoverse N2 errata
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Easwar Hariharan <[email protected]>
commit fb091ff394792c018527b3211bbdfae93ea4ac02 upstream.
Add the MIDR value of Microsoft Azure Cobalt 100, which is a Microsoft implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore suffers from all the same errata.
--- arch/arm64/include/asm/cputype.h | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm64/include/asm/cputype.h +4 -0
@@ -61,6 +61,7 @@#define ARM_CPU_IMP_HISI 0x48#define ARM_CPU_IMP_APPLE 0x61#define ARM_CPU_IMP_AMPERE 0xC0 +#define ARM_CPU_IMP_MICROSOFT 0x6D#define ARM_CPU_PART_AEM_V8 0xD0F#define ARM_CPU_PART_FOUNDATION 0xD00
@@ -130,6 +131,8 @@#define AMPERE_CPU_PART_AMPERE1 0xAC3 +#define MICROSOFT_CPU_PART_AZURE_COBALT_100 0xD49/* Based on r0p0 of ARM Neoverse N2 */ +#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)#define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
@@ -185,6 +188,7 @@#define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM)#define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM)#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1) +#define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_AZURE_COBALT_100)/* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */ #define MIDR_FUJITSU_ERRATUM_010001 MIDR_FUJITSU_A64FX
Greg Kroah-Hartman
maintainerPATCH 334/342 arm64: cputype: Add NVIDIA Olympus definitions
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shanker Donthineni <[email protected]>
commit e185c8a0d84236d14af61faff8147c953a878a77 upstream.
Add cpu part and model macro definitions for NVIDIA Olympus core.
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -121,6 +121,7 @@#define NVIDIA_CPU_PART_DENVER 0x003#define NVIDIA_CPU_PART_CARMEL 0x004 +#define NVIDIA_CPU_PART_OLYMPUS 0x010#define FUJITSU_CPU_PART_A64FX 0x001
@@ -183,6 +184,7 @@#define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER)#define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER)#define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) +#define MIDR_NVIDIA_OLYMPUS MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_OLYMPUS)#define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX)#define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110)#define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM)
Greg Kroah-Hartman
maintainerPATCH 335/342 arm64: cputype: Add C1-Ultra definitions
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
commit 60349e64a6c65f9f0aa118af711b3c7e137f07ff upstream.
Add cputype definitions for C1-Ultra. These will be used for errata detection in subsequent patches.
These values can be found in the C1-Ultra TRM:
https://developer.arm.com/documentation/108014/0100/
... in section A.5.1 ("MIDR_EL1, Main ID Register").
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -97,6 +97,7 @@#define ARM_CPU_PART_NEOVERSE_V3 0xD84#define ARM_CPU_PART_CORTEX_X925 0xD85#define ARM_CPU_PART_CORTEX_A725 0xD87 +#define ARM_CPU_PART_C1_ULTRA 0xD8C#define ARM_CPU_PART_NEOVERSE_N3 0xD8E#define APM_CPU_PART_POTENZA 0x000
@@ -166,6 +167,7 @@#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725) +#define MIDR_C1_ULTRA MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_ULTRA)#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
Greg Kroah-Hartman
maintainerPATCH 336/342 arm64: cputype: Add C1-Premium definitions
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
commit d28413bfc5a255957241f1df5d7fd0c2cd74fe18 upstream.
Add cputype definitions for C1-Premium. These will be used for errata detection in subsequent patches.
These values can be found in the C1-Premium TRM:
https://developer.arm.com/documentation/109416/0100/
... in section A.5.1 ("MIDR_EL1, Main ID Register").
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -99,6 +99,7 @@#define ARM_CPU_PART_CORTEX_A725 0xD87#define ARM_CPU_PART_C1_ULTRA 0xD8C#define ARM_CPU_PART_NEOVERSE_N3 0xD8E +#define ARM_CPU_PART_C1_PREMIUM 0xD90#define APM_CPU_PART_POTENZA 0x000
@@ -169,6 +170,7 @@#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)#define MIDR_C1_ULTRA MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_ULTRA)#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3) +#define MIDR_C1_PREMIUM MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_PREMIUM)#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
Greg Kroah-Hartman
maintainerPATCH 337/342 arm64: errata: Mitigate TLBI errata on various Arm CPUs
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
commit cfd391e74134db664feb499d43af286380b10ba8 upstream.
A number of CPUs developed by Arm suffer from errata whereby a broadcast TLBI;DSB sequence may complete before the global observation of writes which are translated by an affected TLB entry.
These errata ONLY affect the completion of memory accesses which have been translated by an invalidated TLB entry, and these errata DO NOT affect the actual invalidation of TLB entries. TLB entries are removed correctly.
This issue has been assigned CVE ID CVE-2025-10263.
To mitigate this issue, Arm recommends that software follows any affected TLBI;DSB sequence with an additional TLBI;DSB, which will ensure that all memory write effects affected by the first TLBI have been globally observed. The additional TLBI can use any operation that is broadcast to affected CPUs, and the additional DSB can use any option that is sufficient to complete the additional TLBI.
The ARM64_WORKAROUND_REPEAT_TLBI workaround is sufficient to mitigate the issue. Enable this workaround for affected CPUs, and update the silicon errata documentation accordingly.
Note that due to the manner in which Arm develops IP and tracks errata, some CPUs share a common erratum number.
--- Documentation/arm64/silicon-errata.rst | 42 ++++++++++++++++++++++++++++ arch/arm64/Kconfig | 48 +++++++++++++++++++++++++++++++++ arch/arm64/kernel/cpu_errata.c | 32 ++++++++++++++++++++-- 3 files changed, 120 insertions(+), 2 deletions(-)
Documentation/arm64/silicon-errata.rst +42 -0
@@ -96,18 +96,32 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A76 | #3324349 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A76 | #4193800 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A76AE | #4193801 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A77 | #3324348 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A77 | #4193798 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A78 | #4193791 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A78AE | #4193793 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A78C | #3324346,3324347| ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A78C | #4193794 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A510 | #2457168 | ARM64_ERRATUM_2457168 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A710 | #4193788 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 |
@@ -116,16 +130,28 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X1 | #4193791 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-X1C | #3324346 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X1C | #4193792 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-X2 | #3324338 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X2 | #4193788 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-X3 | #3324335 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X3 | #4193786 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X4 | #4118414 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-X925 | #3324334 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X925 | #4193781 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1349291 | N/A |
@@ -134,18 +160,34 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N1 | #4193800 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N2 | #4193789 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-V1 | #4193790 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-V2 | #4193787 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-V3 | #4193784 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V3AE | #3312417 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-V3AE | #4193784 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | C1-Premium | #4193780 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | C1-Ultra | #4193780 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
arch/arm64/Kconfig +48 -0
54 lines not on this page · raw message
arch/arm64/kernel/cpu_errata.c +30 -2
@@ -226,7 +226,35 @@ static const struct arm64_cpu_capabiliti ERRATA_MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xe), }, #endif - {}, +#ifdef CONFIG_ARM64_ERRATUM_4118414 + { + ERRATA_MIDR_RANGE_LIST(((const struct midr_range[]) { + MIDR_ALL_VERSIONS(MIDR_C1_PREMIUM), + MIDR_ALL_VERSIONS(MIDR_C1_ULTRA), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A76), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A76AE), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A77), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A78AE), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X2), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X4), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X925), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3AE), + {} + })), + }, +#endif + {} }; #endif
@@ -476,7 +504,7 @@ const struct arm64_cpu_capabilities arm6#endif #ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI { - .desc = "Qualcomm erratum 1009, or ARM erratum 1286807", + .desc = "Broken broadcast TLBI completion", .capability = ARM64_WORKAROUND_REPEAT_TLBI, .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .matches = cpucap_multi_entry_cap_matches,
Greg Kroah-Hartman
maintainerPATCH 338/342 arm64: errata: Mitigate TLBI errata on NVIDIA Olympus CPU
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shanker Donthineni <[email protected]>
commit ec7216f92e4ebd485b1c6dc6aa3f6064b71a5768 upstream.
NVIDIA Olympus cores are affected by the TLBI completion issue tracked as CVE-2025-10263. The existing ARM64_ERRATUM_4118414 handling already uses ARM64_WORKAROUND_REPEAT_TLBI to issue an additional broadcast TLBI;DSB sequence and ensure affected memory write effects are globally observed.
Add MIDR_NVIDIA_OLYMPUS to the repeat-TLBI match list so the same mitigation is enabled on affected Olympus systems. Also document the NVIDIA Olympus erratum in the arm64 silicon errata table and list it in the Kconfig help text.
--- Documentation/arm64/silicon-errata.rst | 3 +++ arch/arm64/Kconfig | 3 ++- arch/arm64/kernel/cpu_errata.c | 1 + 3 files changed, 6 insertions(+), 1 deletion(-)
Documentation/arm64/silicon-errata.rst +3 -0
@@ -220,6 +220,9 @@ stable kernels. | Marvell | ARM-MMU-500 | #582743 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ +| NVIDIA | Olympus core | T410-OLY-1029 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+ ++----------------+-----------------+-----------------+-----------------------------+ | Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 | +----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+
arch/arm64/Kconfig +2 -1
@@ -745,7 +745,7 @@ config ARM64_ERRATUM_4193714 If unsure, say Y. config ARM64_ERRATUM_4118414 - bool "Cortex-*/Neoverse-*/C1-*: Completion of affected memory accesses might not be guaranteed by completion of a TLBI" + bool "Various: Completion of affected memory accesses might not be guaranteed by completion of a TLBI" default y select ARM64_WORKAROUND_REPEAT_TLBI help
@@ -772,6 +772,7 @@ config ARM64_ERRATUM_4118414 * ARM Neoverse-V2 erratum 4193787 * ARM Neoverse-V3 erratum 4193784 * ARM Neoverse-V3AE erratum 4193784 + * NVIDIA Olympus erratum T410-OLY-1029 On affected cores, some memory accesses might not be completed by broadcast TLB invalidation.
arch/arm64/kernel/cpu_errata.c +1 -0
@@ -250,6 +250,7 @@ static const struct arm64_cpu_capabilitiMIDR_ALL_VERSIONS (MIDR_NEOVERSE_V2 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V3 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V3AE ), + MIDR_ALL_VERSIONS(MIDR_NVIDIA_OLYMPUS), {} })), },
Greg Kroah-Hartman
maintainerPATCH 339/342 arm64: errata: Mitigate TLBI errata on Microsoft Azure Cobalt 100 CPU
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon <[email protected]>
commit 1940e70a8144bf75e6df26bf6f600862ea7f7ea1 upstream.
Commit fb091ff39479 ("arm64: Subscribe Microsoft Azure Cobalt 100 to ARM Neoverse N2 errata") states that Microsoft Azure Cobalt 100 CPU "is a Microsoft implemented CPU based on r0p0 of the ARM Neoverse N2 CPU, and therefore suffers from all the same errata.".
So enable the workaround for the latest broadcast TLB invalidation bug on these parts.
--- Documentation/arm64/silicon-errata.rst | 3 +++ arch/arm64/Kconfig | 1 + arch/arm64/kernel/cpu_errata.c | 1 + 3 files changed, 5 insertions(+)
Documentation/arm64/silicon-errata.rst +3 -0
@@ -262,3 +262,6 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Fujitsu | A64FX | E#010001 | FUJITSU_ERRATUM_010001 | +----------------+-----------------+-----------------+-----------------------------+ ++----------------+-----------------+-----------------+-----------------------------+ +| Microsoft | Azure Cobalt 100| #4193789 | ARM64_ERRATUM_4118414 | ++----------------+-----------------+-----------------+-----------------------------+
arch/arm64/Kconfig +1 -0
@@ -772,6 +772,7 @@ config ARM64_ERRATUM_4118414 * ARM Neoverse-V2 erratum 4193787 * ARM Neoverse-V3 erratum 4193784 * ARM Neoverse-V3AE erratum 4193784 + * Microsoft Azure Cobalt 100 4193789 * NVIDIA Olympus erratum T410-OLY-1029 On affected cores, some memory accesses might not be completed by
arch/arm64/kernel/cpu_errata.c +1 -0
@@ -251,6 +251,7 @@ static const struct arm64_cpu_capabilitiMIDR_ALL_VERSIONS (MIDR_NEOVERSE_V3 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V3AE ),MIDR_ALL_VERSIONS (MIDR_NVIDIA_OLYMPUS ), + MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100), {} })), },
Greg Kroah-Hartman
maintainerPATCH 340/342 fbdev: vt8500lcdfb: Fix dma_free_coherent() cpu_addr parameter
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <[email protected]>
Before commit 63a11adaceb8 "fbdev/vt8500lcdfb: Initialize fb_ops with fbdev macros", the virtual address of the screen buffer was stored in the fb_info::screen_base field and not fb_info::screen_buffer. The backport of commit 88b3b9924337 ("fbdev: vt8500lcdfb: fix missing dma_free_coherent()") did not take that into account.
Change the cpu_addr parameter to dma_free_coherent() accordingly.
--- drivers/video/fbdev/vt8500lcdfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/video/fbdev/vt8500lcdfb.c +1 -1
@@ -434,7 +434,7 @@ failed_free_palette: fbi->palette_cpu, fbi->palette_phys); failed_free_mem_virt:dma_free_coherent (&pdev->dev, fbi->fb.fix.smem_len, - fbi->fb.screen_buffer, fbi->fb.fix.smem_start); + fbi->fb.screen_base, fbi->fb.fix.smem_start); failed_free_io:iounmap (fbi->regbase); failed_free_res:
Greg Kroah-Hartman
maintainerPATCH 341/342 apparmor: validate default DFA states are in bounds
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <[email protected]>
Some backports of commit 9063d7e2615f ("apparmor: validate DFA start states are in bounds in unpack_pdb") limited the bounds checks on DFA start states to the case where the start state was explicit in the policy. However, the default DFA start state (DFA_START = 1) could also be out-of-bounds.
Move these checks out of the else-branches so that they are applied regardless of how the start state was initialised.
--- security/apparmor/policy_unpack.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
security/apparmor/policy_unpack.c +15 -12
@@ -846,6 +846,8 @@ static struct aa_profile *unpack_profile }if (unpack_nameX (e,AA_STRUCT ,"policydb" )) { +size_t state_count; +/* generic policy dfa - optional and may be NULL */ info ="failed to unpack policydb" ; profile->policy.dfa =unpack_dfa (e);
@@ -860,13 +862,12 @@ static struct aa_profile *unpack_profileif (!unpack_u32 (e, &profile->policy.start[0 ],"start" )) {/* default start state */ profile->policy.start[0 ] =DFA_START ; - }else { -size_t state_count = profile->policy.dfa->tables[YYTD_ID_BASE ]->td_lolen; + } -if (profile->policy.start[0 ] >= state_count) { - info ="invalid dfa start state" ; - goto fail; - } + state_count = profile->policy.dfa->tables[YYTD_ID_BASE ]->td_lolen; +if (profile->policy.start[0 ] >= state_count) { + info ="invalid dfa start state" ; + goto fail; }/* setup class index */
@@ -889,16 +890,18 @@ static struct aa_profile *unpack_profile info ="failed to unpack profile file rules" ; goto fail; }else if (profile->file.dfa) { +size_t state_count; +if (!unpack_u32 (e, &profile->file.start,"dfa_start" )) {/* default start state */ profile->file.start =DFA_START ; - }else { -size_t state_count = profile->file.dfa->tables[YYTD_ID_BASE ]->td_lolen; + } + + state_count = profile->file.dfa->tables[YYTD_ID_BASE ]->td_lolen; -if (profile->file.start >= state_count) { - info ="invalid dfa start state" ; - goto fail; - } +if (profile->file.start >= state_count) { + info ="invalid dfa start state" ; + goto fail; } }else if (profile->policy.dfa && profile->policy.start[AA_CLASS_FILE ]) {
Greg Kroah-Hartman
maintainerPATCH 342/342 x86/CPU/AMD: Move the Zen3 BTC_NO detection to the Zen3 init function
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Borislav Petkov (AMD) <[email protected]>
commit affc66cb96f865b3763a8e18add52e133d864f04 upstream.
No functional changes.
Stable-dep-of: 7c81ad8e8bc2 ("x86/CPU/AMD: Rename init_amd_zn() to init_amd_zen_common()") [bwh: Adjusted to apply after backports of the above commit which actually
depended on this]
--- arch/x86/kernel/cpu/amd.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
arch/x86/kernel/cpu/amd.c +10 -8
@@ -1138,14 +1138,6 @@ static void init_amd_zen1(struct cpuinfo/* Erratum 1076: CPB feature bit not being set in CPUID. */ if (!cpu_has (c,X86_FEATURE_CPB ))set_cpu_cap (c,X86_FEATURE_CPB ); - -/* -* Zen3 (Fam19 model < 0x10) parts are not susceptible to -* Branch Type Confusion, but predate the allocation of the -* BTC_NO bit. -*/ -if (c->x86 ==0x19 && !cpu_has (c,X86_FEATURE_BTC_NO )) -set_cpu_cap (c,X86_FEATURE_BTC_NO ); }pr_notice_once ("AMD Zen1 FPDSS bug detected, enabling mitigation.\n" );
@@ -1205,6 +1197,16 @@ static void init_amd_zen2(struct cpuinfostatic void init_amd_zen3 (struct cpuinfo_x86 *c) {init_amd_zen_common (); + +if (!cpu_has (c,X86_FEATURE_HYPERVISOR )) { +/* +* Zen3 (Fam19 model < 0x10) parts are not susceptible to +* Branch Type Confusion, but predate the allocation of the +* BTC_NO bit. +*/ +if (!cpu_has (c,X86_FEATURE_BTC_NO )) +set_cpu_cap (c,X86_FEATURE_BTC_NO ); + } }static void init_amd_zen4 (struct cpuinfo_x86 *c)
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.259 release. There are 342 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 Thu, 18 Jun 2026 14:49:57 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.259-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.y
and the diffstat can be found below.thanks,
greg k-h
Built for i386 and booted OK on a 32 bit laptop.
Greg Kroah-Hartman wrote on Tue, Jun 16, 2026 at 08:24:56PM +0530:
Quoted 5 lines
This is the start of the stable review cycle for the 5.10.259 release. There are 342 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.
Quoted 8 lines
Responses should be made by Thu, 18 Jun 2026 14:49:57 +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/v5.x/stable-review/patch-5.10.259-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.y
and the diffstat can be found below.
Tested b93100fe2cc0 ("Linux 5.10.259-rc1") on:
- arm i.MX6ULL (Armadillo 640)
- arm64 i.MX8MP (Armadillo G4)
- arm64 i.MX8ULP (Armadillo IoT A9E)
No obvious regression in dmesg or basic tests:
Signature · 1 line
Dominique Martinet
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.259 release. There are 342 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 Thu, 18 Jun 2026 14:49:57 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.259-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.y
and the diffstat can be found below.thanks,
greg k-h
I tested 5.10.259-rc1 on a Lenovo ThinkPad T14 Gen 1, and I tested 5.10.258 + stable-queue as of commit b19bf37c38738ddd7047ec98fafdb87eabceb193 (so with all of the post-rc1 changes as of this writing) on a 2017 13" Apple MacBook Air.
Both of them worked well and I did not observe any regressions.
Signature · 1 line
-Barry K. Nathan <[email protected]>
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 5.10.259 release. There are 342 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.
CIP testing did not find any problems here:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-5.10.y
Best regards,
Pavel
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.259 release. There are 342 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 Thu, 18 Jun 2026 14:49:57 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.259-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.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_GENEIRC:
Signature · 1 line
Florian