6.12.44-rc1 review
Subsystems (6)
Greg Kroah-Hartman
maintainerPATCH 153/322 btrfs: send: add and use helper to rename current inode when processing refs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit ec666c84deba56f714505b53556a97565f72db86 ]
Extract the logic to rename the current inode at process_recorded_refs() into a helper function and use it, therefore removing duplicated logic and making it easier for an upcoming patch by avoiding yet more duplicated logic.
Stable-dep-of: 005b0a0c24e1 ("btrfs: send: use fallocate for hole punching with send stream v2")
--- fs/btrfs/send.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
fs/btrfs/send.c +15 -8
@@ -4165,6 +4165,19 @@ out:return ret; } +static int rename_current_inode (struct send_ctx *sctx, +struct fs_path *current_path, +struct fs_path *new_path) +{ +int ret; + + ret =send_rename (sctx, current_path, new_path); +if (ret <0 ) +return ret; + +return fs_path_copy (current_path, new_path); +} +/* * This does all the move/link/unlink/rmdir magic. */
@@ -4450,13 +4463,10 @@ static int process_recorded_refs(struct* it depending on the inode mode. */ if (is_orphan && can_rename) { - ret =send_rename (sctx, valid_path, cur->full_path); + ret =rename_current_inode (sctx, valid_path, cur->full_path);if (ret <0 ) goto out; is_orphan = false; - ret =fs_path_copy (valid_path, cur->full_path); -if (ret <0 ) - goto out; }else if (can_rename) {if (S_ISDIR (sctx->cur_inode_mode)) {/*
@@ -4464,10 +4474,7 @@ static int process_recorded_refs(struct* dirs, we always have one new and one deleted * ref. The deleted ref is ignored later. */ - ret =send_rename (sctx, valid_path, - cur->full_path); -if (!ret) - ret =fs_path_copy (valid_path, + ret =rename_current_inode (sctx, valid_path, cur->full_path);if (ret <0 ) goto out;
Greg Kroah-Hartman
maintainerPATCH 154/322 btrfs: send: keep the current inodes path cached
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit fc746acb7aa9aeaa2cb5dcba449323319ba5c8eb ]
Whenever we need to send a command for the current inode, like sending writes, xattr updates, truncates, utimes, etc, we compute the inode's path each time, which implies doing some memory allocations and traversing the inode hierarchy to extract the name of the inode and each ancestor directory, and that implies doing lookups in the subvolume tree amongst other operations.
Most of the time, by far, the current inode's path doesn't change while we are processing it (like if we need to issue 100 write commands, the path remains the same and it's pointless to compute it 100 times).
To avoid this keep the current inode's path cached in the send context and invalidate it or update it whenever it's needed (after unlinks or renames).
A performance test, and its results, is mentioned in the next patch in the series (subject: "btrfs: send: avoid path allocation for the current inode when issuing commands").
Stable-dep-of: 005b0a0c24e1 ("btrfs: send: use fallocate for hole punching with send stream v2")
--- fs/btrfs/send.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-)
fs/btrfs/send.c +48 -5
@@ -178,6 +178,7 @@ struct send_ctx {u64 cur_inode_rdev;u64 cur_inode_last_extent;u64 cur_inode_next_write_offset; +struct fs_path cur_inode_path;bool cur_inode_new;bool cur_inode_new_gen;bool cur_inode_deleted;
@@ -436,6 +437,14 @@ static void fs_path_reset(struct fs_path } } +static void init_path (struct fs_path *p) +{ + p->reversed =0 ; + p->buf = p->inline_buf; + p->buf_len =FS_PATH_INLINE_SIZE ; +fs_path_reset (p); +} +static struct fs_path *fs_path_alloc (void ) {struct fs_path *p;
@@ -443,10 +452,7 @@ static struct fs_path *fs_path_alloc(voi p =kmalloc (sizeof (*p),GFP_KERNEL );if (!p)return NULL ; - p->reversed =0 ; - p->buf = p->inline_buf; - p->buf_len =FS_PATH_INLINE_SIZE ; -fs_path_reset (p); +init_path (p);return p; }
@@ -624,6 +630,14 @@ static void fs_path_unreverse(struct fs_ p->reversed =0 ; } +static inline bool is_current_inode_path (const struct send_ctx *sctx, +const struct fs_path *path) +{ +const struct fs_path *cur = &sctx->cur_inode_path; + +return (strncmp (path->start, cur->start,fs_path_len (cur)) ==0 ); +} +static struct btrfs_path *alloc_path_for_send (void ) {struct btrfs_path *path;
@@ -2450,6 +2464,14 @@ static int get_cur_path(struct send_ctxu64 parent_inode =0 ;u64 parent_gen =0 ;int stop =0 ; +const bool is_cur_inode = (ino == sctx->cur_ino && gen == sctx->cur_inode_gen); + +if (is_cur_inode &&fs_path_len (&sctx->cur_inode_path) >0 ) { +if (dest != &sctx->cur_inode_path) +return fs_path_copy (dest, &sctx->cur_inode_path); + +return 0 ; + } name =fs_path_alloc ();if (!name) {
@@ -2501,8 +2523,12 @@ static int get_cur_path(struct send_ctx out:fs_path_free (name); -if (!ret) +if (!ret) {fs_path_unreverse (dest); +if (is_cur_inode && dest != &sctx->cur_inode_path) + ret =fs_path_copy (&sctx->cur_inode_path, dest); + } +return ret; }
@@ -3112,6 +3138,11 @@ static int orphanize_inode(struct send_c goto out; ret =send_rename (sctx, path, orphan); +if (ret <0 ) + goto out; + +if (ino == sctx->cur_ino && gen == sctx->cur_inode_gen) + ret =fs_path_copy (&sctx->cur_inode_path, orphan); out:fs_path_free (orphan);
@@ -4175,6 +4206,10 @@ static int rename_current_inode(struct sif (ret <0 )return ret; + ret =fs_path_copy (&sctx->cur_inode_path, new_path); +if (ret <0 ) +return ret; +return fs_path_copy (current_path, new_path); }
@@ -4368,6 +4403,7 @@ static int process_recorded_refs(structif (ret >0 ) { orphanized_ancestor = true;fs_path_reset (valid_path); +fs_path_reset (&sctx->cur_inode_path); ret =get_cur_path (sctx, sctx->cur_ino, sctx->cur_inode_gen, valid_path);
@@ -4567,6 +4603,8 @@ static int process_recorded_refs(struct ret =send_unlink (sctx, cur->full_path);if (ret <0 ) goto out; +if (is_current_inode_path (sctx, cur->full_path)) +fs_path_reset (&sctx->cur_inode_path); } ret =dup_ref (cur, &check_dirs);if (ret <0 )
@@ -6902,6 +6940,7 @@ static int changed_inode(struct send_ctx sctx->cur_inode_last_extent = (u64)-1 ; sctx->cur_inode_next_write_offset =0 ; sctx->ignore_cur_inode = false; +fs_path_reset (&sctx->cur_inode_path);/* * Set send_progress to current inode. This will tell all get_cur_xxx
@@ -8174,6 +8213,7 @@ long btrfs_ioctl_send(struct btrfs_inode goto out; } +init_path (&sctx->cur_inode_path);INIT_LIST_HEAD (&sctx->new_refs);INIT_LIST_HEAD (&sctx->deleted_refs);
@@ -8459,6 +8499,9 @@ out:btrfs_lru_cache_clear (&sctx->dir_created_cache);btrfs_lru_cache_clear (&sctx->dir_utimes_cache); +if (sctx->cur_inode_path.buf != sctx->cur_inode_path.inline_buf) +kfree (sctx->cur_inode_path.buf); +kfree (sctx); }
Greg Kroah-Hartman
maintainerPATCH 155/322 btrfs: send: avoid path allocation for the current inode when issuing commands
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 374d45af6435534a11b01b88762323abf03dd755 ]
Whenever we issue a command we allocate a path and then compute it. For the current inode this is not necessary since we have one preallocated and computed in the send context structure, so we can use it instead and avoid allocating and freeing a path.
For example if we have 100 extents to send (100 write commands) for a file, we are allocating and freeing paths 100 times.
So improve on this by avoiding path allocation and freeing whenever a command is for the current inode by using the current inode's path stored in the send context structure.
A test was run before applying this patch and the previous one in the series:
"btrfs: send: keep the current inode's path cached"
The test script is the following:
$ cat test.sh #!/bin/bash
DEV=/dev/nullb0
MNT=/mnt/nullb0
mkfs.btrfs -f $DEV > /dev/null
mount $DEV $MNT
DIR="$MNT/one/two/three/four"
FILE="$DIR/foobar"
mkdir -p $DIR
# Create some empty files to get a deeper btree and therefore make
# path computations slower.
for ((i = 1; i <= 30000; i++)); do
echo -n > "$DIR/filler_$i"
done for ((i = 0; i < 10000; i += 2)); do
offset=$(( i * 4096 ))
xfs_io -f -c "pwrite -S 0xab $offset 4K" $FILE > /dev/null
donebtrfs subvolume snapshot -r $MNT $MNT/snap
start=$(date +%s%N) btrfs send -f /dev/null $MNT/snap end=$(date +%s%N) echo -e "\nsend took $(( (end - start) / 1000000 )) milliseconds"
umount $MNT
Result before applying the 2 patches: 1121 milliseconds
Result after applying the 2 patches: 815 milliseconds (-31.6%)
Stable-dep-of: 005b0a0c24e1 ("btrfs: send: use fallocate for hole punching with send stream v2")
--- fs/btrfs/send.c | 215 +++++++++++++++++++++++++------------------------------- 1 file changed, 97 insertions(+), 118 deletions(-)
fs/btrfs/send.c +97 -118
@@ -2623,6 +2623,47 @@ out:return ret; } +static struct fs_path *get_cur_inode_path (struct send_ctx *sctx) +{ +if (fs_path_len (&sctx->cur_inode_path) ==0 ) { +int ret; + + ret =get_cur_path (sctx, sctx->cur_ino, sctx->cur_inode_gen, + &sctx->cur_inode_path); +if (ret <0 ) +return ERR_PTR (ret); + } + +return &sctx->cur_inode_path; +} + +static struct fs_path *get_path_for_command (struct send_ctx *sctx,u64 ino,u64 gen) +{ +struct fs_path *path; +int ret; + +if (ino == sctx->cur_ino && gen == sctx->cur_inode_gen) +return get_cur_inode_path (sctx); + + path =fs_path_alloc (); +if (!path) +return ERR_PTR (-ENOMEM ); + + ret =get_cur_path (sctx, ino, gen, path); +if (ret <0 ) { +fs_path_free (path); +return ERR_PTR (ret); + } + +return path; +} + +static void free_path_for_command (const struct send_ctx *sctx,struct fs_path *path) +{ +if (path != &sctx->cur_inode_path) +fs_path_free (path); +} +static int send_truncate (struct send_ctx *sctx,u64 ino,u64 gen,u64 size) {struct btrfs_fs_info *fs_info = sctx->send_root->fs_info;
@@ -2631,17 +2672,14 @@ static int send_truncate(struct send_ctxbtrfs_debug (fs_info,"send_truncate %llu size=%llu" , ino, size); - p =fs_path_alloc (); -if (!p) -return -ENOMEM ; + p =get_path_for_command (sctx, ino, gen); +if (IS_ERR (p)) +return PTR_ERR (p); ret =begin_cmd (sctx,BTRFS_SEND_C_TRUNCATE );if (ret <0 ) goto out; - ret =get_cur_path (sctx, ino, gen, p); -if (ret <0 ) - goto out;TLV_PUT_PATH (sctx,BTRFS_SEND_A_PATH , p);TLV_PUT_U64 (sctx,BTRFS_SEND_A_SIZE , size);
@@ -2649,7 +2687,7 @@ static int send_truncate(struct send_ctx tlv_put_failure: out: -fs_path_free (p); +free_path_for_command (sctx, p);return ret; }
@@ -2661,17 +2699,14 @@ static int send_chmod(struct send_ctx *sbtrfs_debug (fs_info,"send_chmod %llu mode=%llu" , ino, mode); - p =fs_path_alloc (); -if (!p) -return -ENOMEM ; + p =get_path_for_command (sctx, ino, gen); +if (IS_ERR (p)) +return PTR_ERR (p); ret =begin_cmd (sctx,BTRFS_SEND_C_CHMOD );if (ret <0 ) goto out; - ret =get_cur_path (sctx, ino, gen, p); -if (ret <0 ) - goto out;TLV_PUT_PATH (sctx,BTRFS_SEND_A_PATH , p);TLV_PUT_U64 (sctx,BTRFS_SEND_A_MODE , mode &07777 );
@@ -2679,7 +2714,7 @@ static int send_chmod(struct send_ctx *s tlv_put_failure: out: -fs_path_free (p); +free_path_for_command (sctx, p);return ret; }
@@ -2694,17 +2729,14 @@ static int send_fileattr(struct send_ctxbtrfs_debug (fs_info,"send_fileattr %llu fileattr=%llu" , ino, fileattr); - p =fs_path_alloc (); -if (!p) -return -ENOMEM ; + p =get_path_for_command (sctx, ino, gen); +if (IS_ERR (p)) +return PTR_ERR (p); ret =begin_cmd (sctx,BTRFS_SEND_C_FILEATTR );if (ret <0 ) goto out; - ret =get_cur_path (sctx, ino, gen, p); -if (ret <0 ) - goto out;TLV_PUT_PATH (sctx,BTRFS_SEND_A_PATH , p);TLV_PUT_U64 (sctx,BTRFS_SEND_A_FILEATTR , fileattr);
@@ -2712,7 +2744,7 @@ static int send_fileattr(struct send_ctx tlv_put_failure: out: -fs_path_free (p); +free_path_for_command (sctx, p);return ret; }
@@ -2725,17 +2757,14 @@ static int send_chown(struct send_ctx *sbtrfs_debug (fs_info,"send_chown %llu uid=%llu, gid=%llu" , ino, uid, gid); - p =fs_path_alloc (); -if (!p) -return -ENOMEM ; + p =get_path_for_command (sctx, ino, gen); +if (IS_ERR (p)) +return PTR_ERR (p); ret =begin_cmd (sctx,BTRFS_SEND_C_CHOWN );if (ret <0 ) goto out; - ret =get_cur_path (sctx, ino, gen, p); -if (ret <0 ) - goto out;TLV_PUT_PATH (sctx,BTRFS_SEND_A_PATH , p);TLV_PUT_U64 (sctx,BTRFS_SEND_A_UID , uid);TLV_PUT_U64 (sctx,BTRFS_SEND_A_GID , gid);
@@ -2744,7 +2773,7 @@ static int send_chown(struct send_ctx *s tlv_put_failure: out: -fs_path_free (p); +free_path_for_command (sctx, p);return ret; }
@@ -2761,9 +2790,9 @@ static int send_utimes(struct send_ctx *btrfs_debug (fs_info,"send_utimes %llu" , ino); - p =fs_path_alloc (); -if (!p) -return -ENOMEM ; + p =get_path_for_command (sctx, ino, gen); +if (IS_ERR (p)) +return PTR_ERR (p); path =alloc_path_for_send ();if (!path) {
@@ -2788,9 +2817,6 @@ static int send_utimes(struct send_ctx *if (ret <0 ) goto out; - ret =get_cur_path (sctx, ino, gen, p); -if (ret <0 ) - goto out;TLV_PUT_PATH (sctx,BTRFS_SEND_A_PATH , p);TLV_PUT_BTRFS_TIMESPEC (sctx,BTRFS_SEND_A_ATIME , eb, &ii->atime);TLV_PUT_BTRFS_TIMESPEC (sctx,BTRFS_SEND_A_MTIME , eb, &ii->mtime);
@@ -2802,7 +2828,7 @@ static int send_utimes(struct send_ctx * tlv_put_failure: out: -fs_path_free (p); +free_path_for_command (sctx, p);btrfs_free_path (path);return ret; }
@@ -4929,13 +4955,9 @@ static int send_set_xattr(struct send_ctstruct fs_path *path;int ret; - path =fs_path_alloc (); -if (!path) -return -ENOMEM ; - - ret =get_cur_path (sctx, sctx->cur_ino, sctx->cur_inode_gen, path); -if (ret <0 ) - goto out; + path =get_cur_inode_path (sctx); +if (IS_ERR (path)) +return PTR_ERR (path); ret =begin_cmd (sctx,BTRFS_SEND_C_SET_XATTR );if (ret <0 )
@@ -4949,8 +4971,6 @@ static int send_set_xattr(struct send_ct tlv_put_failure: out: -fs_path_free (path); -return ret; }
@@ -5008,23 +5028,14 @@ static int __process_deleted_xattr(int n const char *name, int name_len, const char *data, int data_len, void *ctx) { - int ret; struct send_ctx *sctx = ctx;struct fs_path *p; - p =fs_path_alloc (); -if (!p) -return -ENOMEM ; - - ret =get_cur_path (sctx, sctx->cur_ino, sctx->cur_inode_gen, p); -if (ret <0 ) - goto out; - - ret =send_remove_xattr (sctx, p, name, name_len); + p =get_cur_inode_path (sctx); +if (IS_ERR (p)) +return PTR_ERR (p); -out: -fs_path_free (p); -return ret; +return send_remove_xattr (sctx, p, name, name_len); }static int process_new_xattr (struct send_ctx *sctx)
@@ -5257,21 +5268,13 @@ static int process_verity(struct send_ctif (ret <0 ) goto iput; - p =fs_path_alloc (); -if (!p) { - ret = -ENOMEM ; + p =get_cur_inode_path (sctx); +if (IS_ERR (p)) { + ret =PTR_ERR (p); goto iput; } - ret =get_cur_path (sctx, sctx->cur_ino, sctx->cur_inode_gen, p); -if (ret <0 ) - goto free_path; ret =send_verity (sctx, p, sctx->verity_descriptor); -if (ret <0 ) - goto free_path; - -free_path: -fs_path_free (p); iput:iput (inode);return ret;
@@ -5393,31 +5396,25 @@ static int send_write(struct send_ctx *sint ret =0 ;struct fs_path *p; - p =fs_path_alloc (); -if (!p) -return -ENOMEM ; -btrfs_debug (fs_info,"send_write offset=%llu, len=%d" , offset, len); - ret =begin_cmd (sctx,BTRFS_SEND_C_WRITE ); -if (ret <0 ) - goto out; + p =get_cur_inode_path (sctx); +if (IS_ERR (p)) +return PTR_ERR (p); - ret =get_cur_path (sctx, sctx->cur_ino, sctx->cur_inode_gen, p); + ret =begin_cmd (sctx,BTRFS_SEND_C_WRITE );if (ret <0 ) - goto out; +return ret;TLV_PUT_PATH (sctx,BTRFS_SEND_A_PATH , p);TLV_PUT_U64 (sctx,BTRFS_SEND_A_FILE_OFFSET , offset); ret =put_file_data (sctx, offset, len);if (ret <0 ) - goto out; +return ret; ret =send_cmd (sctx); tlv_put_failure: -out: -fs_path_free (p);return ret; }
@@ -5430,6 +5427,7 @@ static int send_clone(struct send_ctx *s {int ret =0 ;struct fs_path *p; +struct fs_path *cur_inode_path;u64 gen; btrfs_debug(sctx->send_root->fs_info,
@@ -5437,6 +5435,10 @@ static int send_clone(struct send_ctx *s offset, len,btrfs_root_id (clone_root->root), clone_root->ino, clone_root->offset); + cur_inode_path =get_cur_inode_path (sctx); +if (IS_ERR (cur_inode_path)) +return PTR_ERR (cur_inode_path); + p =fs_path_alloc ();if (!p)return -ENOMEM ;
@@ -5445,13 +5447,9 @@ static int send_clone(struct send_ctx *sif (ret <0 ) goto out; - ret =get_cur_path (sctx, sctx->cur_ino, sctx->cur_inode_gen, p); -if (ret <0 ) - goto out; -TLV_PUT_U64 (sctx,BTRFS_SEND_A_FILE_OFFSET , offset);TLV_PUT_U64 (sctx,BTRFS_SEND_A_CLONE_LEN , len); -TLV_PUT_PATH (sctx,BTRFS_SEND_A_PATH , p); +TLV_PUT_PATH (sctx,BTRFS_SEND_A_PATH , cur_inode_path);if (clone_root->root == sctx->send_root) { ret =get_inode_gen (sctx->send_root, clone_root->ino, &gen);
@@ -5502,17 +5500,13 @@ static int send_update_extent(struct senint ret =0 ;struct fs_path *p; - p =fs_path_alloc (); -if (!p) -return -ENOMEM ; + p =get_cur_inode_path (sctx); +if (IS_ERR (p)) +return PTR_ERR (p); ret =begin_cmd (sctx,BTRFS_SEND_C_UPDATE_EXTENT );if (ret <0 ) - goto out; - - ret =get_cur_path (sctx, sctx->cur_ino, sctx->cur_inode_gen, p); -if (ret <0 ) - goto out; +return ret;TLV_PUT_PATH (sctx,BTRFS_SEND_A_PATH , p);TLV_PUT_U64 (sctx,BTRFS_SEND_A_FILE_OFFSET , offset);
@@ -5521,8 +5515,6 @@ static int send_update_extent(struct sen ret =send_cmd (sctx); tlv_put_failure: -out: -fs_path_free (p);return ret; }
@@ -5551,12 +5543,10 @@ static int send_hole(struct send_ctx *scif (sctx->flags &BTRFS_SEND_FLAG_NO_FILE_DATA )return send_update_extent (sctx, offset, end - offset); - p =fs_path_alloc (); -if (!p) -return -ENOMEM ; - ret =get_cur_path (sctx, sctx->cur_ino, sctx->cur_inode_gen, p); -if (ret <0 ) - goto tlv_put_failure; + p =get_cur_inode_path (sctx); +if (IS_ERR (p)) +return PTR_ERR (p); +while (offset < end) {u64 len =min (end - offset, read_size);
@@ -5577,7 +5567,6 @@ static int send_hole(struct send_ctx *sc } sctx->cur_inode_next_write_offset = offset; tlv_put_failure: -fs_path_free (p);return ret; }
@@ -5600,9 +5589,9 @@ static int send_encoded_inline_extent(stif (IS_ERR (inode))return PTR_ERR (inode); - fspath =fs_path_alloc (); -if (!fspath) { - ret = -ENOMEM ; + fspath =get_cur_inode_path (sctx); +if (IS_ERR (fspath)) { + ret =PTR_ERR (fspath); goto out; }
@@ -5610,10 +5599,6 @@ static int send_encoded_inline_extent(stif (ret <0 ) goto out; - ret =get_cur_path (sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath); -if (ret <0 ) - goto out; -btrfs_item_key_to_cpu (leaf, &key, path->slots[0 ]); ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); ram_bytes =btrfs_file_extent_ram_bytes (leaf, ei);
@@ -5642,7 +5627,6 @@ static int send_encoded_inline_extent(st tlv_put_failure: out: -fs_path_free (fspath);iput (inode);return ret; }
@@ -5667,9 +5651,9 @@ static int send_encoded_extent(struct seif (IS_ERR (inode))return PTR_ERR (inode); - fspath =fs_path_alloc (); -if (!fspath) { - ret = -ENOMEM ; + fspath =get_cur_inode_path (sctx); +if (IS_ERR (fspath)) { + ret =PTR_ERR (fspath); goto out; }
@@ -5677,10 +5661,6 @@ static int send_encoded_extent(struct seif (ret <0 ) goto out; - ret =get_cur_path (sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath); -if (ret <0 ) - goto out; -btrfs_item_key_to_cpu (leaf, &key, path->slots[0 ]); ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); disk_bytenr =btrfs_file_extent_disk_bytenr (leaf, ei);
@@ -5747,7 +5727,6 @@ static int send_encoded_extent(struct se tlv_put_failure: out: -fs_path_free (fspath);iput (inode);return ret; }
Greg Kroah-Hartman
maintainerPATCH 156/322 btrfs: send: use fallocate for hole punching with send stream v2
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 005b0a0c24e1628313e951516b675109a92cacfe ]
Currently holes are sent as writes full of zeroes, which results in unnecessarily using disk space at the receiving end and increasing the stream size.
In some cases we avoid sending writes of zeroes, like during a full send operation where we just skip writes for holes.
But for some cases we fill previous holes with writes of zeroes too, like in this scenario:
1) We have a file with a hole in the range [2M, 3M), we snapshot the subvolume and do a full send. The range [2M, 3M) stays as a hole at the receiver since we skip sending write commands full of zeroes;
2) We punch a hole for the range [3M, 4M) in our file, so that now it has a 2M hole in the range [2M, 4M), and snapshot the subvolume. Now if we do an incremental send, we will send write commands full of zeroes for the range [2M, 4M), removing the hole for [2M, 3M) at the receiver.
We could improve cases such as this last one by doing additional comparisons of file extent items (or their absence) between the parent and send snapshots, but that's a lot of code to add plus additional CPU and IO costs.
Since the send stream v2 already has a fallocate command and btrfs-progs implements a callback to execute fallocate since the send stream v2 support was added to it, update the kernel to use fallocate for punching holes for V2+ streams.
Test coverage is provided by btrfs/284 which is a version of btrfs/007 that exercises send stream v2 instead of v1, using fsstress with random operations and fssum to verify file contents.
--- fs/btrfs/send.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
fs/btrfs/send.c +33 -0
@@ -4,6 +4,7 @@*/ #include <linux/bsearch.h> +#include <linux/falloc.h> #include <linux/fs.h> #include <linux/file.h> #include <linux/sort.h>
@@ -5518,6 +5519,30 @@ tlv_put_failure:return ret; } +static int send_fallocate (struct send_ctx *sctx,u32 mode,u64 offset,u64 len) +{ +struct fs_path *path; +int ret; + + path =get_cur_inode_path (sctx); +if (IS_ERR (path)) +return PTR_ERR (path); + + ret =begin_cmd (sctx,BTRFS_SEND_C_FALLOCATE ); +if (ret <0 ) +return ret; + +TLV_PUT_PATH (sctx,BTRFS_SEND_A_PATH , path); +TLV_PUT_U32 (sctx,BTRFS_SEND_A_FALLOCATE_MODE , mode); +TLV_PUT_U64 (sctx,BTRFS_SEND_A_FILE_OFFSET , offset); +TLV_PUT_U64 (sctx,BTRFS_SEND_A_SIZE , len); + + ret =send_cmd (sctx); + +tlv_put_failure: +return ret; +} +static int send_hole (struct send_ctx *sctx,u64 end) {struct fs_path *p =NULL ;
@@ -5526,6 +5551,14 @@ static int send_hole(struct send_ctx *scint ret =0 ;/* +* Starting with send stream v2 we have fallocate and can use it to +* punch holes instead of sending writes full of zeroes. +*/ +if (proto_cmd_ok (sctx,BTRFS_SEND_C_FALLOCATE )) +return send_fallocate (sctx,FALLOC_FL_PUNCH_HOLE |FALLOC_FL_KEEP_SIZE , + offset, end - offset); + +/* * A hole that starts at EOF or beyond it. Since we do not yet support * fallocate (for extent preallocation and hole punching), sending a * write of zeroes starting at EOF or beyond would later require issuing
Greg Kroah-Hartman
maintainerPATCH 157/322 btrfs: send: make fs_path_len() inline and constify its argument
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 920e8ee2bfcaf886fd8c0ad9df097a7dddfeb2d8 ]
The helper function fs_path_len() is trivial and doesn't need to change its path argument, so make it inline and constify the argument.
--- fs/btrfs/send.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/send.c +1 -1
@@ -478,7 +478,7 @@ static void fs_path_free(struct fs_pathkfree (p); } -static int fs_path_len (struct fs_path *p) +static inline int fs_path_len (const struct fs_path *p) {return p->end - p->start; }
Greg Kroah-Hartman
maintainerPATCH 158/322 netfs: Fix unbuffered write error handling
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit a3de58b12ce074ec05b8741fa28d62ccb1070468 ]
If all the subrequests in an unbuffered write stream fail, the subrequest collector doesn't update the stream->transferred value and it retains its initial LONG_MAX value. Unfortunately, if all active streams fail, then we take the smallest value of { LONG_MAX, LONG_MAX, ... } as the value to set in wreq->transferred - which is then returned from ->write_iter().
LONG_MAX was chosen as the initial value so that all the streams can be quickly assessed by taking the smallest value of all stream->transferred - but this only works if we've set any of them.
Fix this by adding a flag to indicate whether the value in stream->transferred is valid and checking that when we integrate the values. stream->transferred can then be initialised to zero.
This was found by running the generic/750 xfstest against cifs with cache=none. It splices data to the target file. Once (if) it has used up all the available scratch space, the writes start failing with ENOSPC. This causes ->write_iter() to fail. However, it was returning wreq->transferred, i.e. LONG_MAX, rather than an error (because it thought the amount transferred was non-zero) and iter_file_splice_write() would then try to clean up that amount of pipe bufferage - leading to an oops when it overran. The kernel log showed:
CIFS: VFS: Send error in write = -28
followed by:
BUG: kernel NULL pointer dereference, address: 0000000000000008
with:
RIP: 0010:iter_file_splice_write+0x3a4/0x520
do_splice+0x197/0x4e0or:
RIP: 0010:pipe_buf_release (include/linux/pipe_fs_i.h:282)
iter_file_splice_write (fs/splice.c:755)Also put a warning check into splice to announce if ->write_iter() returned that it had written more than it was asked to.
--- fs/netfs/write_collect.c | 10 ++++++++-- fs/netfs/write_issue.c | 4 ++-- fs/splice.c | 3 +++ include/linux/netfs.h | 1 + 4 files changed, 14 insertions(+), 4 deletions(-)
fs/netfs/write_collect.c +8 -2
@@ -433,6 +433,7 @@ reassess_streams:if (front->start + front->transferred > stream->collected_to) { stream->collected_to = front->start + front->transferred; stream->transferred = stream->collected_to - wreq->start; + stream->transferred_valid = true; notes |=MADE_PROGRESS ; }if (test_bit (NETFS_SREQ_FAILED , &front->flags)) {
@@ -538,6 +539,7 @@ void netfs_write_collection_worker(struc struct netfs_io_request *wreq = container_of(work, struct netfs_io_request, work);struct netfs_inode *ictx =netfs_inode (wreq->inode);size_t transferred; +bool transferred_valid = false;int s;_enter ("R=%x" , wreq->debug_id);
@@ -568,12 +570,16 @@ void netfs_write_collection_worker(strucnetfs_put_request (wreq, false, netfs_rreq_trace_put_work);return ; } -if (stream->transferred < transferred) +if (stream->transferred_valid && + stream->transferred < transferred) { transferred = stream->transferred; + transferred_valid = true; + } }/* Okay, declare that all I/O is complete. */ - wreq->transferred = transferred; +if (transferred_valid) + wreq->transferred = transferred;trace_netfs_rreq (wreq, netfs_rreq_trace_write_done); if (wreq->io_streams[1].active &&
fs/netfs/write_issue.c +2 -2
@@ -115,12 +115,12 @@ struct netfs_io_request *netfs_create_wr wreq->io_streams[0 ].prepare_write = ictx->ops->prepare_write; wreq->io_streams[0 ].issue_write = ictx->ops->issue_write; wreq->io_streams[0 ].collected_to = start; - wreq->io_streams[0 ].transferred =LONG_MAX ; + wreq->io_streams[0 ].transferred =0 ; wreq->io_streams[1 ].stream_nr =1 ; wreq->io_streams[1 ].source =NETFS_WRITE_TO_CACHE ; wreq->io_streams[1 ].collected_to = start; - wreq->io_streams[1 ].transferred =LONG_MAX ; + wreq->io_streams[1 ].transferred =0 ;if (fscache_resources_valid (&wreq->cache_resources)) { wreq->io_streams[1 ].avail = true; wreq->io_streams[1 ].active = true;
fs/splice.c +3 -0
@@ -744,6 +744,9 @@ iter_file_splice_write(struct pipe_inode sd.pos = kiocb.ki_pos;if (ret <=0 )break ; +WARN_ONCE (ret > sd.total_len - left, +"Splice Exceeded! ret=%zd tot=%zu left=%zu\n" , + ret, sd.total_len, left); sd.num_spliced += ret; sd.total_len -= ret;
include/linux/netfs.h +1 -0
@@ -150,6 +150,7 @@ struct netfs_io_stream {bool active;/* T if stream is active */ bool need_retry;/* T if this stream needs retrying */ bool failed;/* T if this stream failed */ +bool transferred_valid;/* T is ->transferred is valid */ };/*
Greg Kroah-Hartman
maintainerPATCH 159/322 io_uring/net: commit partial buffers on retry
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
commit 41b70df5b38bc80967d2e0ed55cc3c3896bba781 upstream.
Ring provided buffers are potentially only valid within the single execution context in which they were acquired. io_uring deals with this and invalidates them on retry. But on the networking side, if MSG_WAITALL is set, or if the socket is of the streaming type and too little was processed, then it will hang on to the buffer rather than recycle or commit it. This is problematic for two reasons:
1) If someone unregisters the provided buffer ring before a later retry, then the req->buf_list will no longer be valid.
2) If multiple sockers are using the same buffer group, then multiple receives can consume the same memory. This can cause data corruption in the application, as either receive could land in the same userspace buffer.
Fix this by disallowing partial retries from pinning a provided buffer across multiple executions, if ring provided buffers are used.
--- io_uring/net.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
io_uring/net.c +15 -12
@@ -498,6 +498,15 @@ static int io_bundle_nbufs(struct io_asyreturn nbufs; } +static int io_net_kbuf_recyle (struct io_kiocb *req, +struct io_async_msghdr *kmsg,int len) +{ + req->flags |=REQ_F_BL_NO_RECYCLE ; +if (req->flags &REQ_F_BUFFERS_COMMIT ) +io_kbuf_commit (req, req->buf_list, len,io_bundle_nbufs (kmsg, len)); +return -EAGAIN ; +} +static inline bool io_send_finish (struct io_kiocb *req,int *ret,struct io_async_msghdr *kmsg,unsigned issue_flags)
@@ -566,8 +575,7 @@ int io_sendmsg(struct io_kiocb *req, uns kmsg->msg.msg_controllen =0 ; kmsg->msg.msg_control =NULL ; sr->done_io += ret; - req->flags |=REQ_F_BL_NO_RECYCLE ; -return -EAGAIN ; +return io_net_kbuf_recyle (req, kmsg, ret); }if (ret == -ERESTARTSYS ) ret = -EINTR ;
@@ -664,8 +672,7 @@ retry_bundle: sr->len -= ret; sr->buf += ret; sr->done_io += ret; - req->flags |=REQ_F_BL_NO_RECYCLE ; -return -EAGAIN ; +return io_net_kbuf_recyle (req, kmsg, ret); }if (ret == -ERESTARTSYS ) ret = -EINTR ;
@@ -1068,8 +1075,7 @@ retry_multishot: }if (ret >0 &&io_net_retry (sock, flags)) { sr->done_io += ret; - req->flags |=REQ_F_BL_NO_RECYCLE ; -return -EAGAIN ; +return io_net_kbuf_recyle (req, kmsg, ret); }if (ret == -ERESTARTSYS ) ret = -EINTR ;
@@ -1211,8 +1217,7 @@ retry_multishot: sr->len -= ret; sr->buf += ret; sr->done_io += ret; - req->flags |=REQ_F_BL_NO_RECYCLE ; -return -EAGAIN ; +return io_net_kbuf_recyle (req, kmsg, ret); }if (ret == -ERESTARTSYS ) ret = -EINTR ;
@@ -1441,8 +1446,7 @@ int io_send_zc(struct io_kiocb *req, uns zc->len -= ret; zc->buf += ret; zc->done_io += ret; - req->flags |=REQ_F_BL_NO_RECYCLE ; -return -EAGAIN ; +return io_net_kbuf_recyle (req, kmsg, ret); }if (ret == -ERESTARTSYS ) ret = -EINTR ;
@@ -1502,8 +1506,7 @@ int io_sendmsg_zc(struct io_kiocb *req,if (ret >0 &&io_net_retry (sock, flags)) { sr->done_io += ret; - req->flags |=REQ_F_BL_NO_RECYCLE ; -return -EAGAIN ; +return io_net_kbuf_recyle (req, kmsg, ret); }if (ret == -ERESTARTSYS ) ret = -EINTR ;
Greg Kroah-Hartman
maintainerPATCH 160/322 ata: libata-scsi: Return aborted command when missing sense and result TF
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
commit d2be9ea9a75550a35c5127a6c2633658bc38c76b upstream.
ata_gen_ata_sense() is always called for a failed qc missing sense data so that a sense key, code and code qualifier can be generated using ata_to_sense_error() from the qc status and error fields of its result task file. However, if the qc does not have its result task file filled, ata_gen_ata_sense() returns early without setting a sense key.
Improve this by defaulting to returning ABORTED COMMAND without any additional sense code, since we do not know the reason for the failure. The same fix is also applied in ata_gen_passthru_sense() with the additional check that the qc failed (qc->err_mask is set).
--- drivers/ata/libata-scsi.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
drivers/ata/libata-scsi.c +15 -12
@@ -934,6 +934,8 @@ static void ata_gen_passthru_sense(strucif (!(qc->flags &ATA_QCFLAG_RTF_FILLED )) {ata_dev_dbg (dev,"missing result TF: can't generate ATA PT sense data\n" ); +if (qc->err_mask) +ata_scsi_set_sense (dev, cmd,ABORTED_COMMAND ,0 ,0 );return ; }
@@ -991,8 +993,8 @@ static void ata_gen_ata_sense(struct ataif (!(qc->flags &ATA_QCFLAG_RTF_FILLED )) {ata_dev_dbg (dev, -"missing result TF: can't generate sense data\n" ); -return ; +"Missing result TF: reporting aborted command\n" ); + goto aborted; }/* Use ata_to_sense_error() to map status register bits
@@ -1003,19 +1005,20 @@ static void ata_gen_ata_sense(struct ataata_to_sense_error (tf->status, tf->error, &sense_key, &asc, &ascq);ata_scsi_set_sense (dev, cmd, sense_key, asc, ascq); - }else { -/* Could not decode error */ -ata_dev_warn (dev,"could not decode error status 0x%x err_mask 0x%x\n" , - tf->status, qc->err_mask); -ata_scsi_set_sense (dev, cmd,ABORTED_COMMAND ,0 ,0 ); -return ; - } - block =ata_tf_read_block (&qc->result_tf, dev); -if (block ==U64_MAX ) + block =ata_tf_read_block (&qc->result_tf, dev); +if (block !=U64_MAX ) +scsi_set_sense_information (sb,SCSI_SENSE_BUFFERSIZE , + block);return ; + } -scsi_set_sense_information (sb,SCSI_SENSE_BUFFERSIZE , block); +/* Could not decode error */ +ata_dev_warn (dev, +"Could not decode error 0x%x, status 0x%x (err_mask=0x%x)\n" , + tf->error, tf->status, qc->err_mask); +aborted: +ata_scsi_set_sense (dev, cmd,ABORTED_COMMAND ,0 ,0 ); }void ata_scsi_sdev_config (struct scsi_device *sdev)
Greg Kroah-Hartman
maintainerPATCH 161/322 sched_ext: initialize built-in idle state before ops.init()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrea Righi <[email protected]>
commit f0c6eab5e45c529f449fbc595873719e00de6d79 upstream.
A BPF scheduler may want to use the built-in idle cpumasks in ops.init() before the scheduler is fully initialized, either directly or through a BPF timer for example.
However, this would result in an error, since the idle state has not been properly initialized yet.
This can be easily verified by modifying scx_simple to call scx_bpf_get_idle_cpumask() in ops.init():
$ sudo scx_simple
DEBUG DUMP
===========================================================================
scx_simple[121] triggered exit kind 1024:
runtime error (built-in idle tracking is disabled)
...
Fix this by properly initializing the idle state before ops.init() is called. With this change applied:
$ sudo scx_simple local=2 global=0 local=19 global=11 local=23 global=11 ...
[ Backport to 6.12:
- Original commit doesn't apply cleanly to 6.12 since d73249f88743d is not present.
- This backport applies the same logical fix to prevent BPF scheduler failures while accessing idle cpumasks from ops.init(). ]
--- kernel/sched/ext.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
kernel/sched/ext.c +7 -7
@@ -5220,6 +5220,13 @@ static int scx_ops_enable(struct sched_efor_each_possible_cpu (cpu)cpu_rq (cpu)->scx.cpuperf_target =SCX_CPUPERF_ONE ; +if (!ops->update_idle || (ops->flags &SCX_OPS_KEEP_BUILTIN_IDLE )) { +reset_idle_masks (); +static_branch_enable (&scx_builtin_idle_enabled); + }else { +static_branch_disable (&scx_builtin_idle_enabled); + } +/* * Keep CPUs stable during enable so that the BPF scheduler can track * online CPUs by watching ->on/offline_cpu() after ->init().
@@ -5287,13 +5294,6 @@ static int scx_ops_enable(struct sched_eif (scx_ops.cpu_acquire || scx_ops.cpu_release)static_branch_enable (&scx_ops_cpu_preempt); -if (!ops->update_idle || (ops->flags &SCX_OPS_KEEP_BUILTIN_IDLE )) { -reset_idle_masks (); -static_branch_enable (&scx_builtin_idle_enabled); - }else { -static_branch_disable (&scx_builtin_idle_enabled); - } -/* * Lock out forks, cgroup on/offlining and moves before opening the * floodgate so that they don't wander into the operations prematurely.
Greg Kroah-Hartman
maintainerPATCH 162/322 Revert "can: ti_hecc: fix -Woverflow compiler warning"
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman <[email protected]>
This reverts commit 1da38b70d90f8529c060dd380d0c18e6d9595463 which is commit 7cae4d04717b002cffe41169da3f239c845a0723 upstream.
--- drivers/net/can/ti_hecc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/ti_hecc.c +1 -1
@@ -383,7 +383,7 @@ static void ti_hecc_start(struct net_dev* overflows instead of the hardware silently dropping the * messages. */ - mbx_mask = ~BIT_U32 (HECC_RX_LAST_MBOX ); + mbx_mask = ~BIT (HECC_RX_LAST_MBOX );hecc_write (priv,HECC_CANOPC , mbx_mask);/* Enable interrupts */
Greg Kroah-Hartman
maintainerPATCH 163/322 io_uring/futex: ensure io_futex_wait() cleans up properly on failure
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
commit 508c1314b342b78591f51c4b5dadee31a88335df upstream.
The io_futex_data is allocated upfront and assigned to the io_kiocb async_data field, but the request isn't marked with REQ_F_ASYNC_DATA at that point. Those two should always go together, as the flag tells io_uring whether the field is valid or not.
Additionally, on failure cleanup, the futex handler frees the data but does not clear ->async_data. Clear the data and the flag in the error path as well.
Thanks to Trend Micro Zero Day Initiative and particularly ReDress for reporting this.
--- io_uring/futex.c | 3 +++ 1 file changed, 3 insertions(+)
io_uring/futex.c +3 -0
@@ -337,6 +337,7 @@ int io_futex_wait(struct io_kiocb *req, goto done_unlock; } + req->flags |=REQ_F_ASYNC_DATA ; req->async_data = ifd; ifd->q = futex_q_init; ifd->q.bitset = iof->futex_mask;
@@ -359,6 +360,8 @@ done:if (ret <0 )req_set_fail (req);io_req_set_res (req, ret,0 ); + req->async_data =NULL ; + req->flags &= ~REQ_F_ASYNC_DATA ;kfree (ifd);return IOU_OK ; }
Greg Kroah-Hartman
maintainerPATCH 164/322 iov_iter: iterate_folioq: fix handling of offset >= folio size
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dominique Martinet <[email protected]>
commit 808471ddb0fa785559c3e7aee59be20a13b46ef5 upstream.
It's apparently possible to get an iov advanced all the way up to the end of the current page we're looking at, e.g.
(gdb) p *iter
$24 = {iter_type = 4 '\004', nofault = false, data_source = false, iov_offset = 4096, {__ubuf_iovec = {
iov_base = 0xffff88800f5bc000, iov_len = 655}, {{__iov = 0xffff88800f5bc000, kvec = 0xffff88800f5bc000,
bvec = 0xffff88800f5bc000, folioq = 0xffff88800f5bc000, xarray = 0xffff88800f5bc000,
ubuf = 0xffff88800f5bc000}, count = 655}}, {nr_segs = 2, folioq_slot = 2 '\002', xarray_start = 2}}Where iov_offset is 4k with 4k-sized folios
This should have been fine because we're only in the 2nd slot and there's another one after this, but iterate_folioq should not try to map a folio that skips the whole size, and more importantly part here does not end up zero (because 'PAGE_SIZE - skip % PAGE_SIZE' ends up PAGE_SIZE and not zero..), so skip forward to the "advance to next folio" code
--- include/linux/iov_iter.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
include/linux/iov_iter.h +11 -9
@@ -160,7 +160,7 @@ size_t iterate_folioq(struct iov_iter *iter, size_t len, void *priv, void *priv2 do { struct folio *folio = folioq_folio(folioq, slot); - size_t part, remain, consumed; + size_t part, remain = 0, consumed; size_t fsize; void *base;
@@ -168,14 +168,16 @@ size_t iterate_folioq(struct iov_iter *iter, size_t len, void *priv, void *priv2break ; fsize =folioq_folio_size (folioq, slot); - base =kmap_local_folio (folio, skip); - part =umin (len,PAGE_SIZE - skip %PAGE_SIZE ); - remain =step (base, progress, part, priv, priv2); -kunmap_local (base); - consumed = part - remain; - len -= consumed; - progress += consumed; - skip += consumed; +if (skip < fsize) { + base =kmap_local_folio (folio, skip); + part =umin (len,PAGE_SIZE - skip %PAGE_SIZE ); + remain =step (base, progress, part, priv, priv2); +kunmap_local (base); + consumed = part - remain; + len -= consumed; + progress += consumed; + skip += consumed; + }if (skip >= fsize) { skip =0 ; slot++;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 165/322 iommu/arm-smmu-v3: Fix smmu_domain->nr_ats_masters decrement
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolin Chen <[email protected]>
commit 685ca577b408ffd9c5a4057a2acc0cd3e6978b36 upstream.
The arm_smmu_attach_commit() updates master->ats_enabled before calling arm_smmu_remove_master_domain() that is supposed to clean up everything in the old domain, including the old domain's nr_ats_masters. So, it is supposed to use the old ats_enabled state of the device, not an updated state.
This isn't a problem if switching between two domains where:
- old ats_enabled = false; new ats_enabled = false
- old ats_enabled = true; new ats_enabled = true
but can fail cases where:
- old ats_enabled = false; new ats_enabled = true
(old domain should keep the counter but incorrectly decreased it)
- old ats_enabled = true; new ats_enabled = false
(old domain needed to decrease the counter but incorrectly missed it)
Update master->ats_enabled after arm_smmu_remove_master_domain() to fix this.
--- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +1 -1
@@ -2778,9 +2778,9 @@ static void arm_smmu_attach_commit(struc/* ATS is being switched off, invalidate the entire ATC */ arm_smmu_atc_inv_master (master,IOMMU_NO_PASID ); } - master->ats_enabled = state->ats_enabled;arm_smmu_remove_master_domain (master, state->old_domain, state->ssid); + master->ats_enabled = state->ats_enabled; }static int arm_smmu_attach_dev (struct iommu_domain *domain,struct device *dev)
Greg Kroah-Hartman
maintainerPATCH 166/322 mmc: sdhci-pci-gli: Add a new function to simplify the code
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Shih <[email protected]>
commit dec8b38be4b35cae5f7fa086daf2631e2cfa09c1 upstream.
In preparation to fix replay timer timeout, add sdhci_gli_mask_replay_timer_timeout() function to simplify some of the code, allowing it to be re-used.
--- drivers/mmc/host/sdhci-pci-gli.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)
drivers/mmc/host/sdhci-pci-gli.c +16 -14
@@ -215,6 +215,20 @@#define GLI_MAX_TUNING_LOOP 40/* Genesys Logic chipset */ +static void sdhci_gli_mask_replay_timer_timeout (struct pci_dev *pdev) +{ +int aer; +u32 value; + +/* mask the replay timer timeout of AER */ + aer =pci_find_ext_capability (pdev,PCI_EXT_CAP_ID_ERR ); +if (aer) { +pci_read_config_dword (pdev, aer +PCI_ERR_COR_MASK , &value); + value |=PCI_ERR_COR_REP_TIMER ; +pci_write_config_dword (pdev, aer +PCI_ERR_COR_MASK , value); + } +} +static inline void gl9750_wt_on (struct sdhci_host *host) {u32 wt_value;
@@ -535,7 +549,6 @@ static void gl9750_hw_setting(struct sdh {struct sdhci_pci_slot *slot =sdhci_priv (host);struct pci_dev *pdev; -int aer;u32 value; pdev = slot->chip->pdev;
@@ -554,12 +567,7 @@ static void gl9750_hw_setting(struct sdhpci_set_power_state (pdev,PCI_D0 );/* mask the replay timer timeout of AER */ - aer =pci_find_ext_capability (pdev,PCI_EXT_CAP_ID_ERR ); -if (aer) { -pci_read_config_dword (pdev, aer +PCI_ERR_COR_MASK , &value); - value |=PCI_ERR_COR_REP_TIMER ; -pci_write_config_dword (pdev, aer +PCI_ERR_COR_MASK , value); - } +sdhci_gli_mask_replay_timer_timeout (pdev);gl9750_wt_off (host); }
@@ -734,7 +742,6 @@ static void sdhci_gl9755_set_clock(strucstatic void gl9755_hw_setting (struct sdhci_pci_slot *slot) {struct pci_dev *pdev = slot->chip->pdev; -int aer;u32 value;gl9755_wt_on (pdev);
@@ -769,12 +776,7 @@ static void gl9755_hw_setting(struct sdhpci_set_power_state (pdev,PCI_D0 );/* mask the replay timer timeout of AER */ - aer =pci_find_ext_capability (pdev,PCI_EXT_CAP_ID_ERR ); -if (aer) { -pci_read_config_dword (pdev, aer +PCI_ERR_COR_MASK , &value); - value |=PCI_ERR_COR_REP_TIMER ; -pci_write_config_dword (pdev, aer +PCI_ERR_COR_MASK , value); - } +sdhci_gli_mask_replay_timer_timeout (pdev);gl9755_wt_off (pdev); }
Greg Kroah-Hartman
maintainerPATCH 167/322 memstick: Fix deadlock by moving removing flag earlier
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayi Li <[email protected]>
commit 99d7ab8db9d8230b243f5ed20ba0229e54cc0dfa upstream.
The existing memstick core patch: commit 62c59a8786e6 ("memstick: Skip allocating card when removing host") sets host->removing in memstick_remove_host(),but still exists a critical time window where memstick_check can run after host->eject is set but before removing is set.
In the rtsx_usb_ms driver, the problematic sequence is:
rtsx_usb_ms_drv_remove: memstick_check:
host->eject = true
cancel_work_sync(handle_req) if(!host->removing)
... memstick_alloc_card()
memstick_set_rw_addr()
memstick_new_req()
rtsx_usb_ms_request()
if(!host->eject)
skip schedule_work
wait_for_completion()
memstick_remove_host: [blocks indefinitely]
host->removing = true
flush_workqueue()
[block]1. rtsx_usb_ms_drv_remove sets host->eject = true
2. cancel_work_sync(&host->handle_req) runs
3. memstick_check work may be executed here <-- danger window
4. memstick_remove_host sets removing = 1
During this window (step 3), memstick_check calls memstick_alloc_card, which may indefinitely waiting for mrq_complete completion that will never occur because rtsx_usb_ms_request sees eject=true and skips scheduling work, memstick_set_rw_addr waits forever for completion.
This causes a deadlock when memstick_remove_host tries to flush_workqueue, waiting for memstick_check to complete, while memstick_check is blocked waiting for mrq_complete completion.
Fix this by setting removing=true at the start of rtsx_usb_ms_drv_remove, before any work cancellation. This ensures memstick_check will see the removing flag immediately and exit early, avoiding the deadlock.
--- drivers/memstick/core/memstick.c | 1 - drivers/memstick/host/rtsx_usb_ms.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-)
drivers/memstick/core/memstick.c +0 -1
@@ -547,7 +547,6 @@ EXPORT_SYMBOL(memstick_add_host);*/ void memstick_remove_host (struct memstick_host *host) { - host->removing =1 ;flush_workqueue (workqueue);mutex_lock (&host->lock);if (host->card)
drivers/memstick/host/rtsx_usb_ms.c +1 -0
@@ -812,6 +812,7 @@ static void rtsx_usb_ms_drv_remove(strucint err; host->eject = true; + msh->removing = true;cancel_work_sync (&host->handle_req);cancel_delayed_work_sync (&host->poll_card);
Greg Kroah-Hartman
maintainerPATCH 168/322 mmc: sdhci-pci-gli: GL9763e: Mask the replay timer timeout of AER
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Shih <[email protected]>
commit 340be332e420ed37d15d4169a1b4174e912ad6cb upstream.
Due to a flaw in the hardware design, the GL9763e replay timer frequently times out when ASPM is enabled. As a result, the warning messages will often appear in the system log when the system accesses the GL9763e PCI config. Therefore, the replay timer timeout must be masked.
--- drivers/mmc/host/sdhci-pci-gli.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/mmc/host/sdhci-pci-gli.c +3 -0
@@ -1364,6 +1364,9 @@ static void gli_set_gl9763e(struct sdhci value |=FIELD_PREP (GLI_9763E_HS400_RXDLY ,GLI_9763E_HS400_RXDLY_5 );pci_write_config_dword (pdev,PCIE_GLI_9763E_CLKRXDLY , value); +/* mask the replay timer timeout of AER */ +sdhci_gli_mask_replay_timer_timeout (pdev); +pci_read_config_dword (pdev,PCIE_GLI_9763E_VHS , &value); value &= ~GLI_9763E_VHS_REV ; value |=FIELD_PREP (GLI_9763E_VHS_REV ,GLI_9763E_VHS_REV_R );
Greg Kroah-Hartman
maintainerPATCH 169/322 mmc: sdhci-pci-gli: GL9763e: Rename the gli_set_gl9763e() for consistency
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Shih <[email protected]>
commit 293ed0f5f34e1e9df888456af4b0a021f57b5f54 upstream.
In preparation to fix replay timer timeout, rename the gli_set_gl9763e() to gl9763e_hw_setting() for consistency.
--- drivers/mmc/host/sdhci-pci-gli.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mmc/host/sdhci-pci-gli.c +2 -2
@@ -1335,7 +1335,7 @@ cleanup:return ret; } -static void gli_set_gl9763e (struct sdhci_pci_slot *slot) +static void gl9763e_hw_setting (struct sdhci_pci_slot *slot) {struct pci_dev *pdev = slot->chip->pdev;u32 value;
@@ -1510,7 +1510,7 @@ static int gli_probe_slot_gl9763e(structgli_pcie_enable_msi (slot); host->mmc_host_ops.hs400_enhanced_strobe = gl9763e_hs400_enhanced_strobe; -gli_set_gl9763e (slot); +gl9763e_hw_setting (slot);sdhci_enable_v4_mode (host);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 170/322 NFS: Fix a race when updating an existing write
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit 76d2e3890fb169168c73f2e4f8375c7cc24a765e upstream.
After nfs_lock_and_join_requests() tests for whether the request is still attached to the mapping, nothing prevents a call to nfs_inode_remove_request() from succeeding until we actually lock the page group.
The reason is that whoever called nfs_inode_remove_request() doesn't necessarily have a lock on the page group head.
So in order to avoid races, let's take the page group lock earlier in nfs_lock_and_join_requests(), and hold it across the removal of the request in nfs_inode_remove_request().
--- fs/nfs/pagelist.c | 9 +++++---- fs/nfs/write.c | 29 ++++++++++------------------- include/linux/nfs_page.h | 1 + 3 files changed, 16 insertions(+), 23 deletions(-)
fs/nfs/pagelist.c +5 -4
@@ -253,13 +253,14 @@ nfs_page_group_unlock(struct nfs_page *rnfs_page_clear_headlock (req); } -/* -* nfs_page_group_sync_on_bit_locked +/** +* nfs_page_group_sync_on_bit_locked - Test if all requests have @bit set +* @req: request in page group +* @bit: PG_* bit that is used to sync page group * * must be called with page group lock held */ -static bool -nfs_page_group_sync_on_bit_locked (struct nfs_page *req,unsigned int bit) +bool nfs_page_group_sync_on_bit_locked (struct nfs_page *req,unsigned int bit) {struct nfs_page *head = req->wb_head;struct nfs_page *tmp;
fs/nfs/write.c +10 -19
@@ -153,20 +153,10 @@ nfs_page_set_inode_ref(struct nfs_page * } } -static int -nfs_cancel_remove_inode (struct nfs_page *req,struct inode *inode) +static void nfs_cancel_remove_inode (struct nfs_page *req,struct inode *inode) { -int ret; - -if (!test_bit (PG_REMOVE , &req->wb_flags)) -return 0 ; - ret =nfs_page_group_lock (req); -if (ret) -return ret;if (test_and_clear_bit (PG_REMOVE , &req->wb_flags))nfs_page_set_inode_ref (req, inode); -nfs_page_group_unlock (req); -return 0 ; }/**
@@ -585,19 +575,18 @@ retry: } } + ret =nfs_page_group_lock (head); +if (ret <0 ) + goto out_unlock; +/* Ensure that nobody removed the request before we locked it */ if (head != folio->private) { +nfs_page_group_unlock (head);nfs_unlock_and_release_request (head); goto retry; } - ret =nfs_cancel_remove_inode (head, inode); -if (ret <0 ) - goto out_unlock; - - ret =nfs_page_group_lock (head); -if (ret <0 ) - goto out_unlock; +nfs_cancel_remove_inode (head, inode);/* lock each request in the page group */ for (subreq = head->wb_this_page;
@@ -801,7 +790,8 @@ static void nfs_inode_remove_request(str {struct nfs_inode *nfsi =NFS_I (nfs_page_to_inode (req)); -if (nfs_page_group_sync_on_bit (req,PG_REMOVE )) { +nfs_page_group_lock (req); +if (nfs_page_group_sync_on_bit_locked (req,PG_REMOVE )) {struct folio *folio =nfs_page_to_folio (req->wb_head);struct address_space *mapping = folio->mapping;
@@ -812,6 +802,7 @@ static void nfs_inode_remove_request(str }spin_unlock (&mapping->i_private_lock); } +nfs_page_group_unlock (req);if (test_and_clear_bit (PG_INODE_REF , &req->wb_flags)) {atomic_long_dec (&nfsi->nrequests);
include/linux/nfs_page.h +1 -0
@@ -160,6 +160,7 @@ extern void nfs_join_page_group(struct nextern int nfs_page_group_lock (struct nfs_page *);extern void nfs_page_group_unlock (struct nfs_page *);extern bool nfs_page_group_sync_on_bit (struct nfs_page *,unsigned int ); +extern bool nfs_page_group_sync_on_bit_locked (struct nfs_page *,unsigned int );extern int nfs_page_set_headlock (struct nfs_page *req);extern void nfs_page_clear_headlock (struct nfs_page *req);extern bool nfs_async_iocounter_wait (struct rpc_task *,struct nfs_lock_context *);
Greg Kroah-Hartman
maintainerPATCH 171/322 squashfs: fix memory leak in squashfs_fill_super
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phillip Lougher <[email protected]>
commit b64700d41bdc4e9f82f1346c15a3678ebb91a89c upstream.
If sb_min_blocksize returns 0, squashfs_fill_super exits without freeing allocated memory (sb->s_fs_info).
Fix this by moving the call to sb_min_blocksize to before memory is allocated.
--- fs/squashfs/super.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
fs/squashfs/super.c +7 -7
@@ -187,10 +187,15 @@ static int squashfs_fill_super(struct suunsigned short flags;unsigned int fragments;u64 lookup_table_start, xattr_id_table_start, next_table; -int err; +int err, devblksize =sb_min_blocksize (sb,SQUASHFS_DEVBLK_SIZE );TRACE ("Entered squashfs_fill_superblock\n" ); +if (!devblksize) { +errorf (fc,"squashfs: unable to set blocksize\n" ); +return -EINVAL ; + } + sb->s_fs_info =kzalloc (sizeof (*msblk),GFP_KERNEL );if (sb->s_fs_info ==NULL ) {ERROR ("Failed to allocate squashfs_sb_info\n" );
@@ -201,12 +206,7 @@ static int squashfs_fill_super(struct su msblk->panic_on_errors = (opts->errors == Opt_errors_panic); - msblk->devblksize =sb_min_blocksize (sb,SQUASHFS_DEVBLK_SIZE ); -if (!msblk->devblksize) { -errorf (fc,"squashfs: unable to set blocksize\n" ); -return -EINVAL ; - } - + msblk->devblksize = devblksize; msblk->devblksize_log2 =ffz (~msblk->devblksize);mutex_init (&msblk->meta_index_mutex);
Greg Kroah-Hartman
maintainerPATCH 172/322 mm/debug_vm_pgtable: clear page table entries at destroy_args()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herton R. Krzesinski <[email protected]>
commit dde30854bddfb5d69f30022b53c5955a41088b33 upstream.
The mm/debug_vm_pagetable test allocates manually page table entries for the tests it runs, using also its manually allocated mm_struct. That in itself is ok, but when it exits, at destroy_args() it fails to clear those entries with the *_clear functions.
The problem is that leaves stale entries. If another process allocates an mm_struct with a pgd at the same address, it may end up running into the stale entry. This is happening in practice on a debug kernel with CONFIG_DEBUG_VM_PGTABLE=y, for example this is the output with some extra debugging I added (it prints a warning trace if pgtables_bytes goes negative, in addition to the warning at check_mm() function):
[ 2.539353] debug_vm_pgtable: [get_random_vaddr ]: random_vaddr is 0x7ea247140000 [ 2.539366] kmem_cache info [ 2.539374] kmem_cachep 0x000000002ce82385 - freelist 0x0000000000000000 - offset 0x508 [ 2.539447] debug_vm_pgtable: [init_args ]: args->mm is 0x000000002267cc9e (...) [ 2.552800] WARNING: CPU: 5 PID: 116 at include/linux/mm.h:2841 free_pud_range+0x8bc/0x8d0 [ 2.552816] Modules linked in: [ 2.552843] CPU: 5 UID: 0 PID: 116 Comm: modprobe Not tainted 6.12.0-105.debug_vm2.el10.ppc64le+debug #1 VOLUNTARY [ 2.552859] Hardware name: IBM,9009-41A POWER9 (architected) 0x4e0202 0xf000005 of:IBM,FW910.00 (VL910_062) hv:phyp pSeries [ 2.552872] NIP: c0000000007eef3c LR: c0000000007eef30 CTR: c0000000003d8c90 [ 2.552885] REGS: c0000000622e73b0 TRAP: 0700 Not tainted (6.12.0-105.debug_vm2.el10.ppc64le+debug) [ 2.552899] MSR: 800000000282b033 <SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE> CR: 24002822 XER: 0000000a [ 2.552954] CFAR: c0000000008f03f0 IRQMASK: 0 [ 2.552954] GPR00: c0000000007eef30 c0000000622e7650 c000000002b1ac00 0000000000000001 [ 2.552954] GPR04: 0000000000000008 0000000000000000 c0000000007eef30 ffffffffffffffff [ 2.552954] GPR08: 00000000ffff00f5 0000000000000001 0000000000000048 0000000000004000 [ 2.552954] GPR12: 00000003fa440000 c000000017ffa300 c0000000051d9f80 ffffffffffffffdb [ 2.552954] GPR16: 0000000000000000 0000000000000008 000000000000000a 60000000000000e0 [ 2.552954] GPR20: 4080000000000000 c0000000113af038 00007fffcf130000 0000700000000000 [ 2.552954] GPR24: c000000062a6a000 0000000000000001 8000000062a68000 0000000000000001 [ 2.552954] GPR28: 000000000000000a c000000062ebc600 0000000000002000 c000000062ebc760 [ 2.553170] NIP [c0000000007eef3c] free_pud_range+0x8bc/0x8d0 [ 2.553185] LR [c0000000007eef30] free_pud_range+0x8b0/0x8d0 [ 2.553199] Call Trace: [ 2.553207] [c0000000622e7650] [c0000000007eef30] free_pud_range+0x8b0/0x8d0 (unreliable) [ 2.553229] [c0000000622e7750] [c0000000007f40b4] free_pgd_range+0x284/0x3b0 [ 2.553248] [c0000000622e7800] [c0000000007f4630] free_pgtables+0x450/0x570 [ 2.553274] [c0000000622e78e0] [c0000000008161c0] exit_mmap+0x250/0x650 [ 2.553292] [c0000000622e7a30] [c0000000001b95b8] __mmput+0x98/0x290 [ 2.558344] [c0000000622e7a80] [c0000000001d1018] exit_mm+0x118/0x1b0 [ 2.558361] [c0000000622e7ac0] [c0000000001d141c] do_exit+0x2ec/0x870 [ 2.558376] [c0000000622e7b60] [c0000000001d1ca8] do_group_exit+0x88/0x150 [ 2.558391] [c0000000622e7bb0] [c0000000001d1db8] sys_exit_group+0x48/0x50 [ 2.558407] [c0000000622e7be0] [c00000000003d810] system_call_exception+0x1e0/0x4c0 [ 2.558423] [c0000000622e7e50] [c00000000000d05c] system_call_vectored_common+0x15c/0x2ec (...) [ 2.558892] ---[ end trace 0000000000000000 ]--- [ 2.559022] BUG: Bad rss-counter state mm:000000002267cc9e type:MM_ANONPAGES val:1 [ 2.559037] BUG: non-zero pgtables_bytes on freeing mm: -6144
Here the modprobe process ended up with an allocated mm_struct from the mm_struct slab that was used before by the debug_vm_pgtable test. That is not a problem, since the mm_struct is initialized again etc., however, if it ends up using the same pgd table, it bumps into the old stale entry when clearing/freeing the page table entries, so it tries to free an entry already gone (that one which was allocated by the debug_vm_pgtable test), which also explains the negative pgtables_bytes since it's accounting for not allocated entries in the current process.
As far as I looked pgd_{alloc,free} etc. does not clear entries, and clearing of the entries is explicitly done in the free_pgtables-> free_pgd_range->free_p4d_range->free_pud_range->free_pmd_range-> free_pte_range path. However, the debug_vm_pgtable test does not call free_pgtables, since it allocates mm_struct and entries manually for its test and eg. not goes through page faults. So it also should clear manually the entries before exit at destroy_args().
This problem was noticed on a reboot X number of times test being done on a powerpc host, with a debug kernel with CONFIG_DEBUG_VM_PGTABLE enabled. Depends on the system, but on a 100 times reboot loop the problem could manifest once or twice, if a process ends up getting the right mm->pgd entry with the stale entries used by mm/debug_vm_pagetable. After using this patch, I couldn't reproduce/experience the problems anymore. I was able to reproduce the problem as well on latest upstream kernel (6.16).
I also modified destroy_args() to use mmput() instead of mmdrop(), there is no reason to hold mm_users reference and not release the mm_struct entirely, and in the output above with my debugging prints I already had patched it to use mmput, it did not fix the problem, but helped in the debugging as well.
--- mm/debug_vm_pgtable.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
mm/debug_vm_pgtable.c +7 -2
@@ -1049,29 +1049,34 @@ static void __init destroy_args(struct p/* Free page table entries */ if (args->start_ptep) { +pmd_clear (args->pmdp);pte_free (args->mm, args->start_ptep);mm_dec_nr_ptes (args->mm); }if (args->start_pmdp) { +pud_clear (args->pudp);pmd_free (args->mm, args->start_pmdp);mm_dec_nr_pmds (args->mm); }if (args->start_pudp) { +p4d_clear (args->p4dp);pud_free (args->mm, args->start_pudp);mm_dec_nr_puds (args->mm); } -if (args->start_p4dp) +if (args->start_p4dp) { +pgd_clear (args->pgdp);p4d_free (args->mm, args->start_p4dp); + }/* Free vma and mm struct */ if (args->vma)vm_area_free (args->vma);if (args->mm) -mmdrop (args->mm); +mmput (args->mm); } static struct page * __init
Greg Kroah-Hartman
maintainerPATCH 173/322 mm/memory-failure: fix infinite UCE for VM_PFNMAP pfn
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjiang Tu <[email protected]>
commit 2e6053fea379806269c4f7f5e36b523c9c0fb35c upstream.
When memory_failure() is called for a already hwpoisoned pfn, kill_accessing_process() will be called to kill current task. However, if the vma of the accessing vaddr is VM_PFNMAP, walk_page_range() will skip the vma in walk_page_test() and return 0.
Before commit aaf99ac2ceb7 ("mm/hwpoison: do not send SIGBUS to processes with recovered clean pages"), kill_accessing_process() will return EFAULT. For x86, the current task will be killed in kill_me_maybe().
However, after this commit, kill_accessing_process() simplies return 0, that means UCE is handled properly, but it doesn't actually. In such case, the user task will trigger UCE infinitely.
To fix it, add .test_walk callback for hwpoison_walk_ops to scan all vmas.
--- mm/memory-failure.c | 8 ++++++++ 1 file changed, 8 insertions(+)
mm/memory-failure.c +8 -0
@@ -845,9 +845,17 @@ static int hwpoison_hugetlb_range(pte_t#define hwpoison_hugetlb_range NULL#endif +static int hwpoison_test_walk (unsigned long start,unsigned long end, +struct mm_walk *walk) +{ +/* We also want to consider pages mapped into VM_PFNMAP. */ +return 0 ; +} +static const struct mm_walk_ops hwpoison_walk_ops = { .pmd_entry = hwpoison_pte_range, .hugetlb_entry = hwpoison_hugetlb_range, + .test_walk = hwpoison_test_walk, .walk_lock =PGWALK_RDLOCK , };
Greg Kroah-Hartman
maintainerPATCH 174/322 ALSA: hda/realtek: Add support for HP EliteBook x360 830 G6 and EliteBook 830 G6
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Evgeniy Harchenko <[email protected]>
commit eafae0fdd115a71b3a200ef1a31f86da04bac77f upstream.
The HP EliteBook x360 830 G6 and HP EliteBook 830 G6 have Realtek HDA codec ALC215. It needs the ALC285_FIXUP_HP_GPIO_LED quirk to enable the mute LED.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -10576,6 +10576,8 @@ static const struct hda_quirk alc269_fixSND_PCI_QUIRK (0x103c ,0x84e7 ,"HP Pavilion 15" ,ALC269_FIXUP_HP_MUTE_LED_MIC3 ),SND_PCI_QUIRK (0x103c ,0x8519 ,"HP Spectre x360 15-df0xxx" ,ALC285_FIXUP_HP_SPECTRE_X360 ),SND_PCI_QUIRK (0x103c ,0x8537 ,"HP ProBook 440 G6" ,ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF ), +SND_PCI_QUIRK (0x103c ,0x8548 ,"HP EliteBook x360 830 G6" ,ALC285_FIXUP_HP_GPIO_LED ), +SND_PCI_QUIRK (0x103c ,0x854a ,"HP EliteBook 830 G6" ,ALC285_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x85c6 ,"HP Pavilion x360 Convertible 14-dy1xxx" ,ALC295_FIXUP_HP_MUTE_LED_COEFBIT11 ),SND_PCI_QUIRK (0x103c ,0x85de ,"HP Envy x360 13-ar0xxx" ,ALC285_FIXUP_HP_ENVY_X360 ), SND_PCI_QUIRK(0x103c, 0x860f, "HP ZBook 15 G6", ALC285_FIXUP_HP_GPIO_AMP_INIT),
Greg Kroah-Hartman
maintainerPATCH 175/322 RDMA/rxe: Flush delayed SKBs while releasing RXE resources
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Yanjun <[email protected]>
commit 3c3e9a9f2972b364e8c2cfbfdeb23c6d6be4f87f upstream.
When skb packets are sent out, these skb packets still depends on the rxe resources, for example, QP, sk, when these packets are destroyed.
If these rxe resources are released when the skb packets are destroyed, the call traces will appear.
To avoid skb packets hang too long time in some network devices, a timestamp is added when these skb packets are created. If these skb packets hang too long time in network devices, these network devices can free these skb packets to release rxe resources.
--- drivers/infiniband/sw/rxe/rxe_net.c | 29 ++++++++--------------------- drivers/infiniband/sw/rxe/rxe_qp.c | 2 +- 2 files changed, 9 insertions(+), 22 deletions(-)
drivers/infiniband/sw/rxe/rxe_net.c +8 -21
@@ -345,33 +345,15 @@ int rxe_prepare(struct rxe_av *av, struct rxe_pkt_info *pkt,static void rxe_skb_tx_dtor (struct sk_buff *skb) { -struct net_device *ndev = skb->dev; -struct rxe_dev *rxe; -unsigned int qp_index; -struct rxe_qp *qp; +struct rxe_qp *qp = skb->sk->sk_user_data;int skb_out; - rxe =rxe_get_dev_from_net (ndev); -if (!rxe &&is_vlan_dev (ndev)) - rxe =rxe_get_dev_from_net (vlan_dev_real_dev (ndev)); -if (WARN_ON (!rxe)) -return ; - - qp_index = (int )(uintptr_t )skb->sk->sk_user_data; -if (!qp_index) -return ; - - qp =rxe_pool_get_index (&rxe->qp_pool, qp_index); -if (!qp) - goto put_dev; - skb_out =atomic_dec_return (&qp->skb_out); -if (qp->need_req_skb && skb_out <RXE_INFLIGHT_SKBS_PER_QP_LOW ) +if (unlikely (qp->need_req_skb && + skb_out <RXE_INFLIGHT_SKBS_PER_QP_LOW ))rxe_sched_task (&qp->send_task);rxe_put (qp); -put_dev: -ib_device_put (&rxe->ib_dev);sock_put (skb->sk); }
@@ -383,6 +365,7 @@ static int rxe_send(struct sk_buff *skb, struct rxe_pkt_info *pkt)sock_hold (sk); skb->sk = sk; skb->destructor = rxe_skb_tx_dtor; +rxe_get (pkt->qp);atomic_inc (&pkt->qp->skb_out);if (skb->protocol ==htons (ETH_P_IP ))
@@ -405,6 +388,7 @@ static int rxe_loopback(struct sk_buff *skb, struct rxe_pkt_info *pkt)sock_hold (sk); skb->sk = sk; skb->destructor = rxe_skb_tx_dtor; +rxe_get (pkt->qp);atomic_inc (&pkt->qp->skb_out);if (skb->protocol ==htons (ETH_P_IP ))
@@ -497,6 +481,9 @@ struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av, goto out; } +/* Add time stamp to skb. */ + skb->tstamp =ktime_get (); +skb_reserve (skb, hdr_len +LL_RESERVED_SPACE (ndev));/* FIXME: hold reference to this netdev until life of this skb. */
drivers/infiniband/sw/rxe/rxe_qp.c +1 -1
@@ -244,7 +244,7 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp, err =sock_create_kern (&init_net,AF_INET ,SOCK_DGRAM ,0 , &qp->sk);if (err <0 )return err; - qp->sk->sk->sk_user_data = (void *)(uintptr_t )qp->elem.index; + qp->sk->sk->sk_user_data = qp;/* pick a source UDP port number for this QP based on * the source QPN. this spreads traffic for different QPs
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 176/322 s390/sclp: Fix SCCB present check
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Oberparleiter <[email protected]>
commit 430fa71027b6ac9bb0ce5532b8d0676777d4219a upstream.
Tracing code called by the SCLP interrupt handler contains early exits if the SCCB address associated with an interrupt is NULL. This check is performed after physical to virtual address translation.
If the kernel identity mapping does not start at address zero, the resulting virtual address is never zero, so that the NULL checks won't work. Subsequently this may result in incorrect accesses to the first page of the identity mapping.
Fix this by introducing a function that handles the NULL case before address translation.
--- drivers/s390/char/sclp.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/s390/char/sclp.c +9 -2
@@ -76,6 +76,13 @@ unsigned long sclp_console_full;/* The currently active SCLP command word. */ static sclp_cmdw_t active_cmd; +static inline struct sccb_header *sclpint_to_sccb (u32 sccb_int) +{ +if (sccb_int) +return __va (sccb_int); +return NULL ; +} +static inline void sclp_trace (int prio,char *id,u32 a,u64 b,bool err) {struct sclp_trace_entry e;
@@ -619,7 +626,7 @@ __sclp_find_req(u32 sccb)static bool ok_response (u32 sccb_int,sclp_cmdw_t cmd) { -struct sccb_header *sccb = (struct sccb_header *)__va (sccb_int); +struct sccb_header *sccb =sclpint_to_sccb (sccb_int);struct evbuf_header *evbuf;u16 response;
@@ -658,7 +665,7 @@ static void sclp_interrupt_handler(struc/* INT: Interrupt received (a=intparm, b=cmd) */ sclp_trace_sccb (0 ,"INT" , param32, active_cmd, active_cmd, - (struct sccb_header *)__va (finished_sccb), +sclpint_to_sccb (finished_sccb), !ok_response (finished_sccb, active_cmd));if (finished_sccb) {
Greg Kroah-Hartman
maintainerPATCH 177/322 platform/x86/intel-uncore-freq: Check write blocked for ELC
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Pandruvada <[email protected]>
commit dff6f36878799a5ffabd15336ce993dc737374dc upstream.
Add the missing write_blocked check for updating sysfs related to uncore efficiency latency control (ELC). If write operation is blocked return error.
--- drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c +5 -0
@@ -189,9 +189,14 @@ static int uncore_read_control_freq(strustatic int write_eff_lat_ctrl (struct uncore_data *data,unsigned int val,enum uncore_index index) {struct tpmi_uncore_cluster_info *cluster_info; +struct tpmi_uncore_struct *uncore_root;u64 control; cluster_info = container_of(data, struct tpmi_uncore_cluster_info, uncore_data); + uncore_root = cluster_info->uncore_root; + +if (uncore_root->write_blocked) +return -EPERM ;if (cluster_info->root_domain)return -ENODATA ;
Greg Kroah-Hartman
maintainerPATCH 178/322 kvm: retry nx_huge_page_recovery_thread creation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Keith Busch <[email protected]>
commit 916b7f42b3b3b539a71c204a9b49fdc4ca92cd82 upstream.
A VMM may send a non-fatal signal to its threads, including vCPU tasks, at any time, and thus may signal vCPU tasks during KVM_RUN. If a vCPU task receives the signal while its trying to spawn the huge page recovery vhost task, then KVM_RUN will fail due to copy_process() returning -ERESTARTNOINTR.
Rework call_once() to mark the call complete if and only if the called function succeeds, and plumb the function's true error code back to the call_once() invoker. This provides userspace with the correct, non-fatal error code so that the VMM doesn't terminate the VM on -ENOMEM, and allows subsequent KVM_RUN a succeed by virtue of retrying creation of the NX huge page task.
Message-ID: <[email protected]>
--- arch/x86/kvm/mmu/mmu.c | 10 ++++------ include/linux/call_once.h | 43 ++++++++++++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 17 deletions(-)
arch/x86/kvm/mmu/mmu.c +4 -6
@@ -7578,7 +7578,7 @@ static bool kvm_nx_huge_page_recovery_woreturn true; } -static void kvm_mmu_start_lpage_recovery (struct once *once) +static int kvm_mmu_start_lpage_recovery (struct once *once) { struct kvm_arch *ka = container_of(once, struct kvm_arch, nx_once); struct kvm *kvm = container_of(ka, struct kvm, arch);
@@ -7590,12 +7590,13 @@ static void kvm_mmu_start_lpage_recovery kvm, "kvm-nx-lpage-recovery");if (IS_ERR (nx_thread)) -return ; +return PTR_ERR (nx_thread);vhost_task_start (nx_thread);/* Make the task visible only once it is fully started. */ WRITE_ONCE (kvm->arch.nx_huge_page_recovery_thread, nx_thread); +return 0 ; }int kvm_mmu_post_init_vm (struct kvm *kvm)
@@ -7603,10 +7604,7 @@ int kvm_mmu_post_init_vm(struct kvm *kvmif (nx_hugepage_mitigation_hard_disabled)return 0 ; -call_once (&kvm->arch.nx_once, kvm_mmu_start_lpage_recovery); -if (!kvm->arch.nx_huge_page_recovery_thread) -return -ENOMEM ; -return 0 ; +return call_once (&kvm->arch.nx_once, kvm_mmu_start_lpage_recovery); }void kvm_mmu_pre_destroy_vm (struct kvm *kvm)
include/linux/call_once.h +32 -11
52 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 179/322 accel/habanalabs/gaudi2: Use kvfree() for memory allocated with kvcalloc()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
commit a44458dfd5bc0c79c6739c3f4c658361d3a5126b upstream.
Use kvfree() to fix the following Coccinelle/coccicheck warning reported by kfree_mismatch.cocci:
WARNING kvmalloc is used to allocate this memory at line 10398
--- drivers/accel/habanalabs/gaudi2/gaudi2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/accel/habanalabs/gaudi2/gaudi2.c +1 -1
@@ -10437,7 +10437,7 @@ static int gaudi2_memset_device_memory(struct hl_device *hdev, u64 addr, u64 siz (u64 *)(lin_dma_pkts_arr), DEBUGFS_WRITE64);WREG32 (sob_addr,0 ); -kfree (lin_dma_pkts_arr); +kvfree (lin_dma_pkts_arr);return rc; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 180/322 drm/amdgpu/swm14: Update power limit logic
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 79e25cd06e85105c75701ef1773c6c64bb304091 upstream.
Take into account the limits from the vbios. Ported from the SMU13 code.
--- drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +25 -5
@@ -1668,9 +1668,11 @@ static int smu_v14_0_2_get_power_limit(s uint32_t *min_power_limit) {struct smu_table_context *table_context = &smu->smu_table; +struct smu_14_0_2_powerplay_table *powerplay_table = + table_context->power_play_table;PPTable_t *pptable = table_context->driver_pptable;CustomSkuTable_t *skutable = &pptable->CustomSkuTable; -uint32_t power_limit; +uint32_t power_limit, od_percent_upper =0 , od_percent_lower =0 ;uint32_t msg_limit = pptable->SkuTable.MsgLimits.Power[PPT_THROTTLER_PPT0 ][POWER_SOURCE_AC ];if (smu_v14_0_get_current_power_limit (smu, &power_limit))
@@ -1683,11 +1685,29 @@ static int smu_v14_0_2_get_power_limit(sif (default_power_limit) *default_power_limit = power_limit; -if (max_power_limit) - *max_power_limit = msg_limit; +if (powerplay_table) { +if (smu->od_enabled && +smu_v14_0_2_is_od_feature_supported (smu,PP_OD_FEATURE_PPT_BIT )) { + od_percent_upper = pptable->SkuTable.OverDriveLimitsBasicMax.Ppt; + od_percent_lower = pptable->SkuTable.OverDriveLimitsBasicMin.Ppt; + }else if (smu_v14_0_2_is_od_feature_supported (smu,PP_OD_FEATURE_PPT_BIT )) { + od_percent_upper =0 ; + od_percent_lower = pptable->SkuTable.OverDriveLimitsBasicMin.Ppt; + } + } -if (min_power_limit) - *min_power_limit =0 ; +dev_dbg (smu->adev->dev,"od percent upper:%d, od percent lower:%d (default power: %d)\n" , + od_percent_upper, od_percent_lower, power_limit); + +if (max_power_limit) { + *max_power_limit = msg_limit * (100 + od_percent_upper); + *max_power_limit /=100 ; + } + +if (min_power_limit) { + *min_power_limit = power_limit * (100 + od_percent_lower); + *min_power_limit /=100 ; + }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 181/322 drm/amd/display: Avoid a NULL pointer dereference
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 07b93a5704b0b72002f0c4bd1076214af67dc661 upstream.
[WHY]
Although unlikely drm_atomic_get_new_connector_state() or drm_atomic_get_old_connector_state() can return NULL.
[HOW]
Check returns before dereference.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +3 -0
@@ -7583,6 +7583,9 @@ amdgpu_dm_connector_atomic_check(structstruct amdgpu_dm_connector *aconn =to_amdgpu_dm_connector (conn);int ret; +if (WARN_ON (unlikely (!old_con_state || !new_con_state))) +return -EINVAL ; +trace_amdgpu_dm_connector_atomic_check (new_con_state);if (conn->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
Greg Kroah-Hartman
maintainerPATCH 182/322 drm/amd/display: Dont overclock DCE 6 by 15%
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit cb7b7ae53b557d168b4af5cd8549f3eff920bfb5 upstream.
The extra 15% clock was added as a workaround for a Polaris issue which uses DCE 11, and should not have been used on DCE 6 which is already hardcoded to the highest possible display clock. Unfortunately, the extra 15% was mistakenly copied and kept even on code paths which don't affect Polaris.
This commit fixes that and also adds a check to make sure not to exceed the maximum DCE 6 display clock.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c +3 -5
@@ -123,11 +123,9 @@ static void dce60_update_clocks(struct c {struct clk_mgr_internal *clk_mgr_dce =TO_CLK_MGR_INTERNAL (clk_mgr_base);struct dm_pp_power_level_change_request level_change_req; -int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; - -/*TODO: W/A for dal3 linux, investigate why this works */ -if (!clk_mgr_dce->dfs_bypass_active) - patched_disp_clk = patched_disp_clk *115 /100 ; +const int max_disp_clk = + clk_mgr_dce->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE ].display_clk_khz; +int patched_disp_clk =MIN (max_disp_clk, context->bw_ctx.bw.dce.dispclk_khz); level_change_req.power_level =dce_get_required_clocks_state (clk_mgr_base, context);/* get max clock state from PPLIB */
Greg Kroah-Hartman
maintainerPATCH 183/322 drm/amd/display: Fix fractional fb divider in set_pixel_clock_v3
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 10507478468f165ea681605d133991ed05cdff62 upstream.
For later VBIOS versions, the fractional feedback divider is calculated as the remainder of dividing the feedback divider by a factor, which is set to 1000000. For reference, see:
- calculate_fb_and_fractional_fb_divider
- calc_pll_max_vco_construct
However, in case of old VBIOS versions that have set_pixel_clock_v3, they only have 1 byte available for the fractional feedback divider, and it's expected to be set to the remainder from dividing the feedback divider by 10. For reference see the legacy display code:
- amdgpu_pll_compute
- amdgpu_atombios_crtc_program_pll
This commit fixes set_pixel_clock_v3 by dividing the fractional feedback divider passed to the function by 100000.
--- drivers/gpu/drm/amd/display/dc/bios/command_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/bios/command_table.c +1 -1
@@ -993,7 +993,7 @@ static enum bp_result set_pixel_clock_v3 allocation.sPCLKInput.usFbDiv =cpu_to_le16 ((uint16_t )bp_params->feedback_divider); allocation.sPCLKInput.ucFracFbDiv = - (uint8_t )bp_params->fractional_feedback_divider; + (uint8_t )(bp_params->fractional_feedback_divider /100000 ); allocation.sPCLKInput.ucPostDiv = (uint8_t )bp_params->pixel_clock_post_divider;
Greg Kroah-Hartman
maintainerPATCH 184/322 drm/amd/display: Fix Xorg desktop unresponsive on Replay panel
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tom Chung <[email protected]>
commit 66af73a1c319336694a8610fe4c2943f7b33066c upstream.
[WHY & HOW]
IPS & self-fresh feature can cause vblank counter resets between vblank disable and enable.
It may cause system stuck due to wait the vblank counter.
Call the drm_crtc_vblank_restore() during vblank enable to estimate missed vblanks by using timestamps and update the vblank counter in DRM.
It can make the vblank counter increase smoothly and resolve this issue.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 19 +++++++++++++++++ 1 file changed, 19 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +19 -0
@@ -302,6 +302,25 @@ static inline int amdgpu_dm_crtc_set_vbl irq_type =amdgpu_display_crtc_idx_to_irq_type (adev, acrtc->crtc_id);if (enable) { +struct dc *dc = adev->dm.dc; +struct drm_vblank_crtc *vblank =drm_crtc_vblank_crtc (crtc); +struct psr_settings *psr = &acrtc_state->stream->link->psr_settings; +struct replay_settings *pr = &acrtc_state->stream->link->replay_settings; +bool sr_supported = (psr->psr_version !=DC_PSR_VERSION_UNSUPPORTED ) || + pr->config.replay_supported; + +/* +* IPS & self-refresh feature can cause vblank counter resets between +* vblank disable and enable. +* It may cause system stuck due to waiting for the vblank counter. +* Call this function to estimate missed vblanks by using timestamps and +* update the vblank counter in DRM. +*/ +if (dc->caps.ips_support && + dc->config.disable_ips !=DMUB_IPS_DISABLE_ALL && + sr_supported && vblank->config.disable_immediate) +drm_crtc_vblank_restore (crtc); +/* vblank irq on -> Only need vupdate irq in vrr mode */ if (amdgpu_dm_crtc_vrr_active (acrtc_state)) rc =amdgpu_dm_crtc_set_vupdate_irq (crtc, true);
Greg Kroah-Hartman
maintainerPATCH 185/322 drm/amd/display: Fix DP audio DTO1 clock source on DCE 6.
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 297a4833a68aac3316eb808b4123eb016ef242d7 upstream.
On DCE 6, DP audio was not working. However, it worked when an HDMI monitor was also plugged in.
Looking at dce_aud_wall_dto_setup it seems that the main difference is that we use DTO1 when only DP is plugged in.
When programming DTO1, it uses audio_dto_source_clock_in_khz which is set from get_dp_ref_freq_khz
The dce60_get_dp_ref_freq_khz implementation looks incorrect, because DENTIST_DISPCLK_CNTL seems to be always zero on DCE 6, so it isn't usable.
I compared dce60_get_dp_ref_freq_khz to the legacy display code, specifically dce_v6_0_audio_set_dto, and it turns out that in case of DCE 6, it needs to use the display clock. With that, DP audio started working on Pitcairn, Oland and Cape Verde.
However, it still didn't work on Tahiti. Despite having the same DCE version, Tahiti seems to have a different audio device. After some trial and error I realized that it works with the default display clock as reported by the VBIOS, not the current display clock.
The patch was tested on all four SI GPUs:
* Pitcairn (DCE 6.0)
* Oland (DCE 6.4)
* Cape Verde (DCE 6.0)
* Tahiti (DCE 6.0 but different)
The testing was done on Samsung Odyssey G7 LS28BG700EPXEN on each of the above GPUs, at the following settings:
* 4K 60 Hz
* 1080p 60 Hz
* 1080p 144 Hz
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c | 21 +++-------- 1 file changed, 6 insertions(+), 15 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c +6 -15
@@ -83,22 +83,13 @@ static const struct state_dependent_clocstatic int dce60_get_dp_ref_freq_khz (struct clk_mgr *clk_mgr_base) {struct clk_mgr_internal *clk_mgr =TO_CLK_MGR_INTERNAL (clk_mgr_base); -int dprefclk_wdivider; -int dp_ref_clk_khz; -int target_div; +struct dc_context *ctx = clk_mgr_base->ctx; +int dp_ref_clk_khz =0 ; -/* DCE6 has no DPREFCLK_CNTL to read DP Reference Clock source */ - -/* Read the mmDENTIST_DISPCLK_CNTL to get the currently -* programmed DID DENTIST_DPREFCLK_WDIVIDER*/ -REG_GET (DENTIST_DISPCLK_CNTL ,DENTIST_DPREFCLK_WDIVIDER , &dprefclk_wdivider); - -/* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ - target_div =dentist_get_divider_from_did (dprefclk_wdivider); - -/* Calculate the current DFS clock, in kHz.*/ - dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR - * clk_mgr->base.dentist_vco_freq_khz) / target_div; +if (ASIC_REV_IS_TAHITI_P (ctx->asic_id.hw_internal_rev)) + dp_ref_clk_khz = ctx->dc_bios->fw_info.default_display_engine_pll_frequency; +else + dp_ref_clk_khz = clk_mgr_base->clks.dispclk_khz;return dce_adjust_dp_ref_freq_for_ss (clk_mgr, dp_ref_clk_khz); }
Greg Kroah-Hartman
maintainerPATCH 186/322 drm/amd/display: Find first CRTC and its line time in dce110_fill_display_configs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 669f73a26f6112eedbadac53a2f2707ac6d0b9c8 upstream.
dce110_fill_display_configs is shared between DCE 6-11, and finding the first CRTC and its line time is relevant to DCE 6 too. Move the code to find it from DCE 11 specific code.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c | 30 ++++++---- 1 file changed, 20 insertions(+), 10 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c +20 -10
@@ -120,9 +120,12 @@ void dce110_fill_display_configs(const struct dc_state *context, struct dm_pp_display_configuration *pp_display_cfg) { + struct dc *dc = context->clk_mgr->ctx->dc;int j;int num_cfgs =0 ; + pp_display_cfg->crtc_index = dc->res_pool->res_cap->num_timing_generator; +for (j =0 ; j < context->stream_count; j++) {int k;
@@ -164,6 +167,23 @@ void dce110_fill_display_configs( cfg->v_refresh /= stream->timing.h_total; cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total /2 ) / stream->timing.v_total; + +/* Find first CRTC index and calculate its line time. +* This is necessary for DPM on SI GPUs. +*/ +if (cfg->pipe_idx < pp_display_cfg->crtc_index) { +const struct dc_crtc_timing *timing = + &context->streams[0 ]->timing; + + pp_display_cfg->crtc_index = cfg->pipe_idx; + pp_display_cfg->line_time_in_us = + timing->h_total *10000 / timing->pix_clk_100hz; + } + } + +if (!num_cfgs) { + pp_display_cfg->crtc_index =0 ; + pp_display_cfg->line_time_in_us =0 ; } pp_display_cfg->display_count = num_cfgs;
@@ -232,16 +252,6 @@ void dce11_pplib_apply_display_requiremedce110_fill_display_configs (context, pp_display_cfg); -/* TODO: is this still applicable?*/ -if (pp_display_cfg->display_count ==1 ) { -const struct dc_crtc_timing *timing = - &context->streams[0 ]->timing; - - pp_display_cfg->crtc_index = - pp_display_cfg->disp_configs[0 ].pipe_idx; - pp_display_cfg->line_time_in_us = timing->h_total *10000 / timing->pix_clk_100hz; - } -if (memcmp (&dc->current_state->pp_display_cfg, pp_display_cfg,sizeof (*pp_display_cfg)) !=0 )dm_pp_apply_display_requirements (dc->ctx, pp_display_cfg); }
Greg Kroah-Hartman
maintainerPATCH 187/322 drm/amd/display: Fill display clock and vblank time in dce110_fill_display_configs
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
commit 7d07140d37f792f01cfdb8ca9a6a792ab1d29126 upstream.
Also needed by DCE 6.
This way the code that gathers this info can be shared between different DCE versions and doesn't have to be repeated.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c | 2 -- drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c | 10 +++------- drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c | 2 -- 3 files changed, 3 insertions(+), 11 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c +0 -2
@@ -386,8 +386,6 @@ static void dce_pplib_apply_display_requ {struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; - pp_display_cfg->avail_mclk_switch_time_us =dce110_get_min_vblank_time_us (context); -dce110_fill_display_configs (context, pp_display_cfg);if (memcmp (&dc->current_state->pp_display_cfg, pp_display_cfg,sizeof (*pp_display_cfg)) !=0 )
drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c +3 -7
@@ -124,6 +124,9 @@ void dce110_fill_display_configs(int j;int num_cfgs =0 ; + pp_display_cfg->avail_mclk_switch_time_us =dce110_get_min_vblank_time_us (context); + pp_display_cfg->disp_clk_khz = dc->clk_mgr->clks.dispclk_khz; + pp_display_cfg->avail_mclk_switch_time_in_disp_active_us =0 ; pp_display_cfg->crtc_index = dc->res_pool->res_cap->num_timing_generator;for (j =0 ; j < context->stream_count; j++) {
@@ -243,13 +246,6 @@ void dce11_pplib_apply_display_requireme pp_display_cfg->min_engine_clock_deep_sleep_khz = context->bw_ctx.bw.dce.sclk_deep_sleep_khz; - pp_display_cfg->avail_mclk_switch_time_us = -dce110_get_min_vblank_time_us (context); -/* TODO: dce11.2*/ - pp_display_cfg->avail_mclk_switch_time_in_disp_active_us =0 ; - - pp_display_cfg->disp_clk_khz = dc->clk_mgr->clks.dispclk_khz; -dce110_fill_display_configs (context, pp_display_cfg);if (memcmp (&dc->current_state->pp_display_cfg, pp_display_cfg,sizeof (*pp_display_cfg)) !=0 )
drivers/gpu/drm/amd/display/dc/clk_mgr/dce60/dce60_clk_mgr.c +0 -2
@@ -100,8 +100,6 @@ static void dce60_pplib_apply_display_re {struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; - pp_display_cfg->avail_mclk_switch_time_us =dce110_get_min_vblank_time_us (context); -dce110_fill_display_configs (context, pp_display_cfg);if (memcmp (&dc->current_state->pp_display_cfg, pp_display_cfg,sizeof (*pp_display_cfg)) !=0 )
Greg Kroah-Hartman
maintainerPATCH 188/322 scsi: core: Fix command pass through retry regression
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Christie <[email protected]>
commit 8604f633f59375687fa115d6f691de95a42520e3 upstream.
scsi_check_passthrough() is always called, but it doesn't check for if a command completed successfully. As a result, if a command was successful and the caller used SCMD_FAILURE_RESULT_ANY to indicate what failures it wanted to retry, we will end up retrying the command. This will cause delays during device discovery because of the command being sent multiple times. For some USB devices it can also cause the wrong device size to be used.
This patch adds a check for if the command was successful. If it is we return immediately instead of trying to match a failure.
--- drivers/scsi/scsi_lib.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/scsi_lib.c +3 -0
@@ -210,6 +210,9 @@ static int scsi_check_passthrough(structstruct scsi_sense_hdr sshdr;enum sam_status status; +if (!scmd->result) +return 0 ; +if (!failures)return 0 ;
Greg Kroah-Hartman
maintainerPATCH 189/322 soc: qcom: mdt_loader: Fix error return values in mdt_header_valid()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit 9f35ab0e53ccbea57bb9cbad8065e0406d516195 upstream.
This function is supposed to return true for valid headers and false for invalid. In a couple places it returns -EINVAL instead which means the invalid headers are counted as true. Change it to return false.
--- drivers/soc/qcom/mdt_loader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/soc/qcom/mdt_loader.c +2 -2
@@ -33,14 +33,14 @@ static bool mdt_header_valid(const strucreturn false;if (ehdr->e_phentsize !=sizeof (struct elf32_phdr )) -return -EINVAL ; +return false; phend =size_add (size_mul (sizeof (struct elf32_phdr ), ehdr->e_phnum), ehdr->e_phoff);if (phend > fw->size)return false;if (ehdr->e_shentsize !=sizeof (struct elf32_shdr )) -return -EINVAL ; +return false; shend =size_add (size_mul (sizeof (struct elf32_shdr ), ehdr->e_shnum), ehdr->e_shoff);if (shend > fw->size)
Greg Kroah-Hartman
maintainerPATCH 190/322 mptcp: remove duplicate sk_reset_timer call
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geliang Tang <[email protected]>
commit 5d13349472ac8abcbcb94407969aa0fdc2e1f1be upstream.
sk_reset_timer() was called twice in mptcp_pm_alloc_anno_list.
Simplify the code by using a 'goto' statement to eliminate the duplication.
Note that this is not a fix, but it will help backporting the following patch. The same "Fixes" tag has been added for this reason.
[ Before commit e4c28e3d5c09 ("mptcp: pm: move generic PM helpers to
pm.c"), mptcp_pm_alloc_anno_list() was in pm_netlink.c. The same patch can be applied there without conflicts. ]
--- net/mptcp/pm_netlink.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
net/mptcp/pm_netlink.c +2 -3
@@ -372,9 +372,7 @@ bool mptcp_pm_alloc_anno_list(struct mptif (WARN_ON_ONCE (mptcp_pm_is_kernel (msk)))return false; -sk_reset_timer (sk, &add_entry->add_timer, - jiffies +mptcp_get_add_addr_timeout (net)); -return true; + goto reset_timer; } add_entry =kmalloc (sizeof (*add_entry),GFP_ATOMIC );
@@ -388,6 +386,7 @@ bool mptcp_pm_alloc_anno_list(struct mpt add_entry->retrans_times =0 ;timer_setup (&add_entry->add_timer, mptcp_pm_add_timer,0 ); +reset_timer:sk_reset_timer (sk, &add_entry->add_timer, jiffies +mptcp_get_add_addr_timeout (net));
Greg Kroah-Hartman
maintainerPATCH 191/322 mptcp: disable add_addr retransmission when timeout is 0
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geliang Tang <[email protected]>
commit f5ce0714623cffd00bf2a83e890d09c609b7f50a upstream.
When add_addr_timeout was set to 0, this caused the ADD_ADDR to be retransmitted immediately, which looks like a buggy behaviour. Instead, interpret 0 as "no retransmissions needed".
The documentation is updated to explicitly state that setting the timeout to 0 disables retransmission.
[ Before commit e4c28e3d5c09 ("mptcp: pm: move generic PM helpers to
pm.c"), mptcp_pm_alloc_anno_list() was in pm_netlink.c. The same patch can be applied there without conflicts. ]
--- Documentation/networking/mptcp-sysctl.rst | 2 ++ net/mptcp/pm_netlink.c | 13 ++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-)
Documentation/networking/mptcp-sysctl.rst +2 -0
@@ -12,6 +12,8 @@ add_addr_timeout - INTEGER (seconds) resent to an MPTCP peer that has not acknowledged a previous ADD_ADDR message. + Do not retransmit if set to 0. + The default value matches TCP_RTO_MAX. This is a per-namespace sysctl.
net/mptcp/pm_netlink.c +10 -3
@@ -293,6 +293,7 @@ static void mptcp_pm_add_timer(struct tistruct mptcp_pm_add_entry *entry =from_timer (entry, timer, add_timer);struct mptcp_sock *msk = entry->sock;struct sock *sk = (struct sock *)msk; +unsigned int timeout;pr_debug ("msk=%p\n" , msk);
@@ -310,6 +311,10 @@ static void mptcp_pm_add_timer(struct ti goto out; } + timeout =mptcp_get_add_addr_timeout (sock_net (sk)); +if (!timeout) + goto out; +spin_lock_bh (&msk->pm.lock);if (!mptcp_pm_should_add_signal_addr (msk)) {
@@ -321,7 +326,7 @@ static void mptcp_pm_add_timer(struct tiif (entry->retrans_times <ADD_ADDR_RETRANS_MAX )sk_reset_timer (sk, timer, - jiffies +mptcp_get_add_addr_timeout (sock_net (sk))); + jiffies + timeout);spin_unlock_bh (&msk->pm.lock);
@@ -363,6 +368,7 @@ bool mptcp_pm_alloc_anno_list(struct mptstruct mptcp_pm_add_entry *add_entry =NULL ;struct sock *sk = (struct sock *)msk;struct net *net =sock_net (sk); +unsigned int timeout;lockdep_assert_held (&msk->pm.lock);
@@ -387,8 +393,9 @@ bool mptcp_pm_alloc_anno_list(struct mpttimer_setup (&add_entry->add_timer, mptcp_pm_add_timer,0 ); reset_timer: -sk_reset_timer (sk, &add_entry->add_timer, - jiffies +mptcp_get_add_addr_timeout (net)); + timeout =mptcp_get_add_addr_timeout (net); +if (timeout) +sk_reset_timer (sk, &add_entry->add_timer, jiffies + timeout);return true; }
Greg Kroah-Hartman
maintainerPATCH 192/322 Mark xe driver as BROKEN if kernel page size is not 4kB
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Richter <[email protected]>
[ Upstream commit 022906afdf90327bce33d52fb4fb41b6c7d618fb ]
This driver, for the time being, assumes that the kernel page size is 4kB, so it fails on loong64 and aarch64 with 16kB pages, and ppc64el with 64kB pages.
--- drivers/gpu/drm/xe/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/xe/Kconfig +1 -0
@@ -3,6 +3,7 @@ config DRM_XE tristate "Intel Xe Graphics" depends on DRM && PCI && MMU depends on KUNIT || !KUNIT + depends on PAGE_SIZE_4KB || COMPILE_TEST || BROKEN select INTERVAL_TREE # we need shmfs for the swappable backing store, and in particular # the shmem_readpage() which depends upon tmpfs
Greg Kroah-Hartman
maintainerPATCH 193/322 PCI: imx6: Add i.MX8Q PCIe Endpoint (EP) support
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
[ Upstream commit 687aedb73a401addf151c5f60e481e574b4c9ad9 ]
Add support for the i.MX8Q series (i.MX8QM, i.MX8QXP, and i.MX8DXL) PCIe Endpoint (EP). On the i.MX8Q platforms, the PCI bus addresses differ from the CPU addresses. However, the DesignWare (DWC) driver already handles this in the common code.
Stable-dep-of: c523fa63ac1d ("PCI: imx6: Add IMX8MQ_EP third 64-bit BAR in epc_features")
--- drivers/pci/controller/dwc/pci-imx6.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
drivers/pci/controller/dwc/pci-imx6.c +20 -0
@@ -72,6 +72,7 @@ enum imx_pcie_variants {IMX8MQ_EP ,IMX8MM_EP ,IMX8MP_EP , +IMX8Q_EP , IMX95_EP, };
@@ -1103,6 +1104,16 @@ static const struct pci_epc_features imx .align = SZ_64K, }; +static const struct pci_epc_features imx8q_pcie_epc_features = { + .linkup_notifier = false, + .msi_capable = true, + .msix_capable = false, + .bar[BAR_1 ] = { .type =BAR_RESERVED , }, + .bar[BAR_3 ] = { .type =BAR_RESERVED , }, + .bar[BAR_5 ] = { .type =BAR_RESERVED , }, + .align =SZ_64K , +}; +/* * BAR# | Default BAR enable | Default BAR Type | Default BAR Size | BAR Sizing Scheme * ================================================================================================
@@ -1695,6 +1706,14 @@ static const struct imx_pcie_drvdata drv .epc_features = &imx8m_pcie_epc_features, .enable_ref_clk = imx8mm_pcie_enable_ref_clk, }, + [IMX8Q_EP] = { + .variant = IMX8Q_EP, + .flags = IMX_PCIE_FLAG_HAS_PHYDRV, + .mode = DW_PCIE_EP_TYPE, + .epc_features = &imx8q_pcie_epc_features, + .clk_names = imx8q_clks, + .clks_cnt = ARRAY_SIZE(imx8q_clks), + }, [IMX95_EP] = { .variant = IMX95_EP, .flags = IMX_PCIE_FLAG_HAS_SERDES |
@@ -1724,6 +1743,7 @@ static const struct of_device_id imx_pci { .compatible = "fsl,imx8mq-pcie-ep", .data = &drvdata[IMX8MQ_EP], }, { .compatible = "fsl,imx8mm-pcie-ep", .data = &drvdata[IMX8MM_EP], }, { .compatible = "fsl,imx8mp-pcie-ep", .data = &drvdata[IMX8MP_EP], }, + { .compatible = "fsl,imx8q-pcie-ep", .data = &drvdata[IMX8Q_EP], }, { .compatible = "fsl,imx95-pcie-ep", .data = &drvdata[IMX95_EP], }, {}, };
Greg Kroah-Hartman
maintainerPATCH 194/322 PCI: imx6: Add IMX8MQ_EP third 64-bit BAR in epc_features
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Zhu <[email protected]>
[ Upstream commit c523fa63ac1d452abeeb4e699560ec3365037f32 ]
IMX8MQ_EP has three 64-bit BAR0/2/4 capable and programmable BARs. For IMX8MQ_EP, use imx8q_pcie_epc_features (64-bit BARs 0, 2, 4) instead of imx8m_pcie_epc_features (64-bit BARs 0, 2).
--- drivers/pci/controller/dwc/pci-imx6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/dwc/pci-imx6.c +1 -1
@@ -1676,7 +1676,7 @@ static const struct imx_pcie_drvdata drv .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE, .mode_off[1] = IOMUXC_GPR12, .mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE, - .epc_features = &imx8m_pcie_epc_features, + .epc_features = &imx8q_pcie_epc_features, .init_phy = imx8mq_pcie_init_phy, .enable_ref_clk = imx8mm_pcie_enable_ref_clk, },
Greg Kroah-Hartman
maintainerPATCH 195/322 PCI: rockchip: Use standard PCIe definitions
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geraldo Nascimento <[email protected]>
[ Upstream commit cbbfe9f683f0f9b6a1da2eaa53b995a4b5961086 ]
Current code uses custom-defined register offsets and bitfields for the standard PCIe registers. This creates duplication as the PCI header already defines them. So, switch to using the standard PCIe definitions and drop the custom ones.
--- drivers/pci/controller/pcie-rockchip-host.c | 45 ++++++++++++++-------------- drivers/pci/controller/pcie-rockchip.h | 11 ------ 2 files changed, 24 insertions(+), 32 deletions(-)
drivers/pci/controller/pcie-rockchip-host.c +23 -22
@@ -11,6 +11,7 @@* ARM PCI Host generic driver. */ +#include <linux/bitfield.h> #include <linux/bitrev.h> #include <linux/clk.h> #include <linux/delay.h>
@@ -40,18 +41,18 @@ static void rockchip_pcie_enable_bw_int( {u32 status; - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_LCS ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |= (PCI_EXP_LNKCTL_LBMIE |PCI_EXP_LNKCTL_LABIE ); -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_LCS ); +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); }static void rockchip_pcie_clr_bw_int (struct rockchip_pcie *rockchip) {u32 status; - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_LCS ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |= (PCI_EXP_LNKSTA_LBMS |PCI_EXP_LNKSTA_LABS ) <<16 ; -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_LCS ); +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); }static void rockchip_pcie_update_txcredit_mui (struct rockchip_pcie *rockchip)
@@ -269,7 +270,7 @@ static void rockchip_pcie_set_power_limi scale =3 ;/* 0.001x */ curr = curr /1000 ;/* convert to mA */ power = (curr *3300 ) /1000 ;/* milliwatt */ -while (power >PCIE_RC_CONFIG_DCR_CSPL_LIMIT ) { +while (power >FIELD_MAX (PCI_EXP_DEVCAP_PWR_VAL )) {if (!scale) {dev_warn (rockchip->dev,"invalid power supply\n" );return ;
@@ -278,10 +279,10 @@ static void rockchip_pcie_set_power_limi power = power /10 ; } - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_DCR ); - status |= (power <<PCIE_RC_CONFIG_DCR_CSPL_SHIFT ) | - (scale <<PCIE_RC_CONFIG_DCR_CPLS_SHIFT ); -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_DCR ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_DEVCAP ); + status |=FIELD_PREP (PCI_EXP_DEVCAP_PWR_VAL , power); + status |=FIELD_PREP (PCI_EXP_DEVCAP_PWR_SCL , scale); +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_DEVCAP ); }/**
@@ -309,14 +310,14 @@ static int rockchip_pcie_host_init_port(rockchip_pcie_set_power_limit (rockchip);/* Set RC's clock architecture as common clock */ - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_LCS ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |=PCI_EXP_LNKSTA_SLC <<16 ; -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_LCS ); +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL );/* Set RC's RCB to 128 */ - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_LCS ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |=PCI_EXP_LNKCTL_RCB ; -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_LCS ); +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL );/* Enable Gen1 training */ rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE,
@@ -341,9 +342,9 @@ static int rockchip_pcie_host_init_port(* Enable retrain for gen2. This should be configured only after * gen1 finished. */ - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_LCS ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |=PCI_EXP_LNKCTL_RL ; -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_LCS ); +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); err = readl_poll_timeout(rockchip->apb_base + PCIE_CORE_CTRL, status, PCIE_LINK_IS_GEN2(status), 20,
@@ -380,15 +381,15 @@ static int rockchip_pcie_host_init_port(/* Clear L0s from RC's link cap */ if (of_property_read_bool (dev->of_node,"aspm-no-l0s" )) { - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_LINK_CAP ); - status &= ~PCIE_RC_CONFIG_LINK_CAP_L0S ; -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_LINK_CAP ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCAP ); + status &= ~PCI_EXP_LNKCAP_ASPM_L0S ; +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCAP ); } - status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_DCSR ); - status &= ~PCIE_RC_CONFIG_DCSR_MPS_MASK ; - status |=PCIE_RC_CONFIG_DCSR_MPS_256 ; -rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_DCSR ); + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_DEVCTL ); + status &= ~PCI_EXP_DEVCTL_PAYLOAD ; + status |=PCI_EXP_DEVCTL_PAYLOAD_256B ; +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_DEVCTL );return 0 ; err_power_off_phy:
drivers/pci/controller/pcie-rockchip.h +1 -10
@@ -144,16 +144,7 @@#define PCIE_EP_CONFIG_BASE 0xa00000#define PCIE_EP_CONFIG_DID_VID (PCIE_EP_CONFIG_BASE + 0x00)#define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) -#define PCIE_RC_CONFIG_DCR (PCIE_RC_CONFIG_BASE + 0xc4) -#define PCIE_RC_CONFIG_DCR_CSPL_SHIFT 18 -#define PCIE_RC_CONFIG_DCR_CSPL_LIMIT 0xff -#define PCIE_RC_CONFIG_DCR_CPLS_SHIFT 26 -#define PCIE_RC_CONFIG_DCSR (PCIE_RC_CONFIG_BASE + 0xc8) -#define PCIE_RC_CONFIG_DCSR_MPS_MASK GENMASK(7, 5) -#define PCIE_RC_CONFIG_DCSR_MPS_256 (0x1 << 5) -#define PCIE_RC_CONFIG_LINK_CAP (PCIE_RC_CONFIG_BASE + 0xcc) -#define PCIE_RC_CONFIG_LINK_CAP_L0S BIT(10) -#define PCIE_RC_CONFIG_LCS (PCIE_RC_CONFIG_BASE + 0xd0) +#define PCIE_RC_CONFIG_CR (PCIE_RC_CONFIG_BASE + 0xc0)#define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)#define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_CONFIG_BASE + 0x274)#define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK GENMASK(31, 20)
Greg Kroah-Hartman
maintainerPATCH 196/322 PCI: rockchip: Set Target Link Speed to 5.0 GT/s before retraining
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geraldo Nascimento <[email protected]>
[ Upstream commit 114b06ee108cabc82b995fbac6672230a9776936 ]
Rockchip controllers can support up to 5.0 GT/s link speed. But the driver doesn't set the Target Link Speed currently. This may cause failure in retraining the link to 5.0 GT/s if supported by the endpoint. So set the Target Link Speed to 5.0 GT/s in the Link Control and Status Register 2.
--- drivers/pci/controller/pcie-rockchip-host.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/pci/controller/pcie-rockchip-host.c +4 -0
@@ -342,6 +342,10 @@ static int rockchip_pcie_host_init_port(* Enable retrain for gen2. This should be configured only after * gen1 finished. */ + status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL2 ); + status &= ~PCI_EXP_LNKCTL2_TLS ; + status |=PCI_EXP_LNKCTL2_TLS_5_0GT ; +rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL2 ); status =rockchip_pcie_read (rockchip,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL ); status |=PCI_EXP_LNKCTL_RL ;rockchip_pcie_write (rockchip, status,PCIE_RC_CONFIG_CR +PCI_EXP_LNKCTL );
Greg Kroah-Hartman
maintainerPATCH 197/322 iio: adc: ad7173: fix setting ODR in probe
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
[ Upstream commit 6fa908abd19cc35c205f343b79c67ff38dbc9b76 ]
Fix the setting of the ODR register value in the probe function for AD7177. The AD7177 chip has a different ODR value after reset than the other chips (0x7 vs. 0x0) and 0 is a reserved value on that chip.
The driver already has this information available in odr_start_value and uses it when checking valid values when writing to the sampling_frequency attribute, but failed to set the correct initial value in the probe function.
--- drivers/iio/adc/ad7173.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/iio/adc/ad7173.c +2 -1
@@ -1243,6 +1243,7 @@ static int ad7173_fw_parse_channel_confi chan_st_priv->cfg.bipolar = false; chan_st_priv->cfg.input_buf = st->info->has_input_buf; chan_st_priv->cfg.ref_sel =AD7173_SETUP_REF_SEL_INT_REF ; + chan_st_priv->cfg.odr = st->info->odr_start_value; st->adc_mode |=AD7173_ADC_MODE_REF_EN ; chan_index++;
@@ -1307,7 +1308,7 @@ static int ad7173_fw_parse_channel_confi chan->channel = ain[0 ]; chan_st_priv->chan_reg = chan_index; chan_st_priv->cfg.input_buf = st->info->has_input_buf; - chan_st_priv->cfg.odr =0 ; + chan_st_priv->cfg.odr = st->info->odr_start_value; chan_st_priv->cfg.bipolar =fwnode_property_read_bool (child,"bipolar" );if (chan_st_priv->cfg.bipolar)
Greg Kroah-Hartman
maintainerPATCH 198/322 scsi: mpi3mr: Drop unnecessary volatile from __iomem pointers
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranjan Kumar <[email protected]>
[ Upstream commit 6853885b21cb1d7157cc14c9d30cc17141565bae ]
The volatile qualifier is redundant for __iomem pointers.
Cleaned up usage in mpi3mr_writeq() and sysif_regs pointer as per Upstream compliance.
Stable-dep-of: c91e140c82eb ("scsi: mpi3mr: Serialize admin queue BAR writes on 32-bit systems")
--- drivers/scsi/mpi3mr/mpi3mr.h | 2 +- drivers/scsi/mpi3mr/mpi3mr_fw.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/scsi/mpi3mr/mpi3mr.h +1 -1
@@ -1175,7 +1175,7 @@ struct mpi3mr_ioc {char name[MPI3MR_NAME_LENGTH ];char driver_name[MPI3MR_NAME_LENGTH ]; -volatile struct mpi3_sysif_registers __iomem *sysif_regs; +struct mpi3_sysif_registers __iomem *sysif_regs;resource_size_t sysif_regs_phys;int bars;u64 dma_mask;
drivers/scsi/mpi3mr/mpi3mr_fw.c +2 -2
@@ -23,12 +23,12 @@ module_param(poll_queues, int, 0444);MODULE_PARM_DESC (poll_queues,"Number of queues for io_uring poll mode. (Range 1 - 126)" );#if defined(writeq) && defined(CONFIG_64BIT ) -static inline void mpi3mr_writeq (__u64 b,volatile void __iomem *addr) +static inline void mpi3mr_writeq (__u64 b,void __iomem *addr) {writeq (b, addr); }#else -static inline void mpi3mr_writeq (__u64 b,volatile void __iomem *addr) +static inline void mpi3mr_writeq (__u64 b,void __iomem *addr) {__u64 data_out = b;
Greg Kroah-Hartman
maintainerPATCH 199/322 scsi: mpi3mr: Serialize admin queue BAR writes on 32-bit systems
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranjan Kumar <[email protected]>
[ Upstream commit c91e140c82eb58724c435f623702e51cc7896646 ]
On 32-bit systems, 64-bit BAR writes to admin queue registers are performed as two 32-bit writes. Without locking, this can cause partial writes when accessed concurrently.
Updated per-queue spinlocks is used to serialize these writes and prevent race conditions.
--- drivers/scsi/mpi3mr/mpi3mr.h | 4 ++++ drivers/scsi/mpi3mr/mpi3mr_fw.c | 15 +++++++++++---- drivers/scsi/mpi3mr/mpi3mr_os.c | 2 ++ 3 files changed, 17 insertions(+), 4 deletions(-)
drivers/scsi/mpi3mr/mpi3mr.h +4 -0
@@ -1131,6 +1131,8 @@ struct scmd_priv {* @logdata_buf: Circular buffer to store log data entries * @logdata_buf_idx: Index of entry in buffer to store * @logdata_entry_sz: log data entry size +* @adm_req_q_bar_writeq_lock: Admin request queue lock +* @adm_reply_q_bar_writeq_lock: Admin reply queue lock * @pend_large_data_sz: Counter to track pending large data * @io_throttle_data_length: I/O size to track in 512b blocks * @io_throttle_high: I/O size to start throttle in 512b blocks
@@ -1328,6 +1330,8 @@ struct mpi3mr_ioc {u8 *logdata_buf;u16 logdata_buf_idx;u16 logdata_entry_sz; +spinlock_t adm_req_q_bar_writeq_lock; +spinlock_t adm_reply_q_bar_writeq_lock;atomic_t pend_large_data_sz;u32 io_throttle_data_length;
drivers/scsi/mpi3mr/mpi3mr_fw.c +11 -4
@@ -23,17 +23,22 @@ module_param(poll_queues, int, 0444);MODULE_PARM_DESC (poll_queues,"Number of queues for io_uring poll mode. (Range 1 - 126)" );#if defined(writeq) && defined(CONFIG_64BIT ) -static inline void mpi3mr_writeq (__u64 b,void __iomem *addr) +static inline void mpi3mr_writeq (__u64 b,void __iomem *addr, +spinlock_t *write_queue_lock) {writeq (b, addr); }#else -static inline void mpi3mr_writeq (__u64 b,void __iomem *addr) +static inline void mpi3mr_writeq (__u64 b,void __iomem *addr, +spinlock_t *write_queue_lock) {__u64 data_out = b; +unsigned long flags; +spin_lock_irqsave (write_queue_lock, flags);writel ((u32)(data_out), addr);writel ((u32)(data_out >>32 ), (addr +4 )); +spin_unlock_irqrestore (write_queue_lock, flags); }#endif
@@ -2931,9 +2936,11 @@ static int mpi3mr_setup_admin_qpair(stru (mrioc->num_admin_req);writel (num_admin_entries, &mrioc->sysif_regs->admin_queue_num_entries);mpi3mr_writeq (mrioc->admin_req_dma, - &mrioc->sysif_regs->admin_request_queue_address); + &mrioc->sysif_regs->admin_request_queue_address, + &mrioc->adm_req_q_bar_writeq_lock);mpi3mr_writeq (mrioc->admin_reply_dma, - &mrioc->sysif_regs->admin_reply_queue_address); + &mrioc->sysif_regs->admin_reply_queue_address, + &mrioc->adm_reply_q_bar_writeq_lock);writel (mrioc->admin_req_pi, &mrioc->sysif_regs->admin_request_queue_pi);writel (mrioc->admin_reply_ci, &mrioc->sysif_regs->admin_reply_queue_ci);return retval;
drivers/scsi/mpi3mr/mpi3mr_os.c +2 -0
@@ -5251,6 +5251,8 @@ mpi3mr_probe(struct pci_dev *pdev, constspin_lock_init (&mrioc->tgtdev_lock);spin_lock_init (&mrioc->watchdog_lock);spin_lock_init (&mrioc->chain_buf_lock); +spin_lock_init (&mrioc->adm_req_q_bar_writeq_lock); +spin_lock_init (&mrioc->adm_reply_q_bar_writeq_lock);spin_lock_init (&mrioc->sas_node_lock);spin_lock_init (&mrioc->trigger_lock);
Greg Kroah-Hartman
maintainerPATCH 200/322 ext4: preserve SB_I_VERSION on remount
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
[ Upstream commit f2326fd14a224e4cccbab89e14c52279ff79b7ec ]
IMA testing revealed that after an ext4 remount, file accesses triggered full measurements even without modifications, instead of skipping as expected when i_version is unchanged.
Debugging showed SB_I_VERSION was cleared in reconfigure_super() during remount due to commit 1ff20307393e ("ext4: unconditionally enable the i_version counter") removing the fix from commit 960e0ab63b2e ("ext4: fix i_version handling on remount").
To rectify this, SB_I_VERSION is always set for fc->sb_flags in ext4_init_fs_context(), instead of sb->s_flags in __ext4_fill_super(), ensuring it persists across all mounts.
--- fs/ext4/super.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/ext4/super.c +3 -3
@@ -2019,6 +2019,9 @@ int ext4_init_fs_context(struct fs_conte fc->fs_private = ctx; fc->ops = &ext4_context_ops; +/* i_version is always enabled now */ + fc->sb_flags |=SB_I_VERSION ; +return 0 ; }
@@ -5277,9 +5280,6 @@ static int __ext4_fill_super(struct fs_c sb->s_flags = (sb->s_flags & ~SB_POSIXACL ) | (test_opt (sb,POSIX_ACL ) ?SB_POSIXACL :0 ); -/* i_version is always enabled now */ - sb->s_flags |=SB_I_VERSION ; - err =ext4_check_feature_compatibility (sb, es, silent);if (err) goto failed_mount;
Greg Kroah-Hartman
maintainerPATCH 201/322 btrfs: subpage: keep TOWRITE tag until folio is cleaned
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naohiro Aota <[email protected]>
[ Upstream commit b1511360c8ac882b0c52caa263620538e8d73220 ]
btrfs_subpage_set_writeback() calls folio_start_writeback() the first time a folio is written back, and it also clears the PAGECACHE_TAG_TOWRITE tag even if there are still dirty blocks in the folio. This can break ordering guarantees, such as those required by btrfs_wait_ordered_extents().
That ordering breakage leads to a real failure. For example, running generic/464 on a zoned setup will hit the following ASSERT. This happens because the broken ordering fails to flush existing dirty pages before the file size is truncated.
assertion failed: !list_empty(&ordered->list) :: 0, in fs/btrfs/zoned.c:1899
------------[ cut here ]------------ kernel BUG at fs/btrfs/zoned.c:1899! Oops: invalid opcode: 0000 [#1] SMP NOPTI CPU: 2 UID: 0 PID: 1906169 Comm: kworker/u130:2 Kdump: loaded Not tainted 6.16.0-rc6-BTRFS-ZNS+ #554 PREEMPT(voluntary) Hardware name: Supermicro Super Server/H12SSL-NT, BIOS 2.0 02/22/2021 Workqueue: btrfs-endio-write btrfs_work_helper [btrfs] RIP: 0010:btrfs_finish_ordered_zoned.cold+0x50/0x52 [btrfs] RSP: 0018:ffffc9002efdbd60 EFLAGS: 00010246 RAX: 000000000000004c RBX: ffff88811923c4e0 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffff827e38b1 RDI: 00000000ffffffff RBP: ffff88810005d000 R08: 00000000ffffdfff R09: ffffffff831051c8 R10: ffffffff83055220 R11: 0000000000000000 R12: ffff8881c2458c00 R13: ffff88811923c540 R14: ffff88811923c5e8 R15: ffff8881c1bd9680 FS: 0000000000000000(0000) GS:ffff88a04acd0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f907c7a918c CR3: 0000000004024000 CR4: 0000000000350ef0 Call Trace: <TASK> ? srso_return_thunk+0x5/0x5f btrfs_finish_ordered_io+0x4a/0x60 [btrfs] btrfs_work_helper+0xf9/0x490 [btrfs] process_one_work+0x204/0x590 ? srso_return_thunk+0x5/0x5f worker_thread+0x1d6/0x3d0 ? __pfx_worker_thread+0x10/0x10 kthread+0x118/0x230 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x205/0x260 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK>
Consider process A calling writepages() with WB_SYNC_NONE. In zoned mode or for compressed writes, it locks several folios for delalloc and starts writing them out. Let's call the last locked folio folio X. Suppose the write range only partially covers folio X, leaving some pages dirty. Process A calls btrfs_subpage_set_writeback() when building a bio. This function call clears the TOWRITE tag of folio X, whose size = 8K and the block size = 4K. It is following state.
0 4K 8K |/////|/////| (flag: DIRTY, tag: DIRTY)
<-----> Process A will write this range.
Now suppose process B concurrently calls writepages() with WB_SYNC_ALL. It calls tag_pages_for_writeback() to tag dirty folios with PAGECACHE_TAG_TOWRITE. Since folio X is still dirty, it gets tagged. Then, B collects tagged folios using filemap_get_folios_tag() and must wait for folio X to be written before returning from writepages().
0 4K 8K |/////|/////| (flag: DIRTY, tag: DIRTY|TOWRITE)
However, between tagging and collecting, process A may call btrfs_subpage_set_writeback() and clear folio X's TOWRITE tag.
0 4K 8K | |/////| (flag: DIRTY|WRITEBACK, tag: DIRTY)
As a result, process B won't see folio X in its batch, and returns without waiting for it. This breaks the WB_SYNC_ALL ordering requirement.
Fix this by using btrfs_subpage_set_writeback_keepwrite(), which retains the TOWRITE tag. We now manually clear the tag only after the folio becomes clean, via the xas operation.
--- fs/btrfs/subpage.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
fs/btrfs/subpage.c +18 -1
@@ -452,8 +452,25 @@ void btrfs_subpage_set_writeback(const sspin_lock_irqsave (&subpage->lock, flags);bitmap_set (subpage->bitmaps, start_bit, len >> fs_info->sectorsize_bits); + +/* +* Don't clear the TOWRITE tag when starting writeback on a still-dirty +* folio. Doing so can cause WB_SYNC_ALL writepages() to overlook it, +* assume writeback is complete, and exit too early — violating sync +* ordering guarantees. +*/ if (!folio_test_writeback (folio)) -folio_start_writeback (folio); +__folio_start_writeback (folio, true); +if (!folio_test_dirty (folio)) { +struct address_space *mapping =folio_mapping (folio); +XA_STATE (xas, &mapping->i_pages, folio->index); +unsigned long flags; + +xas_lock_irqsave (&xas, flags); +xas_load (&xas); +xas_clear_mark (&xas,PAGECACHE_TAG_TOWRITE ); +xas_unlock_irqrestore (&xas, flags); + }spin_unlock_irqrestore (&subpage->lock, flags); }
Greg Kroah-Hartman
maintainerPATCH 202/322 arm64: dts: ti: k3-am6*: Add boot phase flag to support MMC boot
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Judith Mendez <[email protected]>
[ Upstream commit db3cd905b8c8cd40f15a34e30a225704bb8a2fcb ]
The bootph-all flag was introduced in dt-schema (dtschema/schemas/bootph.yaml) to define node usage across different boot phases.
For eMMC and SD boot modes, voltage regulator nodes, io-expander nodes, gpio nodes, and MMC nodes need to be present in all boot stages, so add missing bootph-all phase flag to these nodes to support SD boot and eMMC boot.
Stable-dep-of: a0b8da04153e ("arm64: dts: ti: k3-am62*: Move eMMC pinmux to top level board file")
--- arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts | 12 ++++++++++++ arch/arm64/boot/dts/ti/k3-am62a7-sk.dts | 2 ++ 2 files changed, 14 insertions(+)
arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts +12 -0
@@ -69,6 +69,7 @@ gpios = <&main_gpio0 31 GPIO_ACTIVE_HIGH>; states = <1800000 0x0>, <3300000 0x1>; + bootph-all; }; };
@@ -77,12 +78,14 @@ pinctrl-single,pins = < AM62X_IOPAD(0x07c, PIN_OUTPUT, 7) /* (M19) GPMC0_CLK.GPIO0_31 */ >; + bootph-all; }; main_gpio1_ioexp_intr_pins_default: main-gpio1-ioexp-intr-default-pins { pinctrl-single,pins = < AM62X_IOPAD(0x01d4, PIN_INPUT, 7) /* (C13) UART0_RTSn.GPIO1_23 */ >; + bootph-all; }; pmic_irq_pins_default: pmic-irq-default-pins {
@@ -118,6 +121,7 @@ pinctrl-names = "default"; pinctrl-0 = <&main_gpio1_ioexp_intr_pins_default>; + bootph-all; }; exp2: gpio@23 {
@@ -229,6 +233,14 @@ DVDD-supply = <&buck2_reg>; }; +&main_gpio0 { + bootph-all; +}; + +&main_gpio1 { + bootph-all; +}; + &gpmc0 { ranges = <0 0 0x00 0x51000000 0x01000000>; /* CS0 space. Min partition = 16MB */ };
arch/arm64/boot/dts/ti/k3-am62a7-sk.dts +2 -0
@@ -301,6 +301,7 @@ AM62AX_IOPAD(0x1fc, PIN_INPUT_PULLUP, 0) /* (AD2) MMC0_DAT6 */ AM62AX_IOPAD(0x1f8, PIN_INPUT_PULLUP, 0) /* (AC2) MMC0_DAT7 */ >; + bootph-all; }; main_mmc1_pins_default: main-mmc1-default-pins {
@@ -603,6 +604,7 @@ pinctrl-names = "default"; pinctrl-0 = <&main_mmc0_pins_default>; disable-wp; + bootph-all; }; &sdhci1 {
Greg Kroah-Hartman
maintainerPATCH 203/322 arm64: dts: ti: k3-am62*: Add non-removable flag for eMMC
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Judith Mendez <[email protected]>
[ Upstream commit d16e7d34352c4107a81888e9aab4ea4748076e70 ]
EMMC device is non-removable so add 'non-removable' DT property to avoid having to redetect the eMMC after suspend/resume.
Stable-dep-of: a0b8da04153e ("arm64: dts: ti: k3-am62*: Move eMMC pinmux to top level board file")
--- arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 1 + arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 1 + arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi | 1 + 3 files changed, 3 insertions(+)
arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts +1 -0
@@ -818,6 +818,7 @@ &sdhci0 { bootph-all; + non-removable; pinctrl-names = "default"; pinctrl-0 = <&emmc_pins_default>; disable-wp;
arch/arm64/boot/dts/ti/k3-am62p5-sk.dts +1 -0
@@ -444,6 +444,7 @@ &sdhci0 { status = "okay"; + non-removable; ti,driver-strength-ohm = <50>; disable-wp; bootph-all;
arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi +1 -0
@@ -416,6 +416,7 @@ &sdhci0 { bootph-all; status = "okay"; + non-removable; pinctrl-names = "default"; pinctrl-0 = <&main_mmc0_pins_default>; disable-wp;
Greg Kroah-Hartman
maintainerPATCH 204/322 arm64: dts: ti: k3-am6*: Remove disable-wp for eMMC
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Judith Mendez <[email protected]>
[ Upstream commit ef839ba8142f14513ba396a033110526b7008096 ]
Remove disable-wp flag for eMMC nodes since this flag is only applicable to SD according to the binding doc (mmc/mmc-controller-common.yaml).
For eMMC, this flag should be ignored but lets remove anyways to cleanup sdhci nodes.
Stable-dep-of: a0b8da04153e ("arm64: dts: ti: k3-am62*: Move eMMC pinmux to top level board file")
--- arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi | 1 - arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 1 - arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi | 1 - arch/arm64/boot/dts/ti/k3-am62a7-sk.dts | 1 - arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 1 - arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi | 1 - arch/arm64/boot/dts/ti/k3-am642-evm.dts | 1 - arch/arm64/boot/dts/ti/k3-am654-base-board.dts | 1 - arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi | 1 - arch/arm64/boot/dts/ti/k3-am69-sk.dts | 1 - 10 files changed, 10 deletions(-)
arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi +0 -1
@@ -317,7 +317,6 @@ &sdhci0 { pinctrl-names = "default"; pinctrl-0 = <&main_mmc0_pins_default>; - disable-wp; non-removable; status = "okay"; };
arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts +0 -1
@@ -821,7 +821,6 @@ non-removable; pinctrl-names = "default"; pinctrl-0 = <&emmc_pins_default>; - disable-wp; status = "okay"; };
arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi +0 -1
@@ -324,7 +324,6 @@ &sdhci0 { pinctrl-names = "default"; pinctrl-0 = <&main_mmc0_pins_default>; - disable-wp; non-removable; status = "okay"; };
arch/arm64/boot/dts/ti/k3-am62a7-sk.dts +0 -1
@@ -603,7 +603,6 @@ non-removable; pinctrl-names = "default"; pinctrl-0 = <&main_mmc0_pins_default>; - disable-wp; bootph-all; };
arch/arm64/boot/dts/ti/k3-am62p5-sk.dts +0 -1
@@ -446,7 +446,6 @@ status = "okay"; non-removable; ti,driver-strength-ohm = <50>; - disable-wp; bootph-all; };
arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi +0 -1
@@ -419,7 +419,6 @@ non-removable; pinctrl-names = "default"; pinctrl-0 = <&main_mmc0_pins_default>; - disable-wp; }; &sdhci1 {
arch/arm64/boot/dts/ti/k3-am642-evm.dts +0 -1
@@ -584,7 +584,6 @@ status = "okay"; non-removable; ti,driver-strength-ohm = <50>; - disable-wp; bootph-all; };
arch/arm64/boot/dts/ti/k3-am654-base-board.dts +0 -1
@@ -456,7 +456,6 @@ bus-width = <8>; non-removable; ti,driver-strength-ohm = <50>; - disable-wp; }; /*
arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi +0 -1
@@ -50,5 +50,4 @@ bus-width = <8>; non-removable; ti,driver-strength-ohm = <50>; - disable-wp; };
arch/arm64/boot/dts/ti/k3-am69-sk.dts +0 -1
@@ -926,7 +926,6 @@ status = "okay"; non-removable; ti,driver-strength-ohm = <50>; - disable-wp; }; &main_sdhci1 {
Greg Kroah-Hartman
maintainerPATCH 205/322 arm64: dts: ti: k3-am62*: Move eMMC pinmux to top level board file
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Judith Mendez <[email protected]>
[ Upstream commit a0b8da04153eb61cc2eaeeea5cc404e91e557f6b ]
This moves pinmux child nodes for sdhci0 node from k3-am62x-sk-common to each top level board file. This is needed since we require internal pullups for AM62x SK and not for AM62 LP SK since it has external pullups on DATA 1-7.
Internal pulls are required for AM62 SK as per JESD84 spec recommendation to prevent unconnected lines floating.
--- arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts | 24 ++++++++++++++++++++++++ arch/arm64/boot/dts/ti/k3-am625-sk.dts | 24 ++++++++++++++++++++++++ arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi | 24 ------------------------ 3 files changed, 48 insertions(+), 24 deletions(-)
arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts +24 -0
@@ -74,6 +74,22 @@ }; &main_pmx0 { + main_mmc0_pins_default: main-mmc0-default-pins { + bootph-all; + pinctrl-single,pins = < + AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (V3) MMC0_CMD */ + AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (Y1) MMC0_CLK */ + AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (V2) MMC0_DAT0 */ + AM62X_IOPAD(0x210, PIN_INPUT, 0) /* (V1) MMC0_DAT1 */ + AM62X_IOPAD(0x20c, PIN_INPUT, 0) /* (W2) MMC0_DAT2 */ + AM62X_IOPAD(0x208, PIN_INPUT, 0) /* (W1) MMC0_DAT3 */ + AM62X_IOPAD(0x204, PIN_INPUT, 0) /* (Y2) MMC0_DAT4 */ + AM62X_IOPAD(0x200, PIN_INPUT, 0) /* (W3) MMC0_DAT5 */ + AM62X_IOPAD(0x1fc, PIN_INPUT, 0) /* (W4) MMC0_DAT6 */ + AM62X_IOPAD(0x1f8, PIN_INPUT, 0) /* (V4) MMC0_DAT7 */ + >; + }; + vddshv_sdio_pins_default: vddshv-sdio-default-pins { pinctrl-single,pins = < AM62X_IOPAD(0x07c, PIN_OUTPUT, 7) /* (M19) GPMC0_CLK.GPIO0_31 */
@@ -144,6 +160,14 @@ }; }; +&sdhci0 { + bootph-all; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&main_mmc0_pins_default>; + status = "okay"; +}; + &sdhci1 { vmmc-supply = <&vdd_mmc1>; vqmmc-supply = <&vddshv_sdio>;
arch/arm64/boot/dts/ti/k3-am625-sk.dts +24 -0
@@ -106,6 +106,22 @@ }; &main_pmx0 { + main_mmc0_pins_default: main-mmc0-default-pins { + bootph-all; + pinctrl-single,pins = < + AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */ + AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLK */ + AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */ + AM62X_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AA1) MMC0_DAT1 */ + AM62X_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (AA3) MMC0_DAT2 */ + AM62X_IOPAD(0x208, PIN_INPUT_PULLUP, 0) /* (Y4) MMC0_DAT3 */ + AM62X_IOPAD(0x204, PIN_INPUT_PULLUP, 0) /* (AB2) MMC0_DAT4 */ + AM62X_IOPAD(0x200, PIN_INPUT_PULLUP, 0) /* (AC1) MMC0_DAT5 */ + AM62X_IOPAD(0x1fc, PIN_INPUT_PULLUP, 0) /* (AD2) MMC0_DAT6 */ + AM62X_IOPAD(0x1f8, PIN_INPUT_PULLUP, 0) /* (AC2) MMC0_DAT7 */ + >; + }; + main_rgmii2_pins_default: main-rgmii2-default-pins { bootph-all; pinctrl-single,pins = <
@@ -195,6 +211,14 @@ }; }; +&sdhci0 { + bootph-all; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&main_mmc0_pins_default>; + status = "okay"; +}; + &sdhci1 { vmmc-supply = <&vdd_mmc1>; vqmmc-supply = <&vdd_sd_dv>;
arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi +0 -24
@@ -182,22 +182,6 @@ >; }; - main_mmc0_pins_default: main-mmc0-default-pins { - bootph-all; - pinctrl-single,pins = < - AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (Y3/V3) MMC0_CMD */ - AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (AB1/Y1) MMC0_CLK */ - AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (AA2/V2) MMC0_DAT0 */ - AM62X_IOPAD(0x210, PIN_INPUT, 0) /* (AA1/V1) MMC0_DAT1 */ - AM62X_IOPAD(0x20c, PIN_INPUT, 0) /* (AA3/W2) MMC0_DAT2 */ - AM62X_IOPAD(0x208, PIN_INPUT, 0) /* (Y4/W1) MMC0_DAT3 */ - AM62X_IOPAD(0x204, PIN_INPUT, 0) /* (AB2/Y2) MMC0_DAT4 */ - AM62X_IOPAD(0x200, PIN_INPUT, 0) /* (AC1/W3) MMC0_DAT5 */ - AM62X_IOPAD(0x1fc, PIN_INPUT, 0) /* (AD2/W4) MMC0_DAT6 */ - AM62X_IOPAD(0x1f8, PIN_INPUT, 0) /* (AC2/V4) MMC0_DAT7 */ - >; - }; - main_mmc1_pins_default: main-mmc1-default-pins { bootph-all; pinctrl-single,pins = <
@@ -413,14 +397,6 @@ clock-frequency = <400000>; }; -&sdhci0 { - bootph-all; - status = "okay"; - non-removable; - pinctrl-names = "default"; - pinctrl-0 = <&main_mmc0_pins_default>; -}; - &sdhci1 { /* SD/MMC */ bootph-all;
Greg Kroah-Hartman
maintainerPATCH 206/322 debugfs: fix mount options not being applied
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charalampos Mitrodimas <[email protected]>
commit ba6cc29351b1fa0cb9adce91b88b9f3c3cbe9c46 upstream.
Mount options (uid, gid, mode) are silently ignored when debugfs is mounted. This is a regression introduced during the conversion to the new mount API.
When the mount API conversion was done, the parsed options were never applied to the superblock when it was reused. As a result, the mount options were ignored when debugfs was mounted.
Fix this by following the same pattern as the tracefs fix in commit e4d32142d1de ("tracing: Fix tracefs mount options"). Call debugfs_reconfigure() in debugfs_get_tree() to apply the mount options to the superblock after it has been created or reused.
As an example, with the bug the "mode" mount option is ignored:
$ mount -o mode=0666 -t debugfs debugfs /tmp/debugfs_test $ mount | grep debugfs_test debugfs on /tmp/debugfs_test type debugfs (rw,relatime) $ ls -ld /tmp/debugfs_test drwx------ 25 root root 0 Aug 4 14:16 /tmp/debugfs_test
With the fix applied, it works as expected:
$ mount -o mode=0666 -t debugfs debugfs /tmp/debugfs_test $ mount | grep debugfs_test debugfs on /tmp/debugfs_test type debugfs (rw,relatime,mode=666) $ ls -ld /tmp/debugfs_test drw-rw-rw- 37 root root 0 Aug 2 17:28 /tmp/debugfs_test
--- fs/debugfs/inode.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
fs/debugfs/inode.c +10 -1
@@ -183,6 +183,9 @@ static int debugfs_reconfigure(struct fsstruct debugfs_fs_info *sb_opts = sb->s_fs_info;struct debugfs_fs_info *new_opts = fc->s_fs_info; +if (!new_opts) +return 0 ; +sync_filesystem (sb);/* structure copy of new mount options to sb */
@@ -269,10 +272,16 @@ static int debugfs_fill_super(struct supstatic int debugfs_get_tree (struct fs_context *fc) { +int err; +if (!(debugfs_allow &DEBUGFS_ALLOW_API ))return -EPERM ; -return get_tree_single (fc, debugfs_fill_super); + err =get_tree_single (fc, debugfs_fill_super); +if (err) +return err; + +return debugfs_reconfigure (fc); }static void debugfs_free_fc (struct fs_context *fc)
Greg Kroah-Hartman
maintainerPATCH 207/322 smb: server: split ksmbd_rdma_stop_listening() out of ksmbd_rdma_destroy()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Metzmacher <[email protected]>
[ Upstream commit bac7b996d42e458a94578f4227795a0d4deef6fa ]
We can't call destroy_workqueue(smb_direct_wq); before stop_sessions()!
Otherwise already existing connections try to use smb_direct_wq as a NULL pointer.
--- fs/smb/server/connection.c | 3 ++- fs/smb/server/transport_rdma.c | 5 ++++- fs/smb/server/transport_rdma.h | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-)
fs/smb/server/connection.c +2 -1
@@ -503,7 +503,8 @@ void ksmbd_conn_transport_destroy(void) {mutex_lock (&init_lock);ksmbd_tcp_destroy (); -ksmbd_rdma_destroy (); +ksmbd_rdma_stop_listening ();stop_sessions (); +ksmbd_rdma_destroy ();mutex_unlock (&init_lock); }
fs/smb/server/transport_rdma.c +4 -1
@@ -2193,7 +2193,7 @@ int ksmbd_rdma_init(void)return 0 ; } -void ksmbd_rdma_destroy (void ) +void ksmbd_rdma_stop_listening (void ) {if (!smb_direct_listener.cm_id)return ;
@@ -2202,7 +2202,10 @@ void ksmbd_rdma_destroy(void)rdma_destroy_id (smb_direct_listener.cm_id); smb_direct_listener.cm_id =NULL ; +} +void ksmbd_rdma_destroy (void ) +{if (smb_direct_wq) {destroy_workqueue (smb_direct_wq); smb_direct_wq =NULL ;
fs/smb/server/transport_rdma.h +3 -1
@@ -54,13 +54,15 @@ struct smb_direct_data_transfer {#ifdef CONFIG_SMB_SERVER_SMBDIRECT int ksmbd_rdma_init (void ); +void ksmbd_rdma_stop_listening (void );void ksmbd_rdma_destroy (void );bool ksmbd_rdma_capable_netdev (struct net_device *netdev);void init_smbd_max_io_size (unsigned int sz);unsigned int get_smbd_max_read_write_size (void );#else static inline int ksmbd_rdma_init (void ) {return 0 ; } -static inline int ksmbd_rdma_destroy (void ) {return 0 ; } +static inline void ksmbd_rdma_stop_listening (void ) { } +static inline void ksmbd_rdma_destroy (void ) { }static inline bool ksmbd_rdma_capable_netdev (struct net_device *netdev) {return false; }static inline void init_smbd_max_io_size (unsigned int sz) { }static inline unsigned int get_smbd_max_read_write_size (void ) {return 0 ; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 208/322 fs/buffer: fix use-after-free when call bh_read() helper
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Bin <[email protected]>
[ Upstream commit 7375f22495e7cd1c5b3b5af9dcc4f6dffe34ce49 ]
There's issue as follows:
BUG: KASAN: stack-out-of-bounds in end_buffer_read_sync+0xe3/0x110 Read of size 8 at addr ffffc9000168f7f8 by task swapper/3/0 CPU: 3 UID: 0 PID: 0 Comm: swapper/3 Not tainted 6.16.0-862.14.0.6.x86_64 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) Call Trace: <IRQ> dump_stack_lvl+0x55/0x70 print_address_description.constprop.0+0x2c/0x390 print_report+0xb4/0x270 kasan_report+0xb8/0xf0 end_buffer_read_sync+0xe3/0x110 end_bio_bh_io_sync+0x56/0x80 blk_update_request+0x30a/0x720 scsi_end_request+0x51/0x2b0 scsi_io_completion+0xe3/0x480 ? scsi_device_unbusy+0x11e/0x160 blk_complete_reqs+0x7b/0x90 handle_softirqs+0xef/0x370 irq_exit_rcu+0xa5/0xd0 sysvec_apic_timer_interrupt+0x6e/0x90 </IRQ>
Above issue happens when do ntfs3 filesystem mount, issue may happens as follows:
mount IRQntfs_fill_super
read_cache_page
do_read_cache_folio
filemap_read_folio
mpage_read_folio
do_mpage_readpage
ntfs_get_block_vbo
bh_read
submit_bh
wait_on_buffer(bh);
blk_complete_reqs
scsi_io_completion
scsi_end_request
blk_update_request
end_bio_bh_io_sync
end_buffer_read_sync
__end_buffer_read_notouch
unlock_buffer
wait_on_buffer(bh);--> return will return to caller
put_bh
--> trigger stack-out-of-boundsIn the mpage_read_folio() function, the stack variable 'map_bh' is passed to ntfs_get_block_vbo(). Once unlock_buffer() unlocks and wait_on_buffer() returns to continue processing, the stack variable is likely to be reclaimed. Consequently, during the end_buffer_read_sync() process, calling put_bh() may result in stack overrun.
If the bh is not allocated on the stack, it belongs to a folio. Freeing a buffer head which belongs to a folio is done by drop_buffers() which will fail to free buffers which are still locked. So it is safe to call put_bh() before __end_buffer_read_notouch().
--- fs/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/buffer.c +1 -1
@@ -157,8 +157,8 @@ static void __end_buffer_read_notouch(struct buffer_head *bh, int uptodate)*/ void end_buffer_read_sync (struct buffer_head *bh,int uptodate) { -__end_buffer_read_notouch (bh, uptodate);put_bh (bh); +__end_buffer_read_notouch (bh, uptodate); }EXPORT_SYMBOL (end_buffer_read_sync);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 209/322 use uniform permission checks for all mount propagation changes
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
[ Upstream commit cffd0441872e7f6b1fce5e78fb1c99187a291330 ]
do_change_type() and do_set_group() are operating on different aspects of the same thing - propagation graph. The latter asks for mounts involved to be mounted in namespace(s) the caller has CAP_SYS_ADMIN for. The former is a mess - originally it didn't even check that mount *is* mounted. That got fixed, but the resulting check turns out to be too strict for userland - in effect, we check that mount is in our namespace, having already checked that we have CAP_SYS_ADMIN there.
What we really need (in both cases) is
* only touch mounts that are mounted. That's a must-have
constraint - data corruption happens if it get violated.
* don't allow to mess with a namespace unless you already
have enough permissions to do so (i.e. CAP_SYS_ADMIN in its userns).
That's an equivalent of what do_set_group() does; let's extract that into a helper (may_change_propagation()) and use it in both do_set_group() and do_change_type().
--- fs/namespace.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-)
fs/namespace.c +20 -14
@@ -2683,6 +2683,19 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)return attach_recursive_mnt (mnt, p, mp,0 ); } +static int may_change_propagation (const struct mount *m) +{ +struct mnt_namespace *ns = m->mnt_ns; + +// it must be mounted in some namespace +if (IS_ERR_OR_NULL (ns))// is_mounted() +return -EINVAL ; +// and the caller must be admin in userns of that namespace +if (!ns_capable (ns->user_ns,CAP_SYS_ADMIN )) +return -EPERM ; +return 0 ; +} +/* * Sanity check the flags to change_mnt_propagation. */
@@ -2719,10 +2732,10 @@ static int do_change_type(struct path *path, int ms_flags)return -EINVAL ;namespace_lock (); -if (!check_mnt (mnt)) { - err = -EINVAL ; + err =may_change_propagation (mnt); +if (err) goto out_unlock; - } +if (type ==MS_SHARED ) { err =invent_group_ids (mnt, recurse);if (err)
@@ -3116,18 +3129,11 @@ static int do_set_group(struct path *from_path, struct path *to_path)namespace_lock (); - err = -EINVAL ; -/* To and From must be mounted */ -if (!is_mounted (&from->mnt)) - goto out; -if (!is_mounted (&to->mnt)) - goto out; - - err = -EPERM ; -/* We should be allowed to modify mount namespaces of both mounts */ -if (!ns_capable (from->mnt_ns->user_ns,CAP_SYS_ADMIN )) + err =may_change_propagation (from); +if (err) goto out; -if (!ns_capable (to->mnt_ns->user_ns,CAP_SYS_ADMIN )) + err =may_change_propagation (to); +if (err) goto out; err = -EINVAL ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 210/322 cpuidle: menu: Remove iowait influence
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Loehle <[email protected]>
[ Upstream commit 38f83090f515b4b5d59382dfada1e7457f19aa47 ]
Remove CPU iowaiters influence on idle state selection.
Remove the menu notion of performance multiplier which increased with the number of tasks that went to iowait sleep on this CPU and haven't woken up yet.
Relying on iowait for cpuidle is problematic for a few reasons:
1. There is no guarantee that an iowaiting task will wake up on the same CPU.
2. The task being in iowait says nothing about the idle duration, we could be selecting shallower states for a long time.
3. The task being in iowait doesn't always imply a performance hit with increased latency.
4. If there is such a performance hit, the number of iowaiting tasks doesn't directly correlate.
5. The definition of iowait altogether is vague at best, it is sprinkled across kernel code.
Stable-dep-of: 779b1a1cb13a ("cpuidle: governors: menu: Avoid selecting states with too much latency")
--- drivers/cpuidle/governors/menu.c | 76 ++++----------------------------------- 1 file changed, 9 insertions(+), 67 deletions(-)
drivers/cpuidle/governors/menu.c +9 -67
@@ -19,7 +19,7 @@#include "gov.h" -#define BUCKETS 12 +#define BUCKETS 6#define INTERVAL_SHIFT 3#define INTERVALS (1UL << INTERVAL_SHIFT)#define RESOLUTION 1024
@@ -29,12 +29,11 @@/* * Concepts and ideas behind the menu governor * -* For the menu governor, there are 3 decision factors for picking a C +* For the menu governor, there are 2 decision factors for picking a C * state: * 1) Energy break even point -* 2) Performance impact -* 3) Latency tolerance (from pmqos infrastructure) -* These three factors are treated independently. +* 2) Latency tolerance (from pmqos infrastructure) +* These two factors are treated independently. * * Energy break even point * -----------------------
@@ -75,30 +74,6 @@* intervals and if the stand deviation of these 8 intervals is below a * threshold value, we use the average of these intervals as prediction. * -* Limiting Performance Impact -* --------------------------- -* C states, especially those with large exit latencies, can have a real -* noticeable impact on workloads, which is not acceptable for most sysadmins, -* and in addition, less performance has a power price of its own. -* -* As a general rule of thumb, menu assumes that the following heuristic -* holds: -* The busier the system, the less impact of C states is acceptable -* -* This rule-of-thumb is implemented using a performance-multiplier: -* If the exit latency times the performance multiplier is longer than -* the predicted duration, the C state is not considered a candidate -* for selection due to a too high performance impact. So the higher -* this multiplier is, the longer we need to be idle to pick a deep C -* state, and thus the less likely a busy CPU will hit such a deep -* C state. -* -* Currently there is only one value determining the factor: -* 10 points are added for each process that is waiting for IO on this CPU. -* (This value was experimentally determined.) -* Utilization is no longer a factor as it was shown that it never contributed -* significantly to the performance multiplier in the first place. -* */ struct menu_device {
@@ -112,19 +87,10 @@ struct menu_device {int interval_ptr; }; -static inline int which_bucket (u64 duration_ns,unsigned int nr_iowaiters) +static inline int which_bucket (u64 duration_ns) {int bucket =0 ; -/* -* We keep two groups of stats; one with no -* IO pending, one without. -* This allows us to calculate -* E(duration)|iowait -*/ -if (nr_iowaiters) - bucket =BUCKETS /2 ; -if (duration_ns <10ULL *NSEC_PER_USEC )return bucket;if (duration_ns <100ULL *NSEC_PER_USEC )
@@ -138,19 +104,6 @@ static inline int which_bucket(u64 duratreturn bucket +5 ; } -/* -* Return a multiplier for the exit latency that is intended -* to take performance requirements into account. -* The more performance critical we estimate the system -* to be, the higher this multiplier, and thus the higher -* the barrier to go to an expensive C state. -*/ -static inline int performance_multiplier (unsigned int nr_iowaiters) -{ -/* for IO wait tasks (per cpu!) we add 10x each */ -return 1 +10 * nr_iowaiters; -} - static DEFINE_PER_CPU(struct menu_device, menu_devices);static void menu_update_intervals (struct menu_device *data,unsigned int interval_us)
@@ -277,8 +230,6 @@ static int menu_select(struct cpuidle_drstruct menu_device *data =this_cpu_ptr (&menu_devices);s64 latency_req =cpuidle_governor_latency_req (dev->cpu);u64 predicted_ns; -u64 interactivity_req; -unsigned int nr_iowaiters;ktime_t delta, delta_tick;int i, idx;
@@ -295,8 +246,6 @@ static int menu_select(struct cpuidle_drmenu_update_intervals (data,UINT_MAX ); } - nr_iowaiters =nr_iowait_cpu (dev->cpu); -/* Find the shortest expected idle interval. */ predicted_ns =get_typical_interval (data) *NSEC_PER_USEC ;if (predicted_ns >RESIDENCY_THRESHOLD_NS ) {
@@ -310,7 +259,7 @@ static int menu_select(struct cpuidle_dr } data->next_timer_ns = delta; - data->bucket =which_bucket (data->next_timer_ns, nr_iowaiters); + data->bucket =which_bucket (data->next_timer_ns);/* Round up the result for half microseconds. */ timer_us = div_u64((RESOLUTION * DECAY * NSEC_PER_USEC) / 2 +
@@ -328,7 +277,7 @@ static int menu_select(struct cpuidle_dr*/ data->next_timer_ns =KTIME_MAX ; delta_tick =TICK_NSEC /2 ; - data->bucket =which_bucket (KTIME_MAX , nr_iowaiters); + data->bucket =which_bucket (KTIME_MAX ); } if (unlikely(drv->state_count <= 1 || latency_req == 0) ||
@@ -355,15 +304,8 @@ static int menu_select(struct cpuidle_dr*/ if (predicted_ns <TICK_NSEC ) predicted_ns = data->next_timer_ns; - }else { -/* -* Use the performance multiplier and the user-configurable -* latency_req to determine the maximum exit latency. -*/ - interactivity_req =div64_u64 (predicted_ns, -performance_multiplier (nr_iowaiters)); -if (latency_req > interactivity_req) - latency_req = interactivity_req; + }else if (latency_req > predicted_ns) { + latency_req = predicted_ns; }/*
Greg Kroah-Hartman
maintainerPATCH 211/322 cpuidle: governors: menu: Avoid selecting states with too much latency
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Rafael J. Wysocki" <[email protected]>
[ Upstream commit 779b1a1cb13ae17028aeddb2fbbdba97357a1e15 ]
Occasionally, the exit latency of the idle state selected by the menu governor may exceed the PM QoS CPU wakeup latency limit. Namely, if the scheduler tick has been stopped already and predicted_ns is greater than the tick period length, the governor may return an idle state whose exit latency exceeds latency_req because that decision is made before checking the current idle state's exit latency.
For instance, say that there are 3 idle states, 0, 1, and 2. For idle states 0 and 1, the exit latency is equal to the target residency and the values are 0 and 5 us, respectively. State 2 is deeper and has the exit latency and target residency of 200 us and 2 ms (which is greater than the tick period length), respectively.
Say that predicted_ns is equal to TICK_NSEC and the PM QoS latency limit is 20 us. After the first two iterations of the main loop in menu_select(), idx becomes 1 and in the third iteration of it the target residency of the current state (state 2) is greater than predicted_ns. State 2 is not a polling one and predicted_ns is not less than TICK_NSEC, so the check on whether or not the tick has been stopped is done. Say that the tick has been stopped already and there are no imminent timers (that is, delta_tick is greater than the target residency of state 2). In that case, idx becomes 2 and it is returned immediately, but the exit latency of state 2 exceeds the latency limit.
Address this issue by modifying the code to compare the exit latency of the current idle state (idle state i) with the latency limit before comparing its target residency with predicted_ns, which allows one more exit_latency_ns check that becomes redundant to be dropped.
However, after the above change, latency_req cannot take the predicted_ns value any more, which takes place after commit 38f83090f515 ("cpuidle:
menu: Remove iowait influence"), because it may cause a polling state to be returned prematurely.
In the context of the previous example say that predicted_ns is 3000 and the PM QoS latency limit is still 20 us. Additionally, say that idle state 0 is a polling one. Moving the exit_latency_ns check before the target_residency_ns one causes the loop to terminate in the second iteration, before the target_residency_ns check, so idle state 0 will be returned even though previously state 1 would be returned if there were no imminent timers.
For this reason, remove the assignment of the predicted_ns value to latency_req from the code.
--- drivers/cpuidle/governors/menu.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-)
drivers/cpuidle/governors/menu.c +12 -17
@@ -293,20 +293,15 @@ static int menu_select(struct cpuidle_drreturn 0 ; } -if (tick_nohz_tick_stopped ()) { -/* -* If the tick is already stopped, the cost of possible short -* idle duration misprediction is much higher, because the CPU -* may be stuck in a shallow idle state for a long time as a -* result of it. In that case say we might mispredict and use -* the known time till the closest timer event for the idle -* state selection. -*/ -if (predicted_ns <TICK_NSEC ) - predicted_ns = data->next_timer_ns; - }else if (latency_req > predicted_ns) { - latency_req = predicted_ns; - } +/* +* If the tick is already stopped, the cost of possible short idle +* duration misprediction is much higher, because the CPU may be stuck +* in a shallow idle state for a long time as a result of it. In that +* case, say we might mispredict and use the known time till the closest +* timer event for the idle state selection. +*/ +if (tick_nohz_tick_stopped () && predicted_ns <TICK_NSEC ) + predicted_ns = data->next_timer_ns;/* * Find the idle state with the lowest power while satisfying
@@ -322,13 +317,15 @@ static int menu_select(struct cpuidle_drif (idx ==-1 ) idx = i;/* first enabled state */ +if (s->exit_latency_ns > latency_req) +break ; +if (s->target_residency_ns > predicted_ns) {/* * Use a physical idle state, not busy polling, unless * a timer is going to trigger soon enough. */ if ((drv->states[idx].flags &CPUIDLE_FLAG_POLLING ) && - s->exit_latency_ns <= latency_req && s->target_residency_ns <= data->next_timer_ns) { predicted_ns = s->target_residency_ns; idx = i;
@@ -360,8 +357,6 @@ static int menu_select(struct cpuidle_drreturn idx; } -if (s->exit_latency_ns > latency_req) -break ; idx = i; }
Greg Kroah-Hartman
maintainerPATCH 212/322 drm/dp: Change AUX DPCD probe address from DPCD_REV to LANE0_1_STATUS
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
[ Upstream commit a40c5d727b8111b5db424a1e43e14a1dcce1e77f ]
Reading DPCD registers has side-effects in general. In particular accessing registers outside of the link training register range (0x102-0x106, 0x202-0x207, 0x200c-0x200f, 0x2216) is explicitly forbidden by the DP v2.1 Standard, see
3.6.5.1 DPTX AUX Transaction Handling Mandates 3.6.7.4 128b/132b DP Link Layer LTTPR Link Training Mandates
Based on my tests, accessing the DPCD_REV register during the link training of an UHBR TBT DP tunnel sink leads to link training failures.
Solve the above by using the DP_LANE0_1_STATUS (0x202) register for the DPCD register access quirk.
--- drivers/gpu/drm/display/drm_dp_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/display/drm_dp_helper.c +1 -1
@@ -664,7 +664,7 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_a* monitor doesn't power down exactly after the throw away read. */ if (!aux->is_remote) { - ret =drm_dp_dpcd_probe (aux,DP_DPCD_REV ); + ret =drm_dp_dpcd_probe (aux,DP_LANE0_1_STATUS );if (ret <0 )return ret; }
Greg Kroah-Hartman
maintainerPATCH 213/322 mmc: sdhci_am654: Disable HS400 for AM62P SR1.0 and SR1.1
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Judith Mendez <[email protected]>
commit d2d7a96b29ea6ab093973a1a37d26126db70c79f upstream.
This adds SDHCI_AM654_QUIRK_DISABLE_HS400 quirk which shall be used to disable HS400 support. AM62P SR1.0 and SR1.1 do not support HS400 due to errata i2458 [0] so disable HS400 for these SoC revisions.
[0] https://www.ti.com/lit/er/sprz574a/sprz574a.pdf
--- drivers/mmc/host/sdhci_am654.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
drivers/mmc/host/sdhci_am654.c +18 -0
@@ -155,6 +155,7 @@ struct sdhci_am654_data {u32 tuning_loop;#define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0) +#define SDHCI_AM654_QUIRK_DISABLE_HS400 BIT(1) };struct window {
@@ -734,6 +735,7 @@ static int sdhci_am654_init(struct sdhci {struct sdhci_pltfm_host *pltfm_host =sdhci_priv (host);struct sdhci_am654_data *sdhci_am654 =sdhci_pltfm_priv (pltfm_host); +struct device *dev =mmc_dev (host->mmc);u32 ctl_cfg_2 =0 ;u32 mask;u32 val;
@@ -789,6 +791,12 @@ static int sdhci_am654_init(struct sdhciif (ret) goto err_cleanup_host; +if (sdhci_am654->quirks &SDHCI_AM654_QUIRK_DISABLE_HS400 && + host->mmc->caps2 & (MMC_CAP2_HS400 |MMC_CAP2_HS400_ES )) { +dev_info (dev,"HS400 mode not supported on this silicon revision, disabling it\n" ); + host->mmc->caps2 &= ~(MMC_CAP2_HS400 |MMC_CAP2_HS400_ES ); + } + ret =__sdhci_add_host (host);if (ret) goto err_cleanup_host;
@@ -852,6 +860,12 @@ static int sdhci_am654_get_of_property(sreturn 0 ; } +static const struct soc_device_attribute sdhci_am654_descope_hs400[] = { + { .family ="AM62PX" , .revision ="SR1.0" }, + { .family ="AM62PX" , .revision ="SR1.1" }, + {/* sentinel */ } +}; +static const struct of_device_id sdhci_am654_of_match[] = { { .compatible ="ti,am654-sdhci-5.1" ,
@@ -943,6 +957,10 @@ static int sdhci_am654_probe(struct plat goto err_pltfm_free; } + soc =soc_device_match (sdhci_am654_descope_hs400); +if (soc) + sdhci_am654->quirks |=SDHCI_AM654_QUIRK_DISABLE_HS400 ; + host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning;pm_runtime_get_noresume (dev);
Greg Kroah-Hartman
maintainerPATCH 214/322 fpga: zynq_fpga: Fix the wrong usage of dma_map_sgtable()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Yilun <[email protected]>
commit 1ca61060de92a4320d73adfe5dc8d335653907ac upstream.
dma_map_sgtable() returns only 0 or the error code. Read sgt->nents to get the number of mapped segments.
--- drivers/fpga/zynq-fpga.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/fpga/zynq-fpga.c +4 -4
@@ -405,12 +405,12 @@ static int zynq_fpga_ops_write(struct fp } } - priv->dma_nelms = -dma_map_sgtable (mgr->dev.parent, sgt,DMA_TO_DEVICE ,0 ); -if (priv->dma_nelms ==0 ) { + err =dma_map_sgtable (mgr->dev.parent, sgt,DMA_TO_DEVICE ,0 ); +if (err) {dev_err (&mgr->dev,"Unable to DMA map (TO_DEVICE)\n" ); -return -ENOMEM ; +return err; } + priv->dma_nelms = sgt->nents;/* enable clock */ err =clk_enable (priv->clk);
Greg Kroah-Hartman
maintainerPATCH 215/322 ftrace: Also allocate and copy hash for reading of filter files
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit bfb336cf97df7b37b2b2edec0f69773e06d11955 upstream.
Currently the reader of set_ftrace_filter and set_ftrace_notrace just adds the pointer to the global tracer hash to its iterator. Unlike the writer that allocates a copy of the hash, the reader keeps the pointer to the filter hashes. This is problematic because this pointer is static across function calls that release the locks that can update the global tracer hashes. This can cause UAF and similar bugs.
Allocate and copy the hash for reading the filter files like it is done for the writers. This not only fixes UAF bugs, but also makes the code a bit simpler as it doesn't have to differentiate when to free the iterator's hash between writers and readers.
--- kernel/trace/ftrace.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
kernel/trace/ftrace.c +10 -9
@@ -4569,13 +4569,17 @@ ftrace_regex_open(struct ftrace_ops *ops }else { iter->hash =alloc_and_copy_ftrace_hash (size_bits, hash); } + }else { +if (hash) + iter->hash =alloc_and_copy_ftrace_hash (hash->size_bits, hash); +else + iter->hash =EMPTY_HASH ; + } -if (!iter->hash) { -trace_parser_put (&iter->parser); - goto out_unlock; - } - }else - iter->hash = hash; +if (!iter->hash) { +trace_parser_put (&iter->parser); + goto out_unlock; + } ret =0 ;
@@ -6445,9 +6449,6 @@ int ftrace_regex_release(struct inode *iftrace_hash_move_and_update_ops (iter->ops, orig_hash, iter->hash, filter_hash);mutex_unlock (&ftrace_lock); - }else { -/* For read only, the hash is the ops hash */ - iter->hash =NULL ; }mutex_unlock (&iter->ops->func_hash->regex_lock);
Greg Kroah-Hartman
maintainerPATCH 216/322 iio: pressure: bmp280: Use IS_ERR() in bmp280_common_probe()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salah Triki <[email protected]>
commit 43c0f6456f801181a80b73d95def0e0fd134e1cc upstream.
devm_gpiod_get_optional() may return non-NULL error pointer on failure. Check its return value using IS_ERR() and propagate the error if necessary.
--- drivers/iio/pressure/bmp280-core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/iio/pressure/bmp280-core.c +5 -4
@@ -2727,11 +2727,12 @@ int bmp280_common_probe(struct device *d/* Bring chip out of reset if there is an assigned GPIO line */ gpiod =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH ); +if (IS_ERR (gpiod)) +return dev_err_probe (dev,PTR_ERR (gpiod),"failed to get reset GPIO\n" ); +/* Deassert the signal */ -if (gpiod) { -dev_info (dev,"release reset\n" ); -gpiod_set_value (gpiod,0 ); - } +dev_info (dev,"release reset\n" ); +gpiod_set_value (gpiod,0 ); data->regmap = regmap;
Greg Kroah-Hartman
maintainerPATCH 217/322 iio: proximity: isl29501: fix buffered read on big-endian systems
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit de18e978d0cda23e4c102e18092b63a5b0b3a800 upstream.
Fix passing a u32 value as a u16 buffer scan item. This works on little- endian systems, but not on big-endian systems.
A new local variable is introduced for getting the register value and the array is changed to a struct to make the data layout more explicit rather than just changing the type and having to recalculate the proper length needed for the timestamp.
--- drivers/iio/proximity/isl29501.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/iio/proximity/isl29501.c +10 -4
@@ -938,12 +938,18 @@ static irqreturn_t isl29501_trigger_handstruct iio_dev *indio_dev = pf->indio_dev;struct isl29501_private *isl29501 =iio_priv (indio_dev);const unsigned long *active_mask = indio_dev->active_scan_mask; -u32 buffer[4 ]__aligned(8) = {};/* 1x16-bit + naturally aligned ts */ +u32 value; +struct { +u16 data; +aligned_s64 ts; + } scan = { }; -if (test_bit (ISL29501_DISTANCE_SCAN_INDEX , active_mask)) -isl29501_register_read (isl29501,REG_DISTANCE , buffer); +if (test_bit (ISL29501_DISTANCE_SCAN_INDEX , active_mask)) { +isl29501_register_read (isl29501,REG_DISTANCE , &value); + scan.data = value; + } -iio_push_to_buffers_with_timestamp (indio_dev, buffer, pf->timestamp); +iio_push_to_buffers_with_timestamp (indio_dev, &scan, pf->timestamp);iio_trigger_notify_done (indio_dev->trig);return IRQ_HANDLED ;
Greg Kroah-Hartman
maintainerPATCH 218/322 most: core: Drop device reference after usage in get_channel()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqian Lin <[email protected]>
commit b47b493d6387ae437098112936f32be27f73516c upstream.
In get_channel(), the reference obtained by bus_find_device_by_name() was dropped via put_device() before accessing the device's driver data Move put_device() after usage to avoid potential issues.
--- drivers/most/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/most/core.c +1 -1
@@ -538,8 +538,8 @@ static struct most_channel *get_channel( dev =bus_find_device_by_name (&mostbus,NULL , mdev);if (!dev)return NULL ; -put_device (dev); iface =dev_get_drvdata (dev); +put_device (dev);list_for_each_entry_safe (c, tmp, &iface->p->channel_list, list) {if (!strcmp (dev_name (&c->dev), mdev_ch))return c;
Greg Kroah-Hartman
maintainerPATCH 219/322 kcov, usb: Dont disable interrupts in kcov_remote_start_usb_softirq()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
commit 9528d32873b38281ae105f2f5799e79ae9d086c2 upstream.
kcov_remote_start_usb_softirq() the begin of urb's completion callback. HCDs marked HCD_BH will invoke this function from the softirq and in_serving_softirq() will detect this properly.
Root-HUB (RH) requests will not be delayed to softirq but complete immediately in IRQ context.
This will confuse kcov because in_serving_softirq() will report true if the softirq is served after the hardirq and if the softirq got interrupted by the hardirq in which currently runs.
This was addressed by simply disabling interrupts in kcov_remote_start_usb_softirq() which avoided the interruption by the RH while a regular completion callback was invoked.
This not only changes the behaviour while kconv is enabled but also breaks PREEMPT_RT because now sleeping locks can no longer be acquired.
Revert the previous fix. Address the issue by invoking kcov_remote_start_usb() only if the context is just "serving softirqs" which is identified by checking in_serving_softirq() and in_hardirq() must be false.
--- drivers/usb/core/hcd.c | 12 +++++------- include/linux/kcov.h | 47 +++++++++-------------------------------------- 2 files changed, 14 insertions(+), 45 deletions(-)
drivers/usb/core/hcd.c +5 -7
@@ -1623,7 +1623,6 @@ static void __usb_hcd_giveback_urb(strucstruct usb_hcd *hcd =bus_to_hcd (urb->dev->bus);struct usb_anchor *anchor = urb->anchor;int status = urb->unlinked; -unsigned long flags; urb->hcpriv =NULL ; if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
@@ -1641,14 +1640,13 @@ static void __usb_hcd_giveback_urb(struc/* pass ownership to the completion handler */ urb->status = status;/* -* Only collect coverage in the softirq context and disable interrupts -* to avoid scenarios with nested remote coverage collection sections -* that KCOV does not support. -* See the comment next to kcov_remote_start_usb_softirq() for details. +* This function can be called in task context inside another remote +* coverage collection section, but kcov doesn't support that kind of +* recursion yet. Only collect coverage in softirq context for now. */ - flags =kcov_remote_start_usb_softirq ((u64 )urb->dev->bus->busnum); +kcov_remote_start_usb_softirq ((u64 )urb->dev->bus->busnum); urb->complete (urb); -kcov_remote_stop_softirq (flags); +kcov_remote_stop_softirq ();usb_anchor_resume_wakeups (anchor);atomic_dec (&urb->use_count);
include/linux/kcov.h +9 -38
67 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 220/322 cdx: Fix off-by-one error in cdx_rpmsg_probe()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
commit 300a0cfe9f375b2843bcb331bcfa7503475ef5dd upstream.
In cdx_rpmsg_probe(), strscpy() is incorrectly called with the length of the source string (excluding the NUL terminator) rather than the size of the destination buffer. This results in one character less being copied from 'cdx_rpmsg_id_table[0].name' to 'chinfo.name'.
Use the destination buffer size instead to ensure the name is copied correctly.
--- drivers/cdx/controller/cdx_rpmsg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/cdx/controller/cdx_rpmsg.c +1 -2
@@ -129,8 +129,7 @@ static int cdx_rpmsg_probe(struct rpmsg_ chinfo.src =RPMSG_ADDR_ANY ; chinfo.dst = rpdev->dst; -strscpy (chinfo.name, cdx_rpmsg_id_table[0 ].name, -strlen (cdx_rpmsg_id_table[0 ].name)); +strscpy (chinfo.name, cdx_rpmsg_id_table[0 ].name,sizeof (chinfo.name)); cdx_mcdi->ept =rpmsg_create_ept (rpdev, cdx_rpmsg_cb,NULL , chinfo);if (!cdx_mcdi->ept) {
Greg Kroah-Hartman
maintainerPATCH 221/322 usb: quirks: Add DELAY_INIT quick for another SanDisk 3.2Gen1 Flash Drive
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miao Li <[email protected]>
commit e664036cf36480414936cd91f4cfa2179a3d8367 upstream.
Another SanDisk 3.2Gen1 Flash Drive also need DELAY_INIT quick, or it will randomly work incorrectly on Huawei hisi platforms when doing reboot test.
--- drivers/usb/core/quirks.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/core/quirks.c +1 -0
@@ -371,6 +371,7 @@ static const struct usb_device_id usb_qu { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM }, /* SanDisk Corp. SanDisk 3.2Gen1 */ + { USB_DEVICE(0x0781, 0x5596), .driver_info = USB_QUIRK_DELAY_INIT }, { USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT },/* SanDisk Extreme 55AE */
Greg Kroah-Hartman
maintainerPATCH 222/322 comedi: Make insn_rw_emulate_bits() do insn->n samples
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott <[email protected]>
commit 7afba9221f70d4cbce0f417c558879cba0eb5e66 upstream.
The insn_rw_emulate_bits() function is used as a default handler for INSN_READ instructions for subdevices that have a handler for INSN_BITS but not for INSN_READ. Similarly, it is used as a default handler for INSN_WRITE instructions for subdevices that have a handler for INSN_BITS but not for INSN_WRITE. It works by emulating the INSN_READ or INSN_WRITE instruction handling with a constructed INSN_BITS instruction. However, INSN_READ and INSN_WRITE instructions are supposed to be able read or write multiple samples, indicated by the insn->n value, but insn_rw_emulate_bits() currently only handles a single sample. For INSN_READ, the comedi core will copy insn->n samples back to user-space. (That triggered KASAN kernel-infoleak errors when insn->n was greater than 1, but that is being fixed more generally elsewhere in the comedi core.)
Make insn_rw_emulate_bits() either handle insn->n samples, or return an error, to conform to the general expectation for INSN_READ and INSN_WRITE handlers.
--- drivers/comedi/drivers.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
drivers/comedi/drivers.c +13 -12
@@ -620,11 +620,9 @@ static int insn_rw_emulate_bits(struct cunsigned int chan =CR_CHAN (insn->chanspec);unsigned int base_chan = (chan <32 ) ?0 : chan;unsigned int _data[2 ]; +unsigned int i;int ret; -if (insn->n ==0 ) -return 0 ; -memset (_data,0 ,sizeof (_data));memset (&_insn,0 ,sizeof (_insn)); _insn.insn =INSN_BITS ;
@@ -635,18 +633,21 @@ static int insn_rw_emulate_bits(struct cif (insn->insn ==INSN_WRITE ) {if (!(s->subdev_flags &SDF_WRITABLE ))return -EINVAL ; - _data[0 ] =1U << (chan - base_chan);/* mask */ - _data[1 ] = data[0 ] ? (1U << (chan - base_chan)) :0 ;/* bits */ + _data[0 ] =1U << (chan - base_chan);/* mask */ } +for (i =0 ; i < insn->n; i++) { +if (insn->insn ==INSN_WRITE ) + _data[1 ] = data[i] ? _data[0 ] :0 ;/* bits */ + + ret = s->insn_bits (dev, s, &_insn, _data); +if (ret <0 ) +return ret; - ret = s->insn_bits (dev, s, &_insn, _data); -if (ret <0 ) -return ret; - -if (insn->insn ==INSN_READ ) - data[0 ] = (_data[1 ] >> (chan - base_chan)) &1 ; +if (insn->insn ==INSN_READ ) + data[i] = (_data[1 ] >> (chan - base_chan)) &1 ; + } -return 1 ; +return insn->n; } static int __comedi_device_postconfig_async(struct comedi_device *dev,
Greg Kroah-Hartman
maintainerPATCH 223/322 comedi: pcl726: Prevent invalid irq number
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
commit 96cb948408b3adb69df7e451ba7da9d21f814d00 upstream.
The reproducer passed in an irq number(0x80008000) that was too large, which triggered the oob.
Added an interrupt number check to prevent users from passing in an irq number that was too large.
If it->options[1] is 31, then 1 << it->options[1] is still invalid because it shifts a 1-bit into the sign bit (which is UB in C). Possible solutions include reducing the upper bound on the it->options[1] value to 30 or lower, or using 1U << it->options[1].
The old code would just not attempt to request the IRQ if the options[1] value were invalid. And it would still configure the device without interrupts even if the call to request_irq returned an error. So it would be better to combine this test with the test below.
--- drivers/comedi/drivers/pcl726.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/comedi/drivers/pcl726.c +2 -1
@@ -328,7 +328,8 @@ static int pcl726_attach(struct comedi_d* Hook up the external trigger source interrupt only if the * user config option is valid and the board supports interrupts. */ -if (it->options[1 ] && (board->irq_mask & (1 << it->options[1 ]))) { +if (it->options[1 ] >0 && it->options[1 ] <16 && + (board->irq_mask & (1U << it->options[1 ]))) { ret =request_irq (it->options[1 ], pcl726_interrupt,0 , dev->board_name, dev);if (ret ==0 ) {
Greg Kroah-Hartman
maintainerPATCH 224/322 comedi: Fix use of uninitialized memory in do_insn_ioctl() and do_insnlist_ioctl()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott <[email protected]>
commit 3cd212e895ca2d58963fdc6422502b10dd3966bb upstream.
syzbot reports a KMSAN kernel-infoleak in do_insn_ioctl(). A kernel buffer is allocated to hold insn->n samples (each of which is an unsigned int). For some instruction types, insn->n samples are copied back to user-space, unless an error code is being returned. The problem is that not all the instruction handlers that need to return data to userspace fill in the whole insn->n samples, so that there is an information leak. There is a similar syzbot report for do_insnlist_ioctl(), although it does not have a reproducer for it at the time of writing.
One culprit is insn_rw_emulate_bits() which is used as the handler for INSN_READ or INSN_WRITE instructions for subdevices that do not have a specific handler for that instruction, but do have an INSN_BITS handler. For INSN_READ it only fills in at most 1 sample, so if insn->n is greater than 1, the remaining insn->n - 1 samples copied to userspace will be uninitialized kernel data.
Another culprit is vm80xx_ai_insn_read() in the "vm80xx" driver. It never returns an error, even if it fails to fill the buffer.
Fix it in do_insn_ioctl() and do_insnlist_ioctl() by making sure that uninitialized parts of the allocated buffer are zeroed before handling each instruction.
Thanks to Arnaud Lecomte for their fix to do_insn_ioctl(). That fix replaced the call to kmalloc_array() with kcalloc(), but it is not always necessary to clear the whole buffer.
--- drivers/comedi/comedi_fops.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/comedi/comedi_fops.c +5 -0
@@ -1587,6 +1587,9 @@ static int do_insnlist_ioctl(struct comememset (&data[n],0 , (MIN_SAMPLES - n) *sizeof (unsigned int )); } + }else { + memset(data, 0, max_t(unsigned int, n, MIN_SAMPLES) * +sizeof (unsigned int )); } ret =parse_insn (dev, insns + i, data, file);if (ret <0 )
@@ -1670,6 +1673,8 @@ static int do_insn_ioctl(struct comedi_dmemset (&data[insn->n],0 , (MIN_SAMPLES - insn->n) *sizeof (unsigned int )); } + }else { +memset (data,0 , n_data *sizeof (unsigned int )); } ret =parse_insn (dev, insn, data, file);if (ret <0 )
Greg Kroah-Hartman
maintainerPATCH 225/322 usb: core: hcd: fix accessing unmapped memory in SINGLE_STEP_SET_FEATURE test
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Yang <[email protected]>
commit 8fe06185e11ae753414aa6117f0e798aa77567ff upstream.
The USB core will unmap urb->transfer_dma after SETUP stage completes. Then the USB controller will access unmapped memory when it received device descriptor. If iommu is equipped, the entire test can't be completed due to the memory accessing is blocked.
Fix it by calling map_urb_for_dma() again for IN stage. To reduce redundant map for urb->transfer_buffer, this will also set URB_NO_TRANSFER_DMA_MAP flag before first map_urb_for_dma() to skip dma map for urb->transfer_buffer and clear URB_NO_TRANSFER_DMA_MAP flag before second map_urb_for_dma().
--- drivers/usb/core/hcd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/usb/core/hcd.c +7 -1
@@ -2151,7 +2151,7 @@ static struct urb *request_single_step_s urb->complete = usb_ehset_completion; urb->status = -EINPROGRESS ; urb->actual_length =0 ; - urb->transfer_flags =URB_DIR_IN ; + urb->transfer_flags =URB_DIR_IN |URB_NO_TRANSFER_DMA_MAP ;usb_get_urb (urb);atomic_inc (&urb->use_count);atomic_inc (&urb->dev->urbnum);
@@ -2215,9 +2215,15 @@ int ehset_single_step_set_feature(struct/* Complete remaining DATA and STATUS stages using the same URB */ urb->status = -EINPROGRESS ; + urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP ;usb_get_urb (urb);atomic_inc (&urb->use_count);atomic_inc (&urb->dev->urbnum); +if (map_urb_for_dma (hcd, urb,GFP_KERNEL )) { +usb_put_urb (urb); + goto out1; + } + retval = hcd->driver->submit_single_step_set_feature (hcd, urb,0 );if (!retval && !wait_for_completion_timeout (&done,msecs_to_jiffies (2000 ))) {
Greg Kroah-Hartman
maintainerPATCH 226/322 usb: renesas-xhci: Fix External ROM access timeouts
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <[email protected]>
commit f9420f4757752f056144896024d5ea89e5a611f1 upstream.
Increase the External ROM access timeouts to prevent failures during programming of External SPI EEPROM chips. The current timeouts are too short for some SPI EEPROMs used with uPD720201 controllers.
The current timeout for Chip Erase in renesas_rom_erase() is 100 ms , the current timeout for Sector Erase issued by the controller before Page Program in renesas_fw_download_image() is also 100 ms. Neither timeout is sufficient for e.g. the Macronix MX25L5121E or MX25V5126F.
MX25L5121E reference manual [1] page 35 section "ERASE AND PROGRAMMING PERFORMANCE" and page 23 section "Table 8. AC CHARACTERISTICS (Temperature = 0°C to 70°C for Commercial grade, VCC = 2.7V ~ 3.6V)" row "tCE" indicate that the maximum time required for Chip Erase opcode to complete is 2 s, and for Sector Erase it is 300 ms .
MX25V5126F reference manual [2] page 47 section "13. ERASE AND PROGRAMMING PERFORMANCE (2.3V - 3.6V)" and page 42 section "Table 8. AC CHARACTERISTICS (Temperature = -40°C to 85°C for Industrial grade, VCC = 2.3V - 3.6V)" row "tCE" indicate that the maximum time required for Chip Erase opcode to complete is 3.2 s, and for Sector Erase it is 400 ms .
Update the timeouts such, that Chip Erase timeout is set to 5 seconds, and Sector Erase timeout is set to 500 ms. Such lengthy timeouts ought to be sufficient for majority of SPI EEPROM chips.
[1] https://www.macronix.com/Lists/Datasheet/Attachments/8634/MX25L5121E,%203V,%20512Kb,%20v1.3.pdf
[2] https://www.macronix.com/Lists/Datasheet/Attachments/8750/MX25V5126F,%202.5V,%20512Kb,%20v1.1.pdf
--- drivers/usb/host/xhci-pci-renesas.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/usb/host/xhci-pci-renesas.c +4 -3
@@ -47,8 +47,9 @@#define RENESAS_ROM_ERASE_MAGIC 0x5A65726F#define RENESAS_ROM_WRITE_MAGIC 0x53524F4D -#define RENESAS_RETRY 10000 -#define RENESAS_DELAY 10 +#define RENESAS_RETRY 50000/* 50000 * RENESAS_DELAY ~= 500ms */ +#define RENESAS_CHIP_ERASE_RETRY 500000/* 500000 * RENESAS_DELAY ~= 5s */ +#define RENESAS_DELAY 10#define RENESAS_FW_NAME "renesas_usb_fw.mem"
@@ -407,7 +408,7 @@ static void renesas_rom_erase(struct pci/* sleep a bit while ROM is erased */ msleep (20 ); -for (i =0 ; i <RENESAS_RETRY ; i++) { +for (i =0 ; i <RENESAS_CHIP_ERASE_RETRY ; i++) { retval =pci_read_config_byte (pdev,RENESAS_ROM_STATUS , &status); status &=RENESAS_ROM_STATUS_ERASE ;
Greg Kroah-Hartman
maintainerPATCH 227/322 USB: storage: Add unusual-devs entry for Novatek NTK96550-based camera
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mael GUERIN <[email protected]>
commit 6ca8af3c8fb584f3424a827f554ff74f898c27cd upstream.
Add the US_FL_BULK_IGNORE_TAG quirk for Novatek NTK96550-based camera to fix USB resets after sending SCSI vendor commands due to CBW and CSW tags difference, leading to undesired slowness while communicating with the device.
Please find below the copy of /sys/kernel/debug/usb/devices with my device plugged in (listed as TechSys USB mass storage here, the underlying chipset being the Novatek NTK96550-based camera):
T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0603 ProdID=8611 Rev= 0.01 S: Manufacturer=TechSys S: Product=USB Mass Storage S: SerialNumber=966110000000100 C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/usb/storage/unusual_devs.h +7 -0
@@ -934,6 +934,13 @@ UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_SANE_SENSE ), +/* Added by Maël GUERIN <[email protected]> */ +UNUSUAL_DEV (0x0603 ,0x8611 ,0x0000 ,0xffff , +"Novatek" , +"NTK96550-based camera" , +USB_SC_SCSI ,USB_PR_BULK ,NULL , + US_FL_BULK_IGNORE_TAG ), +/* * Reported by Hanno Boeck <[email protected]> * Taken from the Lycoris Kernel
Greg Kroah-Hartman
maintainerPATCH 228/322 usb: storage: realtek_cr: Use correct byte order for bcs->Residue
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
commit 98da66a70ad2396e5a508c4245367797ebc052ce upstream.
Since 'bcs->Residue' has the data type '__le32', convert it to the correct byte order of the CPU using this driver when assigning it to the local variable 'residue'.
--- drivers/usb/storage/realtek_cr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/storage/realtek_cr.c +1 -1
@@ -252,7 +252,7 @@ static int rts51x_bulk_transport(structreturn USB_STOR_TRANSPORT_ERROR ; } - residue = bcs->Residue; + residue =le32_to_cpu (bcs->Residue);if (bcs->Tag != us->tag)return USB_STOR_TRANSPORT_ERROR ;
Greg Kroah-Hartman
maintainerPATCH 229/322 USB: storage: Ignore driver CD mode for Realtek multi-mode Wi-Fi dongles
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zenm Chen <[email protected]>
commit a3dc32c635bae0ae569f489e00de0e8f015bfc25 upstream.
Many Realtek USB Wi-Fi dongles released in recent years have two modes:
one is driver CD mode which has Windows driver onboard, another one is Wi-Fi mode. Add the US_FL_IGNORE_DEVICE quirk for these multi-mode devices. Otherwise, usb_modeswitch may fail to switch them to Wi-Fi mode.
Currently there are only two USB IDs known to be used by these multi-mode Wi-Fi dongles: 0bda:1a2b and 0bda:a192.
Information about Mercury MW310UH in /sys/kernel/debug/usb/devices.
T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 12 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0bda ProdID=a192 Rev= 2.00 S: Manufacturer=Realtek S: Product=DISK C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none) E: Ad=8a(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
Information about D-Link AX9U rev. A1 in /sys/kernel/debug/usb/devices.
T: Bus=03 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 55 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0bda ProdID=1a2b Rev= 0.00 S: Manufacturer=Realtek S: Product=DISK C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none) E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/storage/unusual_devs.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
drivers/usb/storage/unusual_devs.h +22 -0
@@ -1501,6 +1501,28 @@ UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9 USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_WP_DETECT ), +/* +* Reported by Zenm Chen <[email protected]> +* Ignore driver CD mode, otherwise usb_modeswitch may fail to switch +* the device into Wi-Fi mode. +*/ +UNUSUAL_DEV (0x0bda ,0x1a2b ,0x0000 ,0xffff , +"Realtek" , +"DISK" , +USB_SC_DEVICE ,USB_PR_DEVICE ,NULL , +US_FL_IGNORE_DEVICE ), + +/* +* Reported by Zenm Chen <[email protected]> +* Ignore driver CD mode, otherwise usb_modeswitch may fail to switch +* the device into Wi-Fi mode. +*/ +UNUSUAL_DEV (0x0bda ,0xa192 ,0x0000 ,0xffff , +"Realtek" , +"DISK" , +USB_SC_DEVICE ,USB_PR_DEVICE ,NULL , +US_FL_IGNORE_DEVICE ), + UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, "Maxtor", "USB to SATA",
Greg Kroah-Hartman
maintainerPATCH 230/322 usb: typec: maxim_contaminant: disable low power mode when reading comparator values
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Sunil Dhamne <[email protected]>
commit cabb6c5f4d9e7f49bdf8c0a13c74bd93ee35f45a upstream.
Low power mode is enabled when reading CC resistance as part of max_contaminant_read_resistance_kohm() and left in that state. However, it's supposed to work with 1uA current source. To read CC comparator values current source is changed to 80uA. This causes a storm of CC interrupts as it (falsely) detects a potential contaminant. To prevent this, disable low power mode current sourcing before reading comparator values.
--- drivers/usb/typec/tcpm/maxim_contaminant.c | 5 +++++ drivers/usb/typec/tcpm/tcpci_maxim.h | 1 + 2 files changed, 6 insertions(+)
drivers/usb/typec/tcpm/maxim_contaminant.c +5 -0
@@ -188,6 +188,11 @@ static int max_contaminant_read_comparatif (ret <0 )return ret; +/* Disable low power mode */ + ret =regmap_update_bits (regmap,TCPC_VENDOR_CC_CTRL2 ,CCLPMODESEL , +FIELD_PREP (CCLPMODESEL , +LOW_POWER_MODE_DISABLE )); +/* Sleep to allow comparators settle */ usleep_range (5000 ,6000 ); ret =regmap_update_bits (regmap,TCPC_TCPC_CTRL ,TCPC_TCPC_CTRL_ORIENTATION ,PLUG_ORNT_CC1 );
drivers/usb/typec/tcpm/tcpci_maxim.h +1 -0
@@ -21,6 +21,7 @@#define CCOVPDIS BIT(6)#define SBURPCTRL BIT(5)#define CCLPMODESEL GENMASK(4, 3) +#define LOW_POWER_MODE_DISABLE 0#define ULTRA_LOW_POWER_MODE 1#define CCRPCTRL GENMASK(2, 0)#define UA_1_SRC 1
Greg Kroah-Hartman
maintainerPATCH 231/322 usb: typec: maxim_contaminant: re-enable cc toggle if cc is open and port is clean
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Sunil Dhamne <[email protected]>
commit a381c6d6f646226924809d0ad01a9465786da463 upstream.
Presently in max_contaminant_is_contaminant() if there's no contaminant detected previously, CC is open & stopped toggling and no contaminant is currently present, TCPC.RC would be programmed to do DRP toggling. However, it didn't actively look for a connection. This would lead to Type-C not detect *any* new connections. Hence, in the above situation, re-enable toggling & program TCPC to look for a new connection.
Also, return early if TCPC was looking for connection as this indicates TCPC has neither detected a potential connection nor a change in contaminant state.
In addition, once dry detection is complete (port is dry), restart toggling.
--- drivers/usb/typec/tcpm/maxim_contaminant.c | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
drivers/usb/typec/tcpm/maxim_contaminant.c +53 -0
@@ -329,6 +329,39 @@ static int max_contaminant_enable_dry_dereturn 0 ; } +static int max_contaminant_enable_toggling (struct max_tcpci_chip *chip) +{ +struct regmap *regmap = chip->data.regmap; +int ret; + +/* Disable dry detection if enabled. */ + ret =regmap_update_bits (regmap,TCPC_VENDOR_CC_CTRL2 ,CCLPMODESEL , +FIELD_PREP (CCLPMODESEL , +LOW_POWER_MODE_DISABLE )); +if (ret) +return ret; + + ret =regmap_update_bits (regmap,TCPC_VENDOR_CC_CTRL1 ,CCCONNDRY ,0 ); +if (ret) +return ret; + + ret =max_tcpci_write8 (chip,TCPC_ROLE_CTRL ,TCPC_ROLE_CTRL_DRP | +FIELD_PREP (TCPC_ROLE_CTRL_CC1 , +TCPC_ROLE_CTRL_CC_RD ) | +FIELD_PREP (TCPC_ROLE_CTRL_CC2 , +TCPC_ROLE_CTRL_CC_RD )); +if (ret) +return ret; + + ret =regmap_update_bits (regmap,TCPC_TCPC_CTRL , +TCPC_TCPC_CTRL_EN_LK4CONN_ALRT , +TCPC_TCPC_CTRL_EN_LK4CONN_ALRT ); +if (ret) +return ret; + +return max_tcpci_write8 (chip,TCPC_COMMAND ,TCPC_CMD_LOOK4CONNECTION ); +} +bool max_contaminant_is_contaminant (struct max_tcpci_chip *chip,bool disconnect_while_debounce,bool *cc_handled) {
@@ -345,6 +378,12 @@ bool max_contaminant_is_contaminant(struif (ret <0 )return false; +if (cc_status &TCPC_CC_STATUS_TOGGLING ) { +if (chip->contaminant_state ==DETECTED ) +return true; +return false; + } +if (chip->contaminant_state ==NOT_DETECTED || chip->contaminant_state ==SINK ) {if (!disconnect_while_debounce)msleep (100 );
@@ -377,6 +416,12 @@ bool max_contaminant_is_contaminant(strumax_contaminant_enable_dry_detection (chip);return true; } + + ret =max_contaminant_enable_toggling (chip); +if (ret) +dev_err (chip->dev, +"Failed to enable toggling, ret=%d" , + ret); } }else if (chip->contaminant_state ==DETECTED ) {if (!(cc_status &TCPC_CC_STATUS_TOGGLING )) {
@@ -384,6 +429,14 @@ bool max_contaminant_is_contaminant(struif (chip->contaminant_state ==DETECTED ) {max_contaminant_enable_dry_detection (chip);return true; + }else { + ret =max_contaminant_enable_toggling (chip); +if (ret) { +dev_err (chip->dev, +"Failed to enable toggling, ret=%d" , + ret); +return true; + } } } }
Greg Kroah-Hartman
maintainerPATCH 232/322 usb: xhci: Fix slot_id resource race conflict
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weitao Wang <[email protected]>
commit 2eb03376151bb8585caa23ed2673583107bb5193 upstream.
xHC controller may immediately reuse a slot_id after it's disabled, giving it to a new enumerating device before the xhci driver freed all resources related to the disabled device.
In such a scenario, device-A with slot_id equal to 1 is disconnecting while device-B is enumerating, device-B will fail to enumerate in the follow sequence.
1.[device-A] send disable slot command
2.[device-B] send enable slot command
3.[device-A] disable slot command completed and wakeup waiting thread 4.[device-B] enable slot command completed with slot_id equal to 1 and
wakeup waiting thread
5.[device-B] driver checks that slot_id is still in use (by device-A) in
xhci_alloc_virt_device, and fail to enumerate due to this conflict
6.[device-A] xhci->devs[slot_id] set to NULL in xhci_free_virt_device
To fix driver's slot_id resources conflict, clear xhci->devs[slot_id] and xhci->dcbba->dev_context_ptrs[slot_id] pointers in the interrupt context when disable slot command completes successfully. Simultaneously, adjust function xhci_free_virt_device to accurately handle device release.
[minor smatch warning and commit message fix -Mathias]
--- drivers/usb/host/xhci-hub.c | 3 +-- drivers/usb/host/xhci-mem.c | 22 +++++++++++----------- drivers/usb/host/xhci-ring.c | 9 +++++++-- drivers/usb/host/xhci.c | 21 ++++++++++++++------- drivers/usb/host/xhci.h | 3 ++- 5 files changed, 35 insertions(+), 23 deletions(-)
drivers/usb/host/xhci-hub.c +1 -2
@@ -704,8 +704,7 @@ static int xhci_enter_test_mode(struct xif (!xhci->devs[i])continue ; - retval =xhci_disable_slot (xhci, i); -xhci_free_virt_device (xhci, i); + retval =xhci_disable_and_free_slot (xhci, i);if (retval)xhci_err (xhci,"Failed to disable slot %d, %d. Enter test mode anyway\n" , i, retval);
drivers/usb/host/xhci-mem.c +11 -11
@@ -842,21 +842,20 @@ free_tts:* will be manipulated by the configure endpoint, allocate device, or update * hub functions while this function is removing the TT entries from the list. */ -void xhci_free_virt_device (struct xhci_hcd *xhci,int slot_id) +void xhci_free_virt_device (struct xhci_hcd *xhci,struct xhci_virt_device *dev, +int slot_id) { -struct xhci_virt_device *dev;int i;int old_active_eps =0 ;/* Slot ID 0 is reserved */ -if (slot_id ==0 || !xhci->devs[slot_id]) +if (slot_id ==0 || !dev)return ; - dev = xhci->devs[slot_id]; - - xhci->dcbaa->dev_context_ptrs[slot_id] =0 ; -if (!dev) -return ; +/* If device ctx array still points to _this_ device, clear it */ +if (dev->out_ctx && + xhci->dcbaa->dev_context_ptrs[slot_id] ==cpu_to_le64 (dev->out_ctx->dma)) + xhci->dcbaa->dev_context_ptrs[slot_id] =0 ;trace_xhci_free_virt_device (dev);
@@ -897,8 +896,9 @@ void xhci_free_virt_device(struct xhci_h dev->udev->slot_id =0 ;if (dev->rhub_port && dev->rhub_port->slot_id == slot_id) dev->rhub_port->slot_id =0 ; -kfree (xhci->devs[slot_id]); - xhci->devs[slot_id] =NULL ; +if (xhci->devs[slot_id] == dev) + xhci->devs[slot_id] =NULL ; +kfree (dev); }/*
@@ -939,7 +939,7 @@ static void xhci_free_virt_devices_depth out:/* we are now at a leaf device */ xhci_debugfs_remove_slot (xhci, slot_id); -xhci_free_virt_device (xhci, slot_id); +xhci_free_virt_device (xhci, vdev, slot_id); } int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
drivers/usb/host/xhci-ring.c +7 -2
@@ -1562,7 +1562,8 @@ static void xhci_handle_cmd_enable_slot( command->slot_id =0 ; } -static void xhci_handle_cmd_disable_slot (struct xhci_hcd *xhci,int slot_id) +static void xhci_handle_cmd_disable_slot (struct xhci_hcd *xhci,int slot_id, +u32 cmd_comp_code) {struct xhci_virt_device *virt_dev;struct xhci_slot_ctx *slot_ctx;
@@ -1577,6 +1578,10 @@ static void xhci_handle_cmd_disable_slotif (xhci->quirks &XHCI_EP_LIMIT_QUIRK )/* Delete default control endpoint resources */ xhci_free_device_endpoint_resources (xhci, virt_dev, true); +if (cmd_comp_code ==COMP_SUCCESS ) { + xhci->dcbaa->dev_context_ptrs[slot_id] =0 ; + xhci->devs[slot_id] =NULL ; + } }static void xhci_handle_cmd_config_ep (struct xhci_hcd *xhci,int slot_id)
@@ -1824,7 +1829,7 @@ static void handle_cmd_completion(structxhci_handle_cmd_enable_slot (slot_id, cmd, cmd_comp_code);break ;case TRB_DISABLE_SLOT : -xhci_handle_cmd_disable_slot (xhci, slot_id); +xhci_handle_cmd_disable_slot (xhci, slot_id, cmd_comp_code);break ;case TRB_CONFIG_EP :if (!cmd->completion)
drivers/usb/host/xhci.c +14 -7
@@ -3763,8 +3763,7 @@ static int xhci_discover_or_reset_device* Obtaining a new device slot to inform the xHCI host that * the USB device has been reset. */ - ret =xhci_disable_slot (xhci, udev->slot_id); -xhci_free_virt_device (xhci, udev->slot_id); + ret =xhci_disable_and_free_slot (xhci, udev->slot_id);if (!ret) { ret =xhci_alloc_dev (hcd, udev);if (ret ==1 )
@@ -3919,7 +3918,7 @@ static void xhci_free_dev(struct usb_hcdxhci_disable_slot (xhci, udev->slot_id);spin_lock_irqsave (&xhci->lock, flags); -xhci_free_virt_device (xhci, udev->slot_id); +xhci_free_virt_device (xhci, virt_dev, udev->slot_id);spin_unlock_irqrestore (&xhci->lock, flags); }
@@ -3968,6 +3967,16 @@ int xhci_disable_slot(struct xhci_hcd *xreturn 0 ; } +int xhci_disable_and_free_slot (struct xhci_hcd *xhci,u32 slot_id) +{ +struct xhci_virt_device *vdev = xhci->devs[slot_id]; +int ret; + + ret =xhci_disable_slot (xhci, slot_id); +xhci_free_virt_device (xhci, vdev, slot_id); +return ret; +} +/* * Checks if we have enough host controller resources for the default control * endpoint.
@@ -4074,8 +4083,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd,return 1 ; disable_slot: -xhci_disable_slot (xhci, udev->slot_id); -xhci_free_virt_device (xhci, udev->slot_id); +xhci_disable_and_free_slot (xhci, udev->slot_id);return 0 ; }
@@ -4211,8 +4219,7 @@ static int xhci_setup_device(struct usb_dev_warn (&udev->dev,"Device not responding to setup %s.\n" , act);mutex_unlock (&xhci->mutex); - ret =xhci_disable_slot (xhci, udev->slot_id); -xhci_free_virt_device (xhci, udev->slot_id); + ret =xhci_disable_and_free_slot (xhci, udev->slot_id);if (!ret) {if (xhci_alloc_dev (hcd, udev) ==1 )xhci_setup_addressable_virt_dev (xhci, udev);
drivers/usb/host/xhci.h +2 -1
@@ -1774,7 +1774,7 @@ void xhci_dbg_trace(struct xhci_hcd *xhc/* xHCI memory management */ void xhci_mem_cleanup (struct xhci_hcd *xhci);int xhci_mem_init (struct xhci_hcd *xhci,gfp_t flags); -void xhci_free_virt_device (struct xhci_hcd *xhci,int slot_id); +void xhci_free_virt_device (struct xhci_hcd *xhci,struct xhci_virt_device *dev,int slot_id);int xhci_alloc_virt_device (struct xhci_hcd *xhci,int slot_id,struct usb_device *udev,gfp_t flags);int xhci_setup_addressable_virt_dev (struct xhci_hcd *xhci,struct usb_device *udev); void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci,
@@ -1866,6 +1866,7 @@ void xhci_reset_bandwidth(struct usb_hcdint xhci_update_hub_device (struct usb_hcd *hcd,struct usb_device *hdev,struct usb_tt *tt,gfp_t mem_flags);int xhci_disable_slot (struct xhci_hcd *xhci,u32 slot_id); +int xhci_disable_and_free_slot (struct xhci_hcd *xhci,u32 slot_id);int xhci_ext_cap_init (struct xhci_hcd *xhci);int xhci_suspend (struct xhci_hcd *xhci,bool do_wakeup);
Greg Kroah-Hartman
maintainerPATCH 233/322 usb: dwc3: Ignore late xferNotReady event to prevent halt timeout
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuen-Han Tsai <[email protected]>
commit 58577118cc7cec9eb7c1836bf88f865ff2c5e3a3 upstream.
During a device-initiated disconnect, the End Transfer command resets the event filter, allowing a new xferNotReady event to be generated before the controller is fully halted. Processing this late event incorrectly triggers a Start Transfer, which prevents the controller from halting and results in a DSTS.DEVCTLHLT bit polling timeout.
Ignore the late xferNotReady event if the controller is already in a disconnected state.
--- drivers/usb/dwc3/gadget.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/usb/dwc3/gadget.c +9 -0
@@ -3707,6 +3707,15 @@ static void dwc3_gadget_endpoint_transfestatic void dwc3_gadget_endpoint_transfer_not_ready (struct dwc3_ep *dep,const struct dwc3_event_depevt *event) { +/* +* During a device-initiated disconnect, a late xferNotReady event can +* be generated after the End Transfer command resets the event filter, +* but before the controller is halted. Ignore it to prevent a new +* transfer from starting. +*/ +if (!dep->dwc->connected) +return ; +dwc3_gadget_endpoint_frame_from_event (dep, event);/*
Greg Kroah-Hartman
maintainerPATCH 234/322 usb: dwc3: Remove WARN_ON for device endpoint command timeouts
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Selvarasu Ganesan <[email protected]>
commit 45eae113dccaf8e502090ecf5b3d9e9b805add6f upstream.
This commit addresses a rarely observed endpoint command timeout which causes kernel panic due to warn when 'panic_on_warn' is enabled and unnecessary call trace prints when 'panic_on_warn' is disabled. It is seen during fast software-controlled connect/disconnect testcases. The following is one such endpoint command timeout that we observed:
1. Connect
=======
->dwc3_thread_interrupt
->dwc3_ep0_interrupt
->configfs_composite_setup
->composite_setup
->usb_ep_queue
->dwc3_gadget_ep0_queue
->__dwc3_gadget_ep0_queue
->__dwc3_ep0_do_control_data
->dwc3_send_gadget_ep_cmd2. Disconnect
==========
->dwc3_thread_interrupt
->dwc3_gadget_disconnect_interrupt
->dwc3_ep0_reset_state
->dwc3_ep0_end_control_data
->dwc3_send_gadget_ep_cmd
In the issue scenario, in Exynos platforms, we observed that control transfers for the previous connect have not yet been completed and end transfer command sent as a part of the disconnect sequence and processing of USB_ENDPOINT_HALT feature request from the host timeout. This maybe an expected scenario since the controller is processing EP commands sent as a part of the previous connect. It maybe better to remove WARN_ON in all places where device endpoint commands are sent to avoid unnecessary kernel panic due to warn.
--- drivers/usb/dwc3/ep0.c | 20 ++++++++++++++++---- drivers/usb/dwc3/gadget.c | 10 ++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-)
drivers/usb/dwc3/ep0.c +16 -4
@@ -288,7 +288,9 @@ void dwc3_ep0_out_start(struct dwc3 *dwcdwc3_ep0_prepare_one_trb (dep, dwc->ep0_trb_addr,8 ,DWC3_TRBCTL_CONTROL_SETUP , false); ret =dwc3_ep0_start_trans (dep); -WARN_ON (ret <0 ); +if (ret <0 ) +dev_err (dwc->dev,"ep0 out start transfer failed: %d\n" , ret); +for (i =2 ; i <DWC3_ENDPOINTS_NUM ; i++) {struct dwc3_ep *dwc3_ep;
@@ -1061,7 +1063,9 @@ static void __dwc3_ep0_do_control_data(s ret =dwc3_ep0_start_trans (dep); } -WARN_ON (ret <0 ); +if (ret <0 ) +dev_err (dwc->dev, +"ep0 data phase start transfer failed: %d\n" , ret); }static int dwc3_ep0_start_control_status (struct dwc3_ep *dep)
@@ -1078,7 +1082,12 @@ static int dwc3_ep0_start_control_statusstatic void __dwc3_ep0_do_control_status (struct dwc3 *dwc,struct dwc3_ep *dep) { -WARN_ON (dwc3_ep0_start_control_status (dep)); +int ret; + + ret =dwc3_ep0_start_control_status (dep); +if (ret) +dev_err (dwc->dev, +"ep0 status phase start transfer failed: %d\n" , ret); } static void dwc3_ep0_do_control_status(struct dwc3 *dwc,
@@ -1121,7 +1130,10 @@ void dwc3_ep0_end_control_data(struct dw cmd |=DWC3_DEPCMD_PARAM (dep->resource_index);memset (¶ms,0 ,sizeof (params)); ret =dwc3_send_gadget_ep_cmd (dep, cmd, ¶ms); -WARN_ON_ONCE (ret); +if (ret) +dev_err_ratelimited (dwc->dev, +"ep0 data phase end transfer failed: %d\n" , ret); + dep->resource_index =0 ; }
drivers/usb/dwc3/gadget.c +8 -2
@@ -1763,7 +1763,11 @@ static int __dwc3_stop_active_transfer(s dep->flags |=DWC3_EP_DELAY_STOP ;return 0 ; } -WARN_ON_ONCE (ret); + +if (ret) +dev_err_ratelimited (dep->dwc->dev, +"end transfer failed: %d\n" , ret); + dep->resource_index =0 ;if (!interrupt)
@@ -4017,7 +4021,9 @@ static void dwc3_clear_stall_all_ep(stru dep->flags &= ~DWC3_EP_STALL ; ret =dwc3_send_clear_stall_ep_cmd (dep); -WARN_ON_ONCE (ret); +if (ret) +dev_err_ratelimited (dwc->dev, +"failed to clear STALL on %s\n" , dep->name); } }
Greg Kroah-Hartman
maintainerPATCH 235/322 usb: dwc3: pci: add support for the Intel Wildcat Lake
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heikki Krogerus <[email protected]>
commit 86f390ba59cd8d5755bafe2b163c3e6b89d6bbd9 upstream.
This patch adds the necessary PCI ID for Intel Wildcat Lake devices.
--- drivers/usb/dwc3/dwc3-pci.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/dwc3/dwc3-pci.c +2 -0
@@ -41,6 +41,7 @@#define PCI_DEVICE_ID_INTEL_TGPLP 0xa0ee#define PCI_DEVICE_ID_INTEL_TGPH 0x43ee#define PCI_DEVICE_ID_INTEL_JSP 0x4dee +#define PCI_DEVICE_ID_INTEL_WCL 0x4d7e#define PCI_DEVICE_ID_INTEL_ADL 0x460e#define PCI_DEVICE_ID_INTEL_ADL_PCH 0x51ee#define PCI_DEVICE_ID_INTEL_ADLN 0x465e
@@ -431,6 +432,7 @@ static const struct pci_device_id dwc3_p { PCI_DEVICE_DATA(INTEL, TGPLP, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, TGPH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, JSP, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, WCL, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ADL, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ADL_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ADLN, &dwc3_pci_intel_swnode) },
Greg Kroah-Hartman
maintainerPATCH 236/322 iio: light: Use aligned_s64 instead of open coding alignment.
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cameron <[email protected]>
[ Upstream commit a801016da0bbb955acf1a551584790e3816bb4db ]
Use this new type to both slightly simplify the code and avoid confusing static analysis tools. Mostly this series is about consistency to avoid this code pattern getting copied into more drivers.
Stable-dep-of: 433b99e92294 ("iio: light: as73211: Ensure buffer holes are zeroed")
--- drivers/iio/light/adjd_s311.c | 2 +- drivers/iio/light/as73211.c | 2 +- drivers/iio/light/bh1745.c | 2 +- drivers/iio/light/isl29125.c | 2 +- drivers/iio/light/ltr501.c | 2 +- drivers/iio/light/max44000.c | 2 +- drivers/iio/light/rohm-bu27034.c | 2 +- drivers/iio/light/rpr0521.c | 2 +- drivers/iio/light/st_uvis25.h | 2 +- drivers/iio/light/tcs3414.c | 2 +- drivers/iio/light/tcs3472.c | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-)
drivers/iio/light/adjd_s311.c +1 -1
@@ -56,7 +56,7 @@ struct adjd_s311_data {struct i2c_client *client;struct {s16 chans[4 ]; -s64 ts__aligned(8) ; +aligned_s64 ts; } scan; };
drivers/iio/light/as73211.c +1 -1
@@ -642,7 +642,7 @@ static irqreturn_t as73211_trigger_handlstruct as73211_data *data =iio_priv (indio_dev);struct {__le16 chan[4 ]; -s64 ts__aligned(8) ; +aligned_s64 ts; } scan;int data_result, ret;
drivers/iio/light/bh1745.c +1 -1
@@ -743,7 +743,7 @@ static irqreturn_t bh1745_trigger_handlestruct bh1745_data *data =iio_priv (indio_dev);struct {u16 chans[4 ]; -s64 timestamp__aligned(8) ; +aligned_s64 timestamp; } scan;u16 value;int ret;
drivers/iio/light/isl29125.c +1 -1
@@ -54,7 +54,7 @@ struct isl29125_data {/* Ensure timestamp is naturally aligned */ struct {u16 chans[3 ]; -s64 timestamp__aligned(8) ; +aligned_s64 timestamp; } scan; };
drivers/iio/light/ltr501.c +1 -1
@@ -1285,7 +1285,7 @@ static irqreturn_t ltr501_trigger_handlestruct ltr501_data *data =iio_priv (indio_dev);struct {u16 channels[3 ]; -s64 ts__aligned(8) ; +aligned_s64 ts; } scan;__le16 als_buf[2 ];u8 mask =0 ;
drivers/iio/light/max44000.c +1 -1
@@ -78,7 +78,7 @@ struct max44000_data {/* Ensure naturally aligned timestamp */ struct {u16 channels[2 ]; -s64 ts__aligned(8) ; +aligned_s64 ts; } scan; };
drivers/iio/light/rohm-bu27034.c +1 -1
@@ -205,7 +205,7 @@ struct bu27034_data {struct {u32 mlux;__le16 channels[BU27034_NUM_HW_DATA_CHANS ]; -s64 ts__aligned(8) ; +aligned_s64 ts; } scan; };
drivers/iio/light/rpr0521.c +1 -1
@@ -203,7 +203,7 @@ struct rpr0521_data {struct {__le16 channels[3 ];u8 garbage; -s64 ts__aligned(8) ; +aligned_s64 ts; } scan; };
drivers/iio/light/st_uvis25.h +1 -1
@@ -30,7 +30,7 @@ struct st_uvis25_hw {/* Ensure timestamp is naturally aligned */ struct {u8 chan; -s64 ts__aligned(8) ; +aligned_s64 ts; } scan; };
drivers/iio/light/tcs3414.c +1 -1
@@ -56,7 +56,7 @@ struct tcs3414_data {/* Ensure timestamp is naturally aligned */ struct {u16 chans[4 ]; -s64 timestamp__aligned(8) ; +aligned_s64 timestamp; } scan; };
drivers/iio/light/tcs3472.c +1 -1
@@ -67,7 +67,7 @@ struct tcs3472_data {/* Ensure timestamp is naturally aligned */ struct {u16 chans[4 ]; -s64 timestamp__aligned(8) ; +aligned_s64 timestamp; } scan; };
Greg Kroah-Hartman
maintainerPATCH 237/322 iio: light: as73211: Ensure buffer holes are zeroed
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cameron <[email protected]>
[ Upstream commit 433b99e922943efdfd62b9a8e3ad1604838181f2 ]
Given that the buffer is copied to a kfifo that ultimately user space can read, ensure we zero it.
--- drivers/iio/light/as73211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/light/as73211.c +1 -1
@@ -643,7 +643,7 @@ static irqreturn_t as73211_trigger_handlstruct {__le16 chan[4 ];aligned_s64 ts; - } scan; + } scan = { };int data_result, ret;mutex_lock (&data->mutex);
Greg Kroah-Hartman
maintainerPATCH 238/322 iio: temperature: maxim_thermocouple: use DMA-safe buffer for spi_read()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
[ Upstream commit ae5bc07ec9f73a41734270ef3f800c5c8a7e0ad3 ]
Replace using stack-allocated buffers with a DMA-safe buffer for use with spi_read(). This allows the driver to be safely used with DMA-enabled SPI controllers.
The buffer array is also converted to a struct with a union to make the usage of the memory in the buffer more clear and ensure proper alignment.
--- drivers/iio/temperature/maxim_thermocouple.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
drivers/iio/temperature/maxim_thermocouple.c +16 -10
@@ -12,6 +12,7 @@#include <linux/mutex.h> #include <linux/err.h> #include <linux/spi/spi.h> +#include <linux/types.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/iio/trigger.h>
@@ -122,8 +123,15 @@ struct maxim_thermocouple_data {struct spi_device *spi;const struct maxim_thermocouple_chip *chip;char tc_type; - -u8 buffer[16 ]__aligned(IIO_DMA_MINALIGN) ; +/* Buffer for reading up to 2 hardware channels. */ +struct { +union { +__be16 raw16; +__be32 raw32; +__be16 raw[2 ]; + }; +aligned_s64 timestamp; + } buffer__aligned(IIO_DMA_MINALIGN) ; }; static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,
@@ -131,18 +139,16 @@ static int maxim_thermocouple_read(struc {unsigned int storage_bytes = data->chip->read_size;unsigned int shift = chan->scan_type.shift + (chan->address *8 ); -__be16 buf16; -__be32 buf32;int ret;switch (storage_bytes) {case 2 : - ret =spi_read (data->spi, (void *)&buf16, storage_bytes); - *val =be16_to_cpu (buf16); + ret =spi_read (data->spi, &data->buffer.raw16, storage_bytes); + *val =be16_to_cpu (data->buffer.raw16);break ;case 4 : - ret =spi_read (data->spi, (void *)&buf32, storage_bytes); - *val =be32_to_cpu (buf32); + ret =spi_read (data->spi, &data->buffer.raw32, storage_bytes); + *val =be32_to_cpu (data->buffer.raw32);break ;default : ret = -EINVAL ;
@@ -167,9 +173,9 @@ static irqreturn_t maxim_thermocouple_trstruct maxim_thermocouple_data *data =iio_priv (indio_dev);int ret; - ret =spi_read (data->spi, data->buffer, data->chip->read_size); + ret =spi_read (data->spi, data->buffer.raw, data->chip->read_size);if (!ret) { -iio_push_to_buffers_with_timestamp (indio_dev, data->buffer, +iio_push_to_buffers_with_timestamp (indio_dev, &data->buffer,iio_get_time_ns (indio_dev)); }
Greg Kroah-Hartman
maintainerPATCH 239/322 tracing: Remove unneeded goto out logic
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
[ Upstream commit c89504a703fb779052213add0e8ed642f4a4f1c8 ]
Several places in the trace.c file there's a goto out where the out is simply a return. There's no reason to jump to the out label if it's not doing any more logic but simply returning from the function.
Replace the goto outs with a return and remove the out labels.
Stable-dep-of: 6a909ea83f22 ("tracing: Limit access to parser->buffer when trace_get_user failed")
--- kernel/trace/trace.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-)
kernel/trace/trace.c +15 -23
@@ -1754,7 +1754,7 @@ int trace_get_user(struct trace_parser * ret =get_user (ch, ubuf++);if (ret) - goto out; +return ret; read++; cnt--;
@@ -1768,7 +1768,7 @@ int trace_get_user(struct trace_parser *while (cnt &&isspace (ch)) { ret =get_user (ch, ubuf++);if (ret) - goto out; +return ret; read++; cnt--; }
@@ -1778,8 +1778,7 @@ int trace_get_user(struct trace_parser */* only spaces were written */ if (isspace (ch) || !ch) { *ppos += read; - ret = read; - goto out; +return read; } }
@@ -1787,13 +1786,12 @@ int trace_get_user(struct trace_parser *while (cnt && !isspace (ch) && ch) {if (parser->idx < parser->size -1 ) parser->buffer[parser->idx++] = ch; -else { - ret = -EINVAL ; - goto out; - } +else +return -EINVAL ; + ret =get_user (ch, ubuf++);if (ret) - goto out; +return ret; read++; cnt--; }
@@ -1808,15 +1806,11 @@ int trace_get_user(struct trace_parser */* Make sure the parsed string always terminates with '\0'. */ parser->buffer[parser->idx] =0 ; }else { - ret = -EINVAL ; - goto out; +return -EINVAL ; } *ppos += read; - ret = read; - -out: -return ret; +return read; }/* TODO add a seq_buf_to_buffer() */
@@ -2318,10 +2312,10 @@ int __init register_tracer(struct tracermutex_unlock (&trace_types_lock);if (ret || !default_bootup_tracer) - goto out_unlock; +return ret;if (strncmp (default_bootup_tracer, type->name,MAX_TRACER_SIZE )) - goto out_unlock; +return 0 ;printk (KERN_INFO "Starting tracer '%s'\n" , type->name);/* Do we want this tracer to start on bootup? */
@@ -2333,8 +2327,7 @@ int __init register_tracer(struct tracer/* disable other selftests, since this will break it. */ disable_tracing_selftest ("running a tracer" ); - out_unlock: -return ret; +return 0 ; }static void tracing_reset_cpu (struct array_buffer *buf,int cpu)
@@ -8563,12 +8556,12 @@ ftrace_trace_snapshot_callback(struct tr out_reg: ret =tracing_arm_snapshot (tr);if (ret <0 ) - goto out; +return ret; ret =register_ftrace_function_probe (glob, tr, ops, count);if (ret <0 )tracing_disarm_snapshot (tr); - out: +return ret <0 ? ret :0 ; }
@@ -10469,7 +10462,7 @@ __init static int tracer_alloc_buffers(vBUILD_BUG_ON (TRACE_ITER_LAST_BIT >TRACE_FLAGS_MAX_SIZE );if (!alloc_cpumask_var (&tracing_buffer_mask,GFP_KERNEL )) - goto out; +return -ENOMEM ;if (!alloc_cpumask_var (&global_trace.tracing_cpumask,GFP_KERNEL )) goto out_free_buffer_mask;
@@ -10582,7 +10575,6 @@ out_free_cpumask:free_cpumask_var (global_trace.tracing_cpumask); out_free_buffer_mask:free_cpumask_var (tracing_buffer_mask); -out:return ret; }
Greg Kroah-Hartman
maintainerPATCH 240/322 tracing: Limit access to parser->buffer when trace_get_user failed
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pu Lehui <[email protected]>
[ Upstream commit 6a909ea83f226803ea0e718f6e88613df9234d58 ]
When the length of the string written to set_ftrace_filter exceeds FTRACE_BUFF_MAX, the following KASAN alarm will be triggered:
BUG: KASAN: slab-out-of-bounds in strsep+0x18c/0x1b0 Read of size 1 at addr ffff0000d00bd5ba by task ash/165 CPU: 1 UID: 0 PID: 165 Comm: ash Not tainted 6.16.0-g6bcdbd62bd56-dirty Hardware name: linux,dummy-virt (DT) Call trace: show_stack+0x34/0x50 (C) dump_stack_lvl+0xa0/0x158 print_address_description.constprop.0+0x88/0x398 print_report+0xb0/0x280 kasan_report+0xa4/0xf0 __asan_report_load1_noabort+0x20/0x30 strsep+0x18c/0x1b0 ftrace_process_regex.isra.0+0x100/0x2d8 ftrace_regex_release+0x484/0x618 __fput+0x364/0xa58 ____fput+0x28/0x40 task_work_run+0x154/0x278 do_notify_resume+0x1f0/0x220 el0_svc+0xec/0xf0 el0t_64_sync_handler+0xa0/0xe8 el0t_64_sync+0x1ac/0x1b0
The reason is that trace_get_user will fail when processing a string longer than FTRACE_BUFF_MAX, but not set the end of parser->buffer to 0. Then an OOB access will be triggered in ftrace_regex_release-> ftrace_process_regex->strsep->strpbrk. We can solve this problem by limiting access to parser->buffer when trace_get_user failed.
--- kernel/trace/trace.c | 18 ++++++++++++------ kernel/trace/trace.h | 8 +++++++- 2 files changed, 19 insertions(+), 7 deletions(-)
kernel/trace/trace.c +12 -6
@@ -1754,7 +1754,7 @@ int trace_get_user(struct trace_parser * ret =get_user (ch, ubuf++);if (ret) -return ret; + goto fail; read++; cnt--;
@@ -1768,7 +1768,7 @@ int trace_get_user(struct trace_parser *while (cnt &&isspace (ch)) { ret =get_user (ch, ubuf++);if (ret) -return ret; + goto fail; read++; cnt--; }
@@ -1786,12 +1786,14 @@ int trace_get_user(struct trace_parser *while (cnt && !isspace (ch) && ch) {if (parser->idx < parser->size -1 ) parser->buffer[parser->idx++] = ch; -else -return -EINVAL ; +else { + ret = -EINVAL ; + goto fail; + } ret =get_user (ch, ubuf++);if (ret) -return ret; + goto fail; read++; cnt--; }
@@ -1806,11 +1808,15 @@ int trace_get_user(struct trace_parser */* Make sure the parsed string always terminates with '\0'. */ parser->buffer[parser->idx] =0 ; }else { -return -EINVAL ; + ret = -EINVAL ; + goto fail; } *ppos += read;return read; +fail: +trace_parser_fail (parser); +return ret; }/* TODO add a seq_buf_to_buffer() */
kernel/trace/trace.h +7 -1
@@ -1230,6 +1230,7 @@ bool ftrace_event_is_function(struct tra*/ struct trace_parser {bool cont; +bool fail;char *buffer;unsigned idx;unsigned size;
@@ -1237,7 +1238,7 @@ struct trace_parser {static inline bool trace_parser_loaded (struct trace_parser *parser) { -return (parser->idx !=0 ); +return !parser->fail && parser->idx !=0 ; }static inline bool trace_parser_cont (struct trace_parser *parser)
@@ -1251,6 +1252,11 @@ static inline void trace_parser_clear(st parser->idx =0 ; } +static inline void trace_parser_fail (struct trace_parser *parser) +{ + parser->fail = true; +} +extern int trace_parser_get_init (struct trace_parser *parser,int size);extern void trace_parser_put (struct trace_parser *parser); extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
Greg Kroah-Hartman
maintainerPATCH 241/322 drm/i915/icl+/tc: Convert AUX powered WARN to a debug message
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
[ Upstream commit d7fa5754e83cd36c4327eb2d806064e598a72ff6 ]
The BIOS can leave the AUX power well enabled on an output, even if this isn't required (on platforms where the AUX power is only needed for an AUX access). This was observed at least on PTL. To avoid the WARN which would be triggered by this during the HW readout, convert the WARN to a debug message.
--- drivers/gpu/drm/i915/display/intel_tc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/display/intel_tc.c +2 -1
@@ -1416,7 +1416,8 @@ static void intel_tc_port_reset_mode(str aux_domain =intel_aux_power_domain (dig_port); aux_powered =intel_display_power_is_enabled (i915, aux_domain); -drm_WARN_ON (&i915->drm, aux_powered); +drm_dbg_kms (&i915->drm,"Port %s: AUX powered %d\n" , + tc->port_name, aux_powered); }tc_phy_disconnect (tc);
Greg Kroah-Hartman
maintainerPATCH 242/322 compiler: remove __ADDRESSABLE_ASM{_STR,}() again
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Beulich <[email protected]>
[ Upstream commit 8ea815399c3fcce1889bd951fec25b5b9a3979c1 ]
__ADDRESSABLE_ASM_STR() is where the necessary stringification happens. As long as "sym" doesn't contain any odd characters, no quoting is required for its use with .quad / .long. In fact the quotation gets in the way with gas 2.25; it's only from 2.26 onwards that quoted symbols are half-way properly supported.
However, assembly being different from C anyway, drop __ADDRESSABLE_ASM_STR() and its helper macro altogether. A simple .global directive will suffice to get the symbol "declared", i.e. into the symbol table. While there also stop open-coding STATIC_CALL_TRAMP() and STATIC_CALL_KEY().
Message-ID: <[email protected]>
--- arch/x86/include/asm/xen/hypercall.h | 5 +++-- include/linux/compiler.h | 8 -------- 2 files changed, 3 insertions(+), 10 deletions(-)
arch/x86/include/asm/xen/hypercall.h +3 -2
@@ -94,12 +94,13 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_h#ifdef MODULE #define __ADDRESSABLE_xen_hypercall#else -#define __ADDRESSABLE_xen_hypercall __ADDRESSABLE_ASM_STR(__SCK__xen_hypercall) +#define __ADDRESSABLE_xen_hypercall \ + __stringify(.global STATIC_CALL_KEY(xen_hypercall);)#endif #define __HYPERCALL \ __ADDRESSABLE_xen_hypercall \ - "call __SCT__xen_hypercall" + __stringify(call STATIC_CALL_TRAMP(xen_hypercall))#define __HYPERCALL_ENTRY (x) "a" (x)
include/linux/compiler.h +0 -8
@@ -223,14 +223,6 @@ static inline void *offset_to_ptr(const#define __ADDRESSABLE (sym) \ ___ADDRESSABLE(sym, __section(".discard.addressable")) -#define __ADDRESSABLE_ASM (sym) \ - .pushsection .discard.addressable,"aw"; \ - .align ARCH_SEL(8,4); \ - ARCH_SEL(.quad, .long) __stringify(sym); \ - .popsection; - -#define __ADDRESSABLE_ASM_STR (sym) __stringify(__ADDRESSABLE_ASM(sym)) -/* &a[0] degrades to a pointer: a different type from an array */ #define __must_be_array (a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
Greg Kroah-Hartman
maintainerPATCH 243/322 drm/i915/icl+/tc: Cache the max lane count value
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
[ Upstream commit 5fd35236546abe780eaadb7561e09953719d4fc3 ]
The PHY's pin assignment value in the TCSS_DDI_STATUS register - as set by the HW/FW based on the connected DP-alt sink's TypeC/PD pin assignment negotiation - gets cleared by the HW/FW on LNL+ as soon as the sink gets disconnected, even if the PHY ownership got acquired already by the driver (and hence the PHY itself is still connected and used by the display). This is similar to how the PHY Ready flag gets cleared on LNL+ in the same register.
To be able to query the max lane count value on LNL+ - which is based on the above pin assignment - at all times even after the sink gets disconnected, the max lane count must be determined and cached during the PHY's HW readout and connect sequences. Do that here, leaving the actual use of the cached value to a follow-up change.
v2: Don't read out the pin configuration if the PHY is disconnected.
--- drivers/gpu/drm/i915/display/intel_tc.c | 55 +++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 8 deletions(-)
drivers/gpu/drm/i915/display/intel_tc.c +47 -8
@@ -63,6 +63,7 @@ struct intel_tc_port {enum tc_port_mode init_mode;enum phy_fia phy_fia;u8 phy_fia_idx; +u8 max_lane_count; }; static enum intel_display_power_domain
@@ -366,12 +367,12 @@ static int intel_tc_port_get_max_lane_co } } -int intel_tc_port_max_lane_count (struct intel_digital_port *dig_port) +static int get_max_lane_count (struct intel_tc_port *tc) { +struct intel_digital_port *dig_port = tc->dig_port;struct drm_i915_private *i915 =to_i915 (dig_port->base.base.dev); -struct intel_tc_port *tc =to_tc_port (dig_port); -if (!intel_encoder_is_tc (&dig_port->base) || tc->mode !=TC_PORT_DP_ALT ) +if (tc->mode !=TC_PORT_DP_ALT )return 4 ;assert_tc_cold_blocked (tc);
@@ -385,6 +386,21 @@ int intel_tc_port_max_lane_count(structreturn intel_tc_port_get_max_lane_count (dig_port); } +static void read_pin_configuration (struct intel_tc_port *tc) +{ + tc->max_lane_count =get_max_lane_count (tc); +} + +int intel_tc_port_max_lane_count (struct intel_digital_port *dig_port) +{ +struct intel_tc_port *tc =to_tc_port (dig_port); + +if (!intel_encoder_is_tc (&dig_port->base)) +return 4 ; + +return get_max_lane_count (tc); +} +void intel_tc_port_set_fia_lane_count (struct intel_digital_port *dig_port,int required_lanes) {
@@ -597,9 +613,12 @@ static void icl_tc_phy_get_hw_state(stru tc_cold_wref =__tc_cold_block (tc, &domain); tc->mode =tc_phy_get_current_mode (tc); -if (tc->mode !=TC_PORT_DISCONNECTED ) +if (tc->mode !=TC_PORT_DISCONNECTED ) { tc->lock_wakeref =tc_cold_block (tc); +read_pin_configuration (tc); + } +__tc_cold_unblock (tc, domain, tc_cold_wref); }
@@ -657,8 +676,11 @@ static bool icl_tc_phy_connect(struct in tc->lock_wakeref =tc_cold_block (tc); -if (tc->mode ==TC_PORT_TBT_ALT ) +if (tc->mode ==TC_PORT_TBT_ALT ) { +read_pin_configuration (tc); +return true; + } if ((!tc_phy_is_ready(tc) || !icl_tc_phy_take_ownership(tc, true)) &&
@@ -669,6 +691,7 @@ static bool icl_tc_phy_connect(struct in goto out_unblock_tc_cold; } +read_pin_configuration (tc);if (!tc_phy_verify_legacy_or_dp_alt_mode (tc, required_lanes)) goto out_release_phy;
@@ -859,9 +882,12 @@ static void adlp_tc_phy_get_hw_state(str port_wakeref =intel_display_power_get (i915, port_power_domain); tc->mode =tc_phy_get_current_mode (tc); -if (tc->mode !=TC_PORT_DISCONNECTED ) +if (tc->mode !=TC_PORT_DISCONNECTED ) { tc->lock_wakeref =tc_cold_block (tc); +read_pin_configuration (tc); + } +intel_display_power_put (i915, port_power_domain, port_wakeref); }
@@ -874,6 +900,9 @@ static bool adlp_tc_phy_connect(struct iif (tc->mode ==TC_PORT_TBT_ALT ) { tc->lock_wakeref =tc_cold_block (tc); + +read_pin_configuration (tc); +return true; }
@@ -895,6 +924,8 @@ static bool adlp_tc_phy_connect(struct i tc->lock_wakeref =tc_cold_block (tc); +read_pin_configuration (tc); +if (!tc_phy_verify_legacy_or_dp_alt_mode (tc, required_lanes)) goto out_unblock_tc_cold;
@@ -1094,9 +1125,12 @@ static void xelpdp_tc_phy_get_hw_state(s tc_cold_wref =__tc_cold_block (tc, &domain); tc->mode =tc_phy_get_current_mode (tc); -if (tc->mode !=TC_PORT_DISCONNECTED ) +if (tc->mode !=TC_PORT_DISCONNECTED ) { tc->lock_wakeref =tc_cold_block (tc); +read_pin_configuration (tc); + } +drm_WARN_ON (&i915->drm, (tc->mode ==TC_PORT_DP_ALT || tc->mode ==TC_PORT_LEGACY ) && !xelpdp_tc_phy_tcss_power_is_enabled (tc));
@@ -1108,14 +1142,19 @@ static bool xelpdp_tc_phy_connect(struct { tc->lock_wakeref =tc_cold_block (tc); -if (tc->mode ==TC_PORT_TBT_ALT ) +if (tc->mode ==TC_PORT_TBT_ALT ) { +read_pin_configuration (tc); +return true; + }if (!xelpdp_tc_phy_enable_tcss_power (tc, true)) goto out_unblock_tccold;xelpdp_tc_phy_take_ownership (tc, true); +read_pin_configuration (tc); +if (!tc_phy_verify_legacy_or_dp_alt_mode (tc, required_lanes)) goto out_release_phy;
Greg Kroah-Hartman
maintainerPATCH 244/322 ovl: use I_MUTEX_PARENT when locking parent in ovl_create_temp()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit 5f1c8965e748c150d580a2ea8fbee1bd80d07a24 upstream.
ovl_create_temp() treats "workdir" as a parent in which it creates an object so it should use I_MUTEX_PARENT.
Prior to the commit identified below the lock was taken by the caller which sometimes used I_MUTEX_PARENT and sometimes used I_MUTEX_NORMAL. The use of I_MUTEX_NORMAL was incorrect but unfortunately copied into ovl_create_temp().
Note to backporters: This patch only applies after the last Fixes given below (post v6.16). To fix the bug in v6.7 and later the inode_lock() call in ovl_copy_up_workdir() needs to nest using I_MUTEX_PARENT.
--- fs/overlayfs/copy_up.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/overlayfs/copy_up.c +1 -1
@@ -780,7 +780,7 @@ static int ovl_copy_up_workdir(struct ovreturn err;ovl_start_write (c->dentry); -inode_lock (wdir); +inode_lock_nested (wdir,I_MUTEX_PARENT ); temp =ovl_create_temp (ofs, c->workdir, &cattr);inode_unlock (wdir);ovl_end_write (c->dentry);
Greg Kroah-Hartman
maintainerPATCH 245/322 powerpc/boot: Fix build with gcc 15
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Suchanek <[email protected]>
commit 5a821e2d69e26b51b7f3740b6b0c3462b8cacaff upstream.
Similar to x86 the ppc boot code does not build with GCC 15.
Copy the fix from
commit ee2ab467bddf ("x86/boot: Use '-std=gnu11' to fix build with GCC 15")
--- arch/powerpc/boot/Makefile | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/boot/Makefile +1 -0
@@ -70,6 +70,7 @@ BOOTCPPFLAGS := -nostdinc $(LINUXINCLUDE BOOTCPPFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include) BOOTCFLAGS := $(BOOTTARGETFLAGS) \ + -std=gnu11 \ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -O2 \ -msoft-float -mno-altivec -mno-vsx \
Greg Kroah-Hartman
maintainerPATCH 246/322 tls: fix handling of zero-length records on the rx_list
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
commit 62708b9452f8eb77513115b17c4f8d1a22ebf843 upstream.
Each recvmsg() call must process either
- only contiguous DATA records (any number of them)
- one non-DATA record
If the next record has different type than what has already been processed we break out of the main processing loop. If the record has already been decrypted (which may be the case for TLS 1.3 where we don't know type until decryption) we queue the pending record to the rx_list. Next recvmsg() will pick it up from there.
Queuing the skb to rx_list after zero-copy decrypt is not possible, since in that case we decrypted directly to the user space buffer, and we don't have an skb to queue (darg.skb points to the ciphertext skb for access to metadata like length).
Only data records are allowed zero-copy, and we break the processing loop after each non-data record. So we should never zero-copy and then find out that the record type has changed. The corner case we missed is when the initial record comes from rx_list, and it's zero length.
--- net/tls/tls_sw.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
net/tls/tls_sw.c +6 -1
@@ -1774,6 +1774,9 @@ int decrypt_skb(struct sock *sk, structreturn tls_decrypt_sg (sk,NULL , sgout, &darg); } +/* All records returned from a recvmsg() call must have the same type. +* 0 is not a valid content type. Use it as "no type reported, yet". +*/ static int tls_record_content_type (struct msghdr *msg,struct tls_msg *tlm,u8 *control) {
@@ -2017,8 +2020,10 @@ int tls_sw_recvmsg(struct sock *sk,if (err <0 ) goto end; +/* process_rx_list() will set @control if it processed any records */ copied = err; -if (len <= copied || (copied && control !=TLS_RECORD_TYPE_DATA ) || rx_more) +if (len <= copied || rx_more || + (control && control !=TLS_RECORD_TYPE_DATA )) goto end; target =sock_rcvlowat (sk, flags &MSG_WAITALL , len);
Greg Kroah-Hartman
maintainerPATCH 247/322 iio: imu: inv_icm42600: switch timestamp type from int64_t __aligned(8) to aligned_s64
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cameron <[email protected]>
[ Upstream commit 27e6ddf291b1c05bfcc3534e8212ed6c46447c60 ]
The vast majority of IIO drivers use aligned_s64 for the type of the timestamp field. It is not a bug to use int64_t and until this series iio_push_to_buffers_with_timestamp() took and int64_t timestamp, it is inconsistent. This change is to remove that inconsistency and ensure there is one obvious choice for future drivers.
Stable-dep-of: dfdc31e7ccf3 ("iio: imu: inv_icm42600: change invalid data error to -EBUSY")
--- drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 2 +- drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +1 -1
@@ -178,7 +178,7 @@ static const struct iio_chan_spec inv_icstruct inv_icm42600_accel_buffer {struct inv_icm42600_fifo_sensor_data accel;int16_t temp; -int64_t timestamp__aligned(8) ; +aligned_s64 timestamp; };#define INV_ICM42600_SCAN_MASK_ACCEL_3AXIS \
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +1 -1
@@ -78,7 +78,7 @@ static const struct iio_chan_spec inv_icstruct inv_icm42600_gyro_buffer {struct inv_icm42600_fifo_sensor_data gyro;int16_t temp; -int64_t timestamp__aligned(8) ; +aligned_s64 timestamp; };#define INV_ICM42600_SCAN_MASK_GYRO_3AXIS \
Greg Kroah-Hartman
maintainerPATCH 248/322 iio: imu: inv_icm42600: use = { } instead of memset()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
[ Upstream commit 352112e2d9aab6a156c2803ae14eb89a9fd93b7d ]
Use { } instead of memset() to zero-initialize stack memory to simplify the code.
Stable-dep-of: dfdc31e7ccf3 ("iio: imu: inv_icm42600: change invalid data error to -EBUSY")
--- drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 5 ++--- drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-)
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +2 -3
@@ -905,7 +905,8 @@ int inv_icm42600_accel_parse_fifo(structconst int8_t *temp;unsigned int odr;int64_t ts_val; -struct inv_icm42600_accel_buffer buffer; +/* buffer is copied to userspace, zeroing it to avoid any data leak */ +struct inv_icm42600_accel_buffer buffer = { };/* parse all fifo packets */ for (i =0 , no =0 ; i < st->fifo.count; i += size, ++no) {
@@ -924,8 +925,6 @@ int inv_icm42600_accel_parse_fifo(structinv_sensors_timestamp_apply_odr (ts, st->fifo.period, st->fifo.nb.total, no); -/* buffer is copied to userspace, zeroing it to avoid any data leak */ -memset (&buffer,0 ,sizeof (buffer));memcpy (&buffer.accel, accel,sizeof (buffer.accel));/* convert 8 bits FIFO temperature in high resolution format */ buffer.temp = temp ? (*temp *64 ) :0 ;
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +2 -3
@@ -809,7 +809,8 @@ int inv_icm42600_gyro_parse_fifo(structconst int8_t *temp;unsigned int odr;int64_t ts_val; -struct inv_icm42600_gyro_buffer buffer; +/* buffer is copied to userspace, zeroing it to avoid any data leak */ +struct inv_icm42600_gyro_buffer buffer = { };/* parse all fifo packets */ for (i =0 , no =0 ; i < st->fifo.count; i += size, ++no) {
@@ -828,8 +829,6 @@ int inv_icm42600_gyro_parse_fifo(structinv_sensors_timestamp_apply_odr (ts, st->fifo.period, st->fifo.nb.total, no); -/* buffer is copied to userspace, zeroing it to avoid any data leak */ -memset (&buffer,0 ,sizeof (buffer));memcpy (&buffer.gyro, gyro,sizeof (buffer.gyro));/* convert 8 bits FIFO temperature in high resolution format */ buffer.temp = temp ? (*temp *64 ) :0 ;
Greg Kroah-Hartman
maintainerPATCH 249/322 iio: imu: inv_icm42600: Convert to uXX and sXX integer types
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit a4135386fa49c2a170b89296da12c4a3be2089d9 ]
The driver code is full of intXX_t and uintXX_t types which is not the pattern we use in the IIO subsystem. Switch the driver to use kernel internal types for that. No functional changes.
Stable-dep-of: dfdc31e7ccf3 ("iio: imu: inv_icm42600: change invalid data error to -EBUSY")
--- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 8 ++-- drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 26 +++++++-------- drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c | 22 ++++++------ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h | 10 ++--- drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 6 +-- drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c | 36 ++++++++++----------- drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c | 6 +-- 7 files changed, 57 insertions(+), 57 deletions(-)
drivers/iio/imu/inv_icm42600/inv_icm42600.h +4 -4
@@ -164,11 +164,11 @@ struct inv_icm42600_state {struct inv_icm42600_suspended suspended;struct iio_dev *indio_gyro;struct iio_dev *indio_accel; -uint8_t buffer[2 ]__aligned(IIO_DMA_MINALIGN) ; +u8 buffer[2 ]__aligned(IIO_DMA_MINALIGN) ;struct inv_icm42600_fifo fifo;struct { -int64_t gyro; -int64_t accel; +s64 gyro; +s64 accel; } timestamp; };
@@ -410,7 +410,7 @@ const struct iio_mount_matrix * inv_icm42600_get_mount_matrix(const struct iio_dev *indio_dev, const struct iio_chan_spec *chan); -uint32_t inv_icm42600_odr_to_period (enum inv_icm42600_odr odr); +u32 inv_icm42600_odr_to_period (enum inv_icm42600_odr odr); int inv_icm42600_set_accel_conf(struct inv_icm42600_state *st, struct inv_icm42600_sensor_conf *conf,
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +13 -13
@@ -177,7 +177,7 @@ static const struct iio_chan_spec inv_ic*/ struct inv_icm42600_accel_buffer {struct inv_icm42600_fifo_sensor_data accel; -int16_t temp; +s16 temp;aligned_s64 timestamp; };
@@ -241,7 +241,7 @@ out_unlock:static int inv_icm42600_accel_read_sensor (struct iio_dev *indio_dev,struct iio_chan_spec const *chan, -int16_t *val) +s16 *val) {struct inv_icm42600_state *st =iio_device_get_drvdata (indio_dev);struct inv_icm42600_sensor_state *accel_st =iio_priv (indio_dev);
@@ -284,7 +284,7 @@ static int inv_icm42600_accel_read_sensoif (ret) goto exit; - *val = (int16_t )be16_to_cpup (data); + *val = (s16 )be16_to_cpup (data);if (*val ==INV_ICM42600_DATA_INVALID ) ret = -EINVAL ; exit:
@@ -492,11 +492,11 @@ static int inv_icm42600_accel_read_offse int *val, int *val2) { struct device *dev = regmap_get_device(st->map); -int64_t val64; -int32_t bias; +s64 val64; +s32 bias;unsigned int reg; -int16_t offset; -uint8_t data[2 ]; +s16 offset; +u8 data[2 ];int ret;if (chan->type !=IIO_ACCEL )
@@ -550,7 +550,7 @@ static int inv_icm42600_accel_read_offse* result in micro (1000000) * (offset * 5 * 9.806650 * 1000000) / 10000 */ - val64 = (int64_t )offset *5LL *9806650LL ; + val64 = (s64 )offset *5LL *9806650LL ;/* for rounding, add + or - divisor (10000) divided by 2 */ if (val64 >=0 ) val64 +=10000LL /2LL ;
@@ -568,10 +568,10 @@ static int inv_icm42600_accel_write_offs int val, int val2) {struct device *dev =regmap_get_device (st->map); -int64_t val64; -int32_t min, max; +s64 val64; +s32 min, max;unsigned int reg, regval; -int16_t offset; +s16 offset;int ret;if (chan->type !=IIO_ACCEL )
@@ -596,7 +596,7 @@ static int inv_icm42600_accel_write_offs inv_icm42600_accel_calibbias[1 ]; max = inv_icm42600_accel_calibbias[4 ] *1000000L + inv_icm42600_accel_calibbias[5 ]; - val64 = (int64_t )val *1000000LL + (int64_t )val2; + val64 = (s64 )val *1000000LL + (s64 )val2;if (val64 < min || val64 > max)return -EINVAL ;
@@ -671,7 +671,7 @@ static int inv_icm42600_accel_read_raw(s int *val, int *val2, long mask) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); -int16_t data; +s16 data;int ret;switch (chan->type) {
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c +11 -11
@@ -26,28 +26,28 @@#define INV_ICM42600_FIFO_HEADER_ODR_GYRO BIT(0)struct inv_icm42600_fifo_1sensor_packet { -uint8_t header; +u8 header;struct inv_icm42600_fifo_sensor_data data; -int8_t temp; +s8 temp; } __packed;#define INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE 8struct inv_icm42600_fifo_2sensors_packet { -uint8_t header; +u8 header;struct inv_icm42600_fifo_sensor_data accel;struct inv_icm42600_fifo_sensor_data gyro; -int8_t temp; +s8 temp;__be16 timestamp; } __packed;#define INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE 16ssize_t inv_icm42600_fifo_decode_packet (const void *packet,const void **accel, -const void **gyro,const int8_t **temp, +const void **gyro,const s8 **temp,const void **timestamp,unsigned int *odr) {const struct inv_icm42600_fifo_1sensor_packet *pack1 = packet;const struct inv_icm42600_fifo_2sensors_packet *pack2 = packet; -uint8_t header = *((const uint8_t *)packet); +u8 header = *((const u8 *)packet);/* FIFO empty */ if (header &INV_ICM42600_FIFO_HEADER_MSG ) {
@@ -100,7 +100,7 @@ ssize_t inv_icm42600_fifo_decode_packet(void inv_icm42600_buffer_update_fifo_period (struct inv_icm42600_state *st) { -uint32_t period_gyro, period_accel, period; +u32 period_gyro, period_accel, period;if (st->fifo.en &INV_ICM42600_SENSOR_GYRO ) period_gyro =inv_icm42600_odr_to_period (st->conf.gyro.odr);
@@ -204,8 +204,8 @@ int inv_icm42600_buffer_update_watermark {size_t packet_size, wm_size;unsigned int wm_gyro, wm_accel, watermark; -uint32_t period_gyro, period_accel, period; -uint32_t latency_gyro, latency_accel, latency; +u32 period_gyro, period_accel, period; +u32 latency_gyro, latency_accel, latency;bool restore;__le16 raw_wm;int ret;
@@ -459,7 +459,7 @@ int inv_icm42600_buffer_fifo_read(struct__be16 *raw_fifo_count;ssize_t i, size;const void *accel, *gyro, *timestamp; -const int8_t *temp; +const s8 *temp;unsigned int odr;int ret;
@@ -550,7 +550,7 @@ int inv_icm42600_buffer_hwfifo_flush(strstruct inv_icm42600_sensor_state *gyro_st =iio_priv (st->indio_gyro);struct inv_icm42600_sensor_state *accel_st =iio_priv (st->indio_accel);struct inv_sensors_timestamp *ts; -int64_t gyro_ts, accel_ts; +s64 gyro_ts, accel_ts;int ret; gyro_ts =iio_get_time_ns (st->indio_gyro);
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h +5 -5
@@ -28,7 +28,7 @@ struct inv_icm42600_state;struct inv_icm42600_fifo {unsigned int on;unsigned int en; -uint32_t period; +u32 period;struct {unsigned int gyro;unsigned int accel;
@@ -41,7 +41,7 @@ struct inv_icm42600_fifo {size_t accel;size_t total; } nb; -uint8_t data[2080 ]__aligned(IIO_DMA_MINALIGN) ; +u8 data[2080 ]__aligned(IIO_DMA_MINALIGN) ; };/* FIFO data packet */
@@ -52,7 +52,7 @@ struct inv_icm42600_fifo_sensor_data { } __packed;#define INV_ICM42600_FIFO_DATA_INVALID -32768 -static inline int16_t inv_icm42600_fifo_get_sensor_data (__be16 d) +static inline s16 inv_icm42600_fifo_get_sensor_data (__be16 d) {return be16_to_cpu (d); }
@@ -60,7 +60,7 @@ static inline int16_t inv_icm42600_fifo_static inline bool inv_icm42600_fifo_is_data_valid (const struct inv_icm42600_fifo_sensor_data *s) { -int16_t x, y, z; +s16 x, y, z; x =inv_icm42600_fifo_get_sensor_data (s->x); y =inv_icm42600_fifo_get_sensor_data (s->y);
@@ -75,7 +75,7 @@ inv_icm42600_fifo_is_data_valid(const st }ssize_t inv_icm42600_fifo_decode_packet (const void *packet,const void **accel, -const void **gyro,const int8_t **temp, +const void **gyro,const s8 **temp,const void **timestamp,unsigned int *odr);extern const struct iio_buffer_setup_ops inv_icm42600_buffer_ops;
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +3 -3
@@ -103,7 +103,7 @@ const struct regmap_config inv_icm42600_EXPORT_SYMBOL_NS_GPL (inv_icm42600_spi_regmap_config,IIO_ICM42600 );struct inv_icm42600_hw { -uint8_t whoami; +u8 whoami;const char *name;const struct inv_icm42600_conf *conf; };
@@ -188,9 +188,9 @@ inv_icm42600_get_mount_matrix(const strureturn &st->orientation; } -uint32_t inv_icm42600_odr_to_period (enum inv_icm42600_odr odr) +u32 inv_icm42600_odr_to_period (enum inv_icm42600_odr odr) { -static uint32_t odr_periods[INV_ICM42600_ODR_NB ] = { +static u32 odr_periods[INV_ICM42600_ODR_NB ] = {/* reserved values */ 0 ,0 ,0 ,/* 8kHz */
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +18 -18
@@ -77,7 +77,7 @@ static const struct iio_chan_spec inv_ic*/ struct inv_icm42600_gyro_buffer {struct inv_icm42600_fifo_sensor_data gyro; -int16_t temp; +s16 temp;aligned_s64 timestamp; };
@@ -139,7 +139,7 @@ out_unlock:static int inv_icm42600_gyro_read_sensor (struct inv_icm42600_state *st,struct iio_chan_spec const *chan, -int16_t *val) +s16 *val) {struct device *dev =regmap_get_device (st->map);struct inv_icm42600_sensor_conf conf =INV_ICM42600_SENSOR_CONF_INIT ;
@@ -179,7 +179,7 @@ static int inv_icm42600_gyro_read_sensorif (ret) goto exit; - *val = (int16_t )be16_to_cpup (data); + *val = (s16 )be16_to_cpup (data);if (*val ==INV_ICM42600_DATA_INVALID ) ret = -EINVAL ; exit:
@@ -399,11 +399,11 @@ static int inv_icm42600_gyro_read_offset int *val, int *val2) { struct device *dev = regmap_get_device(st->map); -int64_t val64; -int32_t bias; +s64 val64; +s32 bias;unsigned int reg; -int16_t offset; -uint8_t data[2 ]; +s16 offset; +u8 data[2 ];int ret;if (chan->type !=IIO_ANGL_VEL )
@@ -457,7 +457,7 @@ static int inv_icm42600_gyro_read_offset* result in nano (1000000000) * (offset * 64 * Pi * 1000000000) / (2048 * 180) */ - val64 = (int64_t )offset *64LL *3141592653LL ; + val64 = (s64 )offset *64LL *3141592653LL ;/* for rounding, add + or - divisor (2048 * 180) divided by 2 */ if (val64 >=0 ) val64 +=2048 *180 /2 ;
@@ -475,9 +475,9 @@ static int inv_icm42600_gyro_write_offse int val, int val2) {struct device *dev =regmap_get_device (st->map); -int64_t val64, min, max; +s64 val64, min, max;unsigned int reg, regval; -int16_t offset; +s16 offset;int ret;if (chan->type !=IIO_ANGL_VEL )
@@ -498,11 +498,11 @@ static int inv_icm42600_gyro_write_offse }/* inv_icm42600_gyro_calibbias: min - step - max in nano */ - min = (int64_t )inv_icm42600_gyro_calibbias[0 ] *1000000000LL + - (int64_t )inv_icm42600_gyro_calibbias[1 ]; - max = (int64_t )inv_icm42600_gyro_calibbias[4 ] *1000000000LL + - (int64_t )inv_icm42600_gyro_calibbias[5 ]; - val64 = (int64_t )val *1000000000LL + (int64_t )val2; + min = (s64 )inv_icm42600_gyro_calibbias[0 ] *1000000000LL + + (s64 )inv_icm42600_gyro_calibbias[1 ]; + max = (s64 )inv_icm42600_gyro_calibbias[4 ] *1000000000LL + + (s64 )inv_icm42600_gyro_calibbias[5 ]; + val64 = (s64 )val *1000000000LL + (s64 )val2;if (val64 < min || val64 > max)return -EINVAL ;
@@ -577,7 +577,7 @@ static int inv_icm42600_gyro_read_raw(st int *val, int *val2, long mask) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); -int16_t data; +s16 data;int ret;switch (chan->type) {
@@ -806,9 +806,9 @@ int inv_icm42600_gyro_parse_fifo(structssize_t i, size;unsigned int no;const void *accel, *gyro, *timestamp; -const int8_t *temp; +const s8 *temp;unsigned int odr; -int64_t ts_val; +s64 ts_val;/* buffer is copied to userspace, zeroing it to avoid any data leak */ struct inv_icm42600_gyro_buffer buffer = { };
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +3 -3
@@ -13,7 +13,7 @@#include "inv_icm42600.h" #include "inv_icm42600_temp.h" -static int inv_icm42600_temp_read (struct inv_icm42600_state *st,int16_t *temp) +static int inv_icm42600_temp_read (struct inv_icm42600_state *st,s16 *temp) {struct device *dev =regmap_get_device (st->map);__be16 *raw;
@@ -31,7 +31,7 @@ static int inv_icm42600_temp_read(structif (ret) goto exit; - *temp = (int16_t )be16_to_cpup (raw); + *temp = (s16 )be16_to_cpup (raw);if (*temp ==INV_ICM42600_DATA_INVALID ) ret = -EINVAL ;
@@ -48,7 +48,7 @@ int inv_icm42600_temp_read_raw(struct ii int *val, int *val2, long mask) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); -int16_t temp; +s16 temp;int ret;if (chan->type !=IIO_TEMP )
Greg Kroah-Hartman
maintainerPATCH 250/322 iio: imu: inv_icm42600: change invalid data error to -EBUSY
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jean-Baptiste Maneyrol <[email protected]>
[ Upstream commit dfdc31e7ccf3ac1d5ec01d5120c71e14745e3dd8 ]
Temperature sensor returns the temperature of the mechanical parts of the chip. If both accel and gyro are off, the temperature sensor is also automatically turned off and returns invalid data.
In this case, returning -EBUSY error code is better then -EINVAL and indicates userspace that it needs to retry reading temperature in another context.
--- drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +5 -1
@@ -32,8 +32,12 @@ static int inv_icm42600_temp_read(struct goto exit; *temp = (s16 )be16_to_cpup (raw); +/* +* Temperature data is invalid if both accel and gyro are off. +* Return -EBUSY in this case. +*/ if (*temp ==INV_ICM42600_DATA_INVALID ) - ret = -EINVAL ; + ret = -EBUSY ; exit:mutex_unlock (&st->lock);
Greg Kroah-Hartman
maintainerPATCH 251/322 x86/cpu/hygon: Add missing resctrl_cpu_detect() in bsp_init helper
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianxiang Peng <[email protected]>
commit d8df126349dad855cdfedd6bbf315bad2e901c2f upstream.
Since
923f3a2b48bd ("x86/resctrl: Query LLC monitoring properties once during boot")
resctrl_cpu_detect() has been moved from common CPU initialization code to the vendor-specific BSP init helper, while Hygon didn't put that call in their code.
This triggers a division by zero fault during early booting stage on our machines with X86_FEATURE_CQM* supported, where get_rdt_mon_resources() tries to calculate mon_l3_config with uninitialized boot_cpu_data.x86_cache_occ_scale.
Add the missing resctrl_cpu_detect() in the Hygon BSP init helper.
[ bp: Massage commit message. ]
--- arch/x86/kernel/cpu/hygon.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/kernel/cpu/hygon.c +3 -0
@@ -15,6 +15,7 @@#include <asm/cacheinfo.h> #include <asm/spec-ctrl.h> #include <asm/delay.h> +#include <asm/resctrl.h> #include "cpu.h"
@@ -116,6 +117,8 @@ static void bsp_init_hygon(struct cpuinf x86_amd_ls_cfg_ssbd_mask =1ULL <<10 ; } } + +resctrl_cpu_detect (c); }static void early_init_hygon (struct cpuinfo_x86 *c)
Greg Kroah-Hartman
maintainerPATCH 252/322 spi: spi-fsl-lpspi: Clamp too high speed_hz
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wahren <[email protected]>
[ Upstream commit af357a6a3b7d685e7aa621c6fb1d4ed6c349ec9e ]
Currently the driver is not able to handle the case that a SPI device specifies a higher spi-max-frequency than half of per-clk:
per-clk should be at least two times of transfer speed
Fix this by clamping to the max possible value and use the minimum SCK period of 2 cycles.
--- drivers/spi/spi-fsl-lpspi.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/spi/spi-fsl-lpspi.c +3 -5
@@ -330,13 +330,11 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) }if (config.speed_hz > perclk_rate /2 ) { -dev_err (fsl_lpspi->dev, -"per-clk should be at least two times of transfer speed" ); -return -EINVAL ; + div =2 ; + }else { + div =DIV_ROUND_UP (perclk_rate, config.speed_hz); } - div =DIV_ROUND_UP (perclk_rate, config.speed_hz); -for (prescale =0 ; prescale <= prescale_max; prescale++) { scldiv = div / (1 << prescale) -2 ;if (scldiv >=0 && scldiv <256 ) {
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 253/322 drm/nouveau/nvif: Fix potential memory leak in nvif_vmm_ctor().
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fanhua Li <[email protected]>
[ Upstream commit bb8aeaa3191b617c6faf8ae937252e059673b7ea ]
When the nvif_vmm_type is invalid, we will return error directly without freeing the args in nvif_vmm_ctor(), which leading a memory leak. Fix it by setting the ret -EINVAL and goto done.
--- drivers/gpu/drm/nouveau/nvif/vmm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nvif/vmm.c +2 -1
@@ -219,7 +219,8 @@ nvif_vmm_ctor(struct nvif_mmu *mmu, const char *name, s32 oclass,case RAW : args->type =NVIF_VMM_V0_TYPE_RAW ;break ;default :WARN_ON (1 ); -return -EINVAL ; + ret = -EINVAL ; + goto done; }memcpy (args->data, argv, argc);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 254/322 cgroup/cpuset: Use static_branch_enable_cpuslocked() on cpusets_insane_config_key
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <[email protected]>
[ Upstream commit 65f97cc81b0adc5f49cf6cff5d874be0058e3f41 ]
The following lockdep splat was observed.
[ 812.359086] ============================================
[ 812.359089] WARNING: possible recursive locking detected
[ 812.359097] --------------------------------------------
[ 812.359100] runtest.sh/30042 is trying to acquire lock:
[ 812.359105] ffffffffa7f27420 (cpu_hotplug_lock){++++}-{0:0}, at: static_key_enable+0xe/0x20
[ 812.359131]
[ 812.359131] but task is already holding lock:
[ 812.359134] ffffffffa7f27420 (cpu_hotplug_lock){++++}-{0:0}, at: cpuset_write_resmask+0x98/0xa70
:
[ 812.359267] Call Trace:
[ 812.359272] <TASK>
[ 812.359367] cpus_read_lock+0x3c/0xe0
[ 812.359382] static_key_enable+0xe/0x20
[ 812.359389] check_insane_mems_config.part.0+0x11/0x30
[ 812.359398] cpuset_write_resmask+0x9f2/0xa70
[ 812.359411] cgroup_file_write+0x1c7/0x660
[ 812.359467] kernfs_fop_write_iter+0x358/0x530
[ 812.359479] vfs_write+0xabe/0x1250
[ 812.359529] ksys_write+0xf9/0x1d0
[ 812.359558] do_syscall_64+0x5f/0xe0Since commit d74b27d63a8b ("cgroup/cpuset: Change cpuset_rwsem and hotplug lock order"), the ordering of cpu hotplug lock and cpuset_mutex had been reversed. That patch correctly used the cpuslocked version of the static branch API to enable cpusets_pre_enable_key and cpusets_enabled_key, but it didn't do the same for cpusets_insane_config_key.
The cpusets_insane_config_key can be enabled in the check_insane_mems_config() which is called from update_nodemask() or cpuset_hotplug_update_tasks() with both cpu hotplug lock and cpuset_mutex held. Deadlock can happen with a pending hotplug event that tries to acquire the cpu hotplug write lock which will block further cpus_read_lock() attempt from check_insane_mems_config(). Fix that by switching to use static_branch_enable_cpuslocked().
--- kernel/cgroup/cpuset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/cgroup/cpuset.c +1 -1
@@ -267,7 +267,7 @@ static inline void check_insane_mems_config(nodemask_t *nodes) {if (!cpusets_insane_config () &&movable_only_nodes (nodes)) { -static_branch_enable (&cpusets_insane_config_key); +static_branch_enable_cpuslocked (&cpusets_insane_config_key);pr_info ("Unsupported (movable nodes only) cpuset configuration detected (nmask=%*pbl)!\n" "Cpuset allocations might fail even with a lot of memory available.\n" ,nodemask_pr_args (nodes));
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 255/322 cgroup/cpuset: Fix a partition error with CPU hotplug
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <[email protected]>
[ Upstream commit 150e298ae0ccbecff2357a72fbabd80f8849ea6e ]
It was found during testing that an invalid leaf partition with an empty effective exclusive CPU list can become a valid empty partition with no CPU afer an offline/online operation of an unrelated CPU. An empty partition root is allowed in the special case that it has no task in its cgroup and has distributed out all its CPUs to its child partitions. That is certainly not the case here.
The problem is in the cpumask_subsets() test in the hotplug case (update with no new mask) of update_parent_effective_cpumask() as it also returns true if the effective exclusive CPU list is empty. Fix that by addding the cpumask_empty() test to root out this exception case. Also add the cpumask_empty() test in cpuset_hotplug_update_tasks() to avoid calling update_parent_effective_cpumask() for this special case.
--- kernel/cgroup/cpuset.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
kernel/cgroup/cpuset.c +4 -3
@@ -1771,7 +1771,7 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,if (is_partition_valid (cs)) adding =cpumask_and (tmp->addmask, xcpus, parent->effective_xcpus); - }else if (is_partition_invalid (cs) && + }else if (is_partition_invalid (cs) && !cpumask_empty (xcpus) &&cpumask_subset (xcpus, parent->effective_xcpus)) {struct cgroup_subsys_state *css;struct cpuset *child;
@@ -3792,9 +3792,10 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp) partcmd = partcmd_invalidate;/* * On the other hand, an invalid partition root may be transitioned -* back to a regular one. +* back to a regular one with a non-empty effective xcpus. */ - else if (is_partition_valid(parent) && is_partition_invalid(cs)) + else if (is_partition_valid(parent) && is_partition_invalid(cs) && + !cpumask_empty(cs->effective_xcpus)) partcmd = partcmd_update;if (partcmd >=0 ) {
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 256/322 drm/tests: Fix endian warning
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: José Expósito <[email protected]>
[ Upstream commit d28b9d2925b4f773adb21b1fc20260ddc370fb13 ]
When compiling with sparse enabled, this warning is thrown:
warning: incorrect type in argument 2 (different base types)
expected restricted __le32 const [usertype] *buf got unsigned int [usertype] *[assigned] buf
Add a cast to fix it.
--- drivers/gpu/drm/tests/drm_format_helper_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/tests/drm_format_helper_test.c +1 -1
@@ -991,7 +991,7 @@ static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test) NULL : &result->dst_pitch;drm_fb_xrgb8888_to_xrgb2101010 (&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state); - buf =le32buf_to_cpu (test, buf, dst_size /sizeof (u32)); + buf =le32buf_to_cpu (test, (__force const __le32 *)buf, dst_size /sizeof (u32));KUNIT_EXPECT_MEMEQ (test, buf, result->expected, dst_size); buf = dst.vaddr;/* restore original value of buf */
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 257/322 drm/panic: Move drawing functions to drm_draw
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jocelyn Falempe <[email protected]>
[ Upstream commit 31fa2c1ca0b239f64eaf682f1685bbbd74fc0181 ]
Move the color conversions, blit and fill functions to drm_draw.c, so that they can be re-used by drm_log.drm_draw is internal to the drm subsystem, and shouldn't be used by gpu drivers.
Stable-dep-of: 05663d88fd0b ("drm/tests: Fix drm_test_fb_xrgb8888_to_xrgb2101010() on big-endian")
--- drivers/gpu/drm/Kconfig | 5 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_draw.c | 233 ++++++++++++++++++++++++ drivers/gpu/drm/drm_draw_internal.h | 56 ++++++ drivers/gpu/drm/drm_panic.c | 269 +++------------------------- 5 files changed, 324 insertions(+), 240 deletions(-) create mode 100644 drivers/gpu/drm/drm_draw.c create mode 100644 drivers/gpu/drm/drm_draw_internal.h
drivers/gpu/drm/Kconfig +5 -0
@@ -105,10 +105,15 @@ config DRM_KMS_HELPER help CRTC helpers for KMS drivers. +config DRM_DRAW + bool + depends on DRM + config DRM_PANIC bool "Display a user-friendly message when a kernel panic occurs" depends on DRM select FONT_SUPPORT + select DRM_DRAW help Enable a drm panic handler, which will display a user-friendly message when a kernel panic occurs. It's useful when using a user-space
drivers/gpu/drm/Makefile +1 -0
@@ -89,6 +89,7 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \ drm_privacy_screen_x86.o drm-$(CONFIG_DRM_ACCEL) += ../../accel/drm_accel.o drm-$(CONFIG_DRM_PANIC) += drm_panic.o +drm-$(CONFIG_DRM_DRAW) += drm_draw.o drm-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_qr.o obj-$(CONFIG_DRM) += drm.o
drivers/gpu/drm/drm_draw.c new file +233 -0
233 lines not on this page · raw message
drivers/gpu/drm/drm_draw_internal.h new file +56 -0
56 lines not on this page · raw message
drivers/gpu/drm/drm_panic.c +29 -240
350 lines not on this page · raw message
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 258/322 drm/format-helper: Add conversion from XRGB8888 to BGR888
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kerem Karabay <[email protected]>
[ Upstream commit c9043706cb11b8005e145debe0a3211acd08e2c1 ]
Add XRGB8888 emulation helper for devices that only support BGR888.
Stable-dep-of: 05663d88fd0b ("drm/tests: Fix drm_test_fb_xrgb8888_to_xrgb2101010() on big-endian")
--- drivers/gpu/drm/drm_format_helper.c | 54 +++++++++++++ .../gpu/drm/tests/drm_format_helper_test.c | 81 +++++++++++++++++++ include/drm/drm_format_helper.h | 3 + 3 files changed, 138 insertions(+)
drivers/gpu/drm/drm_format_helper.c +54 -0
@@ -702,6 +702,57 @@ void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pi }EXPORT_SYMBOL (drm_fb_xrgb8888_to_rgb888); +static void drm_fb_xrgb8888_to_bgr888_line (void *dbuf,const void *sbuf,unsigned int pixels) +{ +u8 *dbuf8 = dbuf; +const __le32 *sbuf32 = sbuf; +unsigned int x; +u32 pix; + +for (x =0 ; x < pixels; x++) { + pix =le32_to_cpu (sbuf32[x]); +/* write red-green-blue to output in little endianness */ + *dbuf8++ = (pix &0x00ff0000 ) >>16 ; + *dbuf8++ = (pix &0x0000ff00 ) >>8 ; + *dbuf8++ = (pix &0x000000ff ) >>0 ; + } +} + +/** +* drm_fb_xrgb8888_to_bgr888 - Convert XRGB8888 to BGR888 clip buffer +* @dst: Array of BGR888 destination buffers +* @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines +* within @dst; can be NULL if scanlines are stored next to each other. +* @src: Array of XRGB8888 source buffers +* @fb: DRM framebuffer +* @clip: Clip rectangle area to copy +* @state: Transform and conversion state +* +* This function copies parts of a framebuffer to display memory and converts the +* color format during the process. Destination and framebuffer formats must match. The +* parameters @dst, @dst_pitch and @src refer to arrays. Each array must have at +* least as many entries as there are planes in @fb's format. Each entry stores the +* value for the format's respective color plane at the same index. +* +* This function does not apply clipping on @dst (i.e. the destination is at the +* top-left corner). +* +* Drivers can use this function for BGR888 devices that don't natively +* support XRGB8888. +*/ +void drm_fb_xrgb8888_to_bgr888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src,const struct drm_framebuffer *fb, +const struct drm_rect *clip,struct drm_format_conv_state *state) +{ +static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES ] = { +3 , + }; + +drm_fb_xfrm (dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, + drm_fb_xrgb8888_to_bgr888_line); +} +EXPORT_SYMBOL (drm_fb_xrgb8888_to_bgr888); +static void drm_fb_xrgb8888_to_argb8888_line (void *dbuf,const void *sbuf,unsigned int pixels) {__le32 *dbuf32 = dbuf;
@@ -1035,6 +1086,9 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d }else if (dst_format ==DRM_FORMAT_RGB888 ) {drm_fb_xrgb8888_to_rgb888 (dst, dst_pitch, src, fb, clip, state);return 0 ; + }else if (dst_format ==DRM_FORMAT_BGR888 ) { +drm_fb_xrgb8888_to_bgr888 (dst, dst_pitch, src, fb, clip, state); +return 0 ; }else if (dst_format ==DRM_FORMAT_ARGB8888 ) {drm_fb_xrgb8888_to_argb8888 (dst, dst_pitch, src, fb, clip, state);return 0 ;
drivers/gpu/drm/tests/drm_format_helper_test.c +81 -0
129 lines not on this page · raw message
include/drm/drm_format_helper.h +3 -0
@@ -96,6 +96,9 @@ void drm_fb_xrgb8888_to_rgba5551(struct iosys_map *dst, const unsigned int *dst_void drm_fb_xrgb8888_to_rgb888 (struct iosys_map *dst,const unsigned int *dst_pitch,const struct iosys_map *src,const struct drm_framebuffer *fb,const struct drm_rect *clip,struct drm_format_conv_state *state); +void drm_fb_xrgb8888_to_bgr888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src,const struct drm_framebuffer *fb, +const struct drm_rect *clip,struct drm_format_conv_state *state);void drm_fb_xrgb8888_to_argb8888 (struct iosys_map *dst,const unsigned int *dst_pitch,const struct iosys_map *src,const struct drm_framebuffer *fb,const struct drm_rect *clip,struct drm_format_conv_state *state);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 259/322 drm/format-helper: Move helpers for pixel conversion to header file
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
[ Upstream commit c46d18f98261d99711003517c444417a303c7fae ]
The DRM draw helpers contain format-conversion helpers that operate on individual pixels. Move them into an internal header file and adopt them as individual API. Update the draw code accordingly. The pixel helpers will also be useful for other format conversion helpers.
Stable-dep-of: 05663d88fd0b ("drm/tests: Fix drm_test_fb_xrgb8888_to_xrgb2101010() on big-endian")
--- drivers/gpu/drm/drm_draw.c | 100 +++------------------- drivers/gpu/drm/drm_format_internal.h | 119 ++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 89 deletions(-) create mode 100644 drivers/gpu/drm/drm_format_internal.h
drivers/gpu/drm/drm_draw.c +11 -89
@@ -11,85 +11,7 @@#include <drm/drm_fourcc.h> #include "drm_draw_internal.h" - -/* -* Conversions from xrgb8888 -*/ - -static u16 convert_xrgb8888_to_rgb565 (u32 pix) -{ -return ((pix &0x00F80000 ) >>8 ) | - ((pix &0x0000FC00 ) >>5 ) | - ((pix &0x000000F8 ) >>3 ); -} - -static u16 convert_xrgb8888_to_rgba5551 (u32 pix) -{ -return ((pix &0x00f80000 ) >>8 ) | - ((pix &0x0000f800 ) >>5 ) | - ((pix &0x000000f8 ) >>2 ) | -BIT (0 );/* set alpha bit */ -} - -static u16 convert_xrgb8888_to_xrgb1555 (u32 pix) -{ -return ((pix &0x00f80000 ) >>9 ) | - ((pix &0x0000f800 ) >>6 ) | - ((pix &0x000000f8 ) >>3 ); -} - -static u16 convert_xrgb8888_to_argb1555 (u32 pix) -{ -return BIT (15 ) |/* set alpha bit */ - ((pix &0x00f80000 ) >>9 ) | - ((pix &0x0000f800 ) >>6 ) | - ((pix &0x000000f8 ) >>3 ); -} - -static u32 convert_xrgb8888_to_argb8888 (u32 pix) -{ -return pix |GENMASK (31 ,24 );/* fill alpha bits */ -} - -static u32 convert_xrgb8888_to_xbgr8888 (u32 pix) -{ -return ((pix &0x00ff0000 ) >>16 ) <<0 | - ((pix &0x0000ff00 ) >>8 ) <<8 | - ((pix &0x000000ff ) >>0 ) <<16 | - ((pix &0xff000000 ) >>24 ) <<24 ; -} - -static u32 convert_xrgb8888_to_abgr8888 (u32 pix) -{ -return ((pix &0x00ff0000 ) >>16 ) <<0 | - ((pix &0x0000ff00 ) >>8 ) <<8 | - ((pix &0x000000ff ) >>0 ) <<16 | -GENMASK (31 ,24 );/* fill alpha bits */ -} - -static u32 convert_xrgb8888_to_xrgb2101010 (u32 pix) -{ - pix = ((pix &0x000000FF ) <<2 ) | - ((pix &0x0000FF00 ) <<4 ) | - ((pix &0x00FF0000 ) <<6 ); -return pix | ((pix >>8 ) &0x00300C03 ); -} - -static u32 convert_xrgb8888_to_argb2101010 (u32 pix) -{ - pix = ((pix &0x000000FF ) <<2 ) | - ((pix &0x0000FF00 ) <<4 ) | - ((pix &0x00FF0000 ) <<6 ); -return GENMASK (31 ,30 )/* set alpha bits */ | pix | ((pix >>8 ) &0x00300C03 ); -} - -static u32 convert_xrgb8888_to_abgr2101010 (u32 pix) -{ - pix = ((pix &0x00FF0000 ) >>14 ) | - ((pix &0x0000FF00 ) <<4 ) | - ((pix &0x000000FF ) <<22 ); -return GENMASK (31 ,30 )/* set alpha bits */ | pix | ((pix >>8 ) &0x00300C03 ); -} +#include "drm_format_internal.h" /** * drm_draw_color_from_xrgb8888 - convert one pixel from xrgb8888 to the desired format
@@ -104,28 +26,28 @@ u32 drm_draw_color_from_xrgb8888(u32 color, u32 format) {switch (format) {case DRM_FORMAT_RGB565 : -return convert_xrgb8888_to_rgb565 (color); +return drm_pixel_xrgb8888_to_rgb565 (color);case DRM_FORMAT_RGBA5551 : -return convert_xrgb8888_to_rgba5551 (color); +return drm_pixel_xrgb8888_to_rgba5551 (color);case DRM_FORMAT_XRGB1555 : -return convert_xrgb8888_to_xrgb1555 (color); +return drm_pixel_xrgb8888_to_xrgb1555 (color);case DRM_FORMAT_ARGB1555 : -return convert_xrgb8888_to_argb1555 (color); +return drm_pixel_xrgb8888_to_argb1555 (color);case DRM_FORMAT_RGB888 :case DRM_FORMAT_XRGB8888 :return color;case DRM_FORMAT_ARGB8888 : -return convert_xrgb8888_to_argb8888 (color); +return drm_pixel_xrgb8888_to_argb8888 (color);case DRM_FORMAT_XBGR8888 : -return convert_xrgb8888_to_xbgr8888 (color); +return drm_pixel_xrgb8888_to_xbgr8888 (color);case DRM_FORMAT_ABGR8888 : -return convert_xrgb8888_to_abgr8888 (color); +return drm_pixel_xrgb8888_to_abgr8888 (color);case DRM_FORMAT_XRGB2101010 : -return convert_xrgb8888_to_xrgb2101010 (color); +return drm_pixel_xrgb8888_to_xrgb2101010 (color);case DRM_FORMAT_ARGB2101010 : -return convert_xrgb8888_to_argb2101010 (color); +return drm_pixel_xrgb8888_to_argb2101010 (color);case DRM_FORMAT_ABGR2101010 : -return convert_xrgb8888_to_abgr2101010 (color); +return drm_pixel_xrgb8888_to_abgr2101010 (color);default :WARN_ONCE (1 ,"Can't convert to %p4cc\n" , &format);return 0 ;
drivers/gpu/drm/drm_format_internal.h new file +119 -0
119 lines not on this page · raw message
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 260/322 drm/format-helper: Add generic conversion to 32-bit formats
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
[ Upstream commit d55d0b066f4eedf030c9c1a67a2a0abffece3abc ]
Add drm_fb_xfrm_line_32to32() to implement conversion from 32-bit pixels to 32-bit pixels. The pixel-conversion is specified by the given callback parameter. Mark the helper as always_inline to avoid overhead from function calls.
Then implement all existing line-conversion functions with the new generic call and the respective pixel-conversion helper.
Stable-dep-of: 05663d88fd0b ("drm/tests: Fix drm_test_fb_xrgb8888_to_xrgb2101010() on big-endian")
--- drivers/gpu/drm/drm_format_helper.c | 84 +++++++---------------------- 1 file changed, 19 insertions(+), 65 deletions(-)
drivers/gpu/drm/drm_format_helper.c +19 -65
@@ -20,6 +20,8 @@#include <drm/drm_print.h> #include <drm/drm_rect.h> +#include "drm_format_internal.h" +/** * drm_format_conv_state_init - Initialize format-conversion state * @state: The state to initialize
@@ -244,6 +246,18 @@ static int drm_fb_xfrm(struct iosys_map *dst, xfrm_line); } +static __always_inline void drm_fb_xfrm_line_32to32(void *dbuf, const void *sbuf, +unsigned int pixels, +u32 (*xfrm_pixel)(u32 )) +{ +__le32 *dbuf32 = dbuf; +const __le32 *sbuf32 = sbuf; +const __le32 *send32 = sbuf32 + pixels; + +while (sbuf32 < send32) + *dbuf32++ =cpu_to_le32 (xfrm_pixel (le32_to_cpup (sbuf32++))); +} +/** * drm_fb_memcpy - Copy clip buffer * @dst: Array of destination buffers
@@ -755,16 +769,7 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_bgr888);static void drm_fb_xrgb8888_to_argb8888_line (void *dbuf,const void *sbuf,unsigned int pixels) { -__le32 *dbuf32 = dbuf; -const __le32 *sbuf32 = sbuf; -unsigned int x; -u32 pix; - -for (x =0 ; x < pixels; x++) { - pix =le32_to_cpu (sbuf32[x]); - pix |=GENMASK (31 ,24 );/* fill alpha bits */ - dbuf32[x] =cpu_to_le32 (pix); - } +drm_fb_xfrm_line_32to32 (dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_argb8888); }/**
@@ -804,19 +809,7 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb8888);static void drm_fb_xrgb8888_to_abgr8888_line (void *dbuf,const void *sbuf,unsigned int pixels) { -__le32 *dbuf32 = dbuf; -const __le32 *sbuf32 = sbuf; -unsigned int x; -u32 pix; - -for (x =0 ; x < pixels; x++) { - pix =le32_to_cpu (sbuf32[x]); - pix = ((pix &0x00ff0000 ) >>16 ) <<0 | - ((pix &0x0000ff00 ) >>8 ) <<8 | - ((pix &0x000000ff ) >>0 ) <<16 | -GENMASK (31 ,24 );/* fill alpha bits */ - *dbuf32++ =cpu_to_le32 (pix); - } +drm_fb_xfrm_line_32to32 (dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_abgr8888); } static void drm_fb_xrgb8888_to_abgr8888(struct iosys_map *dst, const unsigned int *dst_pitch,
@@ -835,19 +828,7 @@ static void drm_fb_xrgb8888_to_abgr8888(struct iosys_map *dst, const unsigned instatic void drm_fb_xrgb8888_to_xbgr8888_line (void *dbuf,const void *sbuf,unsigned int pixels) { -__le32 *dbuf32 = dbuf; -const __le32 *sbuf32 = sbuf; -unsigned int x; -u32 pix; - -for (x =0 ; x < pixels; x++) { - pix =le32_to_cpu (sbuf32[x]); - pix = ((pix &0x00ff0000 ) >>16 ) <<0 | - ((pix &0x0000ff00 ) >>8 ) <<8 | - ((pix &0x000000ff ) >>0 ) <<16 | - ((pix &0xff000000 ) >>24 ) <<24 ; - *dbuf32++ =cpu_to_le32 (pix); - } +drm_fb_xfrm_line_32to32 (dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_xbgr8888); } static void drm_fb_xrgb8888_to_xbgr8888(struct iosys_map *dst, const unsigned int *dst_pitch,
@@ -866,20 +847,7 @@ static void drm_fb_xrgb8888_to_xbgr8888(struct iosys_map *dst, const unsigned instatic void drm_fb_xrgb8888_to_xrgb2101010_line (void *dbuf,const void *sbuf,unsigned int pixels) { -__le32 *dbuf32 = dbuf; -const __le32 *sbuf32 = sbuf; -unsigned int x; -u32 val32; -u32 pix; - -for (x =0 ; x < pixels; x++) { - pix =le32_to_cpu (sbuf32[x]); - val32 = ((pix &0x000000FF ) <<2 ) | - ((pix &0x0000FF00 ) <<4 ) | - ((pix &0x00FF0000 ) <<6 ); - pix = val32 | ((val32 >>8 ) &0x00300C03 ); - *dbuf32++ =cpu_to_le32 (pix); - } +drm_fb_xfrm_line_32to32 (dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_xrgb2101010); }/**
@@ -920,21 +888,7 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb2101010);static void drm_fb_xrgb8888_to_argb2101010_line (void *dbuf,const void *sbuf,unsigned int pixels) { -__le32 *dbuf32 = dbuf; -const __le32 *sbuf32 = sbuf; -unsigned int x; -u32 val32; -u32 pix; - -for (x =0 ; x < pixels; x++) { - pix =le32_to_cpu (sbuf32[x]); - val32 = ((pix &0x000000ff ) <<2 ) | - ((pix &0x0000ff00 ) <<4 ) | - ((pix &0x00ff0000 ) <<6 ); - pix =GENMASK (31 ,30 ) |/* set alpha bits */ - val32 | ((val32 >>8 ) &0x00300c03 ); - *dbuf32++ =cpu_to_le32 (pix); - } +drm_fb_xfrm_line_32to32 (dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_argb2101010); }/**
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 261/322 drm/tests: Do not use drm_fb_blit() in format-helper tests
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
[ Upstream commit 5a4856e0e38109ba994f369962f054ecb445c098 ]
Export additional helpers from the format-helper library and open-code drm_fb_blit() in tests. Prepares for the removal of drm_fb_blit(). Only sysfb drivers use drm_fb_blit(). The function will soon be removed from format helpers and be refactored within sysfb helpers.
Stable-dep-of: 05663d88fd0b ("drm/tests: Fix drm_test_fb_xrgb8888_to_xrgb2101010() on big-endian")
--- drivers/gpu/drm/drm_format_helper.c | 108 ++++++++++++++++-- drivers/gpu/drm/drm_format_internal.h | 8 ++ .../gpu/drm/tests/drm_format_helper_test.c | 108 +++--------------- include/drm/drm_format_helper.h | 9 ++ 4 files changed, 131 insertions(+), 102 deletions(-)
drivers/gpu/drm/drm_format_helper.c +98 -10
@@ -812,11 +812,33 @@ static void drm_fb_xrgb8888_to_abgr8888_line(void *dbuf, const void *sbuf, unsigdrm_fb_xfrm_line_32to32 (dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_abgr8888); } -static void drm_fb_xrgb8888_to_abgr8888 (struct iosys_map *dst,const unsigned int *dst_pitch, -const struct iosys_map *src, -const struct drm_framebuffer *fb, -const struct drm_rect *clip, -struct drm_format_conv_state *state) +/** +* drm_fb_xrgb8888_to_abgr8888 - Convert XRGB8888 to ABGR8888 clip buffer +* @dst: Array of ABGR8888 destination buffers +* @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines +* within @dst; can be NULL if scanlines are stored next to each other. +* @src: Array of XRGB8888 source buffer +* @fb: DRM framebuffer +* @clip: Clip rectangle area to copy +* @state: Transform and conversion state +* +* This function copies parts of a framebuffer to display memory and converts the +* color format during the process. The parameters @dst, @dst_pitch and @src refer +* to arrays. Each array must have at least as many entries as there are planes in +* @fb's format. Each entry stores the value for the format's respective color plane +* at the same index. +* +* This function does not apply clipping on @dst (i.e. the destination is at the +* top-left corner). +* +* Drivers can use this function for ABGR8888 devices that don't support XRGB8888 +* natively. It sets an opaque alpha channel as part of the conversion. +*/ +void drm_fb_xrgb8888_to_abgr8888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src, +const struct drm_framebuffer *fb, +const struct drm_rect *clip, +struct drm_format_conv_state *state) {static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES ] = {4 ,
@@ -825,17 +847,40 @@ static void drm_fb_xrgb8888_to_abgr8888(struct iosys_map *dst, const unsigned indrm_fb_xfrm (dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, drm_fb_xrgb8888_to_abgr8888_line); } +EXPORT_SYMBOL (drm_fb_xrgb8888_to_abgr8888);static void drm_fb_xrgb8888_to_xbgr8888_line (void *dbuf,const void *sbuf,unsigned int pixels) {drm_fb_xfrm_line_32to32 (dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_xbgr8888); } -static void drm_fb_xrgb8888_to_xbgr8888 (struct iosys_map *dst,const unsigned int *dst_pitch, -const struct iosys_map *src, -const struct drm_framebuffer *fb, -const struct drm_rect *clip, -struct drm_format_conv_state *state) +/** +* drm_fb_xrgb8888_to_xbgr8888 - Convert XRGB8888 to XBGR8888 clip buffer +* @dst: Array of XBGR8888 destination buffers +* @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines +* within @dst; can be NULL if scanlines are stored next to each other. +* @src: Array of XRGB8888 source buffer +* @fb: DRM framebuffer +* @clip: Clip rectangle area to copy +* @state: Transform and conversion state +* +* This function copies parts of a framebuffer to display memory and converts the +* color format during the process. The parameters @dst, @dst_pitch and @src refer +* to arrays. Each array must have at least as many entries as there are planes in +* @fb's format. Each entry stores the value for the format's respective color plane +* at the same index. +* +* This function does not apply clipping on @dst (i.e. the destination is at the +* top-left corner). +* +* Drivers can use this function for XBGR8888 devices that don't support XRGB8888 +* natively. +*/ +void drm_fb_xrgb8888_to_xbgr8888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src, +const struct drm_framebuffer *fb, +const struct drm_rect *clip, +struct drm_format_conv_state *state) {static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES ] = {4 ,
@@ -844,6 +889,49 @@ static void drm_fb_xrgb8888_to_xbgr8888(struct iosys_map *dst, const unsigned indrm_fb_xfrm (dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, drm_fb_xrgb8888_to_xbgr8888_line); } +EXPORT_SYMBOL (drm_fb_xrgb8888_to_xbgr8888); + +static void drm_fb_xrgb8888_to_bgrx8888_line (void *dbuf,const void *sbuf,unsigned int pixels) +{ +drm_fb_xfrm_line_32to32 (dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_bgrx8888); +} + +/** +* drm_fb_xrgb8888_to_bgrx8888 - Convert XRGB8888 to BGRX8888 clip buffer +* @dst: Array of BGRX8888 destination buffers +* @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines +* within @dst; can be NULL if scanlines are stored next to each other. +* @src: Array of XRGB8888 source buffer +* @fb: DRM framebuffer +* @clip: Clip rectangle area to copy +* @state: Transform and conversion state +* +* This function copies parts of a framebuffer to display memory and converts the +* color format during the process. The parameters @dst, @dst_pitch and @src refer +* to arrays. Each array must have at least as many entries as there are planes in +* @fb's format. Each entry stores the value for the format's respective color plane +* at the same index. +* +* This function does not apply clipping on @dst (i.e. the destination is at the +* top-left corner). +* +* Drivers can use this function for BGRX8888 devices that don't support XRGB8888 +* natively. +*/ +void drm_fb_xrgb8888_to_bgrx8888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src, +const struct drm_framebuffer *fb, +const struct drm_rect *clip, +struct drm_format_conv_state *state) +{ +static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES ] = { +4 , + }; + +drm_fb_xfrm (dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, + drm_fb_xrgb8888_to_bgrx8888_line); +} +EXPORT_SYMBOL (drm_fb_xrgb8888_to_bgrx8888);static void drm_fb_xrgb8888_to_xrgb2101010_line (void *dbuf,const void *sbuf,unsigned int pixels) {
drivers/gpu/drm/drm_format_internal.h +8 -0
@@ -82,6 +82,14 @@ static inline u32 drm_pixel_xrgb8888_to_xbgr8888(u32 pix) ((pix &0x000000ff ) <<16 ); } +static inline u32 drm_pixel_xrgb8888_to_bgrx8888 (u32 pix) +{ +return ((pix &0xff000000 ) >>24 ) |/* also copy filler bits */ + ((pix &0x00ff0000 ) >>8 ) | + ((pix &0x0000ff00 ) <<8 ) | + ((pix &0x000000ff ) <<24 ); +} +static inline u32 drm_pixel_xrgb8888_to_abgr8888 (u32 pix) { return GENMASK(31, 24) | /* fill alpha bits */
drivers/gpu/drm/tests/drm_format_helper_test.c +16 -92
210 lines not on this page · raw message
include/drm/drm_format_helper.h +9 -0
@@ -102,6 +102,15 @@ void drm_fb_xrgb8888_to_bgr888(struct iosys_map *dst, const unsigned int *dst_pivoid drm_fb_xrgb8888_to_argb8888 (struct iosys_map *dst,const unsigned int *dst_pitch,const struct iosys_map *src,const struct drm_framebuffer *fb,const struct drm_rect *clip,struct drm_format_conv_state *state); +void drm_fb_xrgb8888_to_abgr8888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src,const struct drm_framebuffer *fb, +const struct drm_rect *clip,struct drm_format_conv_state *state); +void drm_fb_xrgb8888_to_xbgr8888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src,const struct drm_framebuffer *fb, +const struct drm_rect *clip,struct drm_format_conv_state *state); +void drm_fb_xrgb8888_to_bgrx8888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src,const struct drm_framebuffer *fb, +const struct drm_rect *clip,struct drm_format_conv_state *state); void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip,
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 262/322 drm/tests: Fix drm_test_fb_xrgb8888_to_xrgb2101010() on big-endian
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: José Expósito <[email protected]>
[ Upstream commit 05663d88fd0b8ee1c54ab2d5fb36f9b6a3ed37f7 ]
Fix failures on big-endian architectures on tests cases single_pixel_source_buffer, single_pixel_clip_rectangle, well_known_colors and destination_pitch.
--- drivers/gpu/drm/tests/drm_format_helper_test.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/tests/drm_format_helper_test.c +1 -0
@@ -1040,6 +1040,7 @@ static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)memset (buf,0 , dst_size);drm_fb_xrgb8888_to_xrgb2101010 (&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state); + buf =le32buf_to_cpu (test, (__force const __le32 *)buf, dst_size /sizeof (u32));KUNIT_EXPECT_MEMEQ (test, buf, result->expected, dst_size); }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 263/322 iosys-map: Fix undefined behavior in iosys_map_clear()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nitin Gote <[email protected]>
[ Upstream commit 5634c8cb298a7146b4e38873473e280b50e27a2c ]
The current iosys_map_clear() implementation reads the potentially uninitialized 'is_iomem' boolean field to decide which union member to clear. This causes undefined behavior when called on uninitialized structures, as 'is_iomem' may contain garbage values like 0xFF.
UBSAN detects this as:
UBSAN: invalid-load in include/linux/iosys-map.h:267
load of value 255 is not a valid value for type '_Bool'Fix by unconditionally clearing the entire structure with memset(), eliminating the need to read uninitialized data and ensuring all fields are set to known good values.
--- include/linux/iosys-map.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
include/linux/iosys-map.h +1 -6
@@ -264,12 +264,7 @@ static inline bool iosys_map_is_set(const struct iosys_map *map)*/ static inline void iosys_map_clear (struct iosys_map *map) { -if (map->is_iomem) { - map->vaddr_iomem =NULL ; - map->is_iomem = false; - }else { - map->vaddr =NULL ; - } +memset (map,0 ,sizeof (*map)); }/**
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 264/322 rust: alloc: replace aligned_size() with Kmalloc::aligned_layout()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich <[email protected]>
[ Upstream commit fde578c86281f27b182680c7642836a0dbbd0be7 ]
aligned_size() dates back to when Rust did support kmalloc() only, but is now used in ReallocFunc::call() and hence for all allocators.
However, the additional padding applied by aligned_size() is only required by the kmalloc() allocator backend.
Hence, replace aligned_size() with Kmalloc::aligned_layout() and use it for the affected allocators, i.e. kmalloc() and kvmalloc(), only.
While at it, make Kmalloc::aligned_layout() public, such that Rust abstractions, which have to call subsystem specific kmalloc() based allocation primitives directly, can make use of it.
--- rust/kernel/alloc/allocator.rs | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-)
rust/kernel/alloc/allocator.rs +18 -12
@@ -43,17 +43,6 @@ pub struct Vmalloc;/// For more details see [self]. pub struct KVmalloc ; -/// Returns a proper size to alloc a new object aligned to `new_layout`'s alignment. -fn aligned_size (new_layout:Layout ) ->usize { -// Customized layouts from `Layout::from_size_align()` can have size < align, so pad first. -let layout = new_layout.pad_to_align (); - -// Note that `layout.size()` (after padding) is guaranteed to be a multiple of `layout.align()` -// which together with the slab guarantees means the `krealloc` will return a properly aligned -// object (see comments in `kmalloc()` for more information). - layout.size () -} -/// # Invariants /// /// One of the following: `krealloc`, `vrealloc`, `kvrealloc`.
@@ -87,7 +76,7 @@ impl ReallocFunc { old_layout: Layout, flags: Flags, ) -> Result<NonNull<[u8]>, AllocError> { -let size =aligned_size (layout); +let size = layout.size ();let ptr =match ptr {Some (ptr) => {if old_layout.size () ==0 {
@@ -122,6 +111,17 @@ impl ReallocFunc { } } +impl Kmalloc { +/// Returns a [`Layout`] that makes [`Kmalloc`] fulfill the requested size and alignment of +/// `layout`. +pub fn aligned_layout (layout:Layout ) ->Layout { +// Note that `layout.size()` (after padding) is guaranteed to be a multiple of +// `layout.align()` which together with the slab guarantees means that `Kmalloc` will return +// a properly aligned object (see comments in `kmalloc()` for more information). + layout.pad_to_align () + } +} +// SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that // - memory remains valid until it is explicitly freed, // - passing a pointer to a valid memory allocation is OK,
@@ -134,6 +134,8 @@ unsafe impl Allocator for Kmalloc { old_layout: Layout, flags: Flags, ) -> Result<NonNull<[u8]>, AllocError> { +let layout =Kmalloc ::aligned_layout (layout); +// SAFETY: `ReallocFunc::call` has the same safety requirements as `Allocator::realloc`. unsafe {ReallocFunc ::KREALLOC .call (ptr, layout, old_layout, flags) } }
@@ -175,6 +177,10 @@ unsafe impl Allocator for KVmalloc { old_layout: Layout, flags: Flags, ) -> Result<NonNull<[u8]>, AllocError> { +// `KVmalloc` may use the `Kmalloc` backend, hence we have to enforce a `Kmalloc` +// compatible layout. +let layout =Kmalloc ::aligned_layout (layout); +// TODO: Support alignments larger than PAGE_SIZE. if layout.align () > bindings::PAGE_SIZE {pr_warn! ("KVmalloc does not support alignments larger than PAGE_SIZE yet.\n" );
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 265/322 RDMA/erdma: Fix ignored return value of init_kernel_qp
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boshi Yu <[email protected]>
[ Upstream commit d5c74713f0117d07f91eb48b10bc2ad44e23c9b9 ]
The init_kernel_qp interface may fail. Check its return value and free related resources properly when it does.
--- drivers/infiniband/hw/erdma/erdma_verbs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/infiniband/hw/erdma/erdma_verbs.c +3 -1
@@ -991,7 +991,9 @@ int erdma_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,if (ret) goto err_out_cmd; }else { -init_kernel_qp (dev, qp, attrs); + ret =init_kernel_qp (dev, qp, attrs); +if (ret) + goto err_out_xa; } qp->attrs.max_send_sge = attrs->cap.max_send_sge;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 266/322 RDMA/hns: Fix querying wrong SCC context for DIP algorithm
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: wenglianfa <[email protected]>
[ Upstream commit 085a1b42e52750769a3fa29d4da6c05ab56f18f8 ]
When using DIP algorithm, all QPs establishing connections with the same destination IP share the same SCC, which is indexed by dip_idx, but dip_idx isn't necessarily equal to qpn. Therefore, dip_idx should be used to query SCC context instead of qpn.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 ++-- drivers/infiniband/hw/hns/hns_roce_restrack.c | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +2 -2
@@ -5498,7 +5498,7 @@ static int hns_roce_v2_query_srqc(struct hns_roce_dev *hr_dev, u32 srqn,return ret; } -static int hns_roce_v2_query_sccc (struct hns_roce_dev *hr_dev,u32 qpn, +static int hns_roce_v2_query_sccc (struct hns_roce_dev *hr_dev,u32 sccn,void *buffer) {struct hns_roce_v2_scc_context *context;
@@ -5510,7 +5510,7 @@ static int hns_roce_v2_query_sccc(struct hns_roce_dev *hr_dev, u32 qpn,return PTR_ERR (mailbox); ret =hns_roce_cmd_mbox (hr_dev,0 , mailbox->dma,HNS_ROCE_CMD_QUERY_SCCC , - qpn); + sccn);if (ret) goto out;
drivers/infiniband/hw/hns/hns_roce_restrack.c +8 -1
@@ -100,6 +100,7 @@ int hns_roce_fill_res_qp_entry_raw(struct sk_buff *msg, struct ib_qp *ib_qp)struct hns_roce_v2_qp_context qpc;struct hns_roce_v2_scc_context sccc; } context = {}; +u32 sccn = hr_qp->qpn;int ret;if (!hr_dev->hw->query_qpc)
@@ -116,7 +117,13 @@ int hns_roce_fill_res_qp_entry_raw(struct sk_buff *msg, struct ib_qp *ib_qp) !hr_dev->hw->query_sccc) goto out; - ret = hr_dev->hw->query_sccc (hr_dev, hr_qp->qpn, &context.sccc); +if (hr_qp->cong_type ==CONG_TYPE_DIP ) { +if (!hr_qp->dip) + goto out; + sccn = hr_qp->dip->dip_idx; + } + + ret = hr_dev->hw->query_sccc (hr_dev, sccn, &context.sccc);if (ret) ibdev_warn_ratelimited(&hr_dev->ib_dev, "failed to query SCCC, ret = %d.\n",
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 267/322 RDMA/bnxt_re: Fix to do SRQ armena by default
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kashyap Desai <[email protected]>
[ Upstream commit 6296f9a5293ada28558f2867ac54c487e1e2b9f2 ]
Whenever SRQ is created, make sure SRQ arm enable is always set. Driver is always ready to receive SRQ ASYNC event.
Additional note -
There is no need to do srq arm enable conditionally. See bnxt_qplib_armen_db in bnxt_qplib_create_cq().
--- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/infiniband/hw/bnxt_re/qplib_fp.c +1 -2
@@ -704,8 +704,7 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, srq->dbinfo.db = srq->dpi->dbr; srq->dbinfo.max_slot =1 ; srq->dbinfo.priv_db = res->dpi_tbl.priv_db; -if (srq->threshold) -bnxt_qplib_armen_db (&srq->dbinfo,DBC_DBC_TYPE_SRQ_ARMENA ); +bnxt_qplib_armen_db (&srq->dbinfo,DBC_DBC_TYPE_SRQ_ARMENA ); srq->arm_req = false;return 0 ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 268/322 RDMA/bnxt_re: Fix to remove workload check in SRQ limit path
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kashyap Desai <[email protected]>
[ Upstream commit 666bce0bd7e771127cb0cda125cc9d32d9f9f15d ]
There should not be any checks of current workload to set srq_limit value to SRQ hw context.
Remove all such workload checks and make a direct call to set srq_limit via doorbell SRQ_ARM.
--- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 8 ++----- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 27 ------------------------ drivers/infiniband/hw/bnxt_re/qplib_fp.h | 2 -- 3 files changed, 2 insertions(+), 35 deletions(-)
drivers/infiniband/hw/bnxt_re/ib_verbs.c +2 -6
@@ -1874,7 +1874,6 @@ int bnxt_re_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr, struct bnxt_re_srq *srq = container_of(ib_srq, struct bnxt_re_srq, ib_srq);struct bnxt_re_dev *rdev = srq->rdev; -int rc;switch (srq_attr_mask) {case IB_SRQ_MAX_WR :
@@ -1886,11 +1885,8 @@ int bnxt_re_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr,return -EINVAL ; srq->qplib_srq.threshold = srq_attr->srq_limit; - rc =bnxt_qplib_modify_srq (&rdev->qplib_res, &srq->qplib_srq); -if (rc) { -ibdev_err (&rdev->ibdev,"Modify HW SRQ failed!" ); -return rc; - } +bnxt_qplib_srq_arm_db (&srq->qplib_srq.dbinfo, srq->qplib_srq.threshold); +/* On success, update the shadow */ srq->srq_limit = srq_attr->srq_limit;/* No need to Build and send response back to udata */
drivers/infiniband/hw/bnxt_re/qplib_fp.c +0 -27
@@ -705,7 +705,6 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, srq->dbinfo.max_slot =1 ; srq->dbinfo.priv_db = res->dpi_tbl.priv_db;bnxt_qplib_armen_db (&srq->dbinfo,DBC_DBC_TYPE_SRQ_ARMENA ); - srq->arm_req = false;return 0 ; fail:
@@ -715,24 +714,6 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,return rc; } -int bnxt_qplib_modify_srq (struct bnxt_qplib_res *res, -struct bnxt_qplib_srq *srq) -{ -struct bnxt_qplib_hwq *srq_hwq = &srq->hwq; -u32 count; - - count =__bnxt_qplib_get_avail (srq_hwq); -if (count > srq->threshold) { - srq->arm_req = false; -bnxt_qplib_srq_arm_db (&srq->dbinfo, srq->threshold); - }else { -/* Deferred arming */ - srq->arm_req = true; - } - -return 0 ; -} -int bnxt_qplib_query_srq (struct bnxt_qplib_res *res,struct bnxt_qplib_srq *srq) {
@@ -774,7 +755,6 @@ int bnxt_qplib_post_srq_recv(struct bnxt_qplib_srq *srq,struct bnxt_qplib_hwq *srq_hwq = &srq->hwq;struct rq_wqe *srqe;struct sq_sge *hw_sge; -u32 count =0 ;int i, next;spin_lock (&srq_hwq->lock);
@@ -806,15 +786,8 @@ int bnxt_qplib_post_srq_recv(struct bnxt_qplib_srq *srq,bnxt_qplib_hwq_incr_prod (&srq->dbinfo, srq_hwq, srq->dbinfo.max_slot); -spin_lock (&srq_hwq->lock); - count =__bnxt_qplib_get_avail (srq_hwq); -spin_unlock (&srq_hwq->lock);/* Ring DB */ bnxt_qplib_ring_prod_db (&srq->dbinfo,DBC_DBC_TYPE_SRQ ); -if (srq->arm_req == true && count > srq->threshold) { - srq->arm_req = false; -bnxt_qplib_srq_arm_db (&srq->dbinfo, srq->threshold); - }return 0 ; }
drivers/infiniband/hw/bnxt_re/qplib_fp.h +0 -2
@@ -521,8 +521,6 @@ int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq, srqn_handler_t srq_handler);int bnxt_qplib_create_srq (struct bnxt_qplib_res *res,struct bnxt_qplib_srq *srq); -int bnxt_qplib_modify_srq (struct bnxt_qplib_res *res, -struct bnxt_qplib_srq *srq);int bnxt_qplib_query_srq (struct bnxt_qplib_res *res,struct bnxt_qplib_srq *srq); void bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res,
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 269/322 RDMA/bnxt_re: Fix a possible memory leak in the driver
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kalesh AP <[email protected]>
[ Upstream commit ba60a1e8cbbd396c69ff9c8bc3242f5ab133e38a ]
The GID context reuse logic requires the context memory to be not freed if and when DEL_GID firmware command fails. But, if there's no subsequent ADD_GID to reuse it, the context memory must be freed when the driver is unloaded. Otherwise it leads to a memory leak.
Below is the kmemleak trace reported:
unreferenced object 0xffff88817a4f34d0 (size 8):
comm "insmod", pid 1072504, jiffies 4402561550
hex dump (first 8 bytes):
01 00 00 00 00 00 00 00 ........
backtrace (crc ccaa009e):
__kmalloc_cache_noprof+0x33e/0x400 0xffffffffc2db9d48 add_modify_gid+0x5e0/0xb60 [ib_core] __ib_cache_gid_add+0x213/0x350 [ib_core] update_gid+0xf2/0x180 [ib_core] enum_netdev_ipv4_ips+0x3f3/0x690 [ib_core] enum_all_gids_of_dev_cb+0x125/0x1b0 [ib_core] ib_enum_roce_netdev+0x14b/0x250 [ib_core] ib_cache_setup_one+0x2e5/0x540 [ib_core] ib_register_device+0x82c/0xf10 [ib_core] 0xffffffffc2df5ad9 0xffffffffc2da8b07 0xffffffffc2db174d auxiliary_bus_probe+0xa5/0x120 really_probe+0x1e4/0x850 __driver_probe_device+0x18f/0x3d0
--- drivers/infiniband/hw/bnxt_re/main.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
drivers/infiniband/hw/bnxt_re/main.c +23 -0
@@ -1615,6 +1615,28 @@ static void bnxt_re_free_nqr_mem(struct bnxt_re_dev *rdev) rdev->nqr =NULL ; } +/* When DEL_GID fails, driver is not freeing GID ctx memory. +* To avoid the memory leak, free the memory during unload +*/ +static void bnxt_re_free_gid_ctx (struct bnxt_re_dev *rdev) +{ +struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl; +struct bnxt_re_gid_ctx *ctx, **ctx_tbl; +int i; + +if (!sgid_tbl->active) +return ; + + ctx_tbl = sgid_tbl->ctx; +for (i =0 ; i < sgid_tbl->max; i++) { +if (sgid_tbl->hw_id[i] ==0xFFFF ) +continue ; + + ctx = ctx_tbl[i]; +kfree (ctx); + } +} +static void bnxt_re_dev_uninit (struct bnxt_re_dev *rdev,u8 op_type) {u8 type;
@@ -1623,6 +1645,7 @@ static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev, u8 op_type)if (test_and_clear_bit (BNXT_RE_FLAG_QOS_WORK_REG , &rdev->flags))cancel_delayed_work_sync (&rdev->worker); +bnxt_re_free_gid_ctx (rdev);if (test_and_clear_bit (BNXT_RE_FLAG_RESOURCES_INITIALIZED , &rdev->flags))bnxt_re_cleanup_res (rdev);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 270/322 RDMA/bnxt_re: Fix to initialize the PBL array
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anantha Prabhu <[email protected]>
[ Upstream commit 806b9f494f62791ee6d68f515a8056c615a0e7b2 ]
memset the PBL page pointer and page map arrays before populating the SGL addresses of the HWQ.
--- drivers/infiniband/hw/bnxt_re/qplib_res.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/infiniband/hw/bnxt_re/qplib_res.c +2 -0
@@ -121,6 +121,7 @@ static int __alloc_pbl(struct bnxt_qplib_res *res, pbl->pg_arr =vmalloc_array (pages,sizeof (void *));if (!pbl->pg_arr)return -ENOMEM ; +memset (pbl->pg_arr,0 , pages *sizeof (void *)); pbl->pg_map_arr =vmalloc_array (pages,sizeof (dma_addr_t));if (!pbl->pg_map_arr) {
@@ -128,6 +129,7 @@ static int __alloc_pbl(struct bnxt_qplib_res *res, pbl->pg_arr =NULL ;return -ENOMEM ; } +memset (pbl->pg_map_arr,0 , pages *sizeof (dma_addr_t)); pbl->pg_count =0 ; pbl->pg_size = sginfo->pgsize;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 271/322 RDMA/hns: Fix dip entries leak on devices newer than hip09
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit fa2e2d31ee3b7212079323b4b09201ef68af3a97 ]
DIP algorithm is also supported on devices newer than hip09, so free dip entries too.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +1 -1
@@ -3028,7 +3028,7 @@ static void hns_roce_v2_exit(struct hns_roce_dev *hr_dev)if (!hr_dev->is_vf)hns_roce_free_link_table (hr_dev); -if (hr_dev->pci_dev->revision ==PCI_REVISION_ID_HIP09 ) +if (hr_dev->pci_dev->revision >=PCI_REVISION_ID_HIP09 )free_dip_entry (hr_dev); }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 272/322 net: xilinx: axienet: Fix RX skb ring management in DMAengine mode
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suraj Gupta <[email protected]>
[ Upstream commit fd980bf6e9cdae885105685259421164f843ca55 ]
Submit multiple descriptors in axienet_rx_cb() to fill Rx skb ring. This ensures the ring "catches up" on previously missed allocations.
Increment Rx skb ring head pointer after BD is successfully allocated. Previously, head pointer was incremented before verifying if descriptor is successfully allocated and has valid entries, which could lead to ring state inconsistency if descriptor setup failed.
These changes improve reliability by maintaining adequate descriptor availability and ensuring proper ring buffer state management.
--- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +6 -2
@@ -1119,6 +1119,7 @@ static void axienet_dma_rx_cb(void *data, const struct dmaengine_result *result)struct axienet_local *lp = data;struct sk_buff *skb;u32 *app_metadata; +int i; skbuf_dma =axienet_get_rx_desc (lp, lp->rx_ring_tail++); skb = skbuf_dma->skb;
@@ -1137,7 +1138,10 @@ static void axienet_dma_rx_cb(void *data, const struct dmaengine_result *result)u64_stats_add (&lp->rx_packets,1 );u64_stats_add (&lp->rx_bytes, rx_len);u64_stats_update_end (&lp->rx_stat_sync); -axienet_rx_submit_desc (lp->ndev); + +for (i =0 ; i <CIRC_SPACE (lp->rx_ring_head, lp->rx_ring_tail, +RX_BUF_NUM_DEFAULT ); i++) +axienet_rx_submit_desc (lp->ndev);dma_async_issue_pending (lp->rx_chan); }
@@ -1394,7 +1398,6 @@ static void axienet_rx_submit_desc(struct net_device *ndev)if (!skbuf_dma)return ; - lp->rx_ring_head++; skb =netdev_alloc_skb (ndev, lp->max_frm_size);if (!skb)return ;
@@ -1419,6 +1422,7 @@ static void axienet_rx_submit_desc(struct net_device *ndev) skbuf_dma->desc = dma_rx_desc; dma_rx_desc->callback_param = lp; dma_rx_desc->callback_result = axienet_dma_rx_cb; + lp->rx_ring_head++;dmaengine_submit (dma_rx_desc);return ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 273/322 net: bridge: fix soft lockup in br_multicast_query_expired()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Liang <[email protected]>
[ Upstream commit d1547bf460baec718b3398365f8de33d25c5f36f ]
When set multicast_query_interval to a large value, the local variable 'time' in br_multicast_send_query() may overflow. If the time is smaller than jiffies, the timer will expire immediately, and then call mod_timer() again, which creates a loop and may trigger the following soft lockup issue.
watchdog: BUG: soft lockup - CPU#1 stuck for 221s! [rb_consumer:66] CPU: 1 UID: 0 PID: 66 Comm: rb_consumer Not tainted 6.16.0+ #259 PREEMPT(none) Call Trace: <IRQ> __netdev_alloc_skb+0x2e/0x3a0 br_ip6_multicast_alloc_query+0x212/0x1b70 __br_multicast_send_query+0x376/0xac0 br_multicast_send_query+0x299/0x510 br_multicast_query_expired.constprop.0+0x16d/0x1b0 call_timer_fn+0x3b/0x2a0 __run_timers+0x619/0x950 run_timer_softirq+0x11c/0x220 handle_softirqs+0x18e/0x560 __irq_exit_rcu+0x158/0x1a0 sysvec_apic_timer_interrupt+0x76/0x90 </IRQ>
This issue can be reproduced with:
ip link add br0 type bridge
echo 1 > /sys/class/net/br0/bridge/multicast_querier echo 0xffffffffffffffff >
/sys/class/net/br0/bridge/multicast_query_interval
ip link set dev br0 up
The multicast_startup_query_interval can also cause this issue. Similar to the commit 99b40610956a ("net: bridge: mcast: add and enforce query interval minimum"), add check for the query interval maximum to fix this issue.
--- net/bridge/br_multicast.c | 16 ++++++++++++++++ net/bridge/br_private.h | 2 ++ 2 files changed, 18 insertions(+)
net/bridge/br_multicast.c +16 -0
@@ -4808,6 +4808,14 @@ void br_multicast_set_query_intvl(struct net_bridge_mcast *brmctx, intvl_jiffies =BR_MULTICAST_QUERY_INTVL_MIN ; } +if (intvl_jiffies >BR_MULTICAST_QUERY_INTVL_MAX ) { +br_info (brmctx->br, +"trying to set multicast query interval above maximum, setting to %lu (%ums)\n" , +jiffies_to_clock_t (BR_MULTICAST_QUERY_INTVL_MAX ), +jiffies_to_msecs (BR_MULTICAST_QUERY_INTVL_MAX )); + intvl_jiffies =BR_MULTICAST_QUERY_INTVL_MAX ; + } + brmctx->multicast_query_interval = intvl_jiffies; }
@@ -4824,6 +4832,14 @@ void br_multicast_set_startup_query_intvl(struct net_bridge_mcast *brmctx, intvl_jiffies =BR_MULTICAST_STARTUP_QUERY_INTVL_MIN ; } +if (intvl_jiffies >BR_MULTICAST_STARTUP_QUERY_INTVL_MAX ) { +br_info (brmctx->br, +"trying to set multicast startup query interval above maximum, setting to %lu (%ums)\n" , +jiffies_to_clock_t (BR_MULTICAST_STARTUP_QUERY_INTVL_MAX ), +jiffies_to_msecs (BR_MULTICAST_STARTUP_QUERY_INTVL_MAX )); + intvl_jiffies =BR_MULTICAST_STARTUP_QUERY_INTVL_MAX ; + } + brmctx->multicast_startup_query_interval = intvl_jiffies; }
net/bridge/br_private.h +2 -0
@@ -31,6 +31,8 @@#define BR_MULTICAST_DEFAULT_HASH_MAX 4096#define BR_MULTICAST_QUERY_INTVL_MIN msecs_to_jiffies(1000)#define BR_MULTICAST_STARTUP_QUERY_INTVL_MIN BR_MULTICAST_QUERY_INTVL_MIN +#define BR_MULTICAST_QUERY_INTVL_MAX msecs_to_jiffies(86400000)/* 24 hours */ +#define BR_MULTICAST_STARTUP_QUERY_INTVL_MAX BR_MULTICAST_QUERY_INTVL_MAX#define BR_HWDOM_MAX BITS_PER_LONG
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 274/322 rtase: Fix Rx descriptor CRC error bit definition
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Lai <[email protected]>
[ Upstream commit 065c31f2c6915b38f45b1c817b31f41f62eaa774 ]
The CRC error bit is located at bit 17 in the Rx descriptor, but the driver was incorrectly using bit 16. Fix it.
--- drivers/net/ethernet/realtek/rtase/rtase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/realtek/rtase/rtase.h +1 -1
@@ -239,7 +239,7 @@ union rtase_rx_desc {#define RTASE_RX_RES BIT(20)#define RTASE_RX_RUNT BIT(19)#define RTASE_RX_RWT BIT(18) -#define RTASE_RX_CRC BIT(16) +#define RTASE_RX_CRC BIT(17)#define RTASE_RX_V6F BIT(31)#define RTASE_RX_V4F BIT(30)#define RTASE_RX_UDPT BIT(29)
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 275/322 scsi: qla4xxx: Prevent a potential error pointer dereference
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 9dcf111dd3e7ed5fce82bb108e3a3fc001c07225 ]
The qla4xxx_get_ep_fwdb() function is supposed to return NULL on error, but qla4xxx_ep_connect() returns error pointers. Propagating the error pointers will lead to an Oops in the caller, so change the error pointers to NULL.
--- drivers/scsi/qla4xxx/ql4_os.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/scsi/qla4xxx/ql4_os.c +2 -0
@@ -6606,6 +6606,8 @@ static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha, ep =qla4xxx_ep_connect (ha->host, (struct sockaddr *)dst_addr,0 );vfree (dst_addr); +if (IS_ERR (ep)) +return NULL ;return ep; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 276/322 iommu/amd: Avoid stack buffer overflow from kernel cmdline
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
[ Upstream commit 8503d0fcb1086a7cfe26df67ca4bd9bd9e99bdec ]
While the kernel command line is considered trusted in most environments, avoid writing 1 byte past the end of "acpiid" if the "str" argument is maximum length.
--- drivers/iommu/amd/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iommu/amd/init.c +2 -2
@@ -3598,7 +3598,7 @@ static int __init parse_ivrs_acpihid(char *str) {u32 seg =0 , bus, dev, fn;char *hid, *uid, *p, *addr; -char acpiid[ACPIID_LEN ] = {0 }; +char acpiid[ACPIID_LEN +1 ] = { };/* size with NULL terminator */ int i; addr =strchr (str,'@' );
@@ -3624,7 +3624,7 @@ static int __init parse_ivrs_acpihid(char *str)/* We have the '@', make it the terminator to get just the acpiid */ *addr++ =0 ; -if (strlen (str) >ACPIID_LEN +1 ) +if (strlen (str) >ACPIID_LEN ) goto not_found;if (sscanf (str,"=%s" , acpiid) !=1 )
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 277/322 Bluetooth: hci_sync: Fix scan state after PA Sync has been established
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit ca88be1a2725a42f8dbad579181611d9dcca8e88 ]
Passive scanning is used to program the address of the peer to be synchronized, so once HCI_EV_LE_PA_SYNC_ESTABLISHED is received it needs to be updated after clearing HCI_PA_SYNC then call hci_update_passive_scan_sync to return it to its original state.
--- net/bluetooth/hci_sync.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/bluetooth/hci_sync.c +5 -2
@@ -6960,8 +6960,6 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err)hci_dev_lock (hdev); -hci_dev_clear_flag (hdev,HCI_PA_SYNC ); -if (!hci_conn_valid (hdev, conn))clear_bit (HCI_CONN_CREATE_PA_SYNC , &conn->flags);
@@ -7055,6 +7053,11 @@ static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data)__hci_cmd_sync_status (hdev,HCI_OP_LE_PA_CREATE_SYNC_CANCEL ,0 ,NULL ,HCI_CMD_TIMEOUT ); +hci_dev_clear_flag (hdev,HCI_PA_SYNC ); + +/* Update passive scan since HCI_PA_SYNC flag has been cleared */ +hci_update_passive_scan_sync (hdev); +return err; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 278/322 Bluetooth: btmtk: Fix wait_on_bit_timeout interruption during shutdown
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiande Lu <[email protected]>
[ Upstream commit 099799fa9b76c5c02b49e07005a85117a25b01ea ]
During the shutdown process, an interrupt occurs that prematurely terminates the wait for the expected event. This change replaces TASK_INTERRUPTIBLE with TASK_UNINTERRUPTIBLE in the wait_on_bit_timeout call to ensure the shutdown process completes as intended without being interrupted by signals.
--- drivers/bluetooth/btmtk.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/bluetooth/btmtk.c +1 -6
@@ -642,12 +642,7 @@ static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,* WMT command. */ err =wait_on_bit_timeout (&data->flags,BTMTK_TX_WAIT_VND_EVT , -TASK_INTERRUPTIBLE ,HCI_INIT_TIMEOUT ); -if (err == -EINTR ) { -bt_dev_err (hdev,"Execution of wmt command interrupted" ); -clear_bit (BTMTK_TX_WAIT_VND_EVT , &data->flags); - goto err_free_wc; - } +TASK_UNINTERRUPTIBLE ,HCI_INIT_TIMEOUT );if (err) {bt_dev_err (hdev,"Execution of wmt command timed out" );
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 279/322 Bluetooth: hci_sync: Prevent unintended PA sync when SID is 0xFF
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Li <[email protected]>
[ Upstream commit 4d19cd228bbe8ff84a63fe7b11bc756b4b4370c7 ]
After LE Extended Scan times out, conn->sid remains 0xFF, so the PA sync creation process should be aborted.
Btmon snippet from PA sync with SID=0xFF:
< HCI Command: LE Set Extended.. (0x08|0x0042) plen 6 #74726 [hci0] 863.107927
Extended scan: Enabled (0x01)
Filter duplicates: Enabled (0x01)
Duration: 0 msec (0x0000)
Period: 0.00 sec (0x0000)Quoted 1 line
HCI Event: Command Complete (
0x0e) plen 4 #74727 [hci0] 863.109389
LE Set Extended Scan Enable (0x08|0x0042) ncmd 1
Status: Success (0x00)
< HCI Command: LE Periodic Ad.. (0x08|0x0044) plen 14 #74728 [hci0] 865.141168
Options: 0x0000
Use advertising SID, Advertiser Address Type and address
Reporting initially enabled
SID: 0xff
Adv address type: Random (0x01)
Adv address: 0D:D7:2C:E7:42:46 (Non-Resolvable)
Skip: 0x0000
Sync timeout: 20000 msec (0x07d0)
Sync CTE type: 0x0000Quoted 1 line
HCI Event: Command Status (
0x0f) plen 4 #74729 [hci0] 865.143223
LE Periodic Advertising Create Sync (0x08|0x0044) ncmd 1
Status: Success (0x00)--- net/bluetooth/hci_sync.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
net/bluetooth/hci_sync.c +8 -4
@@ -7020,10 +7020,13 @@ static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data)/* SID has not been set listen for HCI_EV_LE_EXT_ADV_REPORT to update * it. */ -if (conn->sid ==HCI_SID_INVALID ) -__hci_cmd_sync_status_sk (hdev,HCI_OP_NOP ,0 ,NULL , -HCI_EV_LE_EXT_ADV_REPORT , - conn->conn_timeout,NULL ); +if (conn->sid ==HCI_SID_INVALID ) { + err =__hci_cmd_sync_status_sk (hdev,HCI_OP_NOP ,0 ,NULL , +HCI_EV_LE_EXT_ADV_REPORT , + conn->conn_timeout,NULL ); +if (err == -ETIMEDOUT ) + goto done; + }memset (&cp,0 ,sizeof (cp)); cp.options = qos->bcast.options;
@@ -7053,6 +7056,7 @@ static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data)__hci_cmd_sync_status (hdev,HCI_OP_LE_PA_CREATE_SYNC_CANCEL ,0 ,NULL ,HCI_CMD_TIMEOUT ); +done:hci_dev_clear_flag (hdev,HCI_PA_SYNC );/* Update passive scan since HCI_PA_SYNC flag has been cleared */
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 280/322 Bluetooth: hci_event: fix MTU for BN == 0 in CIS Established
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <[email protected]>
[ Upstream commit 0b3725dbf61b51e7c663834811b3691157ae17d6 ]
BN == 0x00 in CIS Established means no isochronous data for the corresponding direction (Core v6.1 pp. 2394). In this case SDU MTU should be 0.
However, the specification does not say the Max_PDU_C_To_P or P_To_C are then zero. Intel AX210 in Framed CIS mode sets nonzero Max_PDU for direction with zero BN. This causes failure later when we try to LE Setup ISO Data Path for disabled direction, which is disallowed (Core v6.1 pp. 2750).
Fix by setting SDU MTU to 0 if BN == 0.
--- net/bluetooth/hci_event.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/bluetooth/hci_event.c +4 -4
@@ -6725,8 +6725,8 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data, qos->ucast.out.latency =DIV_ROUND_CLOSEST (get_unaligned_le24 (ev->p_latency),1000 ); - qos->ucast.in.sdu =le16_to_cpu (ev->c_mtu); - qos->ucast.out.sdu =le16_to_cpu (ev->p_mtu); + qos->ucast.in.sdu = ev->c_bn ?le16_to_cpu (ev->c_mtu) :0 ; + qos->ucast.out.sdu = ev->p_bn ?le16_to_cpu (ev->p_mtu) :0 ; qos->ucast.in.phy = ev->c_phy; qos->ucast.out.phy = ev->p_phy;break ;
@@ -6740,8 +6740,8 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data, qos->ucast.in.latency =DIV_ROUND_CLOSEST (get_unaligned_le24 (ev->p_latency),1000 ); - qos->ucast.out.sdu =le16_to_cpu (ev->c_mtu); - qos->ucast.in.sdu =le16_to_cpu (ev->p_mtu); + qos->ucast.out.sdu = ev->c_bn ?le16_to_cpu (ev->c_mtu) :0 ; + qos->ucast.in.sdu = ev->p_bn ?le16_to_cpu (ev->p_mtu) :0 ; qos->ucast.out.phy = ev->c_phy; qos->ucast.in.phy = ev->p_phy;break ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 281/322 Bluetooth: hci_conn: do return error from hci_enhanced_setup_sync()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Shtylyov <[email protected]>
[ Upstream commit 0eaf7c7e85da7495c0e03a99375707fc954f5e7b ]
The commit e07a06b4eb41 ("Bluetooth: Convert SCO configure_datapath to hci_sync") missed to update the *return* statement under the *case* of BT_CODEC_TRANSPARENT in hci_enhanced_setup_sync(), which led to returning success (0) instead of the negative error code (-EINVAL). However, the result of hci_enhanced_setup_sync() seems to be ignored anyway, since NULL gets passed to hci_cmd_sync_queue() as the last argument in that case and the only function interested in that result is specified by that argument.
--- net/bluetooth/hci_conn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/bluetooth/hci_conn.c +2 -1
@@ -338,7 +338,8 @@ static int hci_enhanced_setup_sync(struct hci_dev *hdev, void *data)case BT_CODEC_TRANSPARENT :if (!find_next_esco_param (conn, esco_param_msbc,ARRAY_SIZE (esco_param_msbc))) -return false; +return -EINVAL ; + param = &esco_param_msbc[conn->attempt -1 ]; cp.tx_coding_format.id =0x03 ; cp.rx_coding_format.id =0x03 ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 282/322 mlxsw: spectrum: Forward packets with an IPv4 link-local source IP
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit f604d3aaf64ff0d90cc875295474d3abf4155629 ]
By default, the device does not forward IPv4 packets with a link-local source IP (i.e., 169.254.0.0/16). This behavior does not align with the kernel which does forward them.
Fix by instructing the device to forward such packets instead of dropping them.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 2 ++ drivers/net/ethernet/mellanox/mlxsw/trap.h | 1 + 2 files changed, 3 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/spectrum.c +2 -0
@@ -2507,6 +2507,8 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = { ROUTER_EXP, false),MLXSW_SP_RXL_NO_MARK (DISCARD_ING_ROUTER_DIP_LINK_LOCAL ,FORWARD ,ROUTER_EXP , false), +MLXSW_SP_RXL_NO_MARK (DISCARD_ING_ROUTER_SIP_LINK_LOCAL ,FORWARD , +ROUTER_EXP , false),/* Multicast Router Traps */ MLXSW_SP_RXL_MARK (ACL1 ,TRAP_TO_CPU ,MULTICAST , false), MLXSW_SP_RXL_L3_MARK(ACL2, TRAP_TO_CPU, MULTICAST, false),
drivers/net/ethernet/mellanox/mlxsw/trap.h +1 -0
@@ -95,6 +95,7 @@ enum {MLXSW_TRAP_ID_DISCARD_ING_ROUTER_IPV4_SIP_BC =0x16A ,MLXSW_TRAP_ID_DISCARD_ING_ROUTER_IPV4_DIP_LOCAL_NET =0x16B ,MLXSW_TRAP_ID_DISCARD_ING_ROUTER_DIP_LINK_LOCAL =0x16C , +MLXSW_TRAP_ID_DISCARD_ING_ROUTER_SIP_LINK_LOCAL =0x16D ,MLXSW_TRAP_ID_DISCARD_ROUTER_IRIF_EN =0x178 ,MLXSW_TRAP_ID_DISCARD_ROUTER_ERIF_EN =0x179 , MLXSW_TRAP_ID_DISCARD_ROUTER_LPM4 = 0x17B,
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 283/322 rust: alloc: fix `rusttest` by providing `Cmalloc::aligned_layout` too
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
[ Upstream commit 0f580d5d3d9d9cd0953695cd32e43aac3a946338 ]
Commit fde578c86281 ("rust: alloc: replace aligned_size() with Kmalloc::aligned_layout()") provides a public aligned_layout function in Kamlloc, but not in Cmalloc, and thus uses of it will trigger an error in rusttest.
Such a user appeared in the following commit 22ab0641b939 ("rust: drm:
ensure kmalloc() compatible Layout"):
error[E0599]: no function or associated item named `aligned_layout` found for struct `alloc::allocator_test::Cmalloc` in the current scope
--> rust/kernel/drm/device.rs:100:31
|
100 | let layout = Kmalloc::aligned_layout(Layout::new::<Self>());
| ^^^^^^^^^^^^^^ function or associated item not found in `Cmalloc`
|
::: rust/kernel/alloc/allocator_test.rs:19:1
|
19 | pub struct Cmalloc;
| ------------------ function or associated item `aligned_layout` not found for this structThus add an equivalent one for Cmalloc.
--- rust/kernel/alloc/allocator_test.rs | 11 +++++++++++ 1 file changed, 11 insertions(+)
rust/kernel/alloc/allocator_test.rs +11 -0
@@ -22,6 +22,17 @@ pub type Kmalloc = Cmalloc;pub type Vmalloc =Kmalloc ;pub type KVmalloc =Kmalloc ; +impl Cmalloc { +/// Returns a [`Layout`] that makes [`Kmalloc`] fulfill the requested size and alignment of +/// `layout`. +pub fn aligned_layout (layout:Layout ) ->Layout { +// Note that `layout.size()` (after padding) is guaranteed to be a multiple of +// `layout.align()` which together with the slab guarantees means that `Kmalloc` will return +// a properly aligned object (see comments in `kmalloc()` for more information). + layout.pad_to_align () + } +} +extern "C" {#[link_name = "aligned_alloc" ] fn libc_aligned_alloc (align:usize , size:usize ) -> *mut crate ::ffi::c_void ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 284/322 drm/hisilicon/hibmc: refactored struct hibmc_drm_private
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baihan Li <[email protected]>
[ Upstream commit 587013d72c1a217ced9f42a9a08c8013052cabfc ]
Refactored struct hibmc_drm_private to separate VGA module from generic struct.
Stable-dep-of: e5f48bfa2ae0 ("drm/hisilicon/hibmc: fix the i2c device resource leak when vdac init failed")
--- .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 16 ++++---- .../gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c | 41 +++++++++---------- .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 20 ++++----- 3 files changed, 38 insertions(+), 39 deletions(-)
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +8 -8
@@ -20,9 +20,10 @@#include <drm/drm_framebuffer.h> -struct hibmc_connector { -struct drm_connector base; - +struct hibmc_vdac { +struct drm_device *dev; +struct drm_encoder encoder; +struct drm_connector connector;struct i2c_adapter adapter;struct i2c_algo_bit_data bit_data; };
@@ -35,13 +36,12 @@ struct hibmc_drm_private {struct drm_device dev;struct drm_plane primary_plane;struct drm_crtc crtc; -struct drm_encoder encoder; -struct hibmc_connector connector; +struct hibmc_vdac vdac; }; -static inline struct hibmc_connector *to_hibmc_connector (struct drm_connector *connector) +static inline struct hibmc_vdac *to_hibmc_vdac (struct drm_connector *connector) { - return container_of(connector, struct hibmc_connector, base); + return container_of(connector, struct hibmc_vdac, connector); }static inline struct hibmc_drm_private *to_hibmc_drm_private (struct drm_device *dev)
@@ -57,6 +57,6 @@ void hibmc_set_current_gate(struct hibmc_drm_private *priv,int hibmc_de_init (struct hibmc_drm_private *priv);int hibmc_vdac_init (struct hibmc_drm_private *priv); -int hibmc_ddc_create (struct drm_device *drm_dev,struct hibmc_connector *connector); +int hibmc_ddc_create (struct drm_device *drm_dev,struct hibmc_vdac *connector);#endif
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c +20 -21
58 lines not on this page · raw message
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +10 -10
@@ -24,11 +24,11 @@static int hibmc_connector_get_modes (struct drm_connector *connector) { -struct hibmc_connector *hibmc_connector =to_hibmc_connector (connector); +struct hibmc_vdac *vdac =to_hibmc_vdac (connector);const struct drm_edid *drm_edid;int count; - drm_edid =drm_edid_read_ddc (connector, &hibmc_connector->adapter); + drm_edid =drm_edid_read_ddc (connector, &vdac->adapter);drm_edid_connector_update (connector, drm_edid);
@@ -51,9 +51,9 @@ static int hibmc_connector_get_modes(struct drm_connector *connector)static void hibmc_connector_destroy (struct drm_connector *connector) { -struct hibmc_connector *hibmc_connector =to_hibmc_connector (connector); +struct hibmc_vdac *vdac =to_hibmc_vdac (connector); -i2c_del_adapter (&hibmc_connector->adapter); +i2c_del_adapter (&vdac->adapter);drm_connector_cleanup (connector); }
@@ -93,20 +93,20 @@ static const struct drm_encoder_helper_funcs hibmc_encoder_helper_funcs = {int hibmc_vdac_init (struct hibmc_drm_private *priv) {struct drm_device *dev = &priv->dev; -struct hibmc_connector *hibmc_connector = &priv->connector; -struct drm_encoder *encoder = &priv->encoder; +struct hibmc_vdac *vdac = &priv->vdac; +struct drm_encoder *encoder = &vdac->encoder;struct drm_crtc *crtc = &priv->crtc; -struct drm_connector *connector = &hibmc_connector->base; +struct drm_connector *connector = &vdac->connector;int ret; - ret =hibmc_ddc_create (dev, hibmc_connector); + ret =hibmc_ddc_create (dev, vdac);if (ret) {drm_err (dev,"failed to create ddc: %d\n" , ret);return ret; } encoder->possible_crtcs =drm_crtc_mask (crtc); - ret =drm_simple_encoder_init (dev, encoder,DRM_MODE_ENCODER_DAC ); + ret =drmm_encoder_init (dev, encoder,NULL ,DRM_MODE_ENCODER_DAC ,NULL );if (ret) {drm_err (dev,"failed to init encoder: %d\n" , ret);return ret;
@@ -117,7 +117,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) ret =drm_connector_init_with_ddc (dev, connector, &hibmc_connector_funcs,DRM_MODE_CONNECTOR_VGA , - &hibmc_connector->adapter); + &vdac->adapter);if (ret) {drm_err (dev,"failed to init connector: %d\n" , ret);return ret;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 285/322 drm/hisilicon/hibmc: fix the i2c device resource leak when vdac init failed
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baihan Li <[email protected]>
[ Upstream commit e5f48bfa2ae0806d5f51fb8061afc619a73599a7 ]
Currently the driver missed to clean the i2c adapter when vdac init failed. It may cause resource leak.
--- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 1 + drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c | 5 +++++ drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 11 ++++++++--- 3 files changed, 14 insertions(+), 3 deletions(-)
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +1 -0
@@ -58,5 +58,6 @@ int hibmc_de_init(struct hibmc_drm_private *priv);int hibmc_vdac_init (struct hibmc_drm_private *priv);int hibmc_ddc_create (struct drm_device *drm_dev,struct hibmc_vdac *connector); +void hibmc_ddc_del (struct hibmc_vdac *vdac);#endif
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c +5 -0
@@ -95,3 +95,8 @@ int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *vdac)return i2c_bit_add_bus (&vdac->adapter); } + +void hibmc_ddc_del (struct hibmc_vdac *vdac) +{ +i2c_del_adapter (&vdac->adapter); +}
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +8 -3
@@ -53,7 +53,7 @@ static void hibmc_connector_destroy(struct drm_connector *connector) {struct hibmc_vdac *vdac =to_hibmc_vdac (connector); -i2c_del_adapter (&vdac->adapter); +hibmc_ddc_del (vdac);drm_connector_cleanup (connector); }
@@ -109,7 +109,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) ret =drmm_encoder_init (dev, encoder,NULL ,DRM_MODE_ENCODER_DAC ,NULL );if (ret) {drm_err (dev,"failed to init encoder: %d\n" , ret); -return ret; + goto err; }drm_encoder_helper_add (encoder, &hibmc_encoder_helper_funcs);
@@ -120,7 +120,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) &vdac->adapter);if (ret) {drm_err (dev,"failed to init connector: %d\n" , ret); -return ret; + goto err; }drm_connector_helper_add (connector, &hibmc_connector_helper_funcs);
@@ -128,4 +128,9 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv)drm_connector_attach_encoder (connector, encoder);return 0 ; + +err: +hibmc_ddc_del (vdac); + +return ret; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 286/322 drm/hisilicon/hibmc: fix the hibmc loaded failed bug
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baihan Li <[email protected]>
[ Upstream commit 93a08f856fcc5aaeeecad01f71bef3088588216a ]
When hibmc loaded failed, the driver use hibmc_unload to free the resource, but the mutexes in mode.config are not init, which will access an NULL pointer. Just change goto statement to return, because hibnc_hw_init() doesn't need to free anything.
--- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +2 -2
@@ -258,13 +258,13 @@ static int hibmc_load(struct drm_device *dev) ret =hibmc_hw_init (priv);if (ret) - goto err; +return ret; ret =drmm_vram_helper_init (dev,pci_resource_start (pdev,0 ),pci_resource_len (pdev,0 ));if (ret) {drm_err (dev,"Error initializing VRAM MM; %d\n" , ret); - goto err; +return ret; } ret =hibmc_kms_init (priv);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 287/322 ALSA: usb-audio: Fix size validation in convert_chmap_v3()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 89f0addeee3cb2dc49837599330ed9c4612f05b0 ]
The "p" pointer is void so sizeof(*p) is 1. The intent was to check sizeof(*cs_desc), which is 3, instead.
--- sound/usb/stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/stream.c +1 -1
@@ -349,7 +349,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptoru16 cs_len;u8 cs_type; -if (len <sizeof (*p)) +if (len <sizeof (*cs_desc))break ; cs_len =le16_to_cpu (cs_desc->wLength);if (len < cs_len)
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 288/322 drm/amd/display: Add null pointer check in mod_hdcp_hdcp1_create_session()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenyuan Yang <[email protected]>
[ Upstream commit 7a2ca2ea64b1b63c8baa94a8f5deb70b2248d119 ]
The function mod_hdcp_hdcp1_create_session() calls the function get_first_active_display(), but does not check its return value. The return value is a null pointer if the display list is empty. This will lead to a null pointer dereference.
Add a null pointer check for get_first_active_display() and return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND if the function return null.
This is similar to the commit c3e9826a2202
("drm/amd/display: Add null pointer check for get_first_active_display()").
--- drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c +3 -0
@@ -260,6 +260,9 @@ enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp)return MOD_HDCP_STATUS_FAILURE ; } +if (!display) +return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND ; + hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;mutex_lock (&psp->hdcp_context.mutex);
Signature · 1 line
2.50.1