6.6.3-rc1 review
Subsystems (8)
Greg Kroah-Hartman
maintainerPATCH 447/530 net: phylink: initialize carrier state at creation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Klaus Kudielka <[email protected]>
commit 02d5fdbf4f2b8c406f7a4c98fa52aa181a11d733 upstream.
Background: Turris Omnia (Armada 385); eth2 (mvneta) connected to SFP bus; SFP module is present, but no fiber connected, so definitely no carrier.
After booting, eth2 is down, but netdev LED trigger surprisingly reports link active. Then, after "ip link set eth2 up", the link indicator goes away - as I would have expected it from the beginning.
It turns out, that the default carrier state after netdev creation is "carrier ok". Some ethernet drivers explicitly call netif_carrier_off during probing, others (like mvneta) don't - which explains the current
behaviour: only when the device is brought up, phylink_start calls netif_carrier_off.
Fix this for all drivers using phylink, by calling netif_carrier_off in phylink_create.
--- drivers/net/phy/phylink.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/phy/phylink.c +1 -0
@@ -1631,6 +1631,7 @@ struct phylink *phylink_create(struct ph pl->config = config;if (config->type ==PHYLINK_NETDEV ) { pl->netdev =to_net_dev (config->dev); +netif_carrier_off (pl->netdev); }else if (config->type ==PHYLINK_DEV ) { pl->dev = config->dev; }else {
Greg Kroah-Hartman
maintainerPATCH 448/530 gfs2: dont withdraw if init_threads() got interrupted
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
commit 0cdc6f44e9fdc2d20d720145bf99a39f611f6d61 upstream.
In gfs2_fill_super(), when mounting a gfs2 filesystem is interrupted, kthread_create() can return -EINTR. When that happens, we roll back what has already been done and abort the mount.
Since commit 62dd0f98a0e5 ("gfs2: Flag a withdraw if init_threads() fails), we are calling gfs2_withdraw_delayed() in gfs2_fill_super(); first via gfs2_make_fs_rw(), then directly. But gfs2_withdraw_delayed() only marks the filesystem as withdrawing and relies on a caller further up the stack to do the actual withdraw, which doesn't exist in the gfs2_fill_super() case. Because the filesystem is marked as withdrawing / withdrawn, function gfs2_lm_unmount() doesn't release the dlm lockspace, so when we try to mount that filesystem again, we get:
gfs2: fsid=gohan:gohan0: Trying to join cluster "lock_dlm", "gohan:gohan0"
gfs2: fsid=gohan:gohan0: dlm_new_lockspace error -17
Since commit b77b4a4815a9 ("gfs2: Rework freeze / thaw logic"), the deadlock this gfs2_withdraw_delayed() call was supposed to work around cannot occur anymore because freeze_go_callback() won't take the sb->s_umount semaphore unconditionally anymore, so we can get rid of the gfs2_withdraw_delayed() in gfs2_fill_super() entirely.
--- fs/gfs2/ops_fstype.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
fs/gfs2/ops_fstype.c +1 -3
@@ -1281,10 +1281,8 @@ static int gfs2_fill_super(struct super_if (!sb_rdonly (sb)) { error =init_threads (sdp); -if (error) { -gfs2_withdraw_delayed (sdp); +if (error) goto fail_per_node; - } } error =gfs2_freeze_lock_shared (sdp);
Greg Kroah-Hartman
maintainerPATCH 449/530 i2c: i801: fix potential race in i801_block_transaction_byte_by_byte
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiner Kallweit <[email protected]>
commit f78ca48a8ba9cdec96e8839351e49eec3233b177 upstream.
Currently we set SMBHSTCNT_LAST_BYTE only after the host has started receiving the last byte. If we get e.g. preempted before setting SMBHSTCNT_LAST_BYTE, the host may be finished with receiving the byte before SMBHSTCNT_LAST_BYTE is set.
Therefore change the code to set SMBHSTCNT_LAST_BYTE before writing SMBHSTSTS_BYTE_DONE for the byte before the last byte. Now the code is also consistent with what we do in i801_isr_byte_done().
--- drivers/i2c/busses/i2c-i801.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
drivers/i2c/busses/i2c-i801.c +9 -10
@@ -681,15 +681,11 @@ static int i801_block_transaction_byte_breturn result ? priv->status : -ETIMEDOUT ; } -for (i =1 ; i <= len; i++) { -if (i == len && read_write ==I2C_SMBUS_READ ) - smbcmd |=SMBHSTCNT_LAST_BYTE ; -outb_p (smbcmd,SMBHSTCNT (priv)); - -if (i ==1 ) -outb_p (inb (SMBHSTCNT (priv)) |SMBHSTCNT_START , -SMBHSTCNT (priv)); +if (len ==1 && read_write ==I2C_SMBUS_READ ) + smbcmd |=SMBHSTCNT_LAST_BYTE ; +outb_p (smbcmd |SMBHSTCNT_START ,SMBHSTCNT (priv)); +for (i =1 ; i <= len; i++) { status =i801_wait_byte_done (priv);if (status)return status;
@@ -712,9 +708,12 @@ static int i801_block_transaction_byte_b data->block[0 ] = len; } -/* Retrieve/store value in SMBBLKDAT */ -if (read_write ==I2C_SMBUS_READ ) +if (read_write ==I2C_SMBUS_READ ) { data->block[i] =inb_p (SMBBLKDAT (priv)); +if (i == len -1 ) +outb_p (smbcmd |SMBHSTCNT_LAST_BYTE ,SMBHSTCNT (priv)); + } +if (read_write ==I2C_SMBUS_WRITE && i+1 <= len)outb_p (data->block[i+1 ],SMBBLKDAT (priv));
Greg Kroah-Hartman
maintainerPATCH 450/530 f2fs: do not return EFSCORRUPTED, but try to run online repair
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaegeuk Kim <[email protected]>
commit 50a472bbc79ff9d5a88be8019a60e936cadf9f13 upstream.
If we return the error, there's no way to recover the status as of now, since fsck does not fix the xattr boundary issue.
--- fs/f2fs/node.c | 4 +++- fs/f2fs/xattr.c | 20 +++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-)
fs/f2fs/node.c +3 -1
@@ -2751,7 +2751,9 @@ recover_xnid:f2fs_update_inode_page (inode);/* 3: update and set xattr node page dirty */ -memcpy (F2FS_NODE (xpage),F2FS_NODE (page),VALID_XATTR_BLOCK_SIZE ); +if (page) +memcpy (F2FS_NODE (xpage),F2FS_NODE (page), +VALID_XATTR_BLOCK_SIZE );set_page_dirty (xpage);f2fs_put_page (xpage,1 );
fs/f2fs/xattr.c +13 -7
@@ -364,10 +364,10 @@ static int lookup_all_xattrs(struct inod *xe =__find_xattr (cur_addr, last_txattr_addr,NULL , index, len, name);if (!*xe) { -f2fs_err (F2FS_I_SB (inode),"inode (%lu) has corrupted xattr" , +f2fs_err (F2FS_I_SB (inode),"lookup inode (%lu) has corrupted xattr" , inode->i_ino);set_sbi_flag (F2FS_I_SB (inode),SBI_NEED_FSCK ); - err = -EFSCORRUPTED ; + err = -ENODATA ;f2fs_handle_error (F2FS_I_SB (inode),ERROR_CORRUPTED_XATTR ); goto out;
@@ -584,13 +584,12 @@ ssize_t f2fs_listxattr(struct dentry *deif ((void *)(entry) +sizeof (__u32) > last_base_addr || (void *)XATTR_NEXT_ENTRY (entry) > last_base_addr) { -f2fs_err (F2FS_I_SB (inode),"inode (%lu) has corrupted xattr" , +f2fs_err (F2FS_I_SB (inode),"list inode (%lu) has corrupted xattr" , inode->i_ino);set_sbi_flag (F2FS_I_SB (inode),SBI_NEED_FSCK ); - error = -EFSCORRUPTED ;f2fs_handle_error (F2FS_I_SB (inode),ERROR_CORRUPTED_XATTR ); - goto cleanup; +break ; }if (!prefix)
@@ -650,7 +649,7 @@ static int __f2fs_setxattr(struct inodeif (size >MAX_VALUE_LEN (inode))return -E2BIG ; - +retry: error =read_all_xattrs (inode, ipage, &base_addr);if (error)return error;
@@ -660,7 +659,14 @@ static int __f2fs_setxattr(struct inode/* find entry with wanted name. */ here =__find_xattr (base_addr, last_base_addr,NULL , index, len, name);if (!here) { -f2fs_err (F2FS_I_SB (inode),"inode (%lu) has corrupted xattr" , +if (!F2FS_I (inode)->i_xattr_nid) { +f2fs_notice (F2FS_I_SB (inode), +"recover xattr in inode (%lu)" , inode->i_ino); +f2fs_recover_xattr_data (inode,NULL ); +kfree (base_addr); + goto retry; + } +f2fs_err (F2FS_I_SB (inode),"set inode (%lu) has corrupted xattr" , inode->i_ino);set_sbi_flag (F2FS_I_SB (inode),SBI_NEED_FSCK ); error = -EFSCORRUPTED ;
Greg Kroah-Hartman
maintainerPATCH 451/530 f2fs: set the default compress_level on ioctl
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaegeuk Kim <[email protected]>
commit f5f3bd903a5d3e3b2ba89f11e0e29db25e60c048 upstream.
Otherwise, we'll get a broken inode.
# touch $FILE # f2fs_io setflags compression $FILE # f2fs_io set_coption 2 8 $FILE
[ 112.227612] F2FS-fs (dm-51): sanity_check_compress_inode: inode (ino=8d3fe) has unsupported compress level: 0, run fsck to fix
--- fs/f2fs/file.c | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/f2fs/file.c +9 -0
@@ -4006,6 +4006,15 @@ static int f2fs_ioc_set_compress_option(F2FS_I (inode)->i_compress_algorithm = option.algorithm;F2FS_I (inode)->i_log_cluster_size = option.log_cluster_size;F2FS_I (inode)->i_cluster_size =BIT (option.log_cluster_size); +/* Set default level */ +if (F2FS_I (inode)->i_compress_algorithm ==COMPRESS_ZSTD ) +F2FS_I (inode)->i_compress_level =F2FS_ZSTD_DEFAULT_CLEVEL ; +else +F2FS_I (inode)->i_compress_level =0 ; +/* Adjust mount option level */ +if (option.algorithm ==F2FS_OPTION (sbi).compress_algorithm && +F2FS_OPTION (sbi).compress_level) +F2FS_I (inode)->i_compress_level =F2FS_OPTION (sbi).compress_level;f2fs_mark_inode_dirty_sync (inode, true);if (!f2fs_is_compress_backend_ready (inode))
Greg Kroah-Hartman
maintainerPATCH 452/530 f2fs: avoid format-overflow warning
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Su Hui <[email protected]>
commit e0d4e8acb3789c5a8651061fbab62ca24a45c063 upstream.
With gcc and W=1 option, there's a warning like this:
fs/f2fs/compress.c: In function ‘f2fs_init_page_array_cache’:fs/f2fs/compress.c:1984:47: error: ‘%u’ directive writing between 1 and 7 bytes into a region of size between 5 and 8 [-Werror=format-overflow=]
1984 | sprintf(slab_name, "f2fs_page_array_entry-%u:%u", MAJOR(dev),
MINOR(dev));
| ^~String "f2fs_page_array_entry-%u:%u" can up to 35. The first "%u" can up to 4 and the second "%u" can up to 7, so total size is "24 + 4 + 7 = 35". slab_name's size should be 35 rather than 32.
--- fs/f2fs/compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/f2fs/compress.c +1 -1
@@ -1976,7 +1976,7 @@ void f2fs_destroy_compress_inode(structint f2fs_init_page_array_cache (struct f2fs_sb_info *sbi) {dev_t dev = sbi->sb->s_bdev->bd_dev; -char slab_name[32 ]; +char slab_name[35 ];if (!f2fs_sb_has_compression (sbi))return 0 ;
Greg Kroah-Hartman
maintainerPATCH 453/530 f2fs: split initial and dynamic conditions for extent_cache
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaegeuk Kim <[email protected]>
commit f803982190f0265fd36cf84670aa6daefc2b0768 upstream.
Let's allocate the extent_cache tree without dynamic conditions to avoid a missing condition causing a panic as below.
# create a file w/ a compressed flag # disable the compression # panic while updating extent_cache
F2FS-fs (dm-64): Swapfile: last extent is not aligned to section
F2FS-fs (dm-64): Swapfile (3) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate(2097152 * N) Adding 124996k swap on ./swap-file. Priority:0 extents:2 across:17179494468k
==================================================================
BUG: KASAN: null-ptr-deref in instrument_atomic_read_write out/common/include/linux/instrumented.h:101 [inline] BUG: KASAN: null-ptr-deref in atomic_try_cmpxchg_acquire out/common/include/asm-generic/atomic-instrumented.h:705 [inline] BUG: KASAN: null-ptr-deref in queued_write_lock out/common/include/asm-generic/qrwlock.h:92 [inline] BUG: KASAN: null-ptr-deref in __raw_write_lock out/common/include/linux/rwlock_api_smp.h:211 [inline] BUG: KASAN: null-ptr-deref in _raw_write_lock+0x5a/0x110 out/common/kernel/locking/spinlock.c:295 Write of size 4 at addr 0000000000000030 by task syz-executor154/3327 CPU: 0 PID: 3327 Comm: syz-executor154 Tainted: G O 5.10.185 #1 Hardware name: emulation qemu-x86/qemu-x86, BIOS 2023.01-21885-gb3cc1cd24d 01/01/2023 Call Trace: __dump_stack out/common/lib/dump_stack.c:77 [inline] dump_stack_lvl+0x17e/0x1c4 out/common/lib/dump_stack.c:118 __kasan_report+0x16c/0x260 out/common/mm/kasan/report.c:415 kasan_report+0x51/0x70 out/common/mm/kasan/report.c:428 kasan_check_range+0x2f3/0x340 out/common/mm/kasan/generic.c:186 __kasan_check_write+0x14/0x20 out/common/mm/kasan/shadow.c:37 instrument_atomic_read_write out/common/include/linux/instrumented.h:101 [inline] atomic_try_cmpxchg_acquire out/common/include/asm-generic/atomic-instrumented.h:705 [inline] queued_write_lock out/common/include/asm-generic/qrwlock.h:92 [inline] __raw_write_lock out/common/include/linux/rwlock_api_smp.h:211 [inline] _raw_write_lock+0x5a/0x110 out/common/kernel/locking/spinlock.c:295 __drop_extent_tree+0xdf/0x2f0 out/common/fs/f2fs/extent_cache.c:1155 f2fs_drop_extent_tree+0x17/0x30 out/common/fs/f2fs/extent_cache.c:1172 f2fs_insert_range out/common/fs/f2fs/file.c:1600 [inline] f2fs_fallocate+0x19fd/0x1f40 out/common/fs/f2fs/file.c:1764 vfs_fallocate+0x514/0x9b0 out/common/fs/open.c:310 ksys_fallocate out/common/fs/open.c:333 [inline] __do_sys_fallocate out/common/fs/open.c:341 [inline] __se_sys_fallocate out/common/fs/open.c:339 [inline] __x64_sys_fallocate+0xb8/0x100 out/common/fs/open.c:339 do_syscall_64+0x35/0x50 out/common/arch/x86/entry/common.c:46
--- fs/f2fs/extent_cache.c | 53 +++++++++++++++++++------------------------------ 1 file changed, 21 insertions(+), 32 deletions(-)
fs/f2fs/extent_cache.c +21 -32
@@ -74,40 +74,14 @@ static void __set_extent_info(struct ext } } -static bool __may_read_extent_tree (struct inode *inode) -{ -struct f2fs_sb_info *sbi =F2FS_I_SB (inode); - -if (!test_opt (sbi,READ_EXTENT_CACHE )) -return false; -if (is_inode_flag_set (inode,FI_NO_EXTENT )) -return false; -if (is_inode_flag_set (inode,FI_COMPRESSED_FILE ) && - !f2fs_sb_has_readonly (sbi)) -return false; -return S_ISREG (inode->i_mode); -} - -static bool __may_age_extent_tree (struct inode *inode) -{ -struct f2fs_sb_info *sbi =F2FS_I_SB (inode); - -if (!test_opt (sbi,AGE_EXTENT_CACHE )) -return false; -if (is_inode_flag_set (inode,FI_COMPRESSED_FILE )) -return false; -if (file_is_cold (inode)) -return false; - -return S_ISREG (inode->i_mode) ||S_ISDIR (inode->i_mode); -} -static bool __init_may_extent_tree (struct inode *inode,enum extent_type type) {if (type ==EX_READ ) -return __may_read_extent_tree (inode); -else if (type ==EX_BLOCK_AGE ) -return __may_age_extent_tree (inode); +return test_opt (F2FS_I_SB (inode),READ_EXTENT_CACHE ) && +S_ISREG (inode->i_mode); +if (type ==EX_BLOCK_AGE ) +return test_opt (F2FS_I_SB (inode),AGE_EXTENT_CACHE ) && + (S_ISREG (inode->i_mode) ||S_ISDIR (inode->i_mode));return false; }
@@ -120,7 +94,22 @@ static bool __may_extent_tree(struct inoif (list_empty (&F2FS_I_SB (inode)->s_list))return false; -return __init_may_extent_tree (inode, type); +if (!__init_may_extent_tree (inode, type)) +return false; + +if (type ==EX_READ ) { +if (is_inode_flag_set (inode,FI_NO_EXTENT )) +return false; +if (is_inode_flag_set (inode,FI_COMPRESSED_FILE ) && + !f2fs_sb_has_readonly (F2FS_I_SB (inode))) +return false; + }else if (type ==EX_BLOCK_AGE ) { +if (is_inode_flag_set (inode,FI_COMPRESSED_FILE )) +return false; +if (file_is_cold (inode)) +return false; + } +return true; } static void __try_update_largest_extent(struct extent_tree *et,
Greg Kroah-Hartman
maintainerPATCH 454/530 media: lirc: drop trailing space from scancode transmit
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Young <[email protected]>
commit c8a489f820179fb12251e262b50303c29de991ac upstream.
When transmitting, infrared drivers expect an odd number of samples; iow without a trailing space. No problems have been observed so far, so this is just belt and braces.
--- drivers/media/rc/lirc_dev.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/media/rc/lirc_dev.c +5 -1
@@ -276,7 +276,11 @@ static ssize_t lirc_transmit(struct fileif (ret <0 ) goto out_kfree_raw; - count = ret; +/* drop trailing space */ +if (!(ret %2 )) + count = ret -1 ; +else + count = ret; txbuf =kmalloc_array (count,sizeof (unsigned int ),GFP_KERNEL );if (!txbuf) {
Greg Kroah-Hartman
maintainerPATCH 455/530 media: sharp: fix sharp encoding
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Young <[email protected]>
commit 4f7efc71891462ab7606da7039f480d7c1584a13 upstream.
The Sharp protocol[1] encoding has incorrect timings for bit space.
[1] https://www.sbprojects.net/knowledge/ir/sharp.php
--- drivers/media/rc/ir-sharp-decoder.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/media/rc/ir-sharp-decoder.c +5 -3
@@ -15,7 +15,9 @@#define SHARP_UNIT 40/* us */ #define SHARP_BIT_PULSE (8 * SHARP_UNIT)/* 320us */ #define SHARP_BIT_0_PERIOD (25 * SHARP_UNIT)/* 1ms (680us space) */ -#define SHARP_BIT_1_PERIOD (50 * SHARP_UNIT)/* 2ms (1680ms space) */ +#define SHARP_BIT_1_PERIOD (50 * SHARP_UNIT)/* 2ms (1680us space) */ +#define SHARP_BIT_0_SPACE (17 * SHARP_UNIT)/* 680us space */ +#define SHARP_BIT_1_SPACE (42 * SHARP_UNIT)/* 1680us space */ #define SHARP_ECHO_SPACE (1000 * SHARP_UNIT)/* 40 ms */ #define SHARP_TRAILER_SPACE (125 * SHARP_UNIT)/* 5 ms (even longer) */
@@ -168,8 +170,8 @@ static const struct ir_raw_timings_pd ir .header_pulse = 0, .header_space = 0, .bit_pulse = SHARP_BIT_PULSE, - .bit_space[0] = SHARP_BIT_0_PERIOD, - .bit_space[1] = SHARP_BIT_1_PERIOD, + .bit_space[0] = SHARP_BIT_0_SPACE, + .bit_space[1] = SHARP_BIT_1_SPACE, .trailer_pulse = SHARP_BIT_PULSE, .trailer_space = SHARP_ECHO_SPACE, .msb_first = 1,
Greg Kroah-Hartman
maintainerPATCH 456/530 media: venus: hfi_parser: Add check to keep the number of codecs within range
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vikash Garodia <[email protected]>
commit 0768a9dd809ef52440b5df7dce5a1c1c7e97abbd upstream.
Supported codec bitmask is populated from the payload from venus firmware. There is a possible case when all the bits in the codec bitmask is set. In such case, core cap for decoder is filled and MAX_CODEC_NUM is utilized. Now while filling the caps for encoder, it can lead to access the caps array beyong 32 index. Hence leading to OOB write.
The fix counts the supported encoder and decoder. If the count is more than max, then it skips accessing the caps.
--- drivers/media/platform/qcom/venus/hfi_parser.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/media/platform/qcom/venus/hfi_parser.c +3 -0
@@ -19,6 +19,9 @@ static void init_codecs(struct venus_corstruct hfi_plat_caps *caps = core->caps, *cap;unsigned long bit; +if (hweight_long (core->dec_codecs) +hweight_long (core->enc_codecs) >MAX_CODEC_NUM ) +return ; +for_each_set_bit (bit, &core->dec_codecs,MAX_CODEC_NUM ) { cap = &caps[core->codecs_count++]; cap->codec =BIT (bit);
Greg Kroah-Hartman
maintainerPATCH 457/530 media: venus: hfi: fix the check to handle session buffer requirement
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vikash Garodia <[email protected]>
commit b18e36dfd6c935da60a971310374f3dfec3c82e1 upstream.
Buffer requirement, for different buffer type, comes from video firmware. While copying these requirements, there is an OOB possibility when the payload from firmware is more than expected size. Fix the check to avoid the OOB possibility.
--- drivers/media/platform/qcom/venus/hfi_msgs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/qcom/venus/hfi_msgs.c +1 -1
@@ -398,7 +398,7 @@ session_get_prop_buf_req(struct hfi_msg_memcpy (&bufreq[idx], buf_req,sizeof (*bufreq)); idx++; -if (idx >HFI_BUFFER_TYPE_MAX ) +if (idx >=HFI_BUFFER_TYPE_MAX )return HFI_ERR_SESSION_INVALID_PARAMETER ; req_bytes -=sizeof (struct hfi_buffer_requirements );
Greg Kroah-Hartman
maintainerPATCH 458/530 media: venus: hfi: add checks to handle capabilities from firmware
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vikash Garodia <[email protected]>
commit 8d0b89398b7ebc52103e055bf36b60b045f5258f upstream.
The hfi parser, parses the capabilities received from venus firmware and copies them to core capabilities. Consider below api, for example, fill_caps - In this api, caps in core structure gets updated with the number of capabilities received in firmware data payload. If the same api is called multiple times, there is a possibility of copying beyond the max allocated size in core caps.
Similar possibilities in fill_raw_fmts and fill_profile_level functions.
--- drivers/media/platform/qcom/venus/hfi_parser.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/media/platform/qcom/venus/hfi_parser.c +12 -0
@@ -89,6 +89,9 @@ static void fill_profile_level(struct hf {const struct hfi_profile_level *pl = data; +if (cap->num_pl + num >=HFI_MAX_PROFILE_COUNT ) +return ; +memcpy (&cap->pl[cap->num_pl], pl, num *sizeof (*pl)); cap->num_pl += num; }
@@ -114,6 +117,9 @@ fill_caps(struct hfi_plat_caps *cap, con {const struct hfi_capability *caps = data; +if (cap->num_caps + num >=MAX_CAP_ENTRIES ) +return ; +memcpy (&cap->caps[cap->num_caps], caps, num *sizeof (*caps)); cap->num_caps += num; }
@@ -140,6 +146,9 @@ static void fill_raw_fmts(struct hfi_pla {const struct raw_formats *formats = fmts; +if (cap->num_fmts + num_fmts >=MAX_FMT_ENTRIES ) +return ; +memcpy (&cap->fmts[cap->num_fmts], formats, num_fmts *sizeof (*formats)); cap->num_fmts += num_fmts; }
@@ -162,6 +171,9 @@ parse_raw_formats(struct venus_core *cor rawfmts[i].buftype = fmt->buffer_type; i++; +if (i >=MAX_FMT_ENTRIES ) +return ; +if (pinfo->num_planes >MAX_PLANES )break ;
Greg Kroah-Hartman
maintainerPATCH 459/530 media: ccs: Correctly initialise try compose rectangle
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sakari Ailus <[email protected]>
commit 724ff68e968b19d786870d333f9952bdd6b119cb upstream.
Initialise the try sink compose rectangle size to the sink compose rectangle for binner and scaler sub-devices. This was missed due to the faulty condition that lead to the compose rectangles to be initialised for the pixel array sub-device where it is not relevant.
--- drivers/media/i2c/ccs/ccs-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/i2c/ccs/ccs-core.c +1 -1
@@ -3097,7 +3097,7 @@ static int ccs_open(struct v4l2_subdev * try_fmt->code = sensor->internal_csi_format->code; try_fmt->field =V4L2_FIELD_NONE ; -if (ssd != sensor->pixel_array) +if (ssd == sensor->pixel_array)continue ; try_comp =v4l2_subdev_get_try_compose (sd, fh->state, i);
Greg Kroah-Hartman
maintainerPATCH 460/530 drm/mediatek/dp: fix memory leak on ->get_edid callback audio detection
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jani Nikula <[email protected]>
commit dab12fa8d2bd3868cf2de485ed15a3feef28a13d upstream.
The sads returned by drm_edid_to_sad() needs to be freed.
--- drivers/gpu/drm/mediatek/mtk_dp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/mediatek/mtk_dp.c +4 -1
@@ -2034,7 +2034,6 @@ static struct edid *mtk_dp_get_edid(strubool enabled = mtk_dp->enabled;struct edid *new_edid =NULL ;struct mtk_dp_audio_cfg *audio_caps = &mtk_dp->info.audio_cur_cfg; -struct cea_sad *sads;if (!enabled) {drm_atomic_bridge_chain_pre_enable (bridge, connector->state->state);
@@ -2053,7 +2052,11 @@ static struct edid *mtk_dp_get_edid(stru }if (new_edid) { +struct cea_sad *sads; + audio_caps->sad_count =drm_edid_to_sad (new_edid, &sads); +kfree (sads); + audio_caps->detect_monitor =drm_detect_monitor_audio (new_edid); }
Greg Kroah-Hartman
maintainerPATCH 461/530 drm/mediatek/dp: fix memory leak on ->get_edid callback error path
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jani Nikula <[email protected]>
commit fcaf9761fd5884a64eaac48536f8c27ecfd2e6bc upstream.
Setting new_edid to NULL leaks the buffer.
--- drivers/gpu/drm/mediatek/mtk_dp.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/mediatek/mtk_dp.c +1 -0
@@ -2048,6 +2048,7 @@ static struct edid *mtk_dp_get_edid(stru*/ if (mtk_dp_parse_capabilities (mtk_dp)) {drm_err (mtk_dp->drm_dev,"Can't parse capabilities\n" ); +kfree (new_edid); new_edid =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 462/530 dm-bufio: fix no-sleep mode
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit 2a695062a5a42aead8c539a344168d4806b3fda2 upstream.
dm-bufio has a no-sleep mode. When activated (with the DM_BUFIO_CLIENT_NO_SLEEP flag), the bufio client is read-only and we could call dm_bufio_get from tasklets. This is used by dm-verity.
Unfortunately, commit 450e8dee51aa ("dm bufio: improve concurrent IO performance") broke this and the kernel would warn that cache_get() was calling down_read() from no-sleeping context. The bug can be reproduced by using "veritysetup open" with the "--use-tasklets" flag.
This commit fixes dm-bufio, so that the tasklet mode works again, by expanding use of the 'no_sleep_enabled' static_key to conditionally use either a rw_semaphore or rwlock_t (which are colocated in the buffer_tree structure using a union).
--- drivers/md/dm-bufio.c | 87 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 25 deletions(-)
drivers/md/dm-bufio.c +62 -25
@@ -254,7 +254,7 @@ enum evict_result {typedef enum evict_result (*le_predicate )(struct lru_entry *le,void *context); -static struct lru_entry *lru_evict (struct lru *lru,le_predicate pred,void *context) +static struct lru_entry *lru_evict (struct lru *lru,le_predicate pred,void *context,bool no_sleep) {unsigned long tested =0 ;struct list_head *h = lru->cursor;
@@ -295,7 +295,8 @@ static struct lru_entry *lru_evict(struc h = h->next; -cond_resched (); +if (!no_sleep) +cond_resched (); }return NULL ;
@@ -382,7 +383,10 @@ struct dm_buffer {*/ struct buffer_tree { -struct rw_semaphore lock; +union { +struct rw_semaphore lock; +rwlock_t spinlock; + } u;struct rb_root root; }____cacheline_aligned_in_smp ;
@@ -393,9 +397,12 @@ struct dm_buffer_cache {* on the locks. */ unsigned int num_locks; +bool no_sleep;struct buffer_tree trees[]; }; +static DEFINE_STATIC_KEY_FALSE (no_sleep_enabled); +static inline unsigned int cache_index (sector_t block,unsigned int num_locks) {return dm_hash_locks_index (block, num_locks);
@@ -403,22 +410,34 @@ static inline unsigned int cache_index(sstatic inline void cache_read_lock (struct dm_buffer_cache *bc,sector_t block) { -down_read (&bc->trees[cache_index (block, bc->num_locks)].lock); +if (static_branch_unlikely (&no_sleep_enabled) && bc->no_sleep) +read_lock_bh (&bc->trees[cache_index (block, bc->num_locks)].u.spinlock); +else +down_read (&bc->trees[cache_index (block, bc->num_locks)].u.lock); }static inline void cache_read_unlock (struct dm_buffer_cache *bc,sector_t block) { -up_read (&bc->trees[cache_index (block, bc->num_locks)].lock); +if (static_branch_unlikely (&no_sleep_enabled) && bc->no_sleep) +read_unlock_bh (&bc->trees[cache_index (block, bc->num_locks)].u.spinlock); +else +up_read (&bc->trees[cache_index (block, bc->num_locks)].u.lock); }static inline void cache_write_lock (struct dm_buffer_cache *bc,sector_t block) { -down_write (&bc->trees[cache_index (block, bc->num_locks)].lock); +if (static_branch_unlikely (&no_sleep_enabled) && bc->no_sleep) +write_lock_bh (&bc->trees[cache_index (block, bc->num_locks)].u.spinlock); +else +down_write (&bc->trees[cache_index (block, bc->num_locks)].u.lock); }static inline void cache_write_unlock (struct dm_buffer_cache *bc,sector_t block) { -up_write (&bc->trees[cache_index (block, bc->num_locks)].lock); +if (static_branch_unlikely (&no_sleep_enabled) && bc->no_sleep) +write_unlock_bh (&bc->trees[cache_index (block, bc->num_locks)].u.spinlock); +else +up_write (&bc->trees[cache_index (block, bc->num_locks)].u.lock); }/*
@@ -442,18 +461,32 @@ static void lh_init(struct lock_historystatic void __lh_lock (struct lock_history *lh,unsigned int index) { -if (lh->write) -down_write (&lh->cache->trees[index].lock); -else -down_read (&lh->cache->trees[index].lock); +if (lh->write) { +if (static_branch_unlikely (&no_sleep_enabled) && lh->cache->no_sleep) +write_lock_bh (&lh->cache->trees[index].u.spinlock); +else +down_write (&lh->cache->trees[index].u.lock); + }else { +if (static_branch_unlikely (&no_sleep_enabled) && lh->cache->no_sleep) +read_lock_bh (&lh->cache->trees[index].u.spinlock); +else +down_read (&lh->cache->trees[index].u.lock); + } }static void __lh_unlock (struct lock_history *lh,unsigned int index) { -if (lh->write) -up_write (&lh->cache->trees[index].lock); -else -up_read (&lh->cache->trees[index].lock); +if (lh->write) { +if (static_branch_unlikely (&no_sleep_enabled) && lh->cache->no_sleep) +write_unlock_bh (&lh->cache->trees[index].u.spinlock); +else +up_write (&lh->cache->trees[index].u.lock); + }else { +if (static_branch_unlikely (&no_sleep_enabled) && lh->cache->no_sleep) +read_unlock_bh (&lh->cache->trees[index].u.spinlock); +else +up_read (&lh->cache->trees[index].u.lock); + } }/*
@@ -502,14 +535,18 @@ static struct dm_buffer *list_to_buffer(return le_to_buffer (le); } -static void cache_init (struct dm_buffer_cache *bc,unsigned int num_locks) +static void cache_init (struct dm_buffer_cache *bc,unsigned int num_locks,bool no_sleep) {unsigned int i; bc->num_locks = num_locks; + bc->no_sleep = no_sleep;for (i =0 ; i < bc->num_locks; i++) { -init_rwsem (&bc->trees[i].lock); +if (no_sleep) +rwlock_init (&bc->trees[i].u.spinlock); +else +init_rwsem (&bc->trees[i].u.lock); bc->trees[i].root =RB_ROOT ; }
@@ -648,7 +685,7 @@ static struct dm_buffer *__cache_evict(sstruct lru_entry *le;struct dm_buffer *b; - le =lru_evict (&bc->lru[list_mode], __evict_pred, &w); + le =lru_evict (&bc->lru[list_mode], __evict_pred, &w, bc->no_sleep);if (!le)return NULL ;
@@ -702,7 +739,7 @@ static void __cache_mark_many(struct dm_struct evict_wrapper w = {.lh = lh, .pred = pred, .context = context};while (true) { - le =lru_evict (&bc->lru[old_mode], __evict_pred, &w); + le =lru_evict (&bc->lru[old_mode], __evict_pred, &w, bc->no_sleep);if (!le)break ;
@@ -915,10 +952,11 @@ static void cache_remove_range(struct dm {unsigned int i; +BUG_ON (bc->no_sleep);for (i =0 ; i < bc->num_locks; i++) { -down_write (&bc->trees[i].lock); +down_write (&bc->trees[i].u.lock);__remove_range (bc, &bc->trees[i].root, begin, end, pred, release); -up_write (&bc->trees[i].lock); +up_write (&bc->trees[i].u.lock); } }
@@ -979,8 +1017,6 @@ struct dm_bufio_client {struct dm_buffer_cache cache;/* must be last member */ }; -static DEFINE_STATIC_KEY_FALSE (no_sleep_enabled); -/*----------------------------------------------------------------*/ #define dm_bufio_in_request () (!!current->bio_list)
@@ -1871,7 +1907,8 @@ static void *new_read(struct dm_bufio_clif (need_submit)submit_io (b,REQ_OP_READ , read_endio); -wait_on_bit_io (&b->state,B_READING ,TASK_UNINTERRUPTIBLE ); +if (nf !=NF_GET )/* we already tested this condition above */ +wait_on_bit_io (&b->state,B_READING ,TASK_UNINTERRUPTIBLE );if (b->read_error) {int error =blk_status_to_errno (b->read_error);
@@ -2421,7 +2458,7 @@ struct dm_bufio_client *dm_bufio_client_ r = -ENOMEM ; goto bad_client; } -cache_init (&c->cache, num_locks); +cache_init (&c->cache, num_locks, (flags &DM_BUFIO_CLIENT_NO_SLEEP ) !=0 ); c->bdev = bdev; c->block_size = block_size;
Greg Kroah-Hartman
maintainerPATCH 463/530 dm-verity: dont use blocking calls from tasklets
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit 28f07f2ab4b3a2714f1fefcc58ada4bcc195f806 upstream.
The commit 5721d4e5a9cd enhanced dm-verity, so that it can verify blocks from tasklets rather than from workqueues. This reportedly improves performance significantly.
However, dm-verity was using the flag CRYPTO_TFM_REQ_MAY_SLEEP from tasklets which resulted in warnings about sleeping function being called from non-sleeping context.
BUG: sleeping function called from invalid context at crypto/internal.h:206 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 14, name: ksoftirqd/0 preempt_count: 100, expected: 0 RCU nest depth: 0, expected: 0 CPU: 0 PID: 14 Comm: ksoftirqd/0 Tainted: G W 6.7.0-rc1 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x32/0x50 __might_resched+0x110/0x160 crypto_hash_walk_done+0x54/0xb0 shash_ahash_update+0x51/0x60 verity_hash_update.isra.0+0x4a/0x130 [dm_verity] verity_verify_io+0x165/0x550 [dm_verity] ? free_unref_page+0xdf/0x170 ? psi_group_change+0x113/0x390 verity_tasklet+0xd/0x70 [dm_verity] tasklet_action_common.isra.0+0xb3/0xc0 __do_softirq+0xaf/0x1ec ? smpboot_thread_fn+0x1d/0x200 ? sort_range+0x20/0x20 run_ksoftirqd+0x15/0x30 smpboot_thread_fn+0xed/0x200 kthread+0xdc/0x110 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x28/0x40 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork_asm+0x11/0x20 </TASK>
This commit fixes dm-verity so that it doesn't use the flags CRYPTO_TFM_REQ_MAY_SLEEP and CRYPTO_TFM_REQ_MAY_BACKLOG from tasklets. The crypto API would do GFP_ATOMIC allocation instead, it could return -ENOMEM and we catch -ENOMEM in verity_tasklet and requeue the request to the workqueue.
--- drivers/md/dm-verity-fec.c | 4 ++-- drivers/md/dm-verity-target.c | 23 ++++++++++++----------- drivers/md/dm-verity.h | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-)
drivers/md/dm-verity-fec.c +2 -2
@@ -185,7 +185,7 @@ static int fec_is_erasure(struct dm_veri {if (unlikely (verity_hash (v,verity_io_hash_req (v, io), data,1 << v->data_dev_block_bits, -verity_io_real_digest (v, io)))) +verity_io_real_digest (v, io), true)))return 0 ; return memcmp(verity_io_real_digest(v, io), want_digest,
@@ -386,7 +386,7 @@ static int fec_decode_rsb(struct dm_veri/* Always re-validate the corrected block against the expected hash */ r =verity_hash (v,verity_io_hash_req (v, io), fio->output,1 << v->data_dev_block_bits, -verity_io_real_digest (v, io)); +verity_io_real_digest (v, io), true);if (unlikely (r <0 ))return r;
drivers/md/dm-verity-target.c +12 -11
@@ -135,20 +135,21 @@ static int verity_hash_update(struct dm_* Wrapper for crypto_ahash_init, which handles verity salting. */ static int verity_hash_init (struct dm_verity *v,struct ahash_request *req, -struct crypto_wait *wait) +struct crypto_wait *wait,bool may_sleep) {int r;ahash_request_set_tfm (req, v->tfm); -ahash_request_set_callback (req,CRYPTO_TFM_REQ_MAY_SLEEP | -CRYPTO_TFM_REQ_MAY_BACKLOG , - crypto_req_done, (void *)wait); +ahash_request_set_callback (req, + may_sleep ?CRYPTO_TFM_REQ_MAY_SLEEP |CRYPTO_TFM_REQ_MAY_BACKLOG :0 , + crypto_req_done, (void *)wait);crypto_init_wait (wait); r =crypto_wait_req (crypto_ahash_init (req), wait);if (unlikely (r <0 )) { -DMERR ("crypto_ahash_init failed: %d" , r); +if (r != -ENOMEM ) +DMERR ("crypto_ahash_init failed: %d" , r);return r; }
@@ -179,12 +180,12 @@ out: }int verity_hash (struct dm_verity *v,struct ahash_request *req, -const u8 *data,size_t len,u8 *digest) +const u8 *data,size_t len,u8 *digest,bool may_sleep) {int r;struct crypto_wait wait; - r =verity_hash_init (v, req, &wait); + r =verity_hash_init (v, req, &wait, may_sleep);if (unlikely (r <0 )) goto out;
@@ -322,7 +323,7 @@ static int verity_verify_level(struct dm r =verity_hash (v,verity_io_hash_req (v, io), data,1 << v->hash_dev_block_bits, -verity_io_real_digest (v, io)); +verity_io_real_digest (v, io), !io->in_tasklet);if (unlikely (r <0 )) goto release_ret_r;
@@ -556,7 +557,7 @@ static int verity_verify_io(struct dm_vecontinue ; } - r =verity_hash_init (v, req, &wait); + r =verity_hash_init (v, req, &wait, !io->in_tasklet);if (unlikely (r <0 ))return r;
@@ -652,7 +653,7 @@ static void verity_tasklet(unsigned long io->in_tasklet = true; err =verity_verify_io (io); -if (err == -EAGAIN ) { +if (err == -EAGAIN || err == -ENOMEM ) {/* fallback to retrying with work-queue */ INIT_WORK (&io->work, verity_work);queue_work (io->v->verify_wq, &io->work);
@@ -1033,7 +1034,7 @@ static int verity_alloc_zero_digest(stru goto out; r =verity_hash (v, req, zero_data,1 << v->data_dev_block_bits, - v->zero_digest); + v->zero_digest, true); out:kfree (req);
drivers/md/dm-verity.h +1 -1
@@ -128,7 +128,7 @@ extern int verity_for_bv_block(struct dm u8 *data, size_t len));extern int verity_hash (struct dm_verity *v,struct ahash_request *req, -const u8 *data,size_t len,u8 *digest); +const u8 *data,size_t len,u8 *digest,bool may_sleep);extern int verity_hash_for_block (struct dm_verity *v,struct dm_verity_io *io,sector_t block,u8 *digest,bool *is_zero);
Greg Kroah-Hartman
maintainerPATCH 464/530 nfsd: fix file memleak on client_opens_release
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mahmoud Adam <[email protected]>
commit bc1b5acb40201a0746d68a7d7cfc141899937f4f upstream.
seq_release should be called to free the allocated seq_file
--- fs/nfsd/nfs4state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfsd/nfs4state.c +1 -1
@@ -2797,7 +2797,7 @@ static int client_opens_release(struct i/* XXX: alternatively, we could get/drop in seq start/stop */ drop_client (clp); -return 0 ; +return seq_release (inode, file); }static const struct file_operations client_states_fops = {
Greg Kroah-Hartman
maintainerPATCH 465/530 NFSD: Update nfsd_cache_append() to use xdr_stream
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
commit 49cecd8628a9855cd993792a0377559ea32d5e7c upstream.
When inserting a DRC-cached response into the reply buffer, ensure that the reply buffer's xdr_stream is updated properly. Otherwise the server will send a garbage response.
--- fs/nfsd/nfscache.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-)
fs/nfsd/nfscache.c +7 -14
@@ -640,24 +640,17 @@ void nfsd_cache_update(struct svc_rqst *return ; } -/* -* Copy cached reply to current reply buffer. Should always fit. -* FIXME as reply is in a page, we should just attach the page, and -* keep a refcount.... -*/ static int nfsd_cache_append (struct svc_rqst *rqstp,struct kvec *data) { -struct kvec *vec = &rqstp->rq_res.head[0 ]; +__be32 *p; -if (vec->iov_len + data->iov_len >PAGE_SIZE ) { -printk (KERN_WARNING "nfsd: cached reply too large (%zd).\n" , - data->iov_len); -return 0 ; - } -memcpy ((char *)vec->iov_base + vec->iov_len, data->iov_base, data->iov_len); - vec->iov_len += data->iov_len; -return 1 ; + p =xdr_reserve_space (&rqstp->rq_res_stream, data->iov_len); +if (unlikely (!p)) +return false; +memcpy (p, data->iov_base, data->iov_len); +xdr_commit_encode (&rqstp->rq_res_stream); +return true; }/*
Greg Kroah-Hartman
maintainerPATCH 466/530 LoongArch: Mark __percpu functions as always inline
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit 71945968d8b128c955204baa33ec03bdd91bdc26 upstream.
A recent change to the optimization pipeline in LLVM reveals some fragility around the inlining of LoongArch's __percpu functions, which manifests as a BUILD_BUG() failure:
In file included from kernel/sched/build_policy.c:17:
In file included from include/linux/sched/cputime.h:5:
In file included from include/linux/sched/signal.h:5:
In file included from include/linux/rculist.h:11:
In file included from include/linux/rcupdate.h:26:
In file included from include/linux/irqflags.h:18:
arch/loongarch/include/asm/percpu.h:97:3: error: call to '__compiletime_assert_51' declared with 'error' attribute: BUILD_BUG failed
97 | BUILD_BUG();
| ^
include/linux/build_bug.h:59:21: note: expanded from macro 'BUILD_BUG'
59 | #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
| ^
include/linux/build_bug.h:39:37: note: expanded from macro 'BUILD_BUG_ON_MSG'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^
include/linux/compiler_types.h:425:2: note: expanded from macro 'compiletime_assert'
425 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^
include/linux/compiler_types.h:413:2: note: expanded from macro '_compiletime_assert'
413 | __compiletime_assert(condition, msg, prefix, suffix)
| ^
include/linux/compiler_types.h:406:4: note: expanded from macro '__compiletime_assert'
406 | prefix ## suffix(); \
| ^
<scratch space>:86:1: note: expanded from here
86 | __compiletime_assert_51
| ^1 error generated.
If these functions are not inlined (which the compiler is free to do even with functions marked with the standard 'inline' keyword), the BUILD_BUG() in the default case cannot be eliminated since the compiler cannot prove it is never used, resulting in a build failure due to the error attribute.
Mark these functions as __always_inline to guarantee inlining so that the BUILD_BUG() only triggers when the default case genuinely cannot be eliminated due to an unexpected size.
--- arch/loongarch/include/asm/percpu.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
arch/loongarch/include/asm/percpu.h +5 -5
@@ -32,7 +32,7 @@ static inline void set_my_cpu_offset(uns#define __my_cpu_offset __my_cpu_offset#define PERCPU_OP (op, asm_op, c_op) \ -static inline unsigned long __percpu_##op(void *ptr, \ +static __always_inline unsigned long __percpu_##op(void *ptr, \ unsigned long val, int size) \ { \ unsigned long ret; \
@@ -63,7 +63,7 @@ PERCPU_OP(and, and, &) PERCPU_OP(or, or, |) #undef PERCPU_OP -static inline unsigned long __percpu_read(void *ptr, int size) +static __always_inline unsigned long __percpu_read(void *ptr, int size) { unsigned long ret;
@@ -100,7 +100,7 @@ static inline unsigned long __percpu_reareturn ret; } -static inline void __percpu_write (void *ptr,unsigned long val,int size) +static __always_inline void __percpu_write(void *ptr, unsigned long val, int size) {switch (size) {case 1 :
@@ -132,8 +132,8 @@ static inline void __percpu_write(void * } } -static inline unsigned long __percpu_xchg (void *ptr,unsigned long val, -int size) +static __always_inline unsigned long __percpu_xchg (void *ptr,unsigned long val, +int size) {switch (size) {case 1 :
Greg Kroah-Hartman
maintainerPATCH 467/530 tracing: fprobe-event: Fix to check tracepoint event and return
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <[email protected]>
commit ce51e6153f7781bcde0f8bb4c81d6fd85ee422e6 upstream.
Fix to check the tracepoint event is not valid with $retval. The commit 08c9306fc2e3 ("tracing/fprobe-event: Assume fprobe is a return event by $retval") introduced automatic return probe conversion with $retval. But since tracepoint event does not support return probe, $retval is not acceptable.
Without this fix, ftracetest, tprobe_syntax_errors.tc fails;
[22] Tracepoint probe event parser error log check [FAIL]
----
# tail 22-tprobe_syntax_errors.tc-log.mRKroL + ftrace_errlog_check trace_fprobe t kfree ^$retval dynamic_events + printf %s t kfree + wc -c + pos=8 + printf %s t kfree ^$retval + tr -d ^ + command=t kfree $retval + echo Test command: t kfree $retval Test command: t kfree $retval + echo ----
So 't kfree $retval' should fail (tracepoint doesn't support return probe) but passed it.
--- kernel/trace/trace_fprobe.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
kernel/trace/trace_fprobe.c +5 -4
@@ -927,11 +927,12 @@ static int parse_symbol_and_return(int argc, const char *argv[],for (i =2 ; i < argc; i++) { tmp =strstr (argv[i],"$retval" );if (tmp && !isalnum (tmp[7 ]) && tmp[7 ] !='_' ) { +if (is_tracepoint) { +trace_probe_log_set_index (i); +trace_probe_log_err (tmp - argv[i],RETVAL_ON_PROBE ); +return -EINVAL ; + } *is_return = true; -/* -* NOTE: Don't check is_tracepoint here, because it will -* be checked when the argument is parsed. -*/ break ; } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 468/530 swiotlb: do not free decrypted pages if dynamic
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Tesarik <[email protected]>
commit a5e3b127455d073f146a2a4ea3e7117635d34c5c upstream.
Fix these two error paths:
1. When set_memory_decrypted() fails, pages may be left fully or partially decrypted.
2. Decrypted pages may be freed if swiotlb_alloc_tlb() determines that the physical address is too high.
To fix the first issue, call set_memory_encrypted() on the allocated region after a failed decryption attempt. If that also fails, leak the pages.
To fix the second issue, check that the TLB physical address is below the requested limit before decrypting.
Let the caller differentiate between unsuitable physical address (=> retry from a lower zone) and allocation failures (=> no point in retrying).
--- kernel/dma/swiotlb.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-)
kernel/dma/swiotlb.c +16 -9
@@ -558,29 +558,40 @@ void __init swiotlb_exit(void)* alloc_dma_pages() - allocate pages to be used for DMA * @gfp: GFP flags for the allocation. * @bytes: Size of the buffer. +* @phys_limit: Maximum allowed physical address of the buffer. * * Allocate pages from the buddy allocator. If successful, make the allocated * pages decrypted that they can be used for DMA. * -* Return: Decrypted pages, or %NULL on failure. +* Return: Decrypted pages, %NULL on allocation failure, or ERR_PTR(-EAGAIN) +* if the allocated physical address was above @phys_limit. */ -static struct page *alloc_dma_pages (gfp_t gfp,size_t bytes) +static struct page *alloc_dma_pages (gfp_t gfp,size_t bytes,u64 phys_limit) {unsigned int order =get_order (bytes);struct page *page; +phys_addr_t paddr;void *vaddr; page =alloc_pages (gfp, order);if (!page)return NULL ; - vaddr =page_address (page); + paddr =page_to_phys (page); +if (paddr + bytes -1 > phys_limit) { +__free_pages (page, order); +return ERR_PTR (-EAGAIN ); + } + + vaddr =phys_to_virt (paddr);if (set_memory_decrypted ((unsigned long )vaddr,PFN_UP (bytes))) goto error;return page; error: -__free_pages (page, order); +/* Intentional leak if pages cannot be encrypted again. */ +if (!set_memory_encrypted ((unsigned long )vaddr,PFN_UP (bytes))) +__free_pages (page, order);return NULL ; }
@@ -618,11 +629,7 @@ static struct page *swiotlb_alloc_tlb(struct device *dev, size_t bytes,else if (phys_limit <=DMA_BIT_MASK (32 )) gfp |= __GFP_DMA32; -while ((page =alloc_dma_pages (gfp, bytes)) && -page_to_phys (page) + bytes -1 > phys_limit) { -/* allocated, but too high */ -__free_pages (page,get_order (bytes)); - +while (IS_ERR (page =alloc_dma_pages (gfp, bytes, phys_limit))) {if (IS_ENABLED (CONFIG_ZONE_DMA32 ) && phys_limit <DMA_BIT_MASK (64 ) && !(gfp & (__GFP_DMA32 | __GFP_DMA)))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 469/530 swiotlb: fix out-of-bounds TLB allocations with CONFIG_SWIOTLB_DYNAMIC
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Tesarik <[email protected]>
commit 53c87e846e335e3c18044c397cc35178163d7827 upstream.
Limit the free list length to the size of the IO TLB. Transient pool can be smaller than IO_TLB_SEGSIZE, but the free list is initialized with the assumption that the total number of slots is a multiple of IO_TLB_SEGSIZE. As a result, swiotlb_area_find_slots() may allocate slots past the end of a transient IO TLB buffer.
--- kernel/dma/swiotlb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/dma/swiotlb.c +2 -1
@@ -283,7 +283,8 @@ static void swiotlb_init_io_tlb_pool(struct io_tlb_pool *mem, phys_addr_t start, }for (i =0 ; i < mem->nslabs; i++) { - mem->slots[i].list =IO_TLB_SEGSIZE -io_tlb_offset (i); + mem->slots[i].list =min (IO_TLB_SEGSIZE -io_tlb_offset (i), + mem->nslabs - i); mem->slots[i].orig_addr =INVALID_PHYS_ADDR ; mem->slots[i].alloc_size =0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 470/530 riscv: Using TOOLCHAIN_HAS_ZIHINTPAUSE marco replace zihintpause
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Minda Chen <[email protected]>
commit dd16ac404a685cce07e67261a94c6225d90ea7ba upstream.
Actually it is a part of Conor's
commit aae538cd03bc ("riscv: fix detection of toolchain Zihintpause support").
It is looks like a merge issue. Samuel's
commit 0b1d60d6dd9e ("riscv: Fix build with CONFIG_CC_OPTIMIZE_FOR_SIZE=y") do not base on Conor's commit and revert to __riscv_zihintpause. So this patch can fix it.
--- arch/riscv/include/asm/vdso/processor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/include/asm/vdso/processor.h +1 -1
@@ -14,7 +14,7 @@ static inline void cpu_relax(void) __asm__ __volatile__ ("div %0, %0, zero" :"=r" (dummy));#endif -#ifdef __riscv_zihintpause +#ifdef CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE /* * Reduce instruction retirement. * This assumes the PC changes.
Greg Kroah-Hartman
maintainerPATCH 471/530 riscv: put interrupt entries into .irqentry.text
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nam Cao <[email protected]>
commit 87615e95f6f9ccd36d4a3905a2d87f91967ea9d2 upstream.
The interrupt entries are expected to be in the .irqentry.text section. For example, for kprobes to work properly, exception code cannot be probed; this is ensured by blacklisting addresses in the .irqentry.text section.
--- arch/riscv/kernel/entry.S | 2 ++ 1 file changed, 2 insertions(+)
arch/riscv/kernel/entry.S +2 -0
@@ -16,6 +16,8 @@ #include <asm/errata_list.h> #include <linux/sizes.h> + .section .irqentry.text, "ax" + SYM_CODE_START(handle_exception) /* * If coming from userspace, preserve the user thread pointer and load
Greg Kroah-Hartman
maintainerPATCH 472/530 riscv: mm: Update the comment of CONFIG_PAGE_OFFSET
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Song Shuai <[email protected]>
commit 559fe94a449cba5b50a7cffea60474b385598c00 upstream.
Since the commit 011f09d12052 set sv57 as default for CONFIG_64BIT, the comment of CONFIG_PAGE_OFFSET should be updated too.
--- arch/riscv/include/asm/page.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/riscv/include/asm/page.h +2 -2
@@ -33,8 +33,8 @@#define PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)#endif /* -* By default, CONFIG_PAGE_OFFSET value corresponds to SV48 address space so -* define the PAGE_OFFSET value for SV39. +* By default, CONFIG_PAGE_OFFSET value corresponds to SV57 address space so +* define the PAGE_OFFSET value for SV48 and SV39. */ #define PAGE_OFFSET_L4 _AC(0xffffaf8000000000, UL)#define PAGE_OFFSET_L3 _AC(0xffffffd800000000, UL)
Greg Kroah-Hartman
maintainerPATCH 473/530 riscv: correct pt_level name via pgtable_l5/4_enabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Song Shuai <[email protected]>
commit e59e5e2754bf983fc58ad18f99b5eec01f1a0745 upstream.
The pt_level uses CONFIG_PGTABLE_LEVELS to display page table names. But if page mode is downgraded from kernel cmdline or restricted by the hardware in 64BIT, it will give a wrong name.
Like, using no4lvl for sv39, ptdump named the 1G-mapping as "PUD" that should be "PGD":
0xffffffd840000000-0xffffffd900000000 0x00000000c0000000 3G PUD D A G . . W R V
So select "P4D/PUD" or "PGD" via pgtable_l5/4_enabled to correct it.
--- arch/riscv/mm/ptdump.c | 3 +++ 1 file changed, 3 insertions(+)
arch/riscv/mm/ptdump.c +3 -0
@@ -384,6 +384,9 @@ static int __init ptdump_init(void) kernel_ptd_info.base_addr =KERN_VIRT_START ; + pg_level[1 ].name = pgtable_l5_enabled ?"P4D" :"PGD" ; + pg_level[2 ].name = pgtable_l4_enabled ?"PUD" :"PGD" ; +for (i =0 ; i <ARRAY_SIZE (pg_level); i++)for (j =0 ; j <ARRAY_SIZE (pte_bits); j++) pg_level[i].mask |= pte_bits[j].mask;
Greg Kroah-Hartman
maintainerPATCH 474/530 riscv: kprobes: allow writing to x0
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nam Cao <[email protected]>
commit 8cb22bec142624d21bc85ff96b7bad10b6220e6a upstream.
Instructions can write to x0, so we should simulate these instructions normally.
Currently, the kernel hangs if an instruction who writes to x0 is simulated.
--- arch/riscv/kernel/probes/simulate-insn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/kernel/probes/simulate-insn.c +1 -1
@@ -24,7 +24,7 @@ static inline bool rv_insn_reg_set_val(s unsigned long val) {if (index ==0 ) -return false; +return true;else if (index <=31 ) *((unsigned long *)regs + index) = val;else
Greg Kroah-Hartman
maintainerPATCH 475/530 mmc: sdhci-pci-gli: A workaround to allow GL9750 to enter ASPM L1.2
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Shih <[email protected]>
commit d7133797e9e1b72fd89237f68cb36d745599ed86 upstream.
When GL9750 enters ASPM L1 sub-states, it will stay at L1.1 and will not enter L1.2. The workaround is to toggle PM state to allow GL9750 to enter ASPM L1.2.
--- drivers/mmc/host/sdhci-pci-gli.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/mmc/host/sdhci-pci-gli.c +14 -0
@@ -25,6 +25,9 @@#define GLI_9750_WT_EN_ON 0x1#define GLI_9750_WT_EN_OFF 0x0 +#define PCI_GLI_9750_PM_CTRL 0xFC +#define PCI_GLI_9750_PM_STATE GENMASK(1, 0) +#define SDHCI_GLI_9750_CFG2 0x848#define SDHCI_GLI_9750_CFG2_L1DLY GENMASK(28, 24)#define GLI_9750_CFG2_L1DLY_VALUE 0x1F
@@ -539,8 +542,12 @@ static void sdhci_gl9750_set_clock(strucstatic void gl9750_hw_setting (struct sdhci_host *host) { +struct sdhci_pci_slot *slot =sdhci_priv (host); +struct pci_dev *pdev;u32 value; + pdev = slot->chip->pdev; +gl9750_wt_on (host); value =sdhci_readl (host,SDHCI_GLI_9750_CFG2 );
@@ -550,6 +557,13 @@ static void gl9750_hw_setting(struct sdh GLI_9750_CFG2_L1DLY_VALUE);sdhci_writel (host, value,SDHCI_GLI_9750_CFG2 ); +/* toggle PM state to allow GL9750 to enter ASPM L1.2 */ +pci_read_config_dword (pdev,PCI_GLI_9750_PM_CTRL , &value); + value |=PCI_GLI_9750_PM_STATE ; +pci_write_config_dword (pdev,PCI_GLI_9750_PM_CTRL , value); + value &= ~PCI_GLI_9750_PM_STATE ; +pci_write_config_dword (pdev,PCI_GLI_9750_PM_CTRL , value); +gl9750_wt_off (host); }
Greg Kroah-Hartman
maintainerPATCH 476/530 mm: fix for negative counter: nr_file_hugepages
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Roesch <[email protected]>
commit a48d5bdc877b85201e42cef9c2fdf5378164c23a upstream.
While qualifiying the 6.4 release, the following warning was detected in messages:
vmstat_refresh: nr_file_hugepages -15664
The warning is caused by the incorrect updating of the NR_FILE_THPS counter in the function split_huge_page_to_list. The if case is checking for folio_test_swapbacked, but the else case is missing the check for folio_test_pmd_mappable. The other functions that manipulate the counter like __filemap_add_folio and filemap_unaccount_folio have the corresponding check.
I have a test case, which reproduces the problem. It can be found here:
https://github.com/sroeschus/testcase/blob/main/vmstat_refresh/madv.c
The test case reproduces on an XFS filesystem. Running the same test case on a BTRFS filesystem does not reproduce the problem.
AFAIK version 6.1 until 6.6 are affected by this problem.
--- mm/huge_memory.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
mm/huge_memory.c +9 -7
@@ -2737,13 +2737,15 @@ int split_huge_page_to_list(struct pageint nr =folio_nr_pages (folio);xas_split (&xas, folio,folio_order (folio)); -if (folio_test_swapbacked (folio)) { -__lruvec_stat_mod_folio (folio,NR_SHMEM_THPS , - -nr); - }else { -__lruvec_stat_mod_folio (folio,NR_FILE_THPS , - -nr); -filemap_nr_thps_dec (mapping); +if (folio_test_pmd_mappable (folio)) { +if (folio_test_swapbacked (folio)) { +__lruvec_stat_mod_folio (folio, +NR_SHMEM_THPS , -nr); + }else { +__lruvec_stat_mod_folio (folio, +NR_FILE_THPS , -nr); +filemap_nr_thps_dec (mapping); + } } }
Greg Kroah-Hartman
maintainerPATCH 477/530 mm: kmem: drop __GFP_NOFAIL when allocating objcg vectors
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roman Gushchin <[email protected]>
commit 24948e3b7b12e0031a6edb4f49bbb9fb2ad1e4e9 upstream.
Objcg vectors attached to slab pages to store slab object ownership information are allocated using gfp flags for the original slab allocation. Depending on slab page order and the size of slab objects, objcg vector can take several pages.
If the original allocation was done with the __GFP_NOFAIL flag, it triggered a warning in the page allocation code. Indeed, order > 1 pages should not been allocated with the __GFP_NOFAIL flag.
Fix this by simply dropping the __GFP_NOFAIL flag when allocating the objcg vector. It effectively allows to skip the accounting of a single slab object under a heavy memory pressure.
An alternative would be to implement the mechanism to fallback to order-0 allocations for accounting metadata, which is also not perfect because it will increase performance penalty and memory footprint of the kernel memory accounting under memory pressure.
--- mm/memcontrol.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
mm/memcontrol.c +2 -1
@@ -2864,7 +2864,8 @@ static void commit_charge(struct folio ** Moreover, it should not come from DMA buffer and is not readily * reclaimable. So those GFP bits should be masked off. */ -#define OBJCGS_CLEAR_MASK (__GFP_DMA | __GFP_RECLAIMABLE | __GFP_ACCOUNT) +#define OBJCGS_CLEAR_MASK (__GFP_DMA | __GFP_RECLAIMABLE | \ + __GFP_ACCOUNT | __GFP_NOFAIL)/* * mod_objcg_mlstate() may be called with irq enabled, so
Greg Kroah-Hartman
maintainerPATCH 478/530 mptcp: deal with large GSO size
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit 9fce92f050f448a0d1ddd9083ef967d9930f1e52 upstream.
After the blamed commit below, the TCP sockets (and the MPTCP subflows) can build egress packets larger than 64K. That exceeds the maximum DSS data size, the length being misrepresent on the wire and the stream being corrupted, as later observed on the receiver:
WARNING: CPU: 0 PID: 9696 at net/mptcp/protocol.c:705 __mptcp_move_skbs_from_subflow+0x2604/0x26e0 CPU: 0 PID: 9696 Comm: syz-executor.7 Not tainted 6.6.0-rc5-gcd8bdf563d46 #45 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.11.0-2.el7 04/01/2014 netlink: 8 bytes leftover after parsing attributes in process `syz-executor.4'. RIP: 0010:__mptcp_move_skbs_from_subflow+0x2604/0x26e0 net/mptcp/protocol.c:705 RSP: 0018:ffffc90000006e80 EFLAGS: 00010246 RAX: ffffffff83e9f674 RBX: ffff88802f45d870 RCX: ffff888102ad0000 netlink: 8 bytes leftover after parsing attributes in process `syz-executor.4'. RDX: 0000000080000303 RSI: 0000000000013908 RDI: 0000000000003908 RBP: ffffc90000007110 R08: ffffffff83e9e078 R09: 1ffff1100e548c8a R10: dffffc0000000000 R11: ffffed100e548c8b R12: 0000000000013908 R13: dffffc0000000000 R14: 0000000000003908 R15: 000000000031cf29 FS: 00007f239c47e700(0000) GS:ffff88811b200000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f239c45cd78 CR3: 000000006a66c006 CR4: 0000000000770ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000600 PKRU: 55555554 Call Trace: <IRQ> mptcp_data_ready+0x263/0xac0 net/mptcp/protocol.c:819 subflow_data_ready+0x268/0x6d0 net/mptcp/subflow.c:1409 tcp_data_queue+0x21a1/0x7a60 net/ipv4/tcp_input.c:5151 tcp_rcv_established+0x950/0x1d90 net/ipv4/tcp_input.c:6098 tcp_v6_do_rcv+0x554/0x12f0 net/ipv6/tcp_ipv6.c:1483 tcp_v6_rcv+0x2e26/0x3810 net/ipv6/tcp_ipv6.c:1749 ip6_protocol_deliver_rcu+0xd6b/0x1ae0 net/ipv6/ip6_input.c:438 ip6_input+0x1c5/0x470 net/ipv6/ip6_input.c:483 ipv6_rcv+0xef/0x2c0 include/linux/netfilter.h:304 __netif_receive_skb+0x1ea/0x6a0 net/core/dev.c:5532 process_backlog+0x353/0x660 net/core/dev.c:5974 __napi_poll+0xc6/0x5a0 net/core/dev.c:6536 net_rx_action+0x6a0/0xfd0 net/core/dev.c:6603 __do_softirq+0x184/0x524 kernel/softirq.c:553 do_softirq+0xdd/0x130 kernel/softirq.c:454
Address the issue explicitly bounding the maximum GSO size to what MPTCP actually allows.
--- net/mptcp/protocol.c | 4 ++++ 1 file changed, 4 insertions(+)
net/mptcp/protocol.c +4 -0
@@ -1231,6 +1231,8 @@ static void mptcp_update_infinite_map(stmptcp_do_fallback (ssk); } +#define MPTCP_MAX_GSO_SIZE (GSO_LEGACY_MAX_SIZE - (MAX_TCP_HEADER + 1)) +static int mptcp_sendmsg_frag (struct sock *sk,struct sock *ssk,struct mptcp_data_frag *dfrag,struct mptcp_sendmsg_info *info)
@@ -1257,6 +1259,8 @@ static int mptcp_sendmsg_frag(struct socreturn -EAGAIN ;/* compute send limit */ +if (unlikely (ssk->sk_gso_max_size >MPTCP_MAX_GSO_SIZE )) + ssk->sk_gso_max_size =MPTCP_MAX_GSO_SIZE ; info->mss_now =tcp_send_mss (ssk, &info->size_goal, info->flags); copy = info->size_goal;
Greg Kroah-Hartman
maintainerPATCH 479/530 mptcp: add validity check for sending RM_ADDR
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geliang Tang <[email protected]>
commit 8df220b29282e8b450ea57be62e1eccd4996837c upstream.
This patch adds the validity check for sending RM_ADDRs for userspace PM in mptcp_pm_remove_addrs(), only send a RM_ADDR when the address is in the anno_list or conn_list.
--- net/mptcp/pm_netlink.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/mptcp/pm_netlink.c +3 -2
@@ -1538,8 +1538,9 @@ void mptcp_pm_remove_addrs(struct mptcp_struct mptcp_pm_addr_entry *entry;list_for_each_entry (entry, rm_list, list) { -remove_anno_list_by_saddr (msk, &entry->addr); -if (alist.nr <MPTCP_RM_IDS_MAX ) +if ((remove_anno_list_by_saddr (msk, &entry->addr) || +lookup_subflow_by_saddr (&msk->conn_list, &entry->addr)) && + alist.nr <MPTCP_RM_IDS_MAX ) alist.ids[alist.nr++] = entry->addr.id; }
Greg Kroah-Hartman
maintainerPATCH 480/530 mptcp: fix setsockopt(IP_TOS) subflow locking
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit 7679d34f97b7a09fd565f5729f79fd61b7c55329 upstream.
The MPTCP implementation of the IP_TOS socket option uses the lockless variant of the TOS manipulation helper and does not hold such lock at the helper invocation time.
Add the required locking.
--- net/mptcp/sockopt.c | 3 +++ 1 file changed, 3 insertions(+)
net/mptcp/sockopt.c +3 -0
@@ -737,8 +737,11 @@ static int mptcp_setsockopt_v4_set_tos(s val =inet_sk (sk)->tos;mptcp_for_each_subflow (msk, subflow) {struct sock *ssk =mptcp_subflow_tcp_sock (subflow); +bool slow; + slow =lock_sock_fast (ssk);__ip_sock_set_tos (ssk, val); +unlock_sock_fast (ssk, slow); }release_sock (sk);
Greg Kroah-Hartman
maintainerPATCH 481/530 selftests: mptcp: fix fastclose with csum failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
commit 7cefbe5e1dacc7236caa77e9d072423f21422fe2 upstream.
Running the mp_join selftest manually with the following command line:
./mptcp_join.sh -z -C
leads to some failures:
002 fastclose server test
# ... rtx [fail] got 1 MP_RST[s] TX expected 0 # ... rstrx [fail] got 1 MP_RST[s] RX expected 0
The problem is really in the wrong expectations for the RST checks implied by the csum validation. Note that the same check is repeated explicitly in the same test-case, with the correct expectation and pass successfully.
Address the issue explicitly setting the correct expectation for the failing checks.
--- tools/testing/selftests/net/mptcp/mptcp_join.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/net/mptcp/mptcp_join.sh +1 -1
@@ -3237,7 +3237,7 @@ fastclose_tests() if reset_check_counter "fastclose server test" "MPTcpExtMPFastcloseRx"; then test_linkfail=1024 fastclose=server \ run_tests $ns1 $ns2 10.0.1.1 - chk_join_nr 0 0 0 + chk_join_nr 0 0 0 0 0 0 1 chk_fclose_nr 1 1 invert chk_rst_nr 1 1 fi
Greg Kroah-Hartman
maintainerPATCH 482/530 r8169: fix network lost after resume on DASH systems
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChunHao Lin <[email protected]>
commit 868c3b95afef4883bfb66c9397482da6840b5baf upstream.
Device that support DASH may be reseted or powered off during suspend. So driver needs to handle DASH during system suspend and resume. Or DASH firmware will influence device behavior and causes network lost.
--- drivers/net/ethernet/realtek/r8169_main.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/ethernet/realtek/r8169_main.c +6 -0
@@ -4648,10 +4648,16 @@ static void rtl8169_down(struct rtl8169_rtl8169_cleanup (tp);rtl_disable_exit_l1 (tp);rtl_prepare_power_down (tp); + +if (tp->dash_type !=RTL_DASH_NONE ) +rtl8168_driver_stop (tp); }static void rtl8169_up (struct rtl8169_private *tp) { +if (tp->dash_type !=RTL_DASH_NONE ) +rtl8168_driver_start (tp); +pci_set_master (tp->pci_dev);phy_init_hw (tp->phydev);phy_resume (tp->phydev);
Greg Kroah-Hartman
maintainerPATCH 483/530 r8169: add handling DASH when DASH is disabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChunHao Lin <[email protected]>
commit 0ab0c45d8aaea5192328bfa6989673aceafc767c upstream.
For devices that support DASH, even DASH is disabled, there may still exist a default firmware that will influence device behavior. So driver needs to handle DASH for devices that support DASH, no matter the DASH status is.
This patch also prepares for "fix network lost after resume on DASH systems".
--- drivers/net/ethernet/realtek/r8169_main.c | 36 ++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 11 deletions(-)
drivers/net/ethernet/realtek/r8169_main.c +25 -11
@@ -624,6 +624,7 @@ struct rtl8169_private { unsigned supports_gmii:1; unsigned aspm_manageable:1; + unsigned dash_enabled:1;dma_addr_t counters_phys_addr;struct rtl8169_counters *counters;struct rtl8169_tc_offsets tc_offset;
@@ -1253,14 +1254,26 @@ static bool r8168ep_check_dash(struct rtreturn r8168ep_ocp_read (tp,0x128 ) &BIT (0 ); } -static enum rtl_dash_type rtl_check_dash (struct rtl8169_private *tp) +static bool rtl_dash_is_enabled (struct rtl8169_private *tp) +{ +switch (tp->dash_type) { +case RTL_DASH_DP : +return r8168dp_check_dash (tp); +case RTL_DASH_EP : +return r8168ep_check_dash (tp); +default : +return false; + } +} + +static enum rtl_dash_type rtl_get_dash_type (struct rtl8169_private *tp) {switch (tp->mac_version) {case RTL_GIGA_MAC_VER_28 :case RTL_GIGA_MAC_VER_31 : -return r8168dp_check_dash (tp) ?RTL_DASH_DP :RTL_DASH_NONE ; +return RTL_DASH_DP ; case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53: -return r8168ep_check_dash (tp) ?RTL_DASH_EP :RTL_DASH_NONE ; +return RTL_DASH_EP ;default :return RTL_DASH_NONE ; }
@@ -1453,7 +1466,7 @@ static void __rtl8169_set_wol(struct rtldevice_set_wakeup_enable (tp_to_dev (tp), wolopts); -if (tp->dash_type ==RTL_DASH_NONE ) { +if (!tp->dash_enabled) {rtl_set_d3_pll_down (tp, !wolopts); tp->dev->wol_enabled = wolopts ?1 :0 ; }
@@ -2512,7 +2525,7 @@ static void rtl_wol_enable_rx(struct rtlstatic void rtl_prepare_power_down (struct rtl8169_private *tp) { -if (tp->dash_type !=RTL_DASH_NONE ) +if (tp->dash_enabled)return ; if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
@@ -4875,7 +4888,7 @@ static int rtl8169_runtime_idle(struct d {struct rtl8169_private *tp =dev_get_drvdata (device); -if (tp->dash_type !=RTL_DASH_NONE ) +if (tp->dash_enabled)return -EBUSY ;if (!netif_running (tp->dev) || !netif_carrier_ok (tp->dev))
@@ -4901,8 +4914,7 @@ static void rtl_shutdown(struct pci_dev/* Restore original MAC address */ rtl_rar_set (tp, tp->dev->perm_addr); -if (system_state ==SYSTEM_POWER_OFF && - tp->dash_type ==RTL_DASH_NONE ) { +if (system_state ==SYSTEM_POWER_OFF && !tp->dash_enabled) {pci_wake_from_d3 (pdev, tp->saved_wolopts);pci_set_power_state (pdev, PCI_D3hot); }
@@ -5260,7 +5272,8 @@ static int rtl_init_one(struct pci_dev * rc =pci_disable_link_state (pdev,PCIE_LINK_STATE_L1 ); tp->aspm_manageable = !rc; - tp->dash_type =rtl_check_dash (tp); + tp->dash_type =rtl_get_dash_type (tp); + tp->dash_enabled =rtl_dash_is_enabled (tp); tp->cp_cmd =RTL_R16 (tp, CPlusCmd) &CPCMD_MASK ;
@@ -5331,7 +5344,7 @@ static int rtl_init_one(struct pci_dev */* configure chip for default features */ rtl8169_set_features (dev, dev->features); -if (tp->dash_type ==RTL_DASH_NONE ) { +if (!tp->dash_enabled) {rtl_set_d3_pll_down (tp, true); }else {rtl_set_d3_pll_down (tp, false);
@@ -5371,7 +5384,8 @@ static int rtl_init_one(struct pci_dev * "ok" : "ko"); if (tp->dash_type != RTL_DASH_NONE) { -netdev_info (dev,"DASH enabled\n" ); +netdev_info (dev,"DASH %s\n" , + tp->dash_enabled ?"enabled" :"disabled" );rtl8168_driver_start (tp); }
Greg Kroah-Hartman
maintainerPATCH 484/530 mmc: sdhci-pci-gli: GL9750: Mask the replay timer timeout of AER
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Shih <[email protected]>
commit 015c9cbcf0ad709079117d27c2094a46e0eadcdb upstream.
Due to a flaw in the hardware design, the GL9750 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 GL9750 PCI config. Therefore, the replay timer timeout must be masked.
--- drivers/mmc/host/sdhci-pci-gli.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/mmc/host/sdhci-pci-gli.c +8 -0
@@ -28,6 +28,9 @@#define PCI_GLI_9750_PM_CTRL 0xFC#define PCI_GLI_9750_PM_STATE GENMASK(1, 0) +#define PCI_GLI_9750_CORRERR_MASK 0x214 +#define PCI_GLI_9750_CORRERR_MASK_REPLAY_TIMER_TIMEOUT BIT(12) +#define SDHCI_GLI_9750_CFG2 0x848#define SDHCI_GLI_9750_CFG2_L1DLY GENMASK(28, 24)#define GLI_9750_CFG2_L1DLY_VALUE 0x1F
@@ -564,6 +567,11 @@ static void gl9750_hw_setting(struct sdh value &= ~PCI_GLI_9750_PM_STATE ;pci_write_config_dword (pdev,PCI_GLI_9750_PM_CTRL , value); +/* mask the replay timer timeout of AER */ +pci_read_config_dword (pdev,PCI_GLI_9750_CORRERR_MASK , &value); + value |=PCI_GLI_9750_CORRERR_MASK_REPLAY_TIMER_TIMEOUT ; +pci_write_config_dword (pdev,PCI_GLI_9750_CORRERR_MASK , value); +gl9750_wt_off (host); }
Greg Kroah-Hartman
maintainerPATCH 485/530 media: qcom: camss: Fix pm_domain_on sequence in probe
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan O'Donoghue <[email protected]>
commit 7405116519ad70b8c7340359bfac8db8279e7ce4 upstream.
We need to make sure camss_configure_pd() happens before camss_register_entities() as the vfe_get() path relies on the pointer provided by camss_configure_pd().
Fix the ordering sequence in probe to ensure the pointers vfe_get() demands are present by the time camss_register_entities() runs.
In order to facilitate backporting to stable kernels I've moved the configure_pd() call pretty early on the probe() function so that irrespective of the existence of the old error handling jump labels this patch should still apply to -next circa Aug 2023 to v5.13 inclusive.
--- drivers/media/platform/qcom/camss/camss.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/media/platform/qcom/camss/camss.c +6 -6
@@ -1619,6 +1619,12 @@ static int camss_probe(struct platform_dif (ret <0 ) goto err_cleanup; + ret =camss_configure_pd (camss); +if (ret <0 ) { +dev_err (dev,"Failed to configure power domains: %d\n" , ret); + goto err_cleanup; + } + ret =camss_init_subdevices (camss);if (ret <0 ) goto err_cleanup;
@@ -1678,12 +1684,6 @@ static int camss_probe(struct platform_d } } - ret =camss_configure_pd (camss); -if (ret <0 ) { -dev_err (dev,"Failed to configure power domains: %d\n" , ret); -return ret; - } -pm_runtime_enable (dev);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 486/530 media: qcom: camss: Fix vfe_get() error jump
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan O'Donoghue <[email protected]>
commit 26bda3da00c3edef727a6acb00ed2eb4b22f8723 upstream.
Right now it is possible to do a vfe_get() with the internal reference count at 1. If vfe_check_clock_rates() returns non-zero then we will leave the reference count as-is and
run:
- pm_runtime_put_sync()
- vfe->ops->pm_domain_off()
skip:
- camss_disable_clocks()
Subsequent vfe_put() calls will when the ref-count is non-zero unconditionally run:
- pm_runtime_put_sync()
- vfe->ops->pm_domain_off()
- camss_disable_clocks()
vfe_get() should not attempt to roll-back on error when the ref-count is non-zero as the upper layers will still do their own vfe_put() operations.
vfe_put() will drop the reference count and do the necessary power domain release, the cleanup jumps in vfe_get() should only be run when the ref-count is zero.
[ 50.095796] CPU: 7 PID: 3075 Comm: cam Not tainted 6.3.2+ #80 [ 50.095798] Hardware name: LENOVO 21BXCTO1WW/21BXCTO1WW, BIOS N3HET82W (1.54 ) 05/26/2023 [ 50.095799] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 50.095802] pc : refcount_warn_saturate+0xf4/0x148 [ 50.095804] lr : refcount_warn_saturate+0xf4/0x148 [ 50.095805] sp : ffff80000c7cb8b0 [ 50.095806] x29: ffff80000c7cb8b0 x28: ffff16ecc0e3fc10 x27: 0000000000000000 [ 50.095810] x26: 0000000000000000 x25: 0000000000020802 x24: 0000000000000000 [ 50.095813] x23: ffff16ecc7360640 x22: 00000000ffffffff x21: 0000000000000005 [ 50.095815] x20: ffff16ed175f4400 x19: ffffb4d9852942a8 x18: ffffffffffffffff [ 50.095818] x17: ffffb4d9852d4a48 x16: ffffb4d983da5db8 x15: ffff80000c7cb320 [ 50.095821] x14: 0000000000000001 x13: 2e656572662d7265 x12: 7466612d65737520 [ 50.095823] x11: 00000000ffffefff x10: ffffb4d9850cebf0 x9 : ffffb4d9835cf954 [ 50.095826] x8 : 0000000000017fe8 x7 : c0000000ffffefff x6 : 0000000000057fa8 [ 50.095829] x5 : ffff16f813fe3d08 x4 : 0000000000000000 x3 : ffff621e8f4d2000 [ 50.095832] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff16ed32119040 [ 50.095835] Call trace: [ 50.095836] refcount_warn_saturate+0xf4/0x148 [ 50.095838] device_link_put_kref+0x84/0xc8 [ 50.095843] device_link_del+0x38/0x58 [ 50.095846] vfe_pm_domain_off+0x3c/0x50 [qcom_camss] [ 50.095860] vfe_put+0x114/0x140 [qcom_camss] [ 50.095869] csid_set_power+0x2c8/0x408 [qcom_camss] [ 50.095878] pipeline_pm_power_one+0x164/0x170 [videodev] [ 50.095896] pipeline_pm_power+0xc4/0x110 [videodev] [ 50.095909] v4l2_pipeline_pm_use+0x5c/0xa0 [videodev] [ 50.095923] v4l2_pipeline_pm_get+0x1c/0x30 [videodev] [ 50.095937] video_open+0x7c/0x100 [qcom_camss] [ 50.095945] v4l2_open+0x84/0x130 [videodev] [ 50.095960] chrdev_open+0xc8/0x250 [ 50.095964] do_dentry_open+0x1bc/0x498 [ 50.095966] vfs_open+0x34/0x40 [ 50.095968] path_openat+0xb44/0xf20 [ 50.095971] do_filp_open+0xa4/0x160 [ 50.095974] do_sys_openat2+0xc8/0x188 [ 50.095975] __arm64_sys_openat+0x6c/0xb8 [ 50.095977] invoke_syscall+0x50/0x128 [ 50.095982] el0_svc_common.constprop.0+0x4c/0x100 [ 50.095985] do_el0_svc+0x40/0xa8 [ 50.095988] el0_svc+0x2c/0x88 [ 50.095991] el0t_64_sync_handler+0xf4/0x120 [ 50.095994] el0t_64_sync+0x190/0x198 [ 50.095996] ---[ end trace 0000000000000000 ]---
--- drivers/media/platform/qcom/camss/camss-vfe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/qcom/camss/camss-vfe.c +1 -1
@@ -611,7 +611,7 @@ int vfe_get(struct vfe_device *vfe) }else { ret =vfe_check_clock_rates (vfe);if (ret <0 ) - goto error_pm_runtime_get; + goto error_pm_domain; } vfe->power_count++;
Greg Kroah-Hartman
maintainerPATCH 487/530 media: qcom: camss: Fix VFE-17x vfe_disable_output()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan O'Donoghue <[email protected]>
commit 3143ad282fc08bf995ee73e32a9e40c527bf265d upstream.
There are two problems with the current vfe_disable_output() routine.
Firstly we rightly use a spinlock to protect output->gen2.active_num everywhere except for in the IDLE timeout path of vfe_disable_output(). Even if that is not racy "in practice" somehow it is by happenstance not by design.
Secondly we do not get consistent behaviour from this routine. On sc8280xp 50% of the time I get "VFE idle timeout - resetting". In this case the subsequent capture will succeed. The other 50% of the time, we don't hit the idle timeout, never do the VFE reset and subsequent captures stall indefinitely.
Rewrite the vfe_disable_output() routine to
- Quiesce write masters with vfe_wm_stop()
- Set active_num = 0
remembering to hold the spinlock when we do so followed by
- Reset the VFE
Testing on sc8280xp and sdm845 shows this to be a valid fix.
--- drivers/media/platform/qcom/camss/camss-vfe-170.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-)
drivers/media/platform/qcom/camss/camss-vfe-170.c +3 -19
@@ -7,7 +7,6 @@* Copyright (C) 2020-2021 Linaro Ltd. */ -#include <linux/delay.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/iopoll.h>
@@ -494,35 +493,20 @@ static int vfe_enable_output(struct vfe_return 0 ; } -static int vfe_disable_output (struct vfe_line *line) +static void vfe_disable_output (struct vfe_line *line) {struct vfe_device *vfe =to_vfe (line);struct vfe_output *output = &line->output;unsigned long flags;unsigned int i; -bool done; -int timeout =0 ; - -do { -spin_lock_irqsave (&vfe->output_lock, flags); - done = !output->gen2.active_num; -spin_unlock_irqrestore (&vfe->output_lock, flags); -usleep_range (10000 ,20000 ); - -if (timeout++ ==100 ) { -dev_err (vfe->camss->dev,"VFE idle timeout - resetting\n" ); -vfe_reset (vfe); - output->gen2.active_num =0 ; -return 0 ; - } - }while (!done);spin_lock_irqsave (&vfe->output_lock, flags);for (i =0 ; i < output->wm_num; i++)vfe_wm_stop (vfe, output->wm_idx[i]); + output->gen2.active_num =0 ;spin_unlock_irqrestore (&vfe->output_lock, flags); -return 0 ; +vfe_reset (vfe); }/*
Greg Kroah-Hartman
maintainerPATCH 488/530 media: qcom: camss: Fix VFE-480 vfe_disable_output()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan O'Donoghue <[email protected]>
commit 7f24d291350426d40b36dfbe6b3090617cdfd37a upstream.
vfe-480 is copied from vfe-17x and has the same racy idle timeout bug as in 17x.
Fix the vfe_disable_output() logic to no longer be racy and to conform to the 17x way of quiescing and then resetting the VFE.
--- drivers/media/platform/qcom/camss/camss-vfe-480.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-)
drivers/media/platform/qcom/camss/camss-vfe-480.c +3 -19
@@ -8,7 +8,6 @@* Copyright (C) 2021 Jonathan Marek */ -#include <linux/delay.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/iopoll.h>
@@ -328,35 +327,20 @@ static int vfe_enable_output(struct vfe_return 0 ; } -static int vfe_disable_output (struct vfe_line *line) +static void vfe_disable_output (struct vfe_line *line) {struct vfe_device *vfe =to_vfe (line);struct vfe_output *output = &line->output;unsigned long flags;unsigned int i; -bool done; -int timeout =0 ; - -do { -spin_lock_irqsave (&vfe->output_lock, flags); - done = !output->gen2.active_num; -spin_unlock_irqrestore (&vfe->output_lock, flags); -usleep_range (10000 ,20000 ); - -if (timeout++ ==100 ) { -dev_err (vfe->camss->dev,"VFE idle timeout - resetting\n" ); -vfe_reset (vfe); - output->gen2.active_num =0 ; -return 0 ; - } - }while (!done);spin_lock_irqsave (&vfe->output_lock, flags);for (i =0 ; i < output->wm_num; i++)vfe_wm_stop (vfe, output->wm_idx[i]); + output->gen2.active_num =0 ;spin_unlock_irqrestore (&vfe->output_lock, flags); -return 0 ; +vfe_reset (vfe); }/*
Greg Kroah-Hartman
maintainerPATCH 489/530 media: qcom: camss: Fix missing vfe_lite clocks check
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan O'Donoghue <[email protected]>
commit b6e1bdca463a932c1ac02caa7d3e14bf39288e0c upstream.
check_clock doesn't account for vfe_lite which means that vfe_lite will never get validated by this routine. Add the clock name to the expected set to remediate.
--- drivers/media/platform/qcom/camss/camss-vfe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/media/platform/qcom/camss/camss-vfe.c +2 -1
@@ -535,7 +535,8 @@ static int vfe_check_clock_rates(structstruct camss_clock *clock = &vfe->clock[i];if (!strcmp (clock->name,"vfe0" ) || - !strcmp (clock->name,"vfe1" )) { + !strcmp (clock->name,"vfe1" ) || + !strcmp (clock->name,"vfe_lite" )) {u64 min_rate =0 ;unsigned long rate;
Greg Kroah-Hartman
maintainerPATCH 490/530 media: qcom: camss: Fix set CSI2_RX_CFG1_VC_MODE when VC is greater than 3
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan O'Donoghue <[email protected]>
commit e655d1ae9703286cef7fda8675cad62f649dc183 upstream.
VC_MODE = 0 implies a two bit VC address.VC_MODE = 1 is required for VCs with a larger address than two bits.
--- drivers/media/platform/qcom/camss/camss-csid-gen2.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/media/platform/qcom/camss/camss-csid-gen2.c +2 -0
@@ -449,6 +449,8 @@ static void __csid_configure_stream(struwritel_relaxed (val, csid->base +CSID_CSI2_RX_CFG0 ); val =1 <<CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN ; +if (vc >3 ) + val |=1 <<CSI2_RX_CFG1_VC_MODE ; val |=1 <<CSI2_RX_CFG1_MISR_EN ;writel_relaxed (val, csid->base +CSID_CSI2_RX_CFG1 );
Greg Kroah-Hartman
maintainerPATCH 491/530 media: qcom: camss: Fix invalid clock enable bit disjunction
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan O'Donoghue <[email protected]>
commit d8f7e1a60d01739a1d78db2b08603089c6cf7c8e upstream.
define CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE BIT(7)
disjunction for gen2 ? BIT(7) : is a nop we are setting the same bit either way.
--- drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +1 -1
@@ -476,7 +476,7 @@ static void csiphy_lanes_enable(struct c settle_cnt =csiphy_settle_cnt_calc (link_freq, csiphy->timer_clk_rate); - val = is_gen2 ?BIT (7 ) :CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE ; + val =CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE ;for (i =0 ; i < c->num_data; i++) val |=BIT (c->data[i].pos *2 );
Greg Kroah-Hartman
maintainerPATCH 492/530 media: qcom: camss: Fix csid-gen2 for test pattern generator
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrey Konovalov <[email protected]>
commit 87889f1b7ea40d2544b49c62092e6ef2792dced7 upstream.
In the current driver csid Test Pattern Generator (TPG) doesn't work. This change:
- fixes writing frame width and height values into CSID_TPG_DT_n_CFG_0
- fixes the shift by one between test_pattern control value and the actual pattern.
- drops fixed VC of 0x0a which testing showed prohibited some test patterns in the CSID to produce output.
So that TPG starts working, but with the below limitations:
- only test_pattern=9 works as it should
- test_pattern=8 and test_pattern=7 produce black frame (all zeroes)
- the rest of test_pattern's don't work (yavta doesn't get the data)
- regardless of the CFA pattern set by 'media-ctl -V' the actual pixel order is always the same (RGGB for any RAW8 or RAW10P format in 4608x2592 resolution).
Tested with:
RAW10P format, VC0:
media-ctl -V '"msm_csid0":0[fmt:SRGGB10/4608x2592 field:none]' media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB10/4608x2592 field:none]' media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'
v4l2-ctl -d /dev/v4l-subdev6 -c test_pattern=9
yavta -B capture-mplane --capture=3 -n 3 -f SRGGB10P -s 4608x2592 /dev/video0
RAW10P format, VC1:
media-ctl -V '"msm_csid0":2[fmt:SRGGB10/4608x2592 field:none]' media-ctl -V '"msm_vfe0_rdi1":0[fmt:SRGGB10/4608x2592 field:none]' media-ctl -l '"msm_csid0":2->"msm_vfe0_rdi1":0[1]'
v4l2-ctl -d /dev/v4l-subdev6 -c test_pattern=9
yavta -B capture-mplane --capture=3 -n 3 -f SRGGB10P -s 4608x2592 /dev/video1
RAW8 format, VC0:
media-ctl --reset
media-ctl -V '"msm_csid0":0[fmt:SRGGB8/4608x2592 field:none]' media-ctl -V '"msm_vfe0_rdi0":0[fmt:SRGGB8/4608x2592 field:none]' media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'
yavta -B capture-mplane --capture=3 -n 3 -f SRGGB8 -s 4608x2592 /dev/video0
--- drivers/media/platform/qcom/camss/camss-csid-gen2.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/media/platform/qcom/camss/camss-csid-gen2.c +3 -6
@@ -355,9 +355,6 @@ static void __csid_configure_stream(struu8 dt_id = vc;if (tg->enabled) { -/* Config Test Generator */ - vc =0xa ; -/* configure one DT, infinite frames */ val = vc <<TPG_VC_CFG0_VC_NUM ; val |=INTELEAVING_MODE_ONE_SHOT <<TPG_VC_CFG0_LINE_INTERLEAVING_MODE ;
@@ -370,14 +367,14 @@ static void __csid_configure_stream(struwritel_relaxed (0x12345678 , csid->base +CSID_TPG_LFSR_SEED ); - val = input_format->height &0x1fff << TPG_DT_n_CFG_0_FRAME_HEIGHT; - val |= input_format->width &0x1fff << TPG_DT_n_CFG_0_FRAME_WIDTH; + val = (input_format->height &0x1fff ) << TPG_DT_n_CFG_0_FRAME_HEIGHT; + val |= (input_format->width &0x1fff ) << TPG_DT_n_CFG_0_FRAME_WIDTH;writel_relaxed (val, csid->base +CSID_TPG_DT_n_CFG_0 (0 )); val = format->data_type << TPG_DT_n_CFG_1_DATA_TYPE;writel_relaxed (val, csid->base +CSID_TPG_DT_n_CFG_1 (0 )); - val = tg->mode << TPG_DT_n_CFG_2_PAYLOAD_MODE; + val = (tg->mode -1 ) << TPG_DT_n_CFG_2_PAYLOAD_MODE; val |=0xBE << TPG_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD; val |= format->decode_format << TPG_DT_n_CFG_2_ENCODE_FORMAT;writel_relaxed (val, csid->base +CSID_TPG_DT_n_CFG_2 (0 ));
Greg Kroah-Hartman
maintainerPATCH 493/530 Revert "HID: logitech-dj: Add support for a new lightspeed receiver iteration"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Kosina <[email protected]>
commit 5b4ffb176d7979ac66b349addf3f7de433335e00 upstream.
This reverts commit 9d1bd9346241cd6963b58da7ffb7ed303285f684.
Multiple people reported misbehaving devices and reverting this commit fixes the problem for them. As soon as the original commit author starts reacting again, we can try to figure out why he hasn't seen the issues (mismatching report descriptors?), but for the time being, fix for 6.7 by reverting.
--- drivers/hid/hid-ids.h | 1 - drivers/hid/hid-logitech-dj.c | 11 +++-------- 2 files changed, 3 insertions(+), 9 deletions(-)
drivers/hid/hid-ids.h +0 -1
@@ -869,7 +869,6 @@#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f -#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2 0xc547#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a#define USB_DEVICE_ID_SPACETRAVELLER 0xc623#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626
drivers/hid/hid-logitech-dj.c +3 -8
@@ -1695,12 +1695,11 @@ static int logi_dj_raw_event(struct hid_ }/* * Mouse-only receivers send unnumbered mouse data. The 27 MHz -* receiver uses 6 byte packets, the nano receiver 8 bytes, -* the lightspeed receiver (Pro X Superlight) 13 bytes. +* receiver uses 6 byte packets, the nano receiver 8 bytes. */ if (djrcv_dev->unnumbered_application ==HID_GD_MOUSE && - size <=13 ){ -u8 mouse_report[14 ]; + size <=8 ) { +u8 mouse_report[9 ];/* Prepend report id */ mouse_report[0 ] =REPORT_TYPE_MOUSE ;
@@ -1984,10 +1983,6 @@ static const struct hid_device_id logi_dHID_USB_DEVICE (USB_VENDOR_ID_LOGITECH , USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1), .driver_data = recvr_type_gaming_hidpp}, - {/* Logitech lightspeed receiver (0xc547) */ -HID_USB_DEVICE (USB_VENDOR_ID_LOGITECH , - USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2), - .driver_data = recvr_type_gaming_hidpp}, { /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
Greg Kroah-Hartman
maintainerPATCH 494/530 Revert "net: r8169: Disable multicast filter for RTL8168H and RTL8107E"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiner Kallweit <[email protected]>
commit 6a26310273c323380da21eb23fcfd50e31140913 upstream.
This reverts commit efa5f1311c4998e9e6317c52bc5ee93b3a0f36df.
I couldn't reproduce the reported issue. What I did, based on a pcap packet log provided by the reporter:
- Used same chip version (RTL8168h)
- Set MAC address to the one used on the reporters system
- Replayed the EAPOL unicast packet that, according to the reporter, was filtered out by the mc filter.
The packet was properly received.
Therefore the root cause of the reported issue seems to be somewhere else. Disabling mc filtering completely for the most common chip version is a quite big hammer. Therefore revert the change and wait for further analysis results from the reporter.
--- drivers/net/ethernet/realtek/r8169_main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/ethernet/realtek/r8169_main.c +1 -3
@@ -2599,9 +2599,7 @@ static void rtl_set_rx_mode(struct net_d rx_mode &= ~AcceptMulticast; }else if (netdev_mc_count (dev) >MC_FILTER_LIMIT || dev->flags &IFF_ALLMULTI || - tp->mac_version ==RTL_GIGA_MAC_VER_35 || - tp->mac_version ==RTL_GIGA_MAC_VER_46 || - tp->mac_version ==RTL_GIGA_MAC_VER_48 ) { + tp->mac_version ==RTL_GIGA_MAC_VER_35 ) {/* accept all multicasts */ }else if (netdev_mc_empty (dev)) { rx_mode &= ~AcceptMulticast;
Greg Kroah-Hartman
maintainerPATCH 495/530 ext4: fix race between writepages and remount
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 745f17a4166e79315e4b7f33ce89d03e75a76983 upstream.
We got a WARNING in ext4_add_complete_io:
==================================================================
WARNING: at fs/ext4/page-io.c:231 ext4_put_io_end_defer+0x182/0x250 CPU: 10 PID: 77 Comm: ksoftirqd/10 Tainted: 6.3.0-rc2 #85 RIP: 0010:ext4_put_io_end_defer+0x182/0x250 [ext4] [...] Call Trace: <TASK> ext4_end_bio+0xa8/0x240 [ext4] bio_endio+0x195/0x310 blk_update_request+0x184/0x770 scsi_end_request+0x2f/0x240 scsi_io_completion+0x75/0x450 scsi_finish_command+0xef/0x160 scsi_complete+0xa3/0x180 blk_complete_reqs+0x60/0x80 blk_done_softirq+0x25/0x40 __do_softirq+0x119/0x4c8 run_ksoftirqd+0x42/0x70 smpboot_thread_fn+0x136/0x3c0 kthread+0x140/0x1a0 ret_from_fork+0x2c/0x50 ==================================================================
Above issue may happen as follows:
cpu1 cpu2
----------------------------|---------------------------- mount -o dioread_lockext4_writepages
ext4_do_writepages
*if (ext4_should_dioread_nolock(inode))*
// rsv_blocks is not assigned here
mount -o remount,dioread_nolock
ext4_journal_start_with_reserve
__ext4_journal_start
__ext4_journal_start_sb
jbd2__journal_start
*if (rsv_blocks)*
// h_rsv_handle is not initialized here
mpage_map_and_submit_extent
mpage_map_one_extent
dioread_nolock = ext4_should_dioread_nolock(inode)
if (dioread_nolock && (map->m_flags & EXT4_MAP_UNWRITTEN))
mpd->io_submit.io_end->handle = handle->h_rsv_handle
ext4_set_io_unwritten_flag
io_end->flag |= EXT4_IO_END_UNWRITTEN
// now io_end->handle is NULL but has EXT4_IO_END_UNWRITTEN flagscsi_finish_command
scsi_io_completion
scsi_io_completion_action
scsi_end_request
blk_update_request
req_bio_endio
bio_endio
bio->bi_end_io > ext4_end_bio
ext4_put_io_end_defer
ext4_add_complete_io
// trigger WARN_ON(!io_end->handle && sbi->s_journal);The immediate cause of this problem is that ext4_should_dioread_nolock() function returns inconsistent values in the ext4_do_writepages() and mpage_map_one_extent(). There are four conditions in this function that can be changed at mount time to cause this problem. These four conditions can be divided into two categories:
(1) journal_data and EXT4_EXTENTS_FL, which can be changed by ioctl
(2) DELALLOC and DIOREAD_NOLOCK, which can be changed by remount
The two in the first category have been fixed by commit c8585c6fcaf2 ("ext4: fix races between changing inode journal mode and ext4_writepages") and commit cb85f4d23f79 ("ext4: fix race between writepages and enabling EXT4_EXTENTS_FL") respectively.
Two cases in the other category have not yet been fixed, and the above issue is caused by this situation. We refer to the fix for the first category, when applying options during remount, we grab s_writepages_rwsem to avoid racing with writepages ops to trigger this problem.
--- fs/ext4/ext4.h | 3 ++- fs/ext4/super.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-)
fs/ext4/ext4.h +2 -1
@@ -1676,7 +1676,8 @@ struct ext4_sb_info {/* * Barrier between writepages ops and changing any inode's JOURNAL_DATA -* or EXTENTS flag. +* or EXTENTS flag or between writepages ops and changing DELALLOC or +* DIOREAD_NOLOCK mount options on remount. */ struct percpu_rw_semaphore s_writepages_rwsem;struct dax_device *s_daxdev;
fs/ext4/super.c +14 -0
@@ -6443,6 +6443,7 @@ static int __ext4_remount(struct fs_contstruct ext4_mount_options old_opts;ext4_group_t g;int err =0 ; +int alloc_ctx;#ifdef CONFIG_QUOTA int enable_quota =0 ;int i, j;
@@ -6483,7 +6484,16 @@ static int __ext4_remount(struct fs_cont } +/* +* Changing the DIOREAD_NOLOCK or DELALLOC mount options may cause +* two calls to ext4_should_dioread_nolock() to return inconsistent +* values, triggering WARN_ON in ext4_add_complete_io(). we grab +* here s_writepages_rwsem to avoid race between writepages ops and +* remount. +*/ + alloc_ctx =ext4_writepages_down_write (sb);ext4_apply_options (fc, sb); +ext4_writepages_up_write (sb, alloc_ctx);if ((old_opts.s_mount_opt &EXT4_MOUNT_JOURNAL_CHECKSUM ) ^test_opt (sb,JOURNAL_CHECKSUM )) {
@@ -6701,6 +6711,8 @@ restore_opts:if (sb_rdonly (sb) && !(old_sb_flags &SB_RDONLY ) &&sb_any_quota_suspended (sb))dquot_resume (sb,-1 ); + + alloc_ctx =ext4_writepages_down_write (sb); sb->s_flags = old_sb_flags; sbi->s_mount_opt = old_opts.s_mount_opt; sbi->s_mount_opt2 = old_opts.s_mount_opt2;
@@ -6709,6 +6721,8 @@ restore_opts: sbi->s_commit_interval = old_opts.s_commit_interval; sbi->s_min_batch_time = old_opts.s_min_batch_time; sbi->s_max_batch_time = old_opts.s_max_batch_time; +ext4_writepages_up_write (sb, alloc_ctx); +if (!test_opt (sb,BLOCK_VALIDITY ) && sbi->s_system_blks)ext4_release_system_zone (sb);#ifdef CONFIG_QUOTA
Greg Kroah-Hartman
maintainerPATCH 496/530 ext4: no need to generate from free list in mballoc
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Jianjian <[email protected]>
commit ebf6cb7c6e1241984f75f29f1bdbfa2fe7168f88 upstream.
Commit 7a2fcbf7f85 ("ext4: don't use blocks freed but not yet committed in buddy cache init") added a code to mark as used blocks in the list of not yet committed freed blocks during initialization of a buddy page. However ext4_mb_free_metadata() makes sure buddy page is already loaded and takes a reference to it so it cannot happen that ext4_mb_init_cache() is called when efd list is non-empty. Just remove the ext4_mb_generate_from_freelist() call.
--- fs/ext4/mballoc.c | 39 ++++++--------------------------------- 1 file changed, 6 insertions(+), 33 deletions(-)
fs/ext4/mballoc.c +6 -33
@@ -417,8 +417,6 @@ static const char * const ext4_groupinfostatic void ext4_mb_generate_from_pa (struct super_block *sb,void *bitmap,ext4_group_t group); -static void ext4_mb_generate_from_freelist (struct super_block *sb,void *bitmap, -ext4_group_t group);static void ext4_mb_new_preallocation (struct ext4_allocation_context *ac); static bool ext4_mb_good_group(struct ext4_allocation_context *ac,
@@ -1361,17 +1359,17 @@ static int ext4_mb_init_cache(struct pag* We place the buddy block and bitmap block * close together */ + grinfo =ext4_get_group_info (sb, group); +if (!grinfo) { + err = -EFSCORRUPTED ; + goto out; + }if ((first_block + i) &1 ) {/* this is block of buddy */ BUG_ON (incore ==NULL );mb_debug (sb,"put buddy for group %u in page %lu/%x\n" , group, page->index, i * blocksize);trace_ext4_mb_buddy_bitmap_load (sb, group); - grinfo =ext4_get_group_info (sb, group); -if (!grinfo) { - err = -EFSCORRUPTED ; - goto out; - } grinfo->bb_fragments =0 ; memset(grinfo->bb_counters, 0, sizeof(*grinfo->bb_counters) *
@@ -1398,7 +1396,7 @@ static int ext4_mb_init_cache(struct pag/* mark all preallocated blks used in in-core bitmap */ ext4_mb_generate_from_pa (sb, data, group); -ext4_mb_generate_from_freelist (sb, data, group); +WARN_ON_ONCE (!RB_EMPTY_ROOT (&grinfo->bb_free_root));ext4_unlock_group (sb, group);/* set incore so that the buddy information can be
@@ -4959,31 +4957,6 @@ try_group_pa: }/* -* the function goes through all block freed in the group -* but not yet committed and marks them used in in-core bitmap. -* buddy must be generated from this bitmap -* Need to be called with the ext4 group lock held -*/ -static void ext4_mb_generate_from_freelist (struct super_block *sb,void *bitmap, -ext4_group_t group) -{ -struct rb_node *n; -struct ext4_group_info *grp; -struct ext4_free_data *entry; - - grp =ext4_get_group_info (sb, group); -if (!grp) -return ; - n =rb_first (&(grp->bb_free_root)); - -while (n) { - entry = rb_entry(n, struct ext4_free_data, efd_node); -mb_set_bits (bitmap, entry->efd_start_cluster, entry->efd_count); - n =rb_next (n); - } -} - -/* * the function goes through all preallocation in this group and marks them * used in in-core bitmap. buddy must be generated from this bitmap * Need to be called with ext4 group lock held
Greg Kroah-Hartman
maintainerPATCH 497/530 ext4: make sure allocate pending entry not fail
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Yi <[email protected]>
commit 8e387c89e96b9543a339f84043cf9df15fed2632 upstream.
__insert_pending() allocate memory in atomic context, so the allocation could fail, but we are not handling that failure now. It could lead ext4_es_remove_extent() to get wrong reserved clusters, and the global data blocks reservation count will be incorrect. The same to extents_status entry preallocation, preallocate pending entry out of the i_es_lock with __GFP_NOFAIL, make sure __insert_pending() and __revise_pending() always succeeds.
--- fs/ext4/extents_status.c | 123 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 89 insertions(+), 34 deletions(-)
fs/ext4/extents_status.c +89 -34
@@ -152,8 +152,9 @@ static int __es_remove_extent(struct inostatic int es_reclaim_extents (struct ext4_inode_info *ei,int *nr_to_scan);static int __es_shrink (struct ext4_sb_info *sbi,int nr_to_scan,struct ext4_inode_info *locked_ei); -static void __revise_pending (struct inode *inode,ext4_lblk_t lblk, -ext4_lblk_t len); +static int __revise_pending (struct inode *inode,ext4_lblk_t lblk, +ext4_lblk_t len, +struct pending_reservation **prealloc);int __init ext4_init_es (void ) {
@@ -448,6 +449,19 @@ static void ext4_es_list_del(struct inodspin_unlock (&sbi->s_es_lock); } +static inline struct pending_reservation *__alloc_pending (bool nofail) +{ +if (!nofail) +return kmem_cache_alloc (ext4_pending_cachep,GFP_ATOMIC ); + +return kmem_cache_zalloc (ext4_pending_cachep,GFP_KERNEL | __GFP_NOFAIL); +} + +static inline void __free_pending (struct pending_reservation *pr) +{ +kmem_cache_free (ext4_pending_cachep, pr); +} +/* * Returns true if we cannot fail to allocate memory for this extent_status * entry and cannot reclaim it until its status changes.
@@ -836,11 +850,12 @@ void ext4_es_insert_extent(struct inode {struct extent_status newes;ext4_lblk_t end = lblk + len -1 ; -int err1 =0 ; -int err2 =0 ; +int err1 =0 , err2 =0 , err3 =0 ;struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb);struct extent_status *es1 =NULL ;struct extent_status *es2 =NULL ; +struct pending_reservation *pr =NULL ; +bool revise_pending = false;if (EXT4_SB (inode->i_sb)->s_mount_state &EXT4_FC_REPLAY )return ;
@@ -868,11 +883,17 @@ void ext4_es_insert_extent(struct inodeext4_es_insert_extent_check (inode, &newes); + revise_pending = sbi->s_cluster_ratio >1 && +test_opt (inode->i_sb,DELALLOC ) && + (status & (EXTENT_STATUS_WRITTEN | +EXTENT_STATUS_UNWRITTEN )); retry:if (err1 && !es1) es1 =__es_alloc_extent (true);if ((err1 || err2) && !es2) es2 =__es_alloc_extent (true); +if ((err1 || err2 || err3) && revise_pending && !pr) + pr =__alloc_pending (true);write_lock (&EXT4_I (inode)->i_es_lock); err1 =__es_remove_extent (inode, lblk, end,NULL , es1);
@@ -897,13 +918,18 @@ retry: es2 =NULL ; } -if (sbi->s_cluster_ratio >1 &&test_opt (inode->i_sb,DELALLOC ) && - (status &EXTENT_STATUS_WRITTEN || - status &EXTENT_STATUS_UNWRITTEN )) -__revise_pending (inode, lblk, len); +if (revise_pending) { + err3 =__revise_pending (inode, lblk, len, &pr); +if (err3 !=0 ) + goto error; +if (pr) { +__free_pending (pr); + pr =NULL ; + } + } error:write_unlock (&EXT4_I (inode)->i_es_lock); -if (err1 || err2) +if (err1 || err2 || err3) goto retry;ext4_es_print_tree (inode);
@@ -1311,7 +1337,7 @@ static unsigned int get_rsvd(struct inod rc->ndelonly--; node =rb_next (&pr->rb_node);rb_erase (&pr->rb_node, &tree->root); -kmem_cache_free (ext4_pending_cachep, pr); +__free_pending (pr);if (!node)break ; pr = rb_entry(node, struct pending_reservation,
@@ -1907,11 +1933,13 @@ static struct pending_reservation *__get* * @inode - file containing the cluster * @lblk - logical block in the cluster to be added +* @prealloc - preallocated pending entry * * Returns 0 on successful insertion and -ENOMEM on failure. If the * pending reservation is already in the set, returns successfully. */ -static int __insert_pending (struct inode *inode,ext4_lblk_t lblk) +static int __insert_pending (struct inode *inode,ext4_lblk_t lblk, +struct pending_reservation **prealloc) {struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb);struct ext4_pending_tree *tree = &EXT4_I (inode)->i_pending_tree;
@@ -1937,10 +1965,15 @@ static int __insert_pending(struct inode } } - pr =kmem_cache_alloc (ext4_pending_cachep,GFP_ATOMIC ); -if (pr ==NULL ) { - ret = -ENOMEM ; - goto out; +if (likely (*prealloc ==NULL )) { + pr =__alloc_pending (false); +if (!pr) { + ret = -ENOMEM ; + goto out; + } + }else { + pr = *prealloc; + *prealloc =NULL ; } pr->lclu = lclu;
@@ -1970,7 +2003,7 @@ static void __remove_pending(struct inodif (pr !=NULL ) { tree = &EXT4_I (inode)->i_pending_tree;rb_erase (&pr->rb_node, &tree->root); -kmem_cache_free (ext4_pending_cachep, pr); +__free_pending (pr); } }
@@ -2029,10 +2062,10 @@ void ext4_es_insert_delayed_block(struct bool allocated) {struct extent_status newes; -int err1 =0 ; -int err2 =0 ; +int err1 =0 , err2 =0 , err3 =0 ;struct extent_status *es1 =NULL ;struct extent_status *es2 =NULL ; +struct pending_reservation *pr =NULL ;if (EXT4_SB (inode->i_sb)->s_mount_state &EXT4_FC_REPLAY )return ;
@@ -2052,6 +2085,8 @@ retry: es1 =__es_alloc_extent (true);if ((err1 || err2) && !es2) es2 =__es_alloc_extent (true); +if ((err1 || err2 || err3) && allocated && !pr) + pr =__alloc_pending (true);write_lock (&EXT4_I (inode)->i_es_lock); err1 =__es_remove_extent (inode, lblk, lblk,NULL , es1);
@@ -2074,11 +2109,18 @@ retry: es2 =NULL ; } -if (allocated) -__insert_pending (inode, lblk); +if (allocated) { + err3 =__insert_pending (inode, lblk, &pr); +if (err3 !=0 ) + goto error; +if (pr) { +__free_pending (pr); + pr =NULL ; + } + } error:write_unlock (&EXT4_I (inode)->i_es_lock); -if (err1 || err2) +if (err1 || err2 || err3) goto retry;ext4_es_print_tree (inode);
@@ -2184,21 +2226,24 @@ unsigned int ext4_es_delayed_clu(struct* @inode - file containing the range * @lblk - logical block defining the start of range * @len - length of range in blocks +* @prealloc - preallocated pending entry * * Used after a newly allocated extent is added to the extents status tree. * Requires that the extents in the range have either written or unwritten * status. Must be called while holding i_es_lock. */ -static void __revise_pending (struct inode *inode,ext4_lblk_t lblk, -ext4_lblk_t len) +static int __revise_pending (struct inode *inode,ext4_lblk_t lblk, +ext4_lblk_t len, +struct pending_reservation **prealloc) {struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb);ext4_lblk_t end = lblk + len -1 ;ext4_lblk_t first, last;bool f_del = false, l_del = false; +int ret =0 ;if (len ==0 ) -return ; +return 0 ;/* * Two cases - block range within single cluster and block range
@@ -2219,7 +2264,9 @@ static void __revise_pending(struct inod f_del =__es_scan_range (inode, &ext4_es_is_delonly, first, lblk -1 );if (f_del) { -__insert_pending (inode, first); + ret =__insert_pending (inode, first, prealloc); +if (ret <0 ) + goto out; }else { last =EXT4_LBLK_CMASK (sbi, end) + sbi->s_cluster_ratio -1 ;
@@ -2227,9 +2274,11 @@ static void __revise_pending(struct inod l_del =__es_scan_range (inode, &ext4_es_is_delonly, end +1 , last); -if (l_del) -__insert_pending (inode, last); -else +if (l_del) { + ret =__insert_pending (inode, last, prealloc); +if (ret <0 ) + goto out; + }else __remove_pending (inode, last); } }else {
@@ -2237,18 +2286,24 @@ static void __revise_pending(struct inodif (first != lblk) f_del =__es_scan_range (inode, &ext4_es_is_delonly, first, lblk -1 ); -if (f_del) -__insert_pending (inode, first); -else +if (f_del) { + ret =__insert_pending (inode, first, prealloc); +if (ret <0 ) + goto out; + }else __remove_pending (inode, first); last =EXT4_LBLK_CMASK (sbi, end) + sbi->s_cluster_ratio -1 ;if (last != end) l_del =__es_scan_range (inode, &ext4_es_is_delonly, end +1 , last); -if (l_del) -__insert_pending (inode, last); -else +if (l_del) { + ret =__insert_pending (inode, last, prealloc); +if (ret <0 ) + goto out; + }else __remove_pending (inode, last); } +out: +return ret; }
Greg Kroah-Hartman
maintainerPATCH 498/530 ext4: apply umask if ACL support is disabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Max Kellermann <[email protected]>
commit 484fd6c1de13b336806a967908a927cc0356e312 upstream.
The function ext4_init_acl() calls posix_acl_create() which is responsible for applying the umask. But without CONFIG_EXT4_FS_POSIX_ACL, ext4_init_acl() is an empty inline function, and nobody applies the umask.
This fixes a bug which causes the umask to be ignored with O_TMPFILE on ext4:
https://github.com/MusicPlayerDaemon/MPD/issues/558
https://bugs.gentoo.org/show_bug.cgi?id=686142#c3
https://bugzilla.kernel.org/show_bug.cgi?id=203625
--- fs/ext4/acl.h | 5 +++++ 1 file changed, 5 insertions(+)
fs/ext4/acl.h +5 -0
@@ -68,6 +68,11 @@ extern int ext4_init_acl(handle_t *, strstatic inline int ext4_init_acl (handle_t *handle,struct inode *inode,struct inode *dir) { +/* usually, the umask is applied by posix_acl_create(), but if +ext4 ACL support is disabled at compile time, we need to do +it here, because posix_acl_create() will never be called */ + inode->i_mode &= ~current_umask (); +return 0 ; }#endif /* CONFIG_EXT4_FS_POSIX_ACL */
Greg Kroah-Hartman
maintainerPATCH 499/530 ext4: correct offset of gdb backup in non meta_bg group to update_backups
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kemeng Shi <[email protected]>
commit 31f13421c004a420c0e9d288859c9ea9259ea0cc upstream.
Commit 0aeaa2559d6d5 ("ext4: fix corruption when online resizing a 1K bigalloc fs") found that primary superblock's offset in its group is not equal to offset of backup superblock in its group when block size is 1K and bigalloc is enabled. As group descriptor blocks are right after superblock, we can't pass block number of gdb to update_backups for the same reason.
The root casue of the issue above is that leading 1K padding block is count as data block offset for primary block while backup block has no padding block offset in its group.
Remove padding data block count to fix the issue for gdb backups.
For meta_bg case, update_backups treat blk_off as block number, do no conversion in this case.
--- fs/ext4/resize.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/ext4/resize.c +4 -2
@@ -1601,6 +1601,8 @@ exit_journal:int gdb_num_end = ((group + flex_gd->count -1 ) /EXT4_DESC_PER_BLOCK (sb));int meta_bg =ext4_has_feature_meta_bg (sb); +sector_t padding_blocks = meta_bg ?0 : sbi->s_sbh->b_blocknr - +ext4_group_first_block_no (sb,0 );sector_t old_gdb =0 ; update_backups(sb, ext4_group_first_block_no(sb, 0),
@@ -1612,8 +1614,8 @@ exit_journal: gdb_num);if (old_gdb == gdb_bh->b_blocknr)continue ; -update_backups (sb, gdb_bh->b_blocknr, gdb_bh->b_data, - gdb_bh->b_size, meta_bg); +update_backups (sb, gdb_bh->b_blocknr - padding_blocks, + gdb_bh->b_data, gdb_bh->b_size, meta_bg); old_gdb = gdb_bh->b_blocknr; } }
Greg Kroah-Hartman
maintainerPATCH 500/530 ext4: mark buffer new if it is unwritten to avoid stale data exposure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ojaswin Mujoo <[email protected]>
commit 2cd8bdb5efc1e0d5b11a4b7ba6b922fd2736a87f upstream.
** Short Version **
In ext4 with dioread_nolock, we could have a scenario where the bh returned by get_blocks (ext4_get_block_unwritten()) in __block_write_begin_int() has UNWRITTEN and MAPPED flag set. Since such a bh does not have NEW flag set we never zero out the range of bh that is not under write, causing whatever stale data is present in the folio at that time to be written out to disk. To fix this mark the buffer as new, in case it is unwritten, in ext4_get_block_unwritten().
** Long Version **
The issue mentioned above was resulting in two different bugs:
1. On block size < page size case in ext4, generic/269 was reliably failing with dioread_nolock. The state of the write was as follows:
* The write was extending i_size.
* The last block of the file was fallocated and had an unwritten extent
* We were near ENOSPC and hence we were switching to non-delayed alloc allocation.
In this case, the back trace that triggers the bug is as follows:
ext4_da_write_begin()
/* switch to nodelalloc due to low space */
ext4_write_begin()
ext4_should_dioread_nolock() // true since mount flags still have delalloc
__block_write_begin(..., ext4_get_block_unwritten)
__block_write_begin_int()
for(each buffer head in page) {
/* first iteration, this is bh1 which contains i_size */
if (!buffer_mapped)
get_block() /* returns bh with only UNWRITTEN and MAPPED */
/* second iteration, bh2 */
if (!buffer_mapped)
get_block() /* we fail here, could be ENOSPC */
}
if (err)
/*
* this would zero out all new buffers and mark them uptodate.
* Since bh1 was never marked new, we skip it here which causes
* the bug later.
*/
folio_zero_new_buffers();
/* ext4_wrte_begin() error handling */
ext4_truncate_failed_write()
ext4_truncate()
ext4_block_truncate_page()
__ext4_block_zero_page_range()
if(!buffer_uptodate())
ext4_read_bh_lock()
ext4_read_bh() -> ... ext4_submit_bh_wbc()
BUG_ON(buffer_unwritten(bh)); /* !!! */2. The second issue is stale data exposure with page size >= blocksize with dioread_nolock. The conditions needed for it to happen are same as the previous issue ie dioread_nolock around ENOSPC condition. The issue is also similar where in __block_write_begin_int() when we call ext4_get_block_unwritten() on the buffer_head and the underlying extent is unwritten, we get an unwritten and mapped buffer head. Since it is not new, we never zero out the partial range which is not under write, thus writing stale data to disk. This can be easily observed with the following reproducer:
fallocate -l 4k testfile
xfs_io -c "pwrite 2k 2k" testfile
# hexdump output will have stale data in from byte 0 to 2k in testfile hexdump -C testfile
NOTE: To trigger this, we need dioread_nolock enabled and write happening via ext4_write_begin(), which is usually used when we have -o nodealloc. Since dioread_nolock is disabled with nodelalloc, the only alternate way to call ext4_write_begin() is to ensure that delayed alloc switches to nodelalloc ie ext4_da_write_begin() calls ext4_write_begin(). This will usually happen when ext4 is almost full like the way generic/269 was triggering it in Issue 1 above. This might make the issue harder to hit. Hence, for reliable replication, I used the below patch to temporarily allow dioread_nolock with nodelalloc and then mount the disk with -o nodealloc,dioread_nolock. With this you can hit the stale data issue 100% of times:
@@ -508,8 +508,8 @@ static inline int ext4_should_dioread_nolock(struct inode *inode)
if (ext4_should_journal_data(inode))
return 0;
/* temporary fix to prevent generic/422 test failures */
- if (!test_opt(inode->i_sb, DELALLOC))
- return 0;
+ // if (!test_opt(inode->i_sb, DELALLOC))
+ // return 0;
return 1;
}
After applying this patch to mark buffer as NEW, both the above issues are fixed.
--- fs/ext4/inode.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
fs/ext4/inode.c +13 -1
@@ -789,10 +789,22 @@ int ext4_get_block(struct inode *inode,int ext4_get_block_unwritten (struct inode *inode,sector_t iblock,struct buffer_head *bh_result,int create) { +int ret =0 ; +ext4_debug ("ext4_get_block_unwritten: inode %lu, create flag %d\n" , inode->i_ino, create); -return _ext4_get_block (inode, iblock, bh_result, + ret =_ext4_get_block (inode, iblock, bh_result,EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT ); + +/* +* If the buffer is marked unwritten, mark it as new to make sure it is +* zeroed out correctly in case of partial writes. Otherwise, there is +* a chance of stale data getting exposed. +*/ +if (ret ==0 &&buffer_unwritten (bh_result)) +set_buffer_new (bh_result); + +return ret; }/* Maximum number of blocks we map for direct IO at once. */
Greg Kroah-Hartman
maintainerPATCH 501/530 ext4: correct return value of ext4_convert_meta_bg
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kemeng Shi <[email protected]>
commit 48f1551592c54f7d8e2befc72a99ff4e47f7dca0 upstream.
Avoid to ignore error in "err".
--- fs/ext4/resize.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
fs/ext4/resize.c +1 -3
@@ -1982,9 +1982,7 @@ static int ext4_convert_meta_bg(struct s errout: ret =ext4_journal_stop (handle); -if (!err) - err = ret; -return ret; +return err ? err : ret; invalid_resize_inode:ext4_error (sb,"corrupted/inconsistent resize inode" );
Greg Kroah-Hartman
maintainerPATCH 502/530 ext4: correct the start block of counting reserved clusters
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Yi <[email protected]>
commit 40ea98396a3659062267d1fe5f99af4f7e4f05e3 upstream.
When big allocate feature is enabled, we need to count and update reserved clusters before removing a delayed only extent_status entry. {init|count|get}_rsvd() have already done this, but the start block number of this counting isn't correct in the following case.
lblk end
| | v v
-------------------------
| | orig_es
-------------------------
^ ^
len1 is 0 | len2 |
If the start block of the orig_es entry founded is bigger than lblk, we passed lblk as start block to count_rsvd(), but the length is correct, finally, the range to be counted is offset. This patch fix this by passing the start blocks to 'orig_es->lblk + len1'.
--- fs/ext4/extents_status.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/ext4/extents_status.c +2 -2
@@ -1431,8 +1431,8 @@ static int __es_remove_extent(struct ino } }if (count_reserved) -count_rsvd (inode, lblk, orig_es.es_len - len1 - len2, - &orig_es, &rc); +count_rsvd (inode, orig_es.es_lblk + len1, + orig_es.es_len - len1 - len2, &orig_es, &rc); goto out_get_reserved; }
Greg Kroah-Hartman
maintainerPATCH 503/530 ext4: remove gdb backup copy for meta bg in setup_new_flex_group_blocks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kemeng Shi <[email protected]>
commit 40dd7953f4d606c280074f10d23046b6812708ce upstream.
Wrong check of gdb backup in meta bg as following:first_group is the first group of meta_bg which contains target group, so target group is always >= first_group. We check if target group has gdb backup by comparing first_group with [group + 1] and [group + EXT4_DESC_PER_BLOCK(sb) - 1]. As group >= first_group, then [group + N] is
Quoted 1 line
first_group. So no copy of gdb backup in meta bg is done in
setup_new_flex_group_blocks.
No need to do gdb backup copy in meta bg from setup_new_flex_group_blocks as we always copy updated gdb block to backups at end of ext4_flex_group_add as following:
ext4_flex_group_add
/* no gdb backup copy for meta bg any more */
setup_new_flex_group_blocks
/* update current group number */
ext4_update_super
sbi->s_groups_count += flex_gd->count; /*
* if group in meta bg contains backup is added, the primary gdb block
* of the meta bg will be copy to backup in new added group here. */
for (; gdb_num <= gdb_num_end; gdb_num++)
update_backups(...)
In summary, we can remove wrong gdb backup copy code in setup_new_flex_group_blocks.
--- fs/ext4/resize.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
fs/ext4/resize.c +2 -7
@@ -560,13 +560,8 @@ static int setup_new_flex_group_blocks(sif (meta_bg ==0 && !ext4_bg_has_super (sb, group)) goto handle_itb; -if (meta_bg ==1 ) { -ext4_group_t first_group; - first_group =ext4_meta_bg_first_group (sb, group); -if (first_group != group +1 && - first_group != group +EXT4_DESC_PER_BLOCK (sb) -1 ) - goto handle_itb; - } +if (meta_bg ==1 ) + goto handle_itb; block = start +ext4_bg_has_super (sb, group);/* Copy all of the GDT blocks into the backup in this group */
Greg Kroah-Hartman
maintainerPATCH 504/530 ext4: add missed brelse in update_backups
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kemeng Shi <[email protected]>
commit 9adac8b01f4be28acd5838aade42b8daa4f0b642 upstream.
add missed brelse in update_backups
--- fs/ext4/resize.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/ext4/resize.c +3 -1
@@ -1186,8 +1186,10 @@ static void update_backups(struct super_ ext4_group_first_block_no(sb, group));BUFFER_TRACE (bh,"get_write_access" );if ((err =ext4_journal_get_write_access (handle, sb, bh, -EXT4_JTR_NONE ))) +EXT4_JTR_NONE ))) { +brelse (bh);break ; + }lock_buffer (bh);memcpy (bh->b_data, data, size);if (rest)
Greg Kroah-Hartman
maintainerPATCH 505/530 ext4: properly sync file size update after O_SYNC direct IO
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit 91562895f8030cb9a0470b1db49de79346a69f91 upstream.
Gao Xiang has reported that on ext4 O_SYNC direct IO does not properly sync file size update and thus if we crash at unfortunate moment, the file can have smaller size although O_SYNC IO has reported successful completion. The problem happens because update of on-disk inode size is handled in ext4_dio_write_iter() *after* iomap_dio_rw() (and thus dio_complete() in particular) has returned and generic_file_sync() gets called by dio_complete(). Fix the problem by handling on-disk inode size update directly in our ->end_io completion handler.
References: https://lore.kernel.org/all/[email protected]
--- fs/ext4/file.c | 153 ++++++++++++++++++++++++--------------------------------- 1 file changed, 65 insertions(+), 88 deletions(-)
fs/ext4/file.c +65 -88
@@ -306,80 +306,38 @@ out: }static ssize_t ext4_handle_inode_extension (struct inode *inode,loff_t offset, -ssize_t written,size_t count) +ssize_t count) {handle_t *handle; -bool truncate = false; -u8 blkbits = inode->i_blkbits; -ext4_lblk_t written_blk, end_blk; -int ret; - -/* -* Note that EXT4_I(inode)->i_disksize can get extended up to -* inode->i_size while the I/O was running due to writeback of delalloc -* blocks. But, the code in ext4_iomap_alloc() is careful to use -* zeroed/unwritten extents if this is possible; thus we won't leave -* uninitialized blocks in a file even if we didn't succeed in writing -* as much as we intended. -*/ -WARN_ON_ONCE (i_size_read (inode) <EXT4_I (inode)->i_disksize); -if (offset + count <=EXT4_I (inode)->i_disksize) { -/* -* We need to ensure that the inode is removed from the orphan -* list if it has been added prematurely, due to writeback of -* delalloc blocks. -*/ -if (!list_empty (&EXT4_I (inode)->i_orphan) && inode->i_nlink) { - handle =ext4_journal_start (inode,EXT4_HT_INODE ,2 ); - -if (IS_ERR (handle)) { -ext4_orphan_del (NULL , inode); -return PTR_ERR (handle); - } - -ext4_orphan_del (handle, inode); -ext4_journal_stop (handle); - } - -return written; - } - -if (written <0 ) - goto truncate; +lockdep_assert_held_write (&inode->i_rwsem); handle =ext4_journal_start (inode,EXT4_HT_INODE ,2 ); -if (IS_ERR (handle)) { - written =PTR_ERR (handle); - goto truncate; - } +if (IS_ERR (handle)) +return PTR_ERR (handle); -if (ext4_update_inode_size (inode, offset + written)) { - ret =ext4_mark_inode_dirty (handle, inode); +if (ext4_update_inode_size (inode, offset + count)) { +int ret =ext4_mark_inode_dirty (handle, inode);if (unlikely (ret)) { - written = ret;ext4_journal_stop (handle); - goto truncate; +return ret; } } -/* -* We may need to truncate allocated but not written blocks beyond EOF. -*/ - written_blk =ALIGN (offset + written,1 << blkbits); - end_blk =ALIGN (offset + count,1 << blkbits); -if (written_blk < end_blk &&ext4_can_truncate (inode)) - truncate = true; - -/* -* Remove the inode from the orphan list if it has been extended and -* everything went OK. -*/ -if (!truncate && inode->i_nlink) +if (inode->i_nlink)ext4_orphan_del (handle, inode);ext4_journal_stop (handle); -if (truncate) { -truncate: +return count; +} + +/* +* Clean up the inode after DIO or DAX extending write has completed and the +* inode size has been updated using ext4_handle_inode_extension(). +*/ +static void ext4_inode_extension_cleanup (struct inode *inode,ssize_t count) +{ +lockdep_assert_held_write (&inode->i_rwsem); +if (count <0 ) {ext4_truncate_failed_write (inode);/* * If the truncate operation failed early, then the inode may
@@ -388,9 +346,28 @@ truncate:*/ if (inode->i_nlink)ext4_orphan_del (NULL , inode); +return ; } +/* +* If i_disksize got extended due to writeback of delalloc blocks while +* the DIO was running we could fail to cleanup the orphan list in +* ext4_handle_inode_extension(). Do it now. +*/ +if (!list_empty (&EXT4_I (inode)->i_orphan) && inode->i_nlink) { +handle_t *handle =ext4_journal_start (inode,EXT4_HT_INODE ,2 ); -return written; +if (IS_ERR (handle)) { +/* +* The write has successfully completed. Not much to +* do with the error here so just cleanup the orphan +* list and hope for the best. +*/ +ext4_orphan_del (NULL , inode); +return ; + } +ext4_orphan_del (handle, inode); +ext4_journal_stop (handle); + } } static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
@@ -399,31 +376,22 @@ static int ext4_dio_write_end_io(structloff_t pos = iocb->ki_pos;struct inode *inode =file_inode (iocb->ki_filp); +if (!error && size && flags &IOMAP_DIO_UNWRITTEN ) + error =ext4_convert_unwritten_extents (NULL , inode, pos, size);if (error)return error; - -if (size && flags &IOMAP_DIO_UNWRITTEN ) { - error =ext4_convert_unwritten_extents (NULL , inode, pos, size); -if (error <0 ) -return error; - }/* -* If we are extending the file, we have to update i_size here before -* page cache gets invalidated in iomap_dio_rw(). Otherwise racing -* buffered reads could zero out too much from page cache pages. Update -* of on-disk size will happen later in ext4_dio_write_iter() where -* we have enough information to also perform orphan list handling etc. -* Note that we perform all extending writes synchronously under -* i_rwsem held exclusively so i_size update is safe here in that case. -* If the write was not extending, we cannot see pos > i_size here -* because operations reducing i_size like truncate wait for all -* outstanding DIO before updating i_size. +* Note that EXT4_I(inode)->i_disksize can get extended up to +* inode->i_size while the I/O was running due to writeback of delalloc +* blocks. But the code in ext4_iomap_alloc() is careful to use +* zeroed/unwritten extents if this is possible; thus we won't leave +* uninitialized blocks in a file even if we didn't succeed in writing +* as much as we intended. */ - pos += size; -if (pos >i_size_read (inode)) -i_size_write (inode, pos); - -return 0 ; +WARN_ON_ONCE (i_size_read (inode) <READ_ONCE (EXT4_I (inode)->i_disksize)); +if (pos + size <=READ_ONCE (EXT4_I (inode)->i_disksize)) +return size; +return ext4_handle_inode_extension (inode, pos, size); }static const struct iomap_dio_ops ext4_dio_write_ops = {
@@ -606,9 +574,16 @@ static ssize_t ext4_dio_write_iter(struc dio_flags, NULL, 0);if (ret == -ENOTBLK ) ret =0 ; - -if (extend) - ret =ext4_handle_inode_extension (inode, offset, ret, count); +if (extend) { +/* +* We always perform extending DIO write synchronously so by +* now the IO is completed and ext4_handle_inode_extension() +* was called. Cleanup the inode in case of error or race with +* writeback of delalloc blocks. +*/ +WARN_ON_ONCE (ret == -EIOCBQUEUED ); +ext4_inode_extension_cleanup (inode, ret); + } out:if (ilock_shared)
@@ -689,8 +664,10 @@ ext4_dax_write_iter(struct kiocb *iocb, ret =dax_iomap_rw (iocb, from, &ext4_iomap_ops); -if (extend) - ret =ext4_handle_inode_extension (inode, offset, ret, count); +if (extend) { + ret =ext4_handle_inode_extension (inode, offset, ret); +ext4_inode_extension_cleanup (inode, ret); + } out:inode_unlock (inode);if (ret >0 )
Greg Kroah-Hartman
maintainerPATCH 506/530 ext4: fix racy may inline data check in dio write
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian Foster <[email protected]>
commit ce56d21355cd6f6937aca32f1f44ca749d1e4808 upstream.
syzbot reports that the following warning from ext4_iomap_begin() triggers as of the commit referenced below:
if (WARN_ON_ONCE(ext4_has_inline_data(inode)))
return -ERANGE;This occurs during a dio write, which is never expected to encounter an inode with inline data. To enforce this behavior, ext4_dio_write_iter() checks the current inline state of the inode and clears the MAY_INLINE_DATA state flag to either fall back to buffered writes, or enforce that any other writers in progress on the inode are not allowed to create inline data.
The problem is that the check for existing inline data and the state flag can span a lock cycle. For example, if the ilock is originally locked shared and subsequently upgraded to exclusive, another writer may have reacquired the lock and created inline data before the dio write task acquires the lock and proceeds.
The commit referenced below loosens the lock requirements to allow some forms of unaligned dio writes to occur under shared lock, but AFAICT the inline data check was technically already racy for any dio write that would have involved a lock cycle. Regardless, lift clearing of the state bit to the same lock critical section that checks for preexisting inline data on the inode to close the race.
--- fs/ext4/file.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
fs/ext4/file.c +9 -7
@@ -537,18 +537,20 @@ static ssize_t ext4_dio_write_iter(strucreturn ext4_buffered_write_iter (iocb, from); } +/* +* Prevent inline data from being created since we are going to allocate +* blocks for DIO. We know the inode does not currently have inline data +* because ext4_should_use_dio() checked for it, but we have to clear +* the state flag before the write checks because a lock cycle could +* introduce races with other writers. +*/ +ext4_clear_inode_state (inode,EXT4_STATE_MAY_INLINE_DATA ); + ret =ext4_dio_write_checks (iocb, from, &ilock_shared, &extend, &unwritten, &dio_flags);if (ret <=0 )return ret; -/* -* Make sure inline data cannot be created anymore since we are going -* to allocate blocks for DIO. We know the inode does not have any -* inline data now because ext4_dio_supported() checked for that. -*/ -ext4_clear_inode_state (inode,EXT4_STATE_MAY_INLINE_DATA ); - offset = iocb->ki_pos; count = ret;
Greg Kroah-Hartman
maintainerPATCH 507/530 drm/amd/pm: Handle non-terminated overdrive commands.
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bas Nieuwenhuizen <[email protected]>
commit 08e9ebc75b5bcfec9d226f9e16bab2ab7b25a39a upstream.
The incoming strings might not be terminated by a newline or a 0.
(found while testing a program that just wrote the string
itself, causing a crash)
--- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/pm/amdgpu_pm.c +6 -2
@@ -734,7 +734,7 @@ static ssize_t amdgpu_set_pp_od_clk_voltif (adev->in_suspend && !adev->in_runpm)return -EPERM ; -if (count >127 ) +if (count >127 || count ==0 )return -EINVAL ;if (*buf =='s' )
@@ -754,7 +754,8 @@ static ssize_t amdgpu_set_pp_od_clk_voltelse return -EINVAL ; -memcpy (buf_cpy, buf, count+1 ); +memcpy (buf_cpy, buf, count); + buf_cpy[count] =0 ; tmp_str = buf_cpy;
@@ -771,6 +772,9 @@ static ssize_t amdgpu_set_pp_od_clk_voltreturn -EINVAL ; parameter_size++; +if (!tmp_str) +break ; +while (isspace (*tmp_str)) tmp_str++; }
Greg Kroah-Hartman
maintainerPATCH 508/530 drm: bridge: it66121: ->get_edid callback must not return err pointers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jani Nikula <[email protected]>
commit 81995ee1620318b4c7bbeb02bcc372da2c078c76 upstream.
The drm stack does not expect error valued pointers for EDID anywhere.
--- drivers/gpu/drm/bridge/ite-it66121.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/ite-it66121.c +2 -2
@@ -884,14 +884,14 @@ static struct edid *it66121_bridge_get_emutex_lock (&ctx->lock); ret =it66121_preamble_ddc (ctx);if (ret) { - edid =ERR_PTR (ret); + edid =NULL ; goto out_unlock; } ret =regmap_write (ctx->regmap,IT66121_DDC_HEADER_REG ,IT66121_DDC_HEADER_EDID );if (ret) { - edid =ERR_PTR (ret); + edid =NULL ; goto out_unlock; }
Greg Kroah-Hartman
maintainerPATCH 509/530 x86/srso: Move retbleed IBPB check into existing has_microcode code block
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf <[email protected]>
commit 351236947a45a512c517153bbe109fe868d05e6d upstream.
Simplify the code flow a bit by moving the retbleed IBPB check into the existing 'has_microcode' block.
--- arch/x86/kernel/cpu/bugs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
arch/x86/kernel/cpu/bugs.c +1 -3
@@ -2422,10 +2422,8 @@ static void __init srso_select_mitigatiosetup_force_cpu_cap (X86_FEATURE_SRSO_NO );return ; } - } -if (retbleed_mitigation ==RETBLEED_MITIGATION_IBPB ) { -if (has_microcode) { +if (retbleed_mitigation ==RETBLEED_MITIGATION_IBPB ) { srso_mitigation =SRSO_MITIGATION_IBPB ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 510/530 drm/amd/display: Add Null check for DPP resource
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabe Teeger <[email protected]>
commit e186400685d8a9287388a8535e2399bc673bfe95 upstream.
[what and why]
Check whether dpp resource pointer is null in advance and return early if so.
--- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/core/dc_resource.c +1 -1
@@ -996,7 +996,7 @@ static void adjust_recout_for_visual_construct dc *dc = pipe_ctx->stream->ctx->dc;int dpp_offset, base_offset; -if (dc->debug.visual_confirm ==VISUAL_CONFIRM_DISABLE ) +if (dc->debug.visual_confirm ==VISUAL_CONFIRM_DISABLE || !pipe_ctx->plane_res.dpp)return ; dpp_offset = pipe_ctx->stream->timing.v_addressable /VISUAL_CONFIRM_DPP_OFFSET_DENO ;
Greg Kroah-Hartman
maintainerPATCH 511/530 drm/i915/mtl: Support HBR3 rate with C10 phy and eDP in MTL
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chaitanya Kumar Borah <[email protected]>
commit ce4941c2d6459664761c9854701015d8e99414fb upstream.
eDP specification supports HBR3 link rate since v1.4a. Moreover, C10 phy can support HBR3 link rate for both DP and eDP. Therefore, do not clamp the supported rates for eDP at 6.75Gbps.
BSpec: 70073 74224
--- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i915/display/intel_dp.c +1 -1
@@ -430,7 +430,7 @@ static int mtl_max_source_rate(struct inenum phy phy =intel_port_to_phy (i915, dig_port->base.port);if (intel_is_c10phy (i915, phy)) -return intel_dp_is_edp (intel_dp) ?675000 :810000 ; +return 810000 ;return 2000000 ; }
Greg Kroah-Hartman
maintainerPATCH 512/530 drm/i915: Bump GLK CDCLK frequency when driving multiple pipes
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä <[email protected]>
commit 0cb89cd42fd22bbdec0b046c48f35775f5b88bdb upstream.
On GLK CDCLK frequency needs to be at least 2*96 MHz when accessing the audio hardware. Currently we bump the CDCLK frequency up temporarily (if not high enough already) whenever audio hardware is being accessed, and drop it back down afterwards.
With a single active pipe this works just fine as we can switch between all the valid CDCLK frequencies by changing the cd2x divider, which doesn't require a full modeset. However with multiple active pipes the cd2x divider trick no longer works, and thus we end up blinking all displays off and back on.
To avoid this let's just bump the CDCLK frequency to >=2*96MHz whenever multiple pipes are active. The downside is slightly higher power consumption, but that seems like an acceptable tradeoff. With a single active pipe we can stick to the current more optiomal (from power comsumption POV) behaviour.
--- drivers/gpu/drm/i915/display/intel_cdclk.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/gpu/drm/i915/display/intel_cdclk.c +12 -0
@@ -2688,6 +2688,18 @@ static int intel_compute_min_cdclk(strucfor_each_pipe (dev_priv, pipe) min_cdclk =max (cdclk_state->min_cdclk[pipe], min_cdclk); +/* +* Avoid glk_force_audio_cdclk() causing excessive screen +* blinking when multiple pipes are active by making sure +* CDCLK frequency is always high enough for audio. With a +* single active pipe we can always change CDCLK frequency +* by changing the cd2x divider (see glk_cdclk_table[]) and +* thus a full modeset won't be needed then. +*/ +if (IS_GEMINILAKE (dev_priv) && cdclk_state->active_pipes && + !is_power_of_2 (cdclk_state->active_pipes)) + min_cdclk =max (2 *96000 , min_cdclk); +if (min_cdclk > dev_priv->display.cdclk.max_cdclk_freq) { drm_dbg_kms(&dev_priv->drm, "required cdclk (%d kHz) exceeds max (%d kHz)\n",
Greg Kroah-Hartman
maintainerPATCH 513/530 drm/i915: Fix potential spectre vulnerability
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kunwu Chan <[email protected]>
commit 1a8e9bad6ef563c28ab0f8619628d5511be55431 upstream.
Fix smatch warning:drivers/gpu/drm/i915/gem/i915_gem_context.c:847 set_proto_ctx_sseu()
warn: potential spectre issue 'pc->user_engines' [r] (local cap)
--- drivers/gpu/drm/i915/gem/i915_gem_context.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/i915/gem/i915_gem_context.c +1 -0
@@ -844,6 +844,7 @@ static int set_proto_ctx_sseu(struct drmif (idx >= pc->num_user_engines)return -EINVAL ; + idx =array_index_nospec (idx, pc->num_user_engines); pe = &pc->user_engines[idx];/* Only render engine supports RPCS configuration. */
Greg Kroah-Hartman
maintainerPATCH 514/530 drm/i915: Flush WC GGTT only on required platforms
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nirmoy Das <[email protected]>
commit 7d7a328d0e8d6edefb7b0d665185d468667588d0 upstream.
gen8_ggtt_invalidate() is only needed for limited set of platforms where GGTT is mapped as WC. This was added as way to fix WC based GGTT in commit 0f9b91c754b7 ("drm/i915: flush system agent TLBs on SNB") and there are no reference in HW docs that forces us to use this on non-WC backed GGTT.
This can also cause unwanted side-effects on XE_HP platforms where GFX_FLSH_CNTL_GEN6 is not valid anymore.
v2: Add a func to detect wc ggtt detection (Ville)
v3: Improve commit log and add reference commit (Daniel)
--- drivers/gpu/drm/i915/gt/intel_ggtt.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-)
drivers/gpu/drm/i915/gt/intel_ggtt.c +24 -11
@@ -190,6 +190,21 @@ void gen6_ggtt_invalidate(struct i915_ggspin_unlock_irq (&uncore->lock); } +static bool needs_wc_ggtt_mapping (struct drm_i915_private *i915) +{ +/* +* On BXT+/ICL+ writes larger than 64 bit to the GTT pagetable range +* will be dropped. For WC mappings in general we have 64 byte burst +* writes when the WC buffer is flushed, so we can't use it, but have to +* resort to an uncached mapping. The WC issue is easily caught by the +* readback check when writing GTT PTE entries. +*/ +if (!IS_GEN9_LP (i915) &&GRAPHICS_VER (i915) <11 ) +return true; + +return false; +} +static void gen8_ggtt_invalidate (struct i915_ggtt *ggtt) {struct intel_uncore *uncore = ggtt->vm.gt->uncore;
@@ -197,8 +212,12 @@ static void gen8_ggtt_invalidate(struct/* * Note that as an uncached mmio write, this will flush the * WCB of the writes into the GGTT before it triggers the invalidate. +* +* Only perform this when GGTT is mapped as WC, see ggtt_probe_common(). */ -intel_uncore_write_fw (uncore,GFX_FLSH_CNTL_GEN6 ,GFX_FLSH_CNTL_EN ); +if (needs_wc_ggtt_mapping (ggtt->vm.i915)) +intel_uncore_write_fw (uncore,GFX_FLSH_CNTL_GEN6 , +GFX_FLSH_CNTL_EN ); }static void guc_ggtt_invalidate (struct i915_ggtt *ggtt)
@@ -902,17 +921,11 @@ static int ggtt_probe_common(struct i915GEM_WARN_ON (pci_resource_len (pdev,GEN4_GTTMMADR_BAR ) !=gen6_gttmmadr_size (i915)); phys_addr =pci_resource_start (pdev,GEN4_GTTMMADR_BAR ) +gen6_gttadr_offset (i915); -/* -* On BXT+/ICL+ writes larger than 64 bit to the GTT pagetable range -* will be dropped. For WC mappings in general we have 64 byte burst -* writes when the WC buffer is flushed, so we can't use it, but have to -* resort to an uncached mapping. The WC issue is easily caught by the -* readback check when writing GTT PTE entries. -*/ -if (IS_GEN9_LP (i915) ||GRAPHICS_VER (i915) >=11 ) - ggtt->gsm =ioremap (phys_addr, size); -else +if (needs_wc_ggtt_mapping (i915)) ggtt->gsm =ioremap_wc (phys_addr, size); +else + ggtt->gsm =ioremap (phys_addr, size); +if (!ggtt->gsm) {drm_err (&i915->drm,"Failed to map the ggtt page table\n" );return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 515/530 drm/amd/pm: Fix error of MACO flag setting code
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Jun <[email protected]>
commit 7f3e6b840fa8b0889d776639310a5dc672c1e9e1 upstream.
MACO only works if BACO is supported
--- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 8 ++++---- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +4 -4
@@ -352,12 +352,12 @@ static int smu_v13_0_0_check_powerplay_tif (powerplay_table->platform_caps &SMU_13_0_0_PP_PLATFORM_CAP_HARDWAREDC ) smu->dc_controlled_by_gpio = true; -if (powerplay_table->platform_caps &SMU_13_0_0_PP_PLATFORM_CAP_BACO || - powerplay_table->platform_caps &SMU_13_0_0_PP_PLATFORM_CAP_MACO ) +if (powerplay_table->platform_caps &SMU_13_0_0_PP_PLATFORM_CAP_BACO ) { smu_baco->platform_support = true; -if (powerplay_table->platform_caps &SMU_13_0_0_PP_PLATFORM_CAP_MACO ) - smu_baco->maco_support = true; +if (powerplay_table->platform_caps &SMU_13_0_0_PP_PLATFORM_CAP_MACO ) + smu_baco->maco_support = true; + }/* * We are in the transition to a new OD mechanism.
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +5 -4
@@ -341,12 +341,13 @@ static int smu_v13_0_7_check_powerplay_tif (powerplay_table->platform_caps &SMU_13_0_7_PP_PLATFORM_CAP_HARDWAREDC ) smu->dc_controlled_by_gpio = true; -if (powerplay_table->platform_caps &SMU_13_0_7_PP_PLATFORM_CAP_BACO || - powerplay_table->platform_caps &SMU_13_0_7_PP_PLATFORM_CAP_MACO ) +if (powerplay_table->platform_caps &SMU_13_0_7_PP_PLATFORM_CAP_BACO ) { smu_baco->platform_support = true; -if (smu_baco->platform_support && (BoardTable->HsrEnabled || BoardTable->VddqOffEnabled)) - smu_baco->maco_support = true; +if ((powerplay_table->platform_caps &SMU_13_0_7_PP_PLATFORM_CAP_MACO ) + && (BoardTable->HsrEnabled || BoardTable->VddqOffEnabled)) + smu_baco->maco_support = true; + }#if 0 if (!overdrive_lowerlimits->FeatureCtrlMask ||
Greg Kroah-Hartman
maintainerPATCH 516/530 drm/amdgpu/smu13: drop compute workload workaround
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 23170863ea0a0965d224342c0eb2ad8303b1f267 upstream.
This was fixed in PMFW before launch and is no longer required.
--- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 32 +------------------ 1 file changed, 2 insertions(+), 30 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +2 -30
@@ -2163,38 +2163,10 @@ static int smu_v13_0_0_set_power_profile } } -if (smu->power_profile_mode ==PP_SMC_POWER_PROFILE_COMPUTE && - (((smu->adev->pdev->device ==0x744C ) && (smu->adev->pdev->revision ==0xC8 )) || - ((smu->adev->pdev->device ==0x744C ) && (smu->adev->pdev->revision ==0xCC )))) { - ret =smu_cmn_update_table (smu, -SMU_TABLE_ACTIVITY_MONITOR_COEFF , -WORKLOAD_PPLIB_COMPUTE_BIT , - (void *)(&activity_monitor_external), - false); -if (ret) { -dev_err (smu->adev->dev,"[%s] Failed to get activity monitor!" , __func__); -return ret; - } - - ret =smu_cmn_update_table (smu, -SMU_TABLE_ACTIVITY_MONITOR_COEFF , -WORKLOAD_PPLIB_CUSTOM_BIT , - (void *)(&activity_monitor_external), - true); -if (ret) { -dev_err (smu->adev->dev,"[%s] Failed to set activity monitor!" , __func__); -return ret; - } - - workload_type =smu_cmn_to_asic_specific_index (smu, -CMN2ASIC_MAPPING_WORKLOAD , -PP_SMC_POWER_PROFILE_CUSTOM ); - }else { -/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ - workload_type =smu_cmn_to_asic_specific_index (smu, +/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ + workload_type =smu_cmn_to_asic_specific_index (smu,CMN2ASIC_MAPPING_WORKLOAD , smu->power_profile_mode); - }if (workload_type <0 )return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 517/530 drm/amdgpu: dont use pci_is_thunderbolt_attached()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 7b1c6263eaf4fd64ffe1cafdc504a42ee4bfbb33 upstream.
It's only valid on Intel systems with the Intel VSEC. Use dev_is_removable() instead. This should do the right thing regardless of the platform.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 ++++---- drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +4 -4
@@ -43,6 +43,7 @@#include <drm/drm_fb_helper.h> #include <drm/drm_probe_helper.h> #include <drm/amdgpu_drm.h> +#include <linux/device.h> #include <linux/vgaarb.h> #include <linux/vga_switcheroo.h> #include <linux/efi.h>
@@ -2018,7 +2019,6 @@ out:*/ static int amdgpu_device_ip_early_init (struct amdgpu_device *adev) { -struct drm_device *dev =adev_to_drm (adev);struct pci_dev *parent;int i, r;bool total;
@@ -2089,7 +2089,7 @@ static int amdgpu_device_ip_early_init(s (amdgpu_is_atpx_hybrid () ||amdgpu_has_atpx_dgpu_power_cntl ()) && ((adev->flags &AMD_IS_APU ) ==0 ) && - !pci_is_thunderbolt_attached(to_pci_dev(dev->dev))) + !dev_is_removable(&adev->pdev->dev)) adev->flags |= AMD_IS_PX;if (!(adev->flags &AMD_IS_APU )) {
@@ -3903,7 +3903,7 @@ fence_driver_init: px =amdgpu_device_supports_px (ddev); -if (px || (!pci_is_thunderbolt_attached (adev->pdev) && +if (px || (!dev_is_removable (&adev->pdev->dev) &&apple_gmux_detect (NULL ,NULL )))vga_switcheroo_register_client (adev->pdev, &amdgpu_switcheroo_ops, px);
@@ -4048,7 +4048,7 @@ void amdgpu_device_fini_sw(struct amdgpu px =amdgpu_device_supports_px (adev_to_drm (adev)); -if (px || (!pci_is_thunderbolt_attached (adev->pdev) && +if (px || (!dev_is_removable (&adev->pdev->dev) &&apple_gmux_detect (NULL ,NULL )))vga_switcheroo_unregister_client (adev->pdev);
drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c +3 -2
@@ -28,6 +28,7 @@#include "nbio/nbio_2_3_offset.h" #include "nbio/nbio_2_3_sh_mask.h" #include <uapi/linux/kfd_ioctl.h> +#include <linux/device.h> #include <linux/pci.h> #define smnPCIE_CONFIG_CNTL 0x11180044
@@ -361,7 +362,7 @@ static void nbio_v2_3_enable_aspm(struct data |=NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT <<PCIE_LC_CNTL__LC_L0S_INACTIVITY__SHIFT ; -if (pci_is_thunderbolt_attached (adev->pdev)) +if (dev_is_removable (&adev->pdev->dev)) data |=NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT <<PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT ;else data |=NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT <<PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT ;
@@ -480,7 +481,7 @@ static void nbio_v2_3_program_aspm(struc def = data =RREG32_PCIE (smnPCIE_LC_CNTL); data |=NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT <<PCIE_LC_CNTL__LC_L0S_INACTIVITY__SHIFT ; -if (pci_is_thunderbolt_attached (adev->pdev)) +if (dev_is_removable (&adev->pdev->dev)) data |=NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT <<PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT ;else data |=NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT <<PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT ;
Greg Kroah-Hartman
maintainerPATCH 518/530 drm/amdgpu: fix GRBM read timeout when do mes_self_test
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Huang <[email protected]>
commit 36e7ff5c13cb15cb7b06c76d42bb76cbf6b7ea75 upstream.
Use a proper MEID to make sure the CP_HQD_* and CP_GFX_HQD_* registers can be touched when initialize the compute and gfx mqd in mes_self_test. Otherwise, we expect no response from CP and an GRBM eventual timeout.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +16 -0
@@ -556,8 +556,20 @@ static void amdgpu_mes_queue_init_mqd(st mqd_prop.hqd_queue_priority = p->hqd_queue_priority; mqd_prop.hqd_active = false; +if (p->queue_type ==AMDGPU_RING_TYPE_GFX || + p->queue_type ==AMDGPU_RING_TYPE_COMPUTE ) { +mutex_lock (&adev->srbm_mutex); +amdgpu_gfx_select_me_pipe_q (adev, p->ring->me, p->ring->pipe,0 ,0 ,0 ); + } + mqd_mgr->init_mqd (adev, q->mqd_cpu_ptr, &mqd_prop); +if (p->queue_type ==AMDGPU_RING_TYPE_GFX || + p->queue_type ==AMDGPU_RING_TYPE_COMPUTE ) { +amdgpu_gfx_select_me_pipe_q (adev,0 ,0 ,0 ,0 ,0 ); +mutex_unlock (&adev->srbm_mutex); + } +amdgpu_bo_unreserve (q->mqd_obj); }
@@ -993,9 +1005,13 @@ int amdgpu_mes_add_ring(struct amdgpu_deswitch (queue_type) {case AMDGPU_RING_TYPE_GFX : ring->funcs = adev->gfx.gfx_ring[0 ].funcs; + ring->me = adev->gfx.gfx_ring[0 ].me; + ring->pipe = adev->gfx.gfx_ring[0 ].pipe;break ;case AMDGPU_RING_TYPE_COMPUTE : ring->funcs = adev->gfx.compute_ring[0 ].funcs; + ring->me = adev->gfx.compute_ring[0 ].me; + ring->pipe = adev->gfx.compute_ring[0 ].pipe;break ;case AMDGPU_RING_TYPE_SDMA : ring->funcs = adev->sdma.instance[0 ].ring.funcs;
Greg Kroah-Hartman
maintainerPATCH 519/530 drm/amdgpu: add a retry for IP discovery init
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 3938eb956e383ef88b8fc7d556492336ebee52df upstream.
AMD dGPUs have integrated FW that runs as soon as the device gets power and initializes the board (determines the amount of memory, provides configuration details to the driver, etc.). For direct PCIe attached cards this happens as soon as power is applied and normally completes well before the OS has even started loading. However, with hotpluggable ports like USB4, the driver needs to wait for this to complete before initializing the device.
This normally takes 60-100ms, but could take longer on some older boards periodically due to memory training.
Retry for up to a second. In the non-hotplug case, there should be no change in behavior and this should complete on the first try.
v2: adjust test criteria
v3: adjust checks for the masks, only enable on removable devices
v4: skip bif_fb_en check
--- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +21 -2
@@ -93,6 +93,7 @@MODULE_FIRMWARE (FIRMWARE_IP_DISCOVERY );#define mmRCC_CONFIG_MEMSIZE 0xde3 +#define mmMP0_SMN_C2PMSG_33 0x16061#define mmMM_INDEX 0x0#define mmMM_INDEX_HI 0x6#define mmMM_DATA 0x1
@@ -231,8 +232,26 @@ static int amdgpu_discovery_read_binary_static int amdgpu_discovery_read_binary_from_mem (struct amdgpu_device *adev,uint8_t *binary) { -uint64_t vram_size = (uint64_t )RREG32 (mmRCC_CONFIG_MEMSIZE) <<20 ; -int ret =0 ; +uint64_t vram_size; +u32 msg; +int i, ret =0 ; + +/* It can take up to a second for IFWI init to complete on some dGPUs, +* but generally it should be in the 60-100ms range. Normally this starts +* as soon as the device gets power so by the time the OS loads this has long +* completed. However, when a card is hotplugged via e.g., USB4, we need to +* wait for this to complete. Once the C2PMSG is updated, we can +* continue. +*/ +if (dev_is_removable (&adev->pdev->dev)) { +for (i =0 ; i <1000 ; i++) { + msg =RREG32 (mmMP0_SMN_C2PMSG_33); +if (msg &0x80000000 ) +break ; +msleep (1 ); + } + } + vram_size = (uint64_t )RREG32 (mmRCC_CONFIG_MEMSIZE) <<20 ;if (vram_size) {uint64_t pos = vram_size -DISCOVERY_TMR_OFFSET ;
Greg Kroah-Hartman
maintainerPATCH 520/530 drm/amdgpu: dont use ATRM for external devices
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 432e664e7c98c243fab4c3c95bd463bea3aeed28 upstream.
The ATRM ACPI method is for fetching the dGPU vbios rom image on laptops and all-in-one systems. It should not be used for external add in cards. If the dGPU is thunderbolt connected, don't try ATRM.
v2: pci_is_thunderbolt_attached only works for Intel. Use
pdev->external_facing instead.
v3: dev_is_removable() seems to be what we want
--- drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +5 -0
@@ -29,6 +29,7 @@#include "amdgpu.h" #include "atom.h" +#include <linux/device.h> #include <linux/pci.h> #include <linux/slab.h> #include <linux/acpi.h>
@@ -287,6 +288,10 @@ static bool amdgpu_atrm_get_bios(structif (adev->flags &AMD_IS_APU )return false; +/* ATRM is for on-platform devices only */ +if (dev_is_removable (&adev->pdev->dev)) +return false; +while ((pdev =pci_get_class (PCI_CLASS_DISPLAY_VGA <<8 , pdev)) !=NULL ) { dhandle =ACPI_HANDLE (&pdev->dev);if (!dhandle)
Greg Kroah-Hartman
maintainerPATCH 521/530 drm/amdgpu: fix error handling in amdgpu_vm_init
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian König <[email protected]>
commit 8473bfdcb5b1a32fd05629c4535ccacd73bc5567 upstream.
When clearing the root PD fails we need to properly release it again.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +16 -15
@@ -2125,7 +2125,8 @@ long amdgpu_vm_wait_idle(struct amdgpu_v* Returns: * 0 for success, error for failure. */ -int amdgpu_vm_init (struct amdgpu_device *adev,struct amdgpu_vm *vm,int32_t xcp_id) +int amdgpu_vm_init (struct amdgpu_device *adev,struct amdgpu_vm *vm, +int32_t xcp_id) {struct amdgpu_bo *root_bo;struct amdgpu_bo_vm *root;
@@ -2144,6 +2145,7 @@ int amdgpu_vm_init(struct amdgpu_deviceINIT_LIST_HEAD (&vm->done);INIT_LIST_HEAD (&vm->pt_freed);INIT_WORK (&vm->pt_free_work, amdgpu_vm_pt_free_work); +INIT_KFIFO (vm->faults); r =amdgpu_vm_init_entities (adev, vm);if (r)
@@ -2178,34 +2180,33 @@ int amdgpu_vm_init(struct amdgpu_device false, &root, xcp_id);if (r) goto error_free_delayed; - root_bo = &root->bo; + + root_bo =amdgpu_bo_ref (&root->bo); r =amdgpu_bo_reserve (root_bo, true); -if (r) - goto error_free_root; +if (r) { +amdgpu_bo_unref (&root->shadow); +amdgpu_bo_unref (&root_bo); + goto error_free_delayed; + } +amdgpu_vm_bo_base_init (&vm->root, vm, root_bo); r =dma_resv_reserve_fences (root_bo->tbo.base.resv,1 );if (r) - goto error_unreserve; - -amdgpu_vm_bo_base_init (&vm->root, vm, root_bo); + goto error_free_root; r =amdgpu_vm_pt_clear (adev, vm, root, false);if (r) - goto error_unreserve; + goto error_free_root;amdgpu_bo_unreserve (vm->root.bo); - -INIT_KFIFO (vm->faults); +amdgpu_bo_unref (&root_bo);return 0 ; -error_unreserve: -amdgpu_bo_unreserve (vm->root.bo); - error_free_root: -amdgpu_bo_unref (&root->shadow); +amdgpu_vm_pt_free_root (adev, vm); +amdgpu_bo_unreserve (vm->root.bo);amdgpu_bo_unref (&root_bo); - vm->root.bo =NULL ; error_free_delayed:dma_fence_put (vm->last_tlb_flush);
Greg Kroah-Hartman
maintainerPATCH 522/530 drm/amdgpu: fix error handling in amdgpu_bo_list_get()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian König <[email protected]>
commit 12f76050d8d4d10dab96333656b821bd4620d103 upstream.
We should not leak the pointer where we couldn't grab the reference on to the caller because it can be that the error handling still tries to put the reference then.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +1 -0
@@ -183,6 +183,7 @@ int amdgpu_bo_list_get(struct amdgpu_fpr }rcu_read_unlock (); + *result =NULL ;return -ENOENT ; }
Greg Kroah-Hartman
maintainerPATCH 523/530 drm/amdgpu: lower CS errors to debug severity
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian König <[email protected]>
commit 17daf01ab4e3e5a5929747aa05cc15eb2bad5438 upstream.
Otherwise userspace can spam the logs by using incorrect input values.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +1 -1
@@ -1411,7 +1411,7 @@ int amdgpu_cs_ioctl(struct drm_device *dif (r == -ENOMEM )DRM_ERROR ("Not enough memory for command submission!\n" );else if (r != -ERESTARTSYS && r != -EAGAIN ) -DRM_ERROR ("Failed to process the buffer list %d!\n" , r); +DRM_DEBUG ("Failed to process the buffer list %d!\n" , r); goto error_fini; }
Greg Kroah-Hartman
maintainerPATCH 524/530 drm/amdgpu: Fix possible null pointer dereference
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Kuehling <[email protected]>
commit 256503071c2de2b5b5c20e06654aa9a44f13aa62 upstream.
mem = bo->tbo.resource may be NULL in amdgpu_vm_bo_update.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +2 -2
@@ -1095,8 +1095,8 @@ int amdgpu_vm_bo_update(struct amdgpu_de bo =gem_to_amdgpu_bo (gobj); } mem = bo->tbo.resource; -if (mem->mem_type ==TTM_PL_TT || - mem->mem_type ==AMDGPU_PL_PREEMPT ) +if (mem && (mem->mem_type ==TTM_PL_TT || + mem->mem_type ==AMDGPU_PL_PREEMPT )) pages_addr = bo->tbo.ttm->dma_address; }
Greg Kroah-Hartman
maintainerPATCH 525/530 drm/amd/display: Guard against invalid RPTR/WPTR being set
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Kazlauskas <[email protected]>
commit 1ffa8602e39b89469dc703ebab7a7e44c33da0f7 upstream.
[WHY]
HW can return invalid values on register read, guard against these being set and causing us to access memory out of range and page fault.
[HOW]
Guard at sync_inbox1 and guard at pushing commands.
--- drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +15 -3
@@ -658,9 +658,16 @@ enum dmub_status dmub_srv_sync_inbox1(streturn DMUB_STATUS_INVALID ;if (dmub->hw_funcs.get_inbox1_rptr && dmub->hw_funcs.get_inbox1_wptr) { - dmub->inbox1_rb.rptr = dmub->hw_funcs.get_inbox1_rptr (dmub); - dmub->inbox1_rb.wrpt = dmub->hw_funcs.get_inbox1_wptr (dmub); - dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt; +uint32_t rptr = dmub->hw_funcs.get_inbox1_rptr (dmub); +uint32_t wptr = dmub->hw_funcs.get_inbox1_wptr (dmub); + +if (rptr > dmub->inbox1_rb.capacity || wptr > dmub->inbox1_rb.capacity) { +return DMUB_STATUS_HW_FAILURE ; + }else { + dmub->inbox1_rb.rptr = rptr; + dmub->inbox1_rb.wrpt = wptr; + dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt; + } }return DMUB_STATUS_OK ;
@@ -694,6 +701,11 @@ enum dmub_status dmub_srv_cmd_queue(struif (!dmub->hw_init)return DMUB_STATUS_INVALID ; +if (dmub->inbox1_rb.rptr > dmub->inbox1_rb.capacity || + dmub->inbox1_rb.wrpt > dmub->inbox1_rb.capacity) { +return DMUB_STATUS_HW_FAILURE ; + } +if (dmub_rb_push_front (&dmub->inbox1_rb, cmd))return DMUB_STATUS_OK ;
Greg Kroah-Hartman
maintainerPATCH 526/530 drm/amd/display: Fix DSC not Enabled on Direct MST Sink
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangzhi Zuo <[email protected]>
commit a58555359a9f870543aaddef277c3396159895ce upstream.
[WHY & HOW]
For the scenario when a dsc capable MST sink device is directly connected, it needs to use max dsc compression as the link bw constraint.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 29 +++++------- 1 file changed, 14 insertions(+), 15 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +14 -15
@@ -1598,31 +1598,31 @@ enum dc_status dm_dp_mst_is_port_supportunsigned int upper_link_bw_in_kbps =0 , down_link_bw_in_kbps =0 ;unsigned int max_compressed_bw_in_kbps =0 ;struct dc_dsc_bw_range bw_range = {0 }; -struct drm_dp_mst_topology_mgr *mst_mgr; +uint16_t full_pbn = aconnector->mst_output_port->full_pbn;/* -* check if the mode could be supported if DSC pass-through is supported -* AND check if there enough bandwidth available to support the mode -* with DSC enabled. +* Consider the case with the depth of the mst topology tree is equal or less than 2 +* A. When dsc bitstream can be transmitted along the entire path +* 1. dsc is possible between source and branch/leaf device (common dsc params is possible), AND +* 2. dsc passthrough supported at MST branch, or +* 3. dsc decoding supported at leaf MST device +* Use maximum dsc compression as bw constraint +* B. When dsc bitstream cannot be transmitted along the entire path +* Use native bw as bw constraint */ if (is_dsc_common_config_possible (stream, &bw_range) && - aconnector->mst_output_port->passthrough_aux) { - mst_mgr = aconnector->mst_output_port->mgr; -mutex_lock (&mst_mgr->lock); - + (aconnector->mst_output_port->passthrough_aux || + aconnector->dsc_aux == &aconnector->mst_output_port->aux)) { cur_link_settings = stream->link->verified_link_cap; upper_link_bw_in_kbps =dc_link_bandwidth_kbps (aconnector->dc_link, - &cur_link_settings - ); - down_link_bw_in_kbps =kbps_from_pbn (aconnector->mst_output_port->full_pbn); + &cur_link_settings); + down_link_bw_in_kbps =kbps_from_pbn (full_pbn);/* pick the bottleneck */ end_to_end_bw_in_kbps =min (upper_link_bw_in_kbps, down_link_bw_in_kbps); -mutex_unlock (&mst_mgr->lock); -/* * use the maximum dsc compression bandwidth as the required * bandwidth for the mode
@@ -1637,8 +1637,7 @@ enum dc_status dm_dp_mst_is_port_support/* check if mode could be supported within full_pbn */ bpp =convert_dc_color_depth_into_bpc (stream->timing.display_color_depth) *3 ; pbn =drm_dp_calc_pbn_mode (stream->timing.pix_clk_100hz /10 , bpp, false); - -if (pbn > aconnector->mst_output_port->full_pbn) +if (pbn > full_pbn)return DC_FAIL_BANDWIDTH_VALIDATE ; }
Greg Kroah-Hartman
maintainerPATCH 527/530 drm/amd/display: fix a NULL pointer dereference in amdgpu_dm_i2c_xfer()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit b71f4ade1b8900d30c661d6c27f87c35214c398c upstream.
When ddc_service_construct() is called, it explicitly checks both the link type and whether there is something on the link which will dictate whether the pin is marked as hw_supported.
If the pin isn't set or the link is not set (such as from unloading/reloading amdgpu in an IGT test) then fail the amdgpu_dm_i2c_xfer() call.
--- 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
@@ -7430,6 +7430,9 @@ static int amdgpu_dm_i2c_xfer(struct i2cint i;int result = -EIO ; +if (!ddc_service->ddc_pin || !ddc_service->ddc_pin->hw_info.hw_supported) +return result; + cmd.payloads =kcalloc (num,sizeof (struct i2c_payload ),GFP_KERNEL );if (!cmd.payloads)
Greg Kroah-Hartman
maintainerPATCH 528/530 drm/amd/display: Enable fast plane updates on DCN3.2 and above
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianci Yin <[email protected]>
commit 435f5b369657cffee4b04db1f5805b48599f4dbe upstream.
[WHY]
When cursor moves across screen boarder, lag cursor observed, since subvp settings need to sync up with vblank that causes cursor updates being delayed.
[HOW]
Enable fast plane updates on DCN3.2 to fix it.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +4 -4
@@ -9541,14 +9541,14 @@ static bool should_reset_plane(struct drstruct drm_plane *other;struct drm_plane_state *old_other_state, *new_other_state;struct drm_crtc_state *new_crtc_state; +struct amdgpu_device *adev =drm_to_adev (plane->dev);int i;/* -* TODO: Remove this hack once the checks below are sufficient -* enough to determine when we need to reset all the planes on -* the stream. +* TODO: Remove this hack for all asics once it proves that the +* fast updates works fine on DCN3.2+. */ -if (state->allow_modeset) +if (adev->ip_versions[DCE_HWIP ][0 ] <IP_VERSION (3 ,2 ,0 ) && state->allow_modeset)return true;/* Exit early if we know that we're adding or removing the plane. */
Greg Kroah-Hartman
maintainerPATCH 529/530 drm/amd/display: Clear dpcd_sink_ext_caps if not set
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Hsieh <[email protected]>
commit 923bbfe6c888812db1088d684bd30c24036226d2 upstream.
[WHY]
Some eDP panels' ext caps don't set initial values and the value of dpcd_addr (0x317) is random.
It means that sometimes the eDP can be OLED, miniLED and etc, and cause incorrect backlight control interface.
[HOW]
Add remove_sink_ext_caps to remove sink ext caps (HDR, OLED and etc)
--- drivers/gpu/drm/amd/display/dc/dc_types.h | 1 + drivers/gpu/drm/amd/display/dc/link/link_detection.c | 3 +++ 2 files changed, 4 insertions(+)
drivers/gpu/drm/amd/display/dc/dc_types.h +1 -0
@@ -189,6 +189,7 @@ struct dc_panel_patch {unsigned int disable_fams;unsigned int skip_avmute;unsigned int mst_start_top_delay; +unsigned int remove_sink_ext_caps; };struct dc_edid_caps {
drivers/gpu/drm/amd/display/dc/link/link_detection.c +3 -0
@@ -1085,6 +1085,9 @@ static bool detect_link_and_local_sink(sif (sink->edid_caps.panel_patch.skip_scdc_overwrite) link->ctx->dc->debug.hdmi20_disable = true; +if (sink->edid_caps.panel_patch.remove_sink_ext_caps) + link->dpcd_sink_ext_caps.raw =0 ; +if (dc_is_hdmi_signal (link->connector_signal))read_scdc_caps (link->ddc, link->local_sink);
Greg Kroah-Hartman
maintainerPATCH 530/530 drm/amd/display: Change the DMCUB mailbox memory location from FB to inbox
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lewis Huang <[email protected]>
commit 5911d02cac70d7fb52009fbd37423e63f8f6f9bc upstream.
[WHY]
Flush command sent to DMCUB spends more time for execution on a dGPU than on an APU. This causes cursor lag when using high refresh rate mouses.
[HOW]
1. Change the DMCUB mailbox memory location from FB to inbox.
2. Only change windows memory to inbox.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 ++++---- drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 22 +++++++++------ drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 32 ++++++++++++++++------ 3 files changed, 45 insertions(+), 22 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +7 -6
@@ -2084,7 +2084,7 @@ static int dm_dmub_sw_init(struct amdgpustruct dmub_srv_create_params create_params;struct dmub_srv_region_params region_params;struct dmub_srv_region_info region_info; -struct dmub_srv_fb_params fb_params; +struct dmub_srv_memory_params memory_params;struct dmub_srv_fb_info *fb_info;struct dmub_srv *dmub_srv;const struct dmcub_firmware_header_v1_0 *hdr;
@@ -2184,6 +2184,7 @@ static int dm_dmub_sw_init(struct amdgpu adev->dm.dmub_fw->data +le32_to_cpu (hdr->header.ucode_array_offset_bytes) +PSP_HEADER_BYTES ; + region_params.is_mailbox_in_inbox = false; status =dmub_srv_calc_region_info (dmub_srv, ®ion_params, ®ion_info);
@@ -2207,10 +2208,10 @@ static int dm_dmub_sw_init(struct amdgpureturn r;/* Rebase the regions on the framebuffer address. */ -memset (&fb_params,0 ,sizeof (fb_params)); - fb_params.cpu_addr = adev->dm.dmub_bo_cpu_addr; - fb_params.gpu_addr = adev->dm.dmub_bo_gpu_addr; - fb_params.region_info = ®ion_info; +memset (&memory_params,0 ,sizeof (memory_params)); + memory_params.cpu_fb_addr = adev->dm.dmub_bo_cpu_addr; + memory_params.gpu_fb_addr = adev->dm.dmub_bo_gpu_addr; + memory_params.region_info = ®ion_info; adev->dm.dmub_fb_info =kzalloc (sizeof (*adev->dm.dmub_fb_info),GFP_KERNEL );
@@ -2222,7 +2223,7 @@ static int dm_dmub_sw_init(struct amdgpureturn -ENOMEM ; } - status =dmub_srv_calc_fb_info (dmub_srv, &fb_params, fb_info); + status =dmub_srv_calc_mem_info (dmub_srv, &memory_params, fb_info);if (status !=DMUB_STATUS_OK ) {DRM_ERROR ("Error calculating DMUB FB info: %d\n" , status);return -EINVAL ;
drivers/gpu/drm/amd/display/dmub/dmub_srv.h +14 -8
@@ -186,6 +186,7 @@ struct dmub_srv_region_params {uint32_t vbios_size;const uint8_t *fw_inst_const;const uint8_t *fw_bss_data; +bool is_mailbox_in_inbox; };/**
@@ -205,20 +206,25 @@ struct dmub_srv_region_params {*/ struct dmub_srv_region_info {uint32_t fb_size; +uint32_t inbox_size;uint8_t num_regions;struct dmub_region regions[DMUB_WINDOW_TOTAL ]; };/** -* struct dmub_srv_fb_params - parameters used for driver fb setup +* struct dmub_srv_memory_params - parameters used for driver fb setup * @region_info: region info calculated by dmub service -* @cpu_addr: base cpu address for the framebuffer -* @gpu_addr: base gpu virtual address for the framebuffer +* @cpu_fb_addr: base cpu address for the framebuffer +* @cpu_inbox_addr: base cpu address for the gart +* @gpu_fb_addr: base gpu virtual address for the framebuffer +* @gpu_inbox_addr: base gpu virtual address for the gart */ -struct dmub_srv_fb_params { +struct dmub_srv_memory_params {const struct dmub_srv_region_info *region_info; -void *cpu_addr; -uint64_t gpu_addr; +void *cpu_fb_addr; +void *cpu_inbox_addr; +uint64_t gpu_fb_addr; +uint64_t gpu_inbox_addr; };/**
@@ -546,8 +552,8 @@ dmub_srv_calc_region_info(struct dmub_sr* DMUB_STATUS_OK - success * DMUB_STATUS_INVALID - unspecified error */ -enum dmub_status dmub_srv_calc_fb_info (struct dmub_srv *dmub, -const struct dmub_srv_fb_params *params, +enum dmub_status dmub_srv_calc_mem_info (struct dmub_srv *dmub, +const struct dmub_srv_memory_params *params,struct dmub_srv_fb_info *out);/**
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +24 -8
@@ -386,7 +386,7 @@ dmub_srv_calc_region_info(struct dmub_sruint32_t fw_state_size =DMUB_FW_STATE_SIZE ;uint32_t trace_buffer_size =DMUB_TRACE_BUFFER_SIZE ;uint32_t scratch_mem_size =DMUB_SCRATCH_MEM_SIZE ; - +uint32_t previous_top =0 ;if (!dmub->sw_init)return DMUB_STATUS_INVALID ;
@@ -411,8 +411,15 @@ dmub_srv_calc_region_info(struct dmub_sr bios->base =dmub_align (stack->top,256 ); bios->top = bios->base + params->vbios_size; - mail->base =dmub_align (bios->top,256 ); - mail->top = mail->base +DMUB_MAILBOX_SIZE ; +if (params->is_mailbox_in_inbox) { + mail->base =0 ; + mail->top = mail->base +DMUB_MAILBOX_SIZE ; + previous_top = bios->top; + }else { + mail->base =dmub_align (bios->top,256 ); + mail->top = mail->base +DMUB_MAILBOX_SIZE ; + previous_top = mail->top; + } fw_info =dmub_get_fw_meta_info (params);
@@ -431,7 +438,7 @@ dmub_srv_calc_region_info(struct dmub_sr dmub->fw_version = fw_info->fw_version; } - trace_buff->base =dmub_align (mail->top,256 ); + trace_buff->base =dmub_align (previous_top,256 ); trace_buff->top = trace_buff->base +dmub_align (trace_buffer_size,64 ); fw_state->base =dmub_align (trace_buff->top,256 );
@@ -442,11 +449,14 @@ dmub_srv_calc_region_info(struct dmub_sr out->fb_size =dmub_align (scratch_mem->top,4096 ); +if (params->is_mailbox_in_inbox) + out->inbox_size =dmub_align (mail->top,4096 ); +return DMUB_STATUS_OK ; } -enum dmub_status dmub_srv_calc_fb_info (struct dmub_srv *dmub, -const struct dmub_srv_fb_params *params, +enum dmub_status dmub_srv_calc_mem_info (struct dmub_srv *dmub, +const struct dmub_srv_memory_params *params,struct dmub_srv_fb_info *out) {uint8_t *cpu_base;
@@ -461,8 +471,8 @@ enum dmub_status dmub_srv_calc_fb_info(sif (params->region_info->num_regions !=DMUB_NUM_WINDOWS )return DMUB_STATUS_INVALID ; - cpu_base = (uint8_t *)params->cpu_addr; - gpu_base = params->gpu_addr; + cpu_base = (uint8_t *)params->cpu_fb_addr; + gpu_base = params->gpu_fb_addr;for (i =0 ; i <DMUB_NUM_WINDOWS ; ++i) { const struct dmub_region *reg =
@@ -470,6 +480,12 @@ enum dmub_status dmub_srv_calc_fb_info(s out->fb[i].cpu_addr = cpu_base + reg->base; out->fb[i].gpu_addr = gpu_base + reg->base; + +if (i ==DMUB_WINDOW_4_MAILBOX && params->cpu_inbox_addr !=0 ) { + out->fb[i].cpu_addr = (uint8_t *)params->cpu_inbox_addr + reg->base; + out->fb[i].gpu_addr = params->gpu_inbox_addr + reg->base; + } + out->fb[i].size = reg->top - reg->base; }
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.3 release. There are 530 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 26 Nov 2023 17:19:17 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.
Quoted 8 lines
thanks,
greg k-h
Zhen Lei <[email protected]>
rcu: Dump memory object info if callback function is invalid
Following build warnings / errors noticed while building the arm64 tinyconfig on stable-rc linux-6.6.y.
kernel/rcu/update.c:49:kernel/rcu/rcu.h: In function 'debug_rcu_head_callback':kernel/rcu/rcu.h:255:17: error: implicit declaration of function 'kmem_dump_obj'; did you mean 'mem_dump_obj'? [-Werror=implicit-function-declaration]
255 | kmem_dump_obj(rhp);
| ^~~~~~~~~~~~~
| mem_dump_objcc1: some warnings being treated as errors
rcu: Dump memory object info if callback function is invalid [ Upstream commit 2cbc482d325ee58001472c4359b311958c4efdd1 ]
Steps to reproduce:
$ tuxmake --runtime podman --target-arch arm64 --toolchain gcc-11 --kconfig tinyconfig config debugkernel dtbs kernel modules xipkernel
Links:
- https://storage.tuxsuite.com/public/linaro/lkft/builds/2YdN5Tb5NAFPo7H9WWQd0APrWu1/
--
Linaro LKFT
https://lkft.linaro.org
Greg Kroah-Hartman
maintainerQuoted 45 lines · Naresh Kamboju
Quoted 15 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.3 release. There are 530 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 26 Nov 2023 17:19:17 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.Quoted 8 lines
thanks,
greg k-h
Zhen Lei <[email protected]>
rcu: Dump memory object info if callback function is invalidFollowing build warnings / errors noticed while building the arm64 tinyconfig on stable-rc linux-6.6.y.
kernel/rcu/update.c:49:kernel/rcu/rcu.h: In function 'debug_rcu_head_callback':kernel/rcu/rcu.h:255:17: error: implicit declaration of function 'kmem_dump_obj'; did you mean 'mem_dump_obj'? [-Werror=implicit-function-declaration]255 | kmem_dump_obj(rhp); | ^~~~~~~~~~~~~ | mem_dump_objcc1: some warnings being treated as errors
rcu: Dump memory object info if callback function is invalid [ Upstream commit
2cbc482d325ee58001472c4359b311958c4efdd1]
Quoted 8 lines
Steps to reproduce:
$ tuxmake --runtime podman --target-arch arm64 --toolchain gcc-11 --kconfig tinyconfig config debugkernel dtbs kernel modules xipkernelLinks:
- https://storage.tuxsuite.com/public/linaro/lkft/builds/2YdN5Tb5NAFPo7H9WWQd0APrWu1/
Should now be fixed, I'll push out a -rc2 soon to verify.
thanks,
greg k-h
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.3 release. There are 530 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 26 Nov 2023 17:19:17 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
Noticed no problem on my Starfive Visionfive 2 board (RISCV):
Best regards,
Nam
Hi Greg
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.3 release. There are 530 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 26 Nov 2023 17:19:17 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
6.6.3-rc1 tested.
Build successfully completed.
Boot successfully completed.
No dmesg regressions.
Video output normal.
Sound output normal.
Lenovo ThinkPad X1 Carbon Gen10(Intel i7-1260P(x86_64) arch linux)
Thanks
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.3 release. There are 530 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun, 26 Nov 2023 17:19:17 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.3-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 6.6.3 release. There are 530 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
We see build problems on arm64 and probably runtime problems on arm:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/pipelines/1084460663
Best regards,
Pavel
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Erika Unter HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Quoted 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.3 release. There are 530 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Successfully compiled and installed bindeb-pkgs on my computer (Acer Aspire E15, Intel Core i3 Haswell). No noticeable regressions.
Signature · 1 line
An old man doll... just what I always wanted! - Clara