6.1.113-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 538/798 ALSA: line6: add hw monitor volume control to POD HD500X
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans P. Moller <[email protected]>
commit 703235a244e533652346844cfa42623afb36eed1 upstream.
Add hw monitor volume control for POD HD500X. This is done adding LINE6_CAP_HWMON_CTL to the capabilities
--- sound/usb/line6/podhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/line6/podhd.c +1 -1
@@ -507,7 +507,7 @@ static const struct line6_properties pod [LINE6_PODHD500X] = { .id = "PODHD500X", .name = "POD HD500X", - .capabilities =LINE6_CAP_CONTROL + .capabilities =LINE6_CAP_CONTROL |LINE6_CAP_HWMON_CTL | LINE6_CAP_PCM | LINE6_CAP_HWMON, .altsetting = 1, .ep_ctrl_r = 0x81,
Greg Kroah-Hartman
maintainerPATCH 539/798 ALSA: hda/realtek: Add quirk for Huawei MateBook 13 KLV-WX9
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ai Chao <[email protected]>
commit dee476950cbd83125655a3f49e00d63b79f6114e upstream.
The headset mic requires a fixup to be properly detected/used.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -10175,6 +10175,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1849 ,0xa233 ,"Positivo Master C6300" ,ALC269_FIXUP_HEADSET_MIC ),SND_PCI_QUIRK (0x19e5 ,0x3204 ,"Huawei MACH-WX9" ,ALC256_FIXUP_HUAWEI_MACH_WX9_PINS ),SND_PCI_QUIRK (0x19e5 ,0x320f ,"Huawei WRT-WX9 " ,ALC256_FIXUP_ASUS_MIC_NO_PRESENCE ), +SND_PCI_QUIRK (0x19e5 ,0x3212 ,"Huawei KLV-WX9 " ,ALC256_FIXUP_ACER_HEADSET_MIC ),SND_PCI_QUIRK (0x1b35 ,0x1235 ,"CZC B20" ,ALC269_FIXUP_CZC_B20 ),SND_PCI_QUIRK (0x1b35 ,0x1236 ,"CZC TMI" ,ALC269_FIXUP_CZC_TMI ), SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101),
Greg Kroah-Hartman
maintainerPATCH 540/798 ALSA: hda/realtek: Add a quirk for HP Pavilion 15z-ec200
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abhishek Tamboli <[email protected]>
commit d75dba49744478c32f6ce1c16b5f391c2d5cef5f upstream.
Add the quirk for HP Pavilion Gaming laptop 15z-ec200 for enabling the mute led. The fix apply the ALC285_FIXUP_HP_MUTE_LED quirk for this model.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9767,6 +9767,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x8896 ,"HP EliteBook 855 G8 Notebook PC" ,ALC285_FIXUP_HP_MUTE_LED ),SND_PCI_QUIRK (0x103c ,0x8898 ,"HP EliteBook 845 G8 Notebook PC" ,ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST ),SND_PCI_QUIRK (0x103c ,0x88d0 ,"HP Pavilion 15-eh1xxx (mainboard 88D0)" ,ALC287_FIXUP_HP_GPIO_LED ), +SND_PCI_QUIRK (0x103c ,0x88dd ,"HP Pavilion 15z-ec200" ,ALC285_FIXUP_HP_MUTE_LED ),SND_PCI_QUIRK (0x103c ,0x8902 ,"HP OMEN 16" ,ALC285_FIXUP_HP_MUTE_LED ),SND_PCI_QUIRK (0x103c ,0x890e ,"HP 255 G8 Notebook PC" ,ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 ), SND_PCI_QUIRK(0x103c, 0x8919, "HP Pavilion Aero Laptop 13-be0xxx", ALC287_FIXUP_HP_GPIO_LED),
Greg Kroah-Hartman
maintainerPATCH 541/798 ext4: no need to continue when the number of entries is 1
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
commit 1a00a393d6a7fb1e745a41edd09019bd6a0ad64c upstream.
--- fs/ext4/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/namei.c +1 -1
@@ -2047,7 +2047,7 @@ static struct ext4_dir_entry_2 *do_split split = count/2 ; hash2 = map[split].hash; - continued = hash2 == map[split -1 ].hash; + continued = split >0 ? hash2 == map[split -1 ].hash :0 ;dxtrace (printk (KERN_INFO "Split block %lu at %x, %i/%i\n" , (unsigned long )dx_get_block (frame->at), hash2, split, count-split));
Greg Kroah-Hartman
maintainerPATCH 542/798 ext4: correct encrypted dentry name hash when not casefolded
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: yao.ly <[email protected]>
commit 70dd7b573afeba9b8f8a33f2ae1e4a9a2ec8c1ec upstream.
EXT4_DIRENT_HASH and EXT4_DIRENT_MINOR_HASH will access struct ext4_dir_entry_hash followed ext4_dir_entry. But there is no ext4_dir_entry_hash followed when inode is encrypted and not casefolded
--- fs/ext4/dir.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
fs/ext4/dir.c +11 -3
@@ -279,12 +279,20 @@ static int ext4_readdir(struct file *filstruct fscrypt_str de_name =FSTR_INIT (de->name, de->name_len); +u32 hash; +u32 minor_hash; + +if (IS_CASEFOLDED (inode)) { + hash =EXT4_DIRENT_HASH (de); + minor_hash =EXT4_DIRENT_MINOR_HASH (de); + }else { + hash =0 ; + minor_hash =0 ; + }/* Directory is encrypted */ err =fscrypt_fname_disk_to_usr (inode, -EXT4_DIRENT_HASH (de), -EXT4_DIRENT_MINOR_HASH (de), - &de_name, &fstr); + hash, minor_hash, &de_name, &fstr); de_name = fstr; fstr.len = save_len;if (err)
Greg Kroah-Hartman
maintainerPATCH 543/798 ext4: fix slab-use-after-free in ext4_split_extent_at()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit c26ab35702f8cd0cdc78f96aa5856bfb77be798f upstream.
We hit the following use-after-free:
==================================================================
BUG: KASAN: slab-use-after-free in ext4_split_extent_at+0xba8/0xcc0 Read of size 2 at addr ffff88810548ed08 by task kworker/u20:0/40 CPU: 0 PID: 40 Comm: kworker/u20:0 Not tainted 6.9.0-dirty #724 Call Trace: <TASK> kasan_report+0x93/0xc0 ext4_split_extent_at+0xba8/0xcc0 ext4_split_extent.isra.0+0x18f/0x500 ext4_split_convert_extents+0x275/0x750 ext4_ext_handle_unwritten_extents+0x73e/0x1580 ext4_ext_map_blocks+0xe20/0x2dc0 ext4_map_blocks+0x724/0x1700 ext4_do_writepages+0x12d6/0x2a70
[...]
Allocated by task 40: __kmalloc_noprof+0x1ac/0x480 ext4_find_extent+0xf3b/0x1e70 ext4_ext_map_blocks+0x188/0x2dc0 ext4_map_blocks+0x724/0x1700 ext4_do_writepages+0x12d6/0x2a70
[...]
Freed by task 40: kfree+0xf1/0x2b0 ext4_find_extent+0xa71/0x1e70 ext4_ext_insert_extent+0xa22/0x3260 ext4_split_extent_at+0x3ef/0xcc0 ext4_split_extent.isra.0+0x18f/0x500 ext4_split_convert_extents+0x275/0x750 ext4_ext_handle_unwritten_extents+0x73e/0x1580 ext4_ext_map_blocks+0xe20/0x2dc0 ext4_map_blocks+0x724/0x1700 ext4_do_writepages+0x12d6/0x2a70
[...]
==================================================================
The flow of issue triggering is as follows:
ext4_split_extent_at
path = *ppath ext4_ext_insert_extent(ppath)
ext4_ext_create_new_leaf(ppath)
ext4_find_extent(orig_path)
path = *orig_path read_extent_tree_block
// return -ENOMEM or -EIO
ext4_free_ext_path(path)
kfree(path)
*orig_path = NULL
a. If err is -ENOMEM:
ext4_ext_dirty(path + path->p_depth)
// path use-after-free !!!
b. If err is -EIO and we have EXT_DEBUG defined:
ext4_ext_show_leaf(path)
eh = path[depth].p_hdr
// path also use-after-free !!!
So when trying to zeroout or fix the extent length, call ext4_find_extent() to update the path.
In addition we use *ppath directly as an ext4_ext_show_leaf() input to avoid possible use-after-free when EXT_DEBUG is defined, and to avoid unnecessary path updates.
--- fs/ext4/extents.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-)
fs/ext4/extents.c +20 -1
@@ -3232,6 +3232,25 @@ static int ext4_split_extent_at(handle_tif (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM ) goto out; +/* +* Update path is required because previous ext4_ext_insert_extent() +* may have freed or reallocated the path. Using EXT4_EX_NOFAIL +* guarantees that ext4_find_extent() will not return -ENOMEM, +* otherwise -ENOMEM will cause a retry in do_writepages(), and a +* WARN_ON may be triggered in ext4_da_update_reserve_space() due to +* an incorrect ee_len causing the i_reserved_data_blocks exception. +*/ + path =ext4_find_extent (inode, ee_block, ppath, + flags |EXT4_EX_NOFAIL ); +if (IS_ERR (path)) { +EXT4_ERROR_INODE (inode,"Failed split extent on %u, err %ld" , + split,PTR_ERR (path)); +return PTR_ERR (path); + } + depth =ext_depth (inode); + ex = path[depth].p_ext; + *ppath = path; +if (EXT4_EXT_MAY_ZEROOUT & split_flag) {if (split_flag & (EXT4_EXT_DATA_VALID1 |EXT4_EXT_DATA_VALID2 )) {if (split_flag &EXT4_EXT_DATA_VALID1 ) {
@@ -3284,7 +3303,7 @@ fix_extent_len:ext4_ext_dirty (handle, inode, path + path->p_depth);return err; out: -ext4_ext_show_leaf (inode, path); +ext4_ext_show_leaf (inode, *ppath);return err; }
Greg Kroah-Hartman
maintainerPATCH 544/798 ext4: propagate errors from ext4_find_extent() in ext4_insert_range()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 369c944ed1d7c3fb7b35f24e4735761153afe7b3 upstream.
Even though ext4_find_extent() returns an error, ext4_insert_range() still returns 0. This may confuse the user as to why fallocate returns success, but the contents of the file are not as expected. So propagate the error returned by ext4_find_extent() to avoid inconsistencies.
--- fs/ext4/extents.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/extents.c +1 -0
@@ -5570,6 +5570,7 @@ static int ext4_insert_range(struct file path =ext4_find_extent (inode, offset_lblk,NULL ,0 );if (IS_ERR (path)) {up_write (&EXT4_I (inode)->i_data_sem); + ret =PTR_ERR (path); goto out_stop; }
Greg Kroah-Hartman
maintainerPATCH 545/798 ext4: fix incorrect tid assumption in ext4_fc_mark_ineligible()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit ebc4b2c1ac92fc0f8bf3f5a9c285a871d5084a6b upstream.
Function jbd2_journal_shrink_checkpoint_list() assumes that '0' is not a valid value for transaction IDs, which is incorrect.
Furthermore, the sbi->s_fc_ineligible_tid handling also makes the same assumption by being initialised to '0'. Fortunately, the sb flag EXT4_MF_FC_INELIGIBLE can be used to check whether sbi->s_fc_ineligible_tid has been previously set instead of comparing it with '0'.
--- fs/ext4/fast_commit.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
fs/ext4/fast_commit.c +11 -4
@@ -339,22 +339,29 @@ void ext4_fc_mark_ineligible(struct supe {struct ext4_sb_info *sbi =EXT4_SB (sb);tid_t tid; +bool has_transaction = true; +bool is_ineligible;if (ext4_fc_disabled (sb))return ; -ext4_set_mount_flag (sb,EXT4_MF_FC_INELIGIBLE );if (handle && !IS_ERR (handle)) tid = handle->h_transaction->t_tid;else {read_lock (&sbi->s_journal->j_state_lock); - tid = sbi->s_journal->j_running_transaction ? - sbi->s_journal->j_running_transaction->t_tid :0 ; +if (sbi->s_journal->j_running_transaction) + tid = sbi->s_journal->j_running_transaction->t_tid; +else + has_transaction = false;read_unlock (&sbi->s_journal->j_state_lock); }spin_lock (&sbi->s_fc_lock); -if (tid_gt (tid, sbi->s_fc_ineligible_tid)) + is_ineligible =ext4_test_mount_flag (sb,EXT4_MF_FC_INELIGIBLE ); +if (has_transaction && + (!is_ineligible || + (is_ineligible &&tid_gt (tid, sbi->s_fc_ineligible_tid)))) sbi->s_fc_ineligible_tid = tid; +ext4_set_mount_flag (sb,EXT4_MF_FC_INELIGIBLE );spin_unlock (&sbi->s_fc_lock);WARN_ON (reason >=EXT4_FC_REASON_MAX ); sbi->s_fc_stats.fc_ineligible_reason_count[reason]++;
Greg Kroah-Hartman
maintainerPATCH 546/798 ext4: dax: fix overflowing extents beyond inode size when partially writing
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhihao Cheng <[email protected]>
commit dda898d7ffe85931f9cca6d702a51f33717c501e upstream.
The dax_iomap_rw() does two things in each iteration: map written blocks and copy user data to blocks. If the process is killed by user(See signal handling in dax_iomap_iter()), the copied data will be returned and added on inode size, which means that the length of written extents may exceed the inode size, then fsck will fail. An example is given as:
dd if=/dev/urandom of=file bs=4M count=1
dax_iomap_rw
iomap_iter // round 1
ext4_iomap_begin
ext4_iomap_alloc // allocate 0~2M extents(written flag)
dax_iomap_iter // copy 2M data
iomap_iter // round 2
iomap_iter_advance
iter->pos += iter->processed // iter->pos = 2M
ext4_iomap_begin
ext4_iomap_alloc // allocate 2~4M extents(written flag)
dax_iomap_iter
fatal_signal_pending
done = iter->pos - iocb->ki_pos // done = 2M
ext4_handle_inode_extension
ext4_update_inode_size // inode size = 2M
fsck reports: Inode 13, i_size is 2097152, should be 4194304. Fix?
Fix the problem by truncating extents if the written length is smaller than expected.
--- fs/ext4/file.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/ext4/file.c +4 -4
@@ -324,10 +324,10 @@ static ssize_t ext4_handle_inode_extensi* 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) +static void ext4_inode_extension_cleanup (struct inode *inode,bool need_trunc) {lockdep_assert_held_write (&inode->i_rwsem); -if (count <0 ) { +if (need_trunc) {ext4_truncate_failed_write (inode);/* * If the truncate operation failed early, then the inode may
@@ -567,7 +567,7 @@ static ssize_t ext4_dio_write_iter(struc* writeback of delalloc blocks. */ WARN_ON_ONCE (ret == -EIOCBQUEUED ); -ext4_inode_extension_cleanup (inode, ret); +ext4_inode_extension_cleanup (inode, ret <0 ); } out:
@@ -651,7 +651,7 @@ ext4_dax_write_iter(struct kiocb *iocb,if (extend) { ret =ext4_handle_inode_extension (inode, offset, ret); -ext4_inode_extension_cleanup (inode, ret); +ext4_inode_extension_cleanup (inode, ret < (ssize_t )count); } out:inode_unlock (inode);
Greg Kroah-Hartman
maintainerPATCH 547/798 ext4: fix incorrect tid assumption in __jbd2_log_wait_for_space()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit 972090651ee15e51abfb2160e986fa050cfc7a40 upstream.
Function __jbd2_log_wait_for_space() assumes that '0' is not a valid value for transaction IDs, which is incorrect. Don't assume that and invoke jbd2_log_wait_commit() if the journal had a committing transaction instead.
--- fs/jbd2/checkpoint.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/jbd2/checkpoint.c +5 -2
@@ -91,9 +91,12 @@ __releases(&journal->j_state_lock)if (space_left < nblocks) {int chkpt = journal->j_checkpoint_transactions !=NULL ;tid_t tid =0 ; +bool has_transaction = false; -if (journal->j_committing_transaction) +if (journal->j_committing_transaction) { tid = journal->j_committing_transaction->t_tid; + has_transaction = true; + }spin_unlock (&journal->j_list_lock);write_unlock (&journal->j_state_lock);if (chkpt) {
@@ -101,7 +104,7 @@ __releases(&journal->j_state_lock) }else if (jbd2_cleanup_journal_tail (journal) ==0 ) {/* We were able to recover space; yay! */ ; - }else if (tid) { + }else if (has_transaction) {/* * jbd2_journal_commit_transaction() may want * to take the checkpoint_mutex if JBD2_FLUSHED
Greg Kroah-Hartman
maintainerPATCH 548/798 ext4: drop ppath from ext4_ext_replay_update_ex() to avoid double-free
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 5c0f4cc84d3a601c99bc5e6e6eb1cbda542cce95 upstream.
When calling ext4_force_split_extent_at() in ext4_ext_replay_update_ex(), the 'ppath' is updated but it is the 'path' that is freed, thus potentially triggering a double-free in the following process:
ext4_ext_replay_update_ex
ppath = path
ext4_force_split_extent_at(&ppath)
ext4_split_extent_at
ext4_ext_insert_extent
ext4_ext_create_new_leaf
ext4_ext_grow_indepth
ext4_find_extent
if (depth > path[0].p_maxdepth)
kfree(path) ---> path First freed
*orig_path = path = NULL ---> null ppathkfree(path) ---> path double-free !!!
So drop the unnecessary ppath and use path directly to avoid this problem. And use ext4_find_extent() directly to update path, avoiding unnecessary memory allocation and freeing. Also, propagate the error returned by ext4_find_extent() instead of using strange error codes.
--- fs/ext4/extents.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-)
fs/ext4/extents.c +10 -11
@@ -5926,7 +5926,7 @@ out:int ext4_ext_replay_update_ex (struct inode *inode,ext4_lblk_t start,int len,int unwritten,ext4_fsblk_t pblk) { -struct ext4_ext_path *path =NULL , *ppath; +struct ext4_ext_path *path;struct ext4_extent *ex;int ret;
@@ -5942,30 +5942,29 @@ int ext4_ext_replay_update_ex(struct inoif (le32_to_cpu (ex->ee_block) != start ||ext4_ext_get_actual_len (ex) != len) {/* We need to split this extent to match our extent first */ - ppath = path;down_write (&EXT4_I (inode)->i_data_sem); - ret =ext4_force_split_extent_at (NULL , inode, &ppath, start,1 ); + ret =ext4_force_split_extent_at (NULL , inode, &path, start,1 );up_write (&EXT4_I (inode)->i_data_sem);if (ret) goto out; -kfree (path); - path =ext4_find_extent (inode, start,NULL ,0 ); + + path =ext4_find_extent (inode, start, &path,0 );if (IS_ERR (path)) -return -1 ; - ppath = path; +return PTR_ERR (path); ex = path[path->p_depth].p_ext;WARN_ON (le32_to_cpu (ex->ee_block) != start); +if (ext4_ext_get_actual_len (ex) != len) {down_write (&EXT4_I (inode)->i_data_sem); - ret =ext4_force_split_extent_at (NULL , inode, &ppath, + ret =ext4_force_split_extent_at (NULL , inode, &path, start + len,1 );up_write (&EXT4_I (inode)->i_data_sem);if (ret) goto out; -kfree (path); - path =ext4_find_extent (inode, start,NULL ,0 ); + + path =ext4_find_extent (inode, start, &path,0 );if (IS_ERR (path)) -return -EINVAL ; +return PTR_ERR (path); ex = path[path->p_depth].p_ext; } }
Greg Kroah-Hartman
maintainerPATCH 549/798 ext4: aovid use-after-free in ext4_ext_insert_extent()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit a164f3a432aae62ca23d03e6d926b122ee5b860d upstream.
As Ojaswin mentioned in Link, in ext4_ext_insert_extent(), if the path is reallocated in ext4_ext_create_new_leaf(), we'll use the stale path and cause UAF. Below is a sample trace with dummy values:
ext4_ext_insert_extent
path = *ppath = 2000
ext4_ext_create_new_leaf(ppath)
ext4_find_extent(ppath)
path = *ppath = 2000
if (depth > path[0].p_maxdepth)
kfree(path = 2000);
*ppath = path = NULL;
path = kcalloc() = 3000
*ppath = 3000;
return path; /* here path is still 2000, UAF! */
eh = path[depth].p_hdr
==================================================================
BUG: KASAN: slab-use-after-free in ext4_ext_insert_extent+0x26d4/0x3330 Read of size 8 at addr ffff8881027bf7d0 by task kworker/u36:1/179 CPU: 3 UID: 0 PID: 179 Comm: kworker/u6:1 Not tainted 6.11.0-rc2-dirty #866 Call Trace: <TASK> ext4_ext_insert_extent+0x26d4/0x3330 ext4_ext_map_blocks+0xe22/0x2d40 ext4_map_blocks+0x71e/0x1700 ext4_do_writepages+0x1290/0x2800
[...]
Allocated by task 179: ext4_find_extent+0x81c/0x1f70 ext4_ext_map_blocks+0x146/0x2d40 ext4_map_blocks+0x71e/0x1700 ext4_do_writepages+0x1290/0x2800 ext4_writepages+0x26d/0x4e0 do_writepages+0x175/0x700
[...]
Freed by task 179: kfree+0xcb/0x240 ext4_find_extent+0x7c0/0x1f70 ext4_ext_insert_extent+0xa26/0x3330 ext4_ext_map_blocks+0xe22/0x2d40 ext4_map_blocks+0x71e/0x1700 ext4_do_writepages+0x1290/0x2800 ext4_writepages+0x26d/0x4e0 do_writepages+0x175/0x700
[...]
==================================================================
So use *ppath to update the path to avoid the above problem.
--- fs/ext4/extents.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/extents.c +1 -0
@@ -2103,6 +2103,7 @@ prepend: ppath, newext);if (err) goto cleanup; + path = *ppath; depth =ext_depth (inode); eh = path[depth].p_hdr;
Greg Kroah-Hartman
maintainerPATCH 550/798 ext4: fix double brelse() the buffer of the extents path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit dcaa6c31134c0f515600111c38ed7750003e1b9c upstream.
In ext4_ext_try_to_merge_up(), set path[1].p_bh to NULL after it has been released, otherwise it may be released twice. An example of what triggers this is as follows:
split2 map split1
|--------|-------|--------|
ext4_ext_map_blocks
ext4_ext_handle_unwritten_extents
ext4_split_convert_extents
// path->p_depth == 0
ext4_split_extent
// 1. do split1
ext4_split_extent_at
|ext4_ext_insert_extent
| ext4_ext_create_new_leaf
| ext4_ext_grow_indepth
| le16_add_cpu(&neh->eh_depth, 1)
| ext4_find_extent
| // return -ENOMEM
|// get error and try zeroout
|path = ext4_find_extent
| path->p_depth = 1
|ext4_ext_try_to_merge
| ext4_ext_try_to_merge_up
| path->p_depth = 0
| brelse(path[1].p_bh) ---> not set to NULL here
|// zeroout success
// 2. update path
ext4_find_extent
// 3. do split2
ext4_split_extent_at
ext4_ext_insert_extent
ext4_ext_create_new_leaf
ext4_ext_grow_indepth
le16_add_cpu(&neh->eh_depth, 1)
ext4_find_extent
path[0].p_bh = NULL;
path->p_depth = 1
read_extent_tree_block ---> return err
// path[1].p_bh is still the old value
ext4_free_ext_path
ext4_ext_drop_refs
// path->p_depth == 1
brelse(path[1].p_bh) ---> brelse a buffer twiceFinally got the following WARRNING when removing the buffer from lru:
============================================
VFS: brelse: Trying to free free buffer
WARNING: CPU: 2 PID: 72 at fs/buffer.c:1241 __brelse+0x58/0x90 CPU: 2 PID: 72 Comm: kworker/u19:1 Not tainted 6.9.0-dirty #716 RIP: 0010:__brelse+0x58/0x90 Call Trace: <TASK> __find_get_block+0x6e7/0x810 bdev_getblk+0x2b/0x480 __ext4_get_inode_loc+0x48a/0x1240 ext4_get_inode_loc+0xb2/0x150 ext4_reserve_inode_write+0xb7/0x230 __ext4_mark_inode_dirty+0x144/0x6a0 ext4_ext_insert_extent+0x9c8/0x3230 ext4_ext_map_blocks+0xf45/0x2dc0 ext4_map_blocks+0x724/0x1700 ext4_do_writepages+0x12d6/0x2a70
[...]
============================================
--- fs/ext4/extents.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/extents.c +1 -0
@@ -1877,6 +1877,7 @@ static void ext4_ext_try_to_merge_up(han path[0 ].p_hdr->eh_max =cpu_to_le16 (max_root);brelse (path[1 ].p_bh); + path[1 ].p_bh =NULL ;ext4_free_blocks (handle, inode,NULL , blk,1 ,EXT4_FREE_BLOCKS_METADATA |EXT4_FREE_BLOCKS_FORGET ); }
Greg Kroah-Hartman
maintainerPATCH 551/798 ext4: update orig_path in ext4_find_extent()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 5b4b2dcace35f618fe361a87bae6f0d13af31bc1 upstream.
In ext4_find_extent(), if the path is not big enough, we free it and set *orig_path to NULL. But after reallocating and successfully initializing the path, we don't update *orig_path, in which case the caller gets a valid path but a NULL ppath, and this may cause a NULL pointer dereference or a path memory leak. For example:
ext4_split_extent
path = *ppath = 2000
ext4_find_extent
if (depth > path[0].p_maxdepth)
kfree(path = 2000);
*orig_path = path = NULL;
path = kcalloc() = 3000
ext4_split_extent_at(*ppath = NULL)
path = *ppath;
ex = path[depth].p_ext;
// NULL pointer dereference!==================================================================
BUG: kernel NULL pointer dereference, address: 0000000000000010 CPU: 6 UID: 0 PID: 576 Comm: fsstress Not tainted 6.11.0-rc2-dirty #847 RIP: 0010:ext4_split_extent_at+0x6d/0x560 Call Trace: <TASK> ext4_split_extent.isra.0+0xcb/0x1b0 ext4_ext_convert_to_initialized+0x168/0x6c0 ext4_ext_handle_unwritten_extents+0x325/0x4d0 ext4_ext_map_blocks+0x520/0xdb0 ext4_map_blocks+0x2b0/0x690 ext4_iomap_begin+0x20e/0x2c0
[...]
==================================================================
Therefore, *orig_path is updated when the extent lookup succeeds, so that the caller can safely use path or *ppath.
--- fs/ext4/extents.c | 3 ++- fs/ext4/move_extent.c | 1 - 2 files changed, 2 insertions(+), 2 deletions(-)
fs/ext4/extents.c +2 -1
@@ -957,6 +957,8 @@ ext4_find_extent(struct inode *inode, exext4_ext_show_path (inode, path); +if (orig_path) + *orig_path = path;return path; err:
@@ -3251,7 +3253,6 @@ static int ext4_split_extent_at(handle_t } depth =ext_depth (inode); ex = path[depth].p_ext; - *ppath = path;if (EXT4_EXT_MAY_ZEROOUT & split_flag) {if (split_flag & (EXT4_EXT_DATA_VALID1 |EXT4_EXT_DATA_VALID2 )) {
fs/ext4/move_extent.c +0 -1
@@ -36,7 +36,6 @@ get_ext_path(struct inode *inode, ext4_l *ppath =NULL ;return -ENODATA ; } - *ppath = path;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 552/798 ext4: fix incorrect tid assumption in ext4_wait_for_tail_page_commit()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit dd589b0f1445e1ea1085b98edca6e4d5dedb98d0 upstream.
Function ext4_wait_for_tail_page_commit() assumes that '0' is not a valid value for transaction IDs, which is incorrect. Don't assume that and invoke jbd2_log_wait_commit() if the journal had a committing transaction instead.
--- fs/ext4/inode.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
fs/ext4/inode.c +7 -4
@@ -5350,8 +5350,9 @@ static void ext4_wait_for_tail_page_comm {unsigned offset;journal_t *journal =EXT4_SB (inode->i_sb)->s_journal; -tid_t commit_tid =0 ; +tid_t commit_tid;int ret; +bool has_transaction; offset = inode->i_size & (PAGE_SIZE -1 );/*
@@ -5376,12 +5377,14 @@ static void ext4_wait_for_tail_page_commfolio_put (folio);if (ret != -EBUSY )return ; - commit_tid =0 ; + has_transaction = false;read_lock (&journal->j_state_lock); -if (journal->j_committing_transaction) +if (journal->j_committing_transaction) { commit_tid = journal->j_committing_transaction->t_tid; + has_transaction = true; + }read_unlock (&journal->j_state_lock); -if (commit_tid) +if (has_transaction)jbd2_log_wait_commit (journal, commit_tid); } }
Greg Kroah-Hartman
maintainerPATCH 553/798 ext4: fix incorrect tid assumption in jbd2_journal_shrink_checkpoint_list()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit 7a6443e1dad70281f99f0bd394d7fd342481a632 upstream.
Function jbd2_journal_shrink_checkpoint_list() assumes that '0' is not a valid value for transaction IDs, which is incorrect. Don't assume that and use two extra boolean variables to control the loop iterations and keep track of the first and last tid.
--- fs/jbd2/checkpoint.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/jbd2/checkpoint.c +5 -2
@@ -424,6 +424,7 @@ unsigned long jbd2_journal_shrink_checkptid_t tid =0 ;unsigned long nr_freed =0 ;unsigned long freed; +bool first_set = false; again:spin_lock (&journal->j_list_lock);
@@ -443,8 +444,10 @@ again:else transaction = journal->j_checkpoint_transactions; -if (!first_tid) +if (!first_set) { first_tid = transaction->t_tid; + first_set = true; + } last_transaction = journal->j_checkpoint_transactions->t_cpprev; next_transaction = transaction; last_tid = last_transaction->t_tid;
@@ -474,7 +477,7 @@ again:spin_unlock (&journal->j_list_lock);cond_resched (); -if (*nr_to_scan && next_tid) +if (*nr_to_scan && journal->j_shrink_transaction) goto again; out: trace_jbd2_shrink_checkpoint_list(journal, first_tid, tid, last_tid,
Greg Kroah-Hartman
maintainerPATCH 554/798 ext4: fix fast commit inode enqueueing during a full journal commit
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit 6db3c1575a750fd417a70e0178bdf6efa0dd5037 upstream.
When a full journal commit is on-going, any fast commit has to be enqueued into a different queue: FC_Q_STAGING instead of FC_Q_MAIN. This enqueueing is done only once, i.e. if an inode is already queued in a previous fast commit entry it won't be enqueued again. However, if a full commit starts _after_ the inode is enqueued into FC_Q_MAIN, the next fast commit needs to be done into FC_Q_STAGING. And this is not being done in function ext4_fc_track_template().
This patch fixes the issue by re-enqueuing an inode into the STAGING queue during the fast commit clean-up callback when doing a full commit. However, to prevent a race with a fast-commit, the clean-up callback has to be called with the journal locked.
This bug was found using fstest generic/047. This test creates several 32k bytes files, sync'ing each of them after it's creation, and then shutting down the filesystem. Some data may be loss in this operation; for example a file may have it's size truncated to zero.
--- fs/ext4/fast_commit.c | 15 ++++++++++++++- fs/jbd2/journal.c | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-)
fs/ext4/fast_commit.c +14 -1
@@ -1317,8 +1317,21 @@ static void ext4_fc_cleanup(journal_t *jlist_del_init (&iter->i_fc_list);ext4_clear_inode_state (&iter->vfs_inode,EXT4_STATE_FC_COMMITTING ); -if (tid_geq (tid, iter->i_sync_tid)) +if (tid_geq (tid, iter->i_sync_tid)) {ext4_fc_reset_inode (&iter->vfs_inode); + }else if (full) { +/* +* We are called after a full commit, inode has been +* modified while the commit was running. Re-enqueue +* the inode into STAGING, which will then be splice +* back into MAIN. This cannot happen during +* fastcommit because the journal is locked all the +* time in that case (and tid doesn't increase so +* tid check above isn't reliable). +*/ +list_add_tail (&EXT4_I (&iter->vfs_inode)->i_fc_list, + &sbi->s_fc_q[FC_Q_STAGING ]); + }/* Make sure EXT4_STATE_FC_COMMITTING bit is clear */ smp_mb ();#if (BITS_PER_LONG <64 )
fs/jbd2/journal.c +1 -1
@@ -767,9 +767,9 @@ EXPORT_SYMBOL(jbd2_fc_begin_commit);*/ static int __jbd2_fc_end_commit (journal_t *journal,tid_t tid,bool fallback) { -jbd2_journal_unlock_updates (journal);if (journal->j_fc_cleanup_callback) journal->j_fc_cleanup_callback (journal,0 , tid); +jbd2_journal_unlock_updates (journal);write_lock (&journal->j_state_lock); journal->j_flags &= ~JBD2_FAST_COMMIT_ONGOING ;if (fallback)
Greg Kroah-Hartman
maintainerPATCH 555/798 ext4: use handle to mark fc as ineligible in __track_dentry_update()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit faab35a0370fd6e0821c7a8dd213492946fc776f upstream.
Calling ext4_fc_mark_ineligible() with a NULL handle is racy and may result in a fast-commit being done before the filesystem is effectively marked as ineligible. This patch fixes the calls to this function in __track_dentry_update() by adding an extra parameter to the callback used in ext4_fc_track_template().
--- fs/ext4/fast_commit.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
fs/ext4/fast_commit.c +11 -8
@@ -379,7 +379,7 @@ void ext4_fc_mark_ineligible(struct supe*/ static int ext4_fc_track_template (handle_t *handle,struct inode *inode, -int (*__fc_track_fn)(struct inode *,void *,bool ), +int (*__fc_track_fn)(handle_t *handle,struct inode *,void *,bool ),void *args,int enqueue) {bool update = false;
@@ -396,7 +396,7 @@ static int ext4_fc_track_template(ext4_fc_reset_inode (inode); ei->i_sync_tid = tid; } - ret =__fc_track_fn (inode, args, update); + ret =__fc_track_fn (handle, inode, args, update);mutex_unlock (&ei->i_fc_lock);if (!enqueue)
@@ -420,7 +420,8 @@ struct __track_dentry_update_args { };/* __track_fn for directory entry updates. Called with ei->i_fc_lock. */ -static int __track_dentry_update (struct inode *inode,void *arg,bool update) +static int __track_dentry_update (handle_t *handle,struct inode *inode, +void *arg,bool update) {struct ext4_fc_dentry_update *node;struct ext4_inode_info *ei =EXT4_I (inode);
@@ -435,14 +436,14 @@ static int __track_dentry_update(structif (IS_ENCRYPTED (dir)) {ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_ENCRYPTED_FILENAME , -NULL ); + handle);mutex_lock (&ei->i_fc_lock);return -EOPNOTSUPP ; } node =kmem_cache_alloc (ext4_fc_dentry_cachep,GFP_NOFS );if (!node) { -ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_NOMEM ,NULL ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_NOMEM , handle);mutex_lock (&ei->i_fc_lock);return -ENOMEM ; }
@@ -454,7 +455,7 @@ static int __track_dentry_update(struct node->fcd_name.name =kmalloc (dentry->d_name.len,GFP_NOFS );if (!node->fcd_name.name) {kmem_cache_free (ext4_fc_dentry_cachep, node); -ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_NOMEM ,NULL ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_NOMEM , handle);mutex_lock (&ei->i_fc_lock);return -ENOMEM ; }
@@ -576,7 +577,8 @@ void ext4_fc_track_create(handle_t *hand }/* __track_fn for inode tracking */ -static int __track_inode (struct inode *inode,void *arg,bool update) +static int __track_inode (handle_t *handle,struct inode *inode,void *arg, +bool update) {if (update)return -EEXIST ;
@@ -614,7 +616,8 @@ struct __track_range_args { };/* __track_fn for tracking data updates */ -static int __track_range (struct inode *inode,void *arg,bool update) +static int __track_range (handle_t *handle,struct inode *inode,void *arg, +bool update) {struct ext4_inode_info *ei =EXT4_I (inode);ext4_lblk_t oldstart;
Greg Kroah-Hartman
maintainerPATCH 556/798 ext4: mark fc as ineligible using an handle in ext4_xattr_set()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit 04e6ce8f06d161399e5afde3df5dcfa9455b4952 upstream.
Calling ext4_fc_mark_ineligible() with a NULL handle is racy and may result in a fast-commit being done before the filesystem is effectively marked as ineligible. This patch moves the call to this function so that an handle can be used. If a transaction fails to start, then there's not point in trying to mark the filesystem as ineligible, and an error will eventually be returned to user-space.
--- fs/ext4/xattr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ext4/xattr.c +2 -1
@@ -2505,6 +2505,8 @@ retry: error =ext4_xattr_set_handle (handle, inode, name_index, name, value, value_len, flags); +ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_XATTR , + handle); error2 =ext4_journal_stop (handle);if (error == -ENOSPC &&ext4_should_retry_alloc (sb, &retries))
@@ -2512,7 +2514,6 @@ retry:if (error ==0 ) error = error2; } -ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_XATTR ,NULL );return error; }
Greg Kroah-Hartman
maintainerPATCH 557/798 parisc: Fix 64-bit userspace syscall path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit d24449864da5838936669618356b0e30ca2999c3 upstream.
Currently the glibc isn't yet ported to 64-bit for hppa, so there is no usable userspace available yet.
But it's possible to manually build a static 64-bit binary and run that for testing. One such 64-bit test program is available at http://ftp.parisc-linux.org/src/64bit.tar.gz
and it shows various issues with the existing 64-bit syscall path in the kernel.
This patch fixes those issues.
--- arch/parisc/kernel/syscall.S | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
arch/parisc/kernel/syscall.S +8 -6
@@ -232,10 +232,10 @@ linux_gateway_entry: #ifdef CONFIG_64BIT ldil L%sys_call_table, %r1 - or,= %r2,%r2,%r2 - addil L%(sys_call_table64-sys_call_table), %r1 + or,ev %r2,%r2,%r2 + ldil L%sys_call_table64, %r1 ldo R%sys_call_table(%r1), %r19 - or,= %r2,%r2,%r2 + or,ev %r2,%r2,%r2 ldo R%sys_call_table64(%r1), %r19 #else load32 sys_call_table, %r19
@@ -368,10 +368,10 @@ tracesys_next: extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */ ldil L%sys_call_table, %r1 - or,= %r2,%r2,%r2 - addil L%(sys_call_table64-sys_call_table), %r1 + or,ev %r2,%r2,%r2 + ldil L%sys_call_table64, %r1 ldo R%sys_call_table(%r1), %r19 - or,= %r2,%r2,%r2 + or,ev %r2,%r2,%r2 ldo R%sys_call_table64(%r1), %r19 #else load32 sys_call_table, %r19
@@ -1310,6 +1310,8 @@ ENTRY(sys_call_table) END(sys_call_table) #ifdef CONFIG_64BIT +#undef __SYSCALL_WITH_COMPAT +#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native) .align 8 ENTRY(sys_call_table64) #include <asm/syscall_table_64.h> /* 64-bit syscalls */
Greg Kroah-Hartman
maintainerPATCH 558/798 parisc: Fix stack start for ADDR_NO_RANDOMIZE personality
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit f31b256994acec6929306dfa86ac29716e7503d6 upstream.
Fix the stack start address calculation for the parisc architecture in setup_arg_pages() when address randomization is disabled. When the ADDR_NO_RANDOMIZE process personality is disabled there is no need to add additional space for the stack.
Note that this patch touches code inside an #ifdef CONFIG_STACK_GROWSUP hunk, which is why only the parisc architecture is affected since it's the only Linux architecture where the stack grows upwards.
Without this patch you will find the stack in the middle of some mapped libaries and suddenly limited to 6MB instead of 8MB:
root@parisc:~# setarch -R /bin/bash -c "cat /proc/self/maps" 00010000-00019000 r-xp 00000000 08:05 1182034 /usr/bin/cat 00019000-0001a000 rwxp 00009000 08:05 1182034 /usr/bin/cat 0001a000-0003b000 rwxp 00000000 00:00 0 [heap] f90c4000-f9283000 r-xp 00000000 08:05 1573004 /usr/lib/hppa-linux-gnu/libc.so.6 f9283000-f9285000 r--p 001bf000 08:05 1573004 /usr/lib/hppa-linux-gnu/libc.so.6 f9285000-f928a000 rwxp 001c1000 08:05 1573004 /usr/lib/hppa-linux-gnu/libc.so.6 f928a000-f9294000 rwxp 00000000 00:00 0 f9301000-f9323000 rwxp 00000000 00:00 0 [stack] f98b4000-f98e4000 r-xp 00000000 08:05 1572869 /usr/lib/hppa-linux-gnu/ld.so.1 f98e4000-f98e5000 r--p 00030000 08:05 1572869 /usr/lib/hppa-linux-gnu/ld.so.1 f98e5000-f98e9000 rwxp 00031000 08:05 1572869 /usr/lib/hppa-linux-gnu/ld.so.1 f9ad8000-f9b00000 rw-p 00000000 00:00 0 f9b00000-f9b01000 r-xp 00000000 00:00 0 [vdso]
With the patch the stack gets correctly mapped at the end of the process memory map:
root@panama:~# setarch -R /bin/bash -c "cat /proc/self/maps" 00010000-00019000 r-xp 00000000 08:13 16385582 /usr/bin/cat 00019000-0001a000 rwxp 00009000 08:13 16385582 /usr/bin/cat 0001a000-0003b000 rwxp 00000000 00:00 0 [heap] fef29000-ff0eb000 r-xp 00000000 08:13 16122400 /usr/lib/hppa-linux-gnu/libc.so.6 ff0eb000-ff0ed000 r--p 001c2000 08:13 16122400 /usr/lib/hppa-linux-gnu/libc.so.6 ff0ed000-ff0f2000 rwxp 001c4000 08:13 16122400 /usr/lib/hppa-linux-gnu/libc.so.6 ff0f2000-ff0fc000 rwxp 00000000 00:00 0 ff4b4000-ff4e4000 r-xp 00000000 08:13 16121913 /usr/lib/hppa-linux-gnu/ld.so.1 ff4e4000-ff4e6000 r--p 00030000 08:13 16121913 /usr/lib/hppa-linux-gnu/ld.so.1 ff4e6000-ff4ea000 rwxp 00032000 08:13 16121913 /usr/lib/hppa-linux-gnu/ld.so.1 ff6d7000-ff6ff000 rw-p 00000000 00:00 0 ff6ff000-ff700000 r-xp 00000000 00:00 0 [vdso] ff700000-ff722000 rwxp 00000000 00:00 0 [stack]
--- fs/exec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/exec.c +2 -1
@@ -771,7 +771,8 @@ int setup_arg_pages(struct linux_binprm stack_base =calc_max_stack_size (stack_base);/* Add space for stack randomization. */ - stack_base += (STACK_RND_MASK <<PAGE_SHIFT ); +if (current->flags &PF_RANDOMIZE ) + stack_base += (STACK_RND_MASK <<PAGE_SHIFT );/* Make sure we didn't let the argument array grow too large. */ if (vma->vm_end - vma->vm_start > stack_base)
Greg Kroah-Hartman
maintainerPATCH 559/798 drm/rockchip: vop: clear DMA stop bit on RK3066
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Val Packett <[email protected]>
commit 6b44aa559d6c7f4ea591ef9d2352a7250138d62a upstream.
The RK3066 VOP sets a dma_stop bit when it's done scanning out a frame and needs the driver to acknowledge that by clearing the bit.
Unless we clear it "between" frames, the RGB output only shows noise instead of the picture. atomic_flush is the place for it that least affects other code (doing it on vblank would require converting all other usages of the reg_lock to spin_(un)lock_irq, which would affect performance for everyone).
This seems to be a redundant synchronization mechanism that was removed in later iterations of the VOP hardware block.
--- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 ++++ drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 + drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 1 + 3 files changed, 6 insertions(+)
drivers/gpu/drm/rockchip/rockchip_drm_vop.c +4 -0
@@ -1559,6 +1559,10 @@ static void vop_crtc_atomic_flush(structVOP_AFBC_SET (vop, enable, s->enable_afbc);vop_cfg_done (vop); +/* Ack the DMA transfer of the previous frame (RK3066). */ +if (VOP_HAS_REG (vop, common, dma_stop)) +VOP_REG_SET (vop, common, dma_stop,0 ); +spin_unlock (&vop->reg_lock);/*
drivers/gpu/drm/rockchip/rockchip_drm_vop.h +1 -0
@@ -117,6 +117,7 @@ struct vop_common {struct vop_reg lut_buffer_index;struct vop_reg gate_en;struct vop_reg mmu_en; +struct vop_reg dma_stop;struct vop_reg out_mode;struct vop_reg standby; };
drivers/gpu/drm/rockchip/rockchip_vop_reg.c +1 -0
@@ -431,6 +431,7 @@ static const struct vop_output rk3066_ou };static const struct vop_common rk3066_common = { + .dma_stop =VOP_REG (RK3066_SYS_CTRL0 ,0x1 ,0 ), .standby =VOP_REG (RK3066_SYS_CTRL0 ,0x1 ,1 ), .out_mode =VOP_REG (RK3066_DSP_CTRL0 ,0xf ,0 ), .cfg_done =VOP_REG (RK3066_REG_CFG_DONE ,0x1 ,0 ),
Greg Kroah-Hartman
maintainerPATCH 560/798 of/irq: Support #msi-cells=<0> in of_msi_get_domain
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Jones <[email protected]>
commit db8e81132cf051843c9a59b46fa5a071c45baeb3 upstream.
An 'msi-parent' property with a single entry and no accompanying '#msi-cells' property is considered the legacy definition as opposed to its definition after being expanded with commit 126b16e2ad98 ("Docs: dt: add generic MSI bindings"). However, the legacy definition is completely compatible with the current definition and, since of_phandle_iterator_next() tolerates missing and present-but- zero *cells properties since commit e42ee61017f5 ("of: Let of_for_each_phandle fallback to non-negative cell_count"), there's no need anymore to special case the legacy definition in of_msi_get_domain().
Indeed, special casing has turned out to be harmful, because, as of commit 7c025238b47a ("dt-bindings: irqchip: Describe the IMX MU block as a MSI controller"), MSI controller DT bindings have started specifying '#msi-cells' as a required property (even when the value must be zero) as an effort to make the bindings more explicit. But, since the special casing of 'msi-parent' only uses the existence of '#msi-cells' for its heuristic, and not whether or not it's also nonzero, the legacy path is not taken. Furthermore, the path to support the new, broader definition isn't taken either since that path has been restricted to the platform-msi bus.
But, neither the definition of 'msi-parent' nor the definition of '#msi-cells' is platform-msi-specific (the platform-msi bus was just the first bus that needed '#msi-cells'), so remove both the special casing and the restriction. The code removal also requires changing to of_parse_phandle_with_optional_args() in order to ensure the legacy (but compatible) use of 'msi-parent' remains supported. This not only simplifies the code but also resolves an issue with PCI devices finding their MSI controllers on riscv, as the riscv,imsics binding requires '#msi-cells=<0>'.
--- drivers/of/irq.c | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-)
drivers/of/irq.c +7 -27
@@ -710,8 +710,7 @@ struct irq_domain *of_msi_map_get_device* @np: device node for @dev * @token: bus type for this domain * -* Parse the msi-parent property (both the simple and the complex -* versions), and returns the corresponding MSI domain. +* Parse the msi-parent property and returns the corresponding MSI domain. * * Returns: the MSI domain for this device (or NULL on failure). */
@@ -719,33 +718,14 @@ struct irq_domain *of_msi_get_domain(strstruct device_node *np, enum irq_domain_bus_token token) { - struct device_node *msi_np; + struct of_phandle_iterator it;struct irq_domain *d; +int err; -/* Check for a single msi-parent property */ - msi_np =of_parse_phandle (np,"msi-parent" ,0 ); -if (msi_np && !of_property_read_bool (msi_np,"#msi-cells" )) { - d =irq_find_matching_host (msi_np, token); -if (!d) -of_node_put (msi_np); -return d; - } - -if (token ==DOMAIN_BUS_PLATFORM_MSI ) { -/* Check for the complex msi-parent version */ -struct of_phandle_args args; -int index =0 ; - -while (!of_parse_phandle_with_args (np,"msi-parent" , -"#msi-cells" , - index, &args)) { - d =irq_find_matching_host (args.np, token); -if (d) -return d; - -of_node_put (args.np); - index++; - } +of_for_each_phandle (&it, err, np,"msi-parent" ,"#msi-cells" ,0 ) { + d =irq_find_matching_host (it.node, token); +if (d) +return d; }return NULL ;
Greg Kroah-Hartman
maintainerPATCH 561/798 drm: omapdrm: Add missing check for alloc_ordered_workqueue
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit e794b7b9b92977365c693760a259f8eef940c536 upstream.
As it may return NULL pointer and cause NULL pointer dereference. Add check for the return value of alloc_ordered_workqueue.
--- drivers/gpu/drm/omapdrm/omap_drv.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/omapdrm/omap_drv.c +5 -0
@@ -746,6 +746,10 @@ static int omapdrm_init(struct omap_drm_ soc =soc_device_match (omapdrm_soc_devices); priv->omaprev = soc ? (uintptr_t )soc->data :0 ; priv->wq =alloc_ordered_workqueue ("omapdrm" ,0 ); +if (!priv->wq) { + ret = -ENOMEM ; + goto err_alloc_workqueue; + }mutex_init (&priv->list_lock);INIT_LIST_HEAD (&priv->obj_list);
@@ -808,6 +812,7 @@ err_gem_deinit:drm_mode_config_cleanup (ddev);omap_gem_deinit (ddev);destroy_workqueue (priv->wq); +err_alloc_workqueue:omap_disconnect_pipelines (ddev);drm_dev_put (ddev);return ret;
Greg Kroah-Hartman
maintainerPATCH 562/798 resource: fix region_intersects() vs add_memory_driver_managed()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huang Ying <[email protected]>
commit b4afe4183ec77f230851ea139d91e5cf2644c68b upstream.
On a system with CXL memory, the resource tree (/proc/iomem) related to CXL memory may look like something as follows.
490000000-50fffffff : CXL Window 0
490000000-50fffffff : region0
490000000-50fffffff : dax0.0
490000000-50fffffff : System RAM (kmem)Because drivers/dax/kmem.c calls add_memory_driver_managed() during onlining CXL memory, which makes "System RAM (kmem)" a descendant of "CXL Window X". This confuses region_intersects(), which expects all "System RAM" resources to be at the top level of iomem_resource. This can lead to bugs.
For example, when the following command line is executed to write some memory in CXL memory range via /dev/mem,
$ dd if=data of=/dev/mem bs=$((1 << 10)) seek=$((0x490000000 >> 10)) count=1 dd: error writing '/dev/mem': Bad address 1+0 records in 0+0 records out 0 bytes copied, 0.0283507 s, 0.0 kB/s
the command fails as expected. However, the error code is wrong. It should be "Operation not permitted" instead of "Bad address". More seriously, the /dev/mem permission checking in devmem_is_allowed() passes incorrectly. Although the accessing is prevented later because ioremap() isn't allowed to map system RAM, it is a potential security issue. During command executing, the following warning is reported in the kernel log for calling ioremap() on system RAM.
ioremap on RAM at 0x0000000490000000 - 0x0000000490000fff
WARNING: CPU: 2 PID: 416 at arch/x86/mm/ioremap.c:216 __ioremap_caller.constprop.0+0x131/0x35d Call Trace: memremap+0xcb/0x184 xlate_dev_mem_ptr+0x25/0x2f write_mem+0x94/0xfb vfs_write+0x128/0x26d ksys_write+0xac/0xfe do_syscall_64+0x9a/0xfd entry_SYSCALL_64_after_hwframe+0x4b/0x53
The details of command execution process are as follows. In the above resource tree, "System RAM" is a descendant of "CXL Window 0" instead of a top level resource. So, region_intersects() will report no System RAM resources in the CXL memory region incorrectly, because it only checks the top level resources. Consequently, devmem_is_allowed() will return 1 (allow access via /dev/mem) for CXL memory region incorrectly. Fortunately, ioremap() doesn't allow to map System RAM and reject the access.
So, region_intersects() needs to be fixed to work correctly with the resource tree with "System RAM" not at top level as above. To fix it, if we found a unmatched resource in the top level, we will continue to search matched resources in its descendant resources. So, we will not miss any matched resources in resource tree anymore.
In the new implementation, an example resource tree
|------------- "CXL Window 0" ------------| |-- "System RAM" --|
will behave similar as the following fake resource tree for region_intersects(, IORESOURCE_SYSTEM_RAM, ),
|-- "System RAM" --||-- "CXL Window 0a" --|
Where "CXL Window 0a" is part of the original "CXL Window 0" that isn't covered by "System RAM".
--- kernel/resource.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 8 deletions(-)
kernel/resource.c +50 -8
@@ -493,20 +493,62 @@ static int __region_intersects(struct re size_t size, unsigned long flags, unsigned long desc) { - struct resource res; + resource_size_t ostart, oend;int type =0 ;int other =0 ; -struct resource *p; +struct resource *p, *dp; +bool is_type, covered; +struct resource res; res.start = start; res.end = start + size -1 ;for (p = parent->child; p ; p = p->sibling) { -bool is_type = (((p->flags & flags) == flags) && - ((desc ==IORES_DESC_NONE ) || - (desc == p->desc))); - -if (resource_overlaps (p, &res)) - is_type ? type++ : other++; +if (!resource_overlaps (p, &res)) +continue ; + is_type = (p->flags & flags) == flags && + (desc ==IORES_DESC_NONE || desc == p->desc); +if (is_type) { + type++; +continue ; + } +/* +* Continue to search in descendant resources as if the +* matched descendant resources cover some ranges of 'p'. +* +* |------------- "CXL Window 0" ------------| +* |-- "System RAM" --| +* +* will behave similar as the following fake resource +* tree when searching "System RAM". +* +* |-- "System RAM" --||-- "CXL Window 0a" --| +*/ + covered = false; + ostart =max (res.start, p->start); + oend =min (res.end, p->end); +for_each_resource (p, dp, false) { +if (!resource_overlaps (dp, &res)) +continue ; + is_type = (dp->flags & flags) == flags && + (desc ==IORES_DESC_NONE || desc == dp->desc); +if (is_type) { + type++; +/* +* Range from 'ostart' to 'dp->start' +* isn't covered by matched resource. +*/ +if (dp->start > ostart) +break ; +if (dp->end >= oend) { + covered = true; +break ; + } +/* Remove covered range */ + ostart =max (ostart, dp->end +1 ); + } + } +if (!covered) + other++; }if (type ==0 )
Greg Kroah-Hartman
maintainerPATCH 563/798 jbd2: stop waiting for space when jbd2_cleanup_journal_tail() returns error
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit f5cacdc6f2bb2a9bf214469dd7112b43dd2dd68a upstream.
In __jbd2_log_wait_for_space(), we might call jbd2_cleanup_journal_tail() to recover some journal space. But if an error occurs while executing jbd2_cleanup_journal_tail() (e.g., an EIO), we don't stop waiting for free space right away, we try other branches, and if j_committing_transaction is NULL (i.e., the tid is 0), we will get the following complain:
============================================
JBD2: I/O error when updating journal superblock for sdd-8. __jbd2_log_wait_for_space: needed 256 blocks and only had 217 space available __jbd2_log_wait_for_space: no way to get more journal space in sdd-8
------------[ cut here ]------------ WARNING: CPU: 2 PID: 139804 at fs/jbd2/checkpoint.c:109 __jbd2_log_wait_for_space+0x251/0x2e0 Modules linked in: CPU: 2 PID: 139804 Comm: kworker/u8:3 Not tainted 6.6.0+ #1 RIP: 0010:__jbd2_log_wait_for_space+0x251/0x2e0 Call Trace: <TASK> add_transaction_credits+0x5d1/0x5e0 start_this_handle+0x1ef/0x6a0 jbd2__journal_start+0x18b/0x340 ext4_dirty_inode+0x5d/0xb0 __mark_inode_dirty+0xe4/0x5d0 generic_update_time+0x60/0x70
[...]
============================================
So only if jbd2_cleanup_journal_tail() returns 1, i.e., there is nothing to clean up at the moment, continue to try to reclaim free space in other ways.
Note that this fix relies on commit 6f6a6fda2945 ("jbd2: fix ocfs2 corrupt when updating journal superblock fails") to make jbd2_cleanup_journal_tail return the correct error code.
--- fs/jbd2/checkpoint.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/jbd2/checkpoint.c +5 -2
@@ -101,8 +101,11 @@ __releases(&journal->j_state_lock)write_unlock (&journal->j_state_lock);if (chkpt) {jbd2_log_do_checkpoint (journal); - }else if (jbd2_cleanup_journal_tail (journal) ==0 ) { -/* We were able to recover space; yay! */ + }else if (jbd2_cleanup_journal_tail (journal) <=0 ) { +/* +* We were able to recover space or the +* journal was aborted due to an error. +*/ ; }else if (has_transaction) {/*
Greg Kroah-Hartman
maintainerPATCH 564/798 jbd2: correctly compare tids with tid_geq function in jbd2_fc_begin_commit
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kemeng Shi <[email protected]>
commit f0e3c14802515f60a47e6ef347ea59c2733402aa upstream.
Use tid_geq to compare tids to work over sequence number wraps.
--- fs/jbd2/journal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/jbd2/journal.c +1 -1
@@ -737,7 +737,7 @@ int jbd2_fc_begin_commit(journal_t *jourreturn -EINVAL ;write_lock (&journal->j_state_lock); -if (tid <= journal->j_commit_sequence) { +if (tid_geq (journal->j_commit_sequence, tid)) {write_unlock (&journal->j_state_lock);return -EALREADY ; }
Greg Kroah-Hartman
maintainerPATCH 565/798 mm: krealloc: consider spare memory for __GFP_ZERO
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich <[email protected]>
commit 1a83a716ec233990e1fd5b6fbb1200ade63bf450 upstream.
As long as krealloc() is called with __GFP_ZERO consistently, starting with the initial memory allocation, __GFP_ZERO should be fully honored.
However, if for an existing allocation krealloc() is called with a decreased size, it is not ensured that the spare portion the allocation is zeroed. Thus, if krealloc() is subsequently called with a larger size again, __GFP_ZERO can't be fully honored, since we don't know the previous size, but only the bucket size.
Example:
buf = kzalloc(64, GFP_KERNEL); memset(buf, 0xff, 64); buf = krealloc(buf, 48, GFP_KERNEL | __GFP_ZERO); /* After this call the last 16 bytes are still 0xff. */ buf = krealloc(buf, 64, GFP_KERNEL | __GFP_ZERO);
Fix this, by explicitly setting spare memory to zero, when shrinking an allocation with __GFP_ZERO flag set or init_on_alloc enabled.
--- mm/slab_common.c | 7 +++++++ 1 file changed, 7 insertions(+)
mm/slab_common.c +7 -0
@@ -1322,6 +1322,13 @@ __do_krealloc(const void *p, size_t new_/* If the object still fits, repoison it precisely. */ if (ks >= new_size) { +/* Zero out spare memory. */ +if (want_init_on_alloc (flags)) { +kasan_disable_current (); +memset ((void *)p + new_size,0 , ks - new_size); +kasan_enable_current (); + } + p =kasan_krealloc ((void *)p, new_size, flags);return (void *)p; }
Greg Kroah-Hartman
maintainerPATCH 566/798 ocfs2: fix the la space leak when unmounting an ocfs2 volume
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heming Zhao <[email protected]>
commit dfe6c5692fb525e5e90cefe306ee0dffae13d35f upstream.
This bug has existed since the initial OCFS2 code. The code logic in ocfs2_sync_local_to_main() is wrong, as it ignores the last contiguous free bits, which causes an OCFS2 volume to lose the last free clusters of LA window on each umount command.
--- fs/ocfs2/localalloc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
fs/ocfs2/localalloc.c +19 -0
@@ -1008,6 +1008,25 @@ static int ocfs2_sync_local_to_main(stru start = bit_off +1 ; } +/* clear the contiguous bits until the end boundary */ +if (count) { + blkno = la_start_blk + +ocfs2_clusters_to_blocks (osb->sb, + start - count); + +trace_ocfs2_sync_local_to_main_free ( + count, start - count, + (unsigned long long )la_start_blk, + (unsigned long long )blkno); + + status =ocfs2_release_clusters (handle, + main_bm_inode, + main_bm_bh, blkno, + count); +if (status <0 ) +mlog_errno (status); + } + bail:if (status)mlog_errno (status);
Greg Kroah-Hartman
maintainerPATCH 567/798 ocfs2: fix uninit-value in ocfs2_get_block()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joseph Qi <[email protected]>
commit 2af148ef8549a12f8025286b8825c2833ee6bcb8 upstream.
syzbot reported an uninit-value BUG:
BUG: KMSAN: uninit-value in ocfs2_get_block+0xed2/0x2710 fs/ocfs2/aops.c:159 ocfs2_get_block+0xed2/0x2710 fs/ocfs2/aops.c:159 do_mpage_readpage+0xc45/0x2780 fs/mpage.c:225 mpage_readahead+0x43f/0x840 fs/mpage.c:374 ocfs2_readahead+0x269/0x320 fs/ocfs2/aops.c:381 read_pages+0x193/0x1110 mm/readahead.c:160 page_cache_ra_unbounded+0x901/0x9f0 mm/readahead.c:273 do_page_cache_ra mm/readahead.c:303 [inline] force_page_cache_ra+0x3b1/0x4b0 mm/readahead.c:332 force_page_cache_readahead mm/internal.h:347 [inline] generic_fadvise+0x6b0/0xa90 mm/fadvise.c:106 vfs_fadvise mm/fadvise.c:185 [inline] ksys_fadvise64_64 mm/fadvise.c:199 [inline] __do_sys_fadvise64 mm/fadvise.c:214 [inline] __se_sys_fadvise64 mm/fadvise.c:212 [inline] __x64_sys_fadvise64+0x1fb/0x3a0 mm/fadvise.c:212 x64_sys_call+0xe11/0x3ba0 arch/x86/include/generated/asm/syscalls_64.h:222 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
This is because when ocfs2_extent_map_get_blocks() fails, p_blkno is uninitialized. So the error log will trigger the above uninit-value access.
The error log is out-of-date since get_blocks() was removed long time ago. And the error code will be logged in ocfs2_extent_map_get_blocks() once ocfs2_get_cluster() fails, so fix this by only logging inode and block.
--- fs/ocfs2/aops.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
fs/ocfs2/aops.c +2 -3
@@ -156,9 +156,8 @@ int ocfs2_get_block(struct inode *inode, err =ocfs2_extent_map_get_blocks (inode, iblock, &p_blkno, &count, &ext_flags);if (err) { -mlog (ML_ERROR ,"Error %d from get_blocks(0x%p, %llu, 1, " -"%llu, NULL)\n" , err, inode, (unsigned long long )iblock, - (unsigned long long )p_blkno); +mlog (ML_ERROR ,"get_blocks() failed, inode: 0x%p, " +"block: %llu\n" , inode, (unsigned long long )iblock); goto bail; }
Greg Kroah-Hartman
maintainerPATCH 568/798 ocfs2: reserve space for inline xattr before attaching reflink tree
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gautham Ananthakrishna <[email protected]>
commit 5ca60b86f57a4d9648f68418a725b3a7de2816b0 upstream.
One of our customers reported a crash and a corrupted ocfs2 filesystem. The crash was due to the detection of corruption. Upon troubleshooting, the fsck -fn output showed the below corruption
[EXTENT_LIST_FREE] Extent list in owner 33080590 claims 230 as the next free chain record, but fsck believes the largest valid value is 227. Clamp the next record value? n
The stat output from the debugfs.ocfs2 showed the following corruption where the "Next Free Rec:" had overshot the "Count:" in the root metadata block.
Inode: 33080590 Mode: 0640 Generation: 2619713622 (0x9c25a856)
FS Generation: 904309833 (0x35e6ac49)
CRC32: 00000000 ECC: 0000
Type: Regular Attr: 0x0 Flags: Valid
Dynamic Features: (0x16) HasXattr InlineXattr Refcounted
Extended Attributes Block: 0 Extended Attributes Inline Size: 256
User: 0 (root) Group: 0 (root) Size: 281320357888
Links: 1 Clusters: 141738
ctime: 0x66911b56 0x316edcb8 -- Fri Jul 12 06:02:30.829349048 2024
atime: 0x66911d6b 0x7f7a28d -- Fri Jul 12 06:11:23.133669517 2024
mtime: 0x66911b56 0x12ed75d7 -- Fri Jul 12 06:02:30.317552087 2024
dtime: 0x0 -- Wed Dec 31 17:00:00 1969
Refcount Block: 2777346
Last Extblk: 2886943 Orphan Slot: 0
Sub Alloc Slot: 0 Sub Alloc Bit: 14
Tree Depth: 1 Count: 227 Next Free Rec: 230
## Offset Clusters Block#
0 0 2310 2776351
1 2310 2139 2777375
2 4449 1221 2778399
3 5670 731 2779423
4 6401 566 2780447
....... .... .......
....... .... .......The issue was in the reflink workfow while reserving space for inline xattr. The problematic function is ocfs2_reflink_xattr_inline(). By the time this function is called the reflink tree is already recreated at the destination inode from the source inode. At this point, this function reserves space for inline xattrs at the destination inode without even checking if there is space at the root metadata block. It simply reduces the l_count from 243 to 227 thereby making space of 256 bytes for inline xattr whereas the inode already has extents beyond this index (in this case up to 230), thereby causing corruption.
The fix for this is to reserve space for inline metadata at the destination inode before the reflink tree gets recreated. The customer has verified the fix.
--- fs/ocfs2/refcounttree.c | 26 ++++++++++++++++++++++++-- fs/ocfs2/xattr.c | 11 +---------- 2 files changed, 25 insertions(+), 12 deletions(-)
fs/ocfs2/refcounttree.c +24 -2
@@ -25,6 +25,7 @@#include "namei.h" #include "ocfs2_trace.h" #include "file.h" +#include "symlink.h" #include <linux/bio.h> #include <linux/blkdev.h>
@@ -4154,8 +4155,9 @@ static int __ocfs2_reflink(struct dentryint ret;struct inode *inode =d_inode (old_dentry);struct buffer_head *new_bh =NULL ; +struct ocfs2_inode_info *oi =OCFS2_I (inode); -if (OCFS2_I (inode)->ip_flags &OCFS2_INODE_SYSTEM_FILE ) { +if (oi->ip_flags &OCFS2_INODE_SYSTEM_FILE ) { ret = -EINVAL ;mlog_errno (ret); goto out;
@@ -4181,6 +4183,26 @@ static int __ocfs2_reflink(struct dentry goto out_unlock; } +if ((oi->ip_dyn_features &OCFS2_HAS_XATTR_FL ) && + (oi->ip_dyn_features &OCFS2_INLINE_XATTR_FL )) { +/* +* Adjust extent record count to reserve space for extended attribute. +* Inline data count had been adjusted in ocfs2_duplicate_inline_data(). +*/ +struct ocfs2_inode_info *new_oi =OCFS2_I (new_inode); + +if (!(new_oi->ip_dyn_features &OCFS2_INLINE_DATA_FL ) && + !(ocfs2_inode_is_fast_symlink (new_inode))) { +struct ocfs2_dinode *new_di = (struct ocfs2_dinode *)new_bh->b_data; +struct ocfs2_dinode *old_di = (struct ocfs2_dinode *)old_bh->b_data; +struct ocfs2_extent_list *el = &new_di->id2.i_list; +int inline_size =le16_to_cpu (old_di->i_xattr_inline_size); + +le16_add_cpu (&el->l_count, -(inline_size / +sizeof (struct ocfs2_extent_rec ))); + } + } + ret =ocfs2_create_reflink_node (inode, old_bh, new_inode, new_bh, preserve);if (ret) {
@@ -4188,7 +4210,7 @@ static int __ocfs2_reflink(struct dentry goto inode_unlock; } -if (OCFS2_I (inode)->ip_dyn_features &OCFS2_HAS_XATTR_FL ) { +if (oi->ip_dyn_features &OCFS2_HAS_XATTR_FL ) { ret =ocfs2_reflink_xattrs (inode, old_bh, new_inode, new_bh, preserve);
fs/ocfs2/xattr.c +1 -10
@@ -6524,16 +6524,7 @@ static int ocfs2_reflink_xattr_inline(st } new_oi =OCFS2_I (args->new_inode); -/* -* Adjust extent record count to reserve space for extended attribute. -* Inline data count had been adjusted in ocfs2_duplicate_inline_data(). -*/ -if (!(new_oi->ip_dyn_features &OCFS2_INLINE_DATA_FL ) && - !(ocfs2_inode_is_fast_symlink (args->new_inode))) { -struct ocfs2_extent_list *el = &new_di->id2.i_list; -le16_add_cpu (&el->l_count, -(inline_size / -sizeof (struct ocfs2_extent_rec ))); - } +spin_lock (&new_oi->ip_lock); new_oi->ip_dyn_features |=OCFS2_HAS_XATTR_FL |OCFS2_INLINE_XATTR_FL ; new_di->i_dyn_features =cpu_to_le16 (new_oi->ip_dyn_features);
Greg Kroah-Hartman
maintainerPATCH 569/798 ocfs2: cancel dqi_sync_work before freeing oinfo
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joseph Qi <[email protected]>
commit 35fccce29feb3706f649726d410122dd81b92c18 upstream.
ocfs2_global_read_info() will initialize and schedule dqi_sync_work at the end, if error occurs after successfully reading global quota, it will trigger the following warning with CONFIG_DEBUG_OBJECTS_* enabled:
ODEBUG: free active (active state 0) object: 00000000d8b0ce28 object type: timer_list hint: qsync_work_fn+0x0/0x16c
This reports that there is an active delayed work when freeing oinfo in error handling, so cancel dqi_sync_work first. BTW, return status instead of -1 when .read_file_info fails.
--- fs/ocfs2/quota_local.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
fs/ocfs2/quota_local.c +6 -2
@@ -689,7 +689,7 @@ static int ocfs2_local_read_info(structint status;struct buffer_head *bh =NULL ;struct ocfs2_quota_recovery *rec; -int locked =0 ; +int locked =0 , global_read =0 ; info->dqi_max_spc_limit =0x7fffffffffffffffLL ; info->dqi_max_ino_limit =0x7fffffffffffffffLL ;
@@ -697,6 +697,7 @@ static int ocfs2_local_read_info(structif (!oinfo) {mlog (ML_ERROR ,"failed to allocate memory for ocfs2 quota" " info." ); + status = -ENOMEM ; goto out_err; } info->dqi_priv = oinfo;
@@ -709,6 +710,7 @@ static int ocfs2_local_read_info(struct status =ocfs2_global_read_info (sb, type);if (status <0 ) goto out_err; + global_read =1 ; status =ocfs2_inode_lock (lqinode, &oinfo->dqi_lqi_bh,1 );if (status <0 ) {
@@ -779,10 +781,12 @@ out_err:if (locked)ocfs2_inode_unlock (lqinode,1 );ocfs2_release_local_quota_bitmaps (&oinfo->dqi_chunk); +if (global_read) +cancel_delayed_work_sync (&oinfo->dqi_sync_work);kfree (oinfo); }brelse (bh); -return -1 ; +return status; }/* Write local info to quota file */
Greg Kroah-Hartman
maintainerPATCH 570/798 ocfs2: remove unreasonable unlock in ocfs2_read_blocks
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Xu <[email protected]>
commit c03a82b4a0c935774afa01fd6d128b444fd930a1 upstream.
Patch series "Misc fixes for ocfs2_read_blocks", v5.
This series contains 2 fixes for ocfs2_read_blocks(). The first patch fix the issue reported by syzbot, which detects bad unlock balance in ocfs2_read_blocks(). The second patch fixes an issue reported by Heming Zhao when reviewing above fix.
This patch (of 2):
There was a lock release before exiting, so remove the unreasonable unlock.
--- fs/ocfs2/buffer_head_io.c | 1 - 1 file changed, 1 deletion(-)
fs/ocfs2/buffer_head_io.c +0 -1
@@ -235,7 +235,6 @@ int ocfs2_read_blocks(struct ocfs2_cachiif (bhs[i] ==NULL ) { bhs[i] =sb_getblk (sb, block++);if (bhs[i] ==NULL ) { -ocfs2_metadata_cache_io_unlock (ci); status = -ENOMEM ;mlog_errno (status);/* Don't forget to put previous bh! */
Greg Kroah-Hartman
maintainerPATCH 571/798 ocfs2: fix null-ptr-deref when journal load failed.
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Sun <[email protected]>
commit 5784d9fcfd43bd853654bb80c87ef293b9e8e80a upstream.
During the mounting process, if journal_reset() fails because of too short journal, then lead to jbd2_journal_load() fails with NULL j_sb_buffer. Subsequently, ocfs2_journal_shutdown() calls jbd2_journal_flush()->jbd2_cleanup_journal_tail()-> __jbd2_update_log_tail()->jbd2_journal_update_sb_log_tail() ->lock_buffer(journal->j_sb_buffer), resulting in a null-pointer dereference error.
To resolve this issue, we should check the JBD2_LOADED flag to ensure the journal was properly loaded. Additionally, use journal instead of osb->journal directly to simplify the code.
--- fs/ocfs2/journal.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/ocfs2/journal.c +4 -3
@@ -1022,7 +1022,7 @@ void ocfs2_journal_shutdown(struct ocfs2if (!igrab (inode))BUG (); - num_running_trans =atomic_read (&(osb->journal->j_num_trans)); + num_running_trans =atomic_read (&(journal->j_num_trans));trace_ocfs2_journal_shutdown (num_running_trans);/* Do a commit_cache here. It will flush our journal, *and*
@@ -1041,9 +1041,10 @@ void ocfs2_journal_shutdown(struct ocfs2 osb->commit_task =NULL ; } -BUG_ON (atomic_read (&(osb->journal->j_num_trans)) !=0 ); +BUG_ON (atomic_read (&(journal->j_num_trans)) !=0 ); -if (ocfs2_mount_local (osb)) { +if (ocfs2_mount_local (osb) && + (journal->j_journal->j_flags &JBD2_LOADED )) {jbd2_journal_lock_updates (journal->j_journal); status =jbd2_journal_flush (journal->j_journal,0 );jbd2_journal_unlock_updates (journal->j_journal);
Greg Kroah-Hartman
maintainerPATCH 572/798 ocfs2: fix possible null-ptr-deref in ocfs2_set_buffer_uptodate
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Xu <[email protected]>
commit 33b525cef4cff49e216e4133cc48452e11c0391e upstream.
When doing cleanup, if flags without OCFS2_BH_READAHEAD, it may trigger NULL pointer dereference in the following ocfs2_set_buffer_uptodate() if bh is NULL.
--- fs/ocfs2/buffer_head_io.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ocfs2/buffer_head_io.c +2 -1
@@ -388,7 +388,8 @@ read_failure:/* Always set the buffer in the cache, even if it was * a forced read, or read-ahead which hasn't yet * completed. */ -ocfs2_set_buffer_uptodate (ci, bh); +if (bh) +ocfs2_set_buffer_uptodate (ci, bh); }ocfs2_metadata_cache_io_unlock (ci);
Greg Kroah-Hartman
maintainerPATCH 573/798 riscv: define ILLEGAL_POINTER_VALUE for 64bit
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jisheng Zhang <[email protected]>
commit 5c178472af247c7b50f962495bb7462ba453b9fb upstream.
This is used in poison.h for poison pointer offset. Based on current SV39, SV48 and SV57 vm layout, 0xdead000000000000 is a proper value that is not mappable, this can avoid potentially turning an oops to an expolit.
--- arch/riscv/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
arch/riscv/Kconfig +5 -0
@@ -216,6 +216,11 @@ config GENERIC_HWEIGHT config FIX_EARLYCON_MEM def_bool MMU +config ILLEGAL_POINTER_VALUE + hex + default 0 if 32BIT + default 0xdead000000000000 if 64BIT + config PGTABLE_LEVELS int default 5 if 64BIT
Greg Kroah-Hartman
maintainerPATCH 574/798 exfat: fix memory leak in exfat_load_bitmap()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuezhang Mo <[email protected]>
commit d2b537b3e533f28e0d97293fe9293161fe8cd137 upstream.
If the first directory entry in the root directory is not a bitmap directory entry, 'bh' will not be released and reassigned, which will cause a memory leak.
--- fs/exfat/balloc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
fs/exfat/balloc.c +5 -5
@@ -110,11 +110,8 @@ int exfat_load_bitmap(struct super_blockreturn -EIO ; type =exfat_get_entry_type (ep); -if (type ==TYPE_UNUSED ) -break ; -if (type !=TYPE_BITMAP ) -continue ; -if (ep->dentry.bitmap.flags ==0x0 ) { +if (type ==TYPE_BITMAP && + ep->dentry.bitmap.flags ==0x0 ) {int err; err =exfat_allocate_bitmap (sb, ep);
@@ -122,6 +119,9 @@ int exfat_load_bitmap(struct super_blockreturn err; }brelse (bh); + +if (type ==TYPE_UNUSED ) +return -EINVAL ; }if (exfat_get_next_cluster (sb, &clu.dir))
Greg Kroah-Hartman
maintainerPATCH 575/798 perf hist: Update hist symbol when updating maps
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Fleming <[email protected]>
commit ac01c8c4246546fd8340a232f3ada1921dc0ee48 upstream.
AddressSanitizer found a use-after-free bug in the symbol code which manifested as 'perf top' segfaulting.
==1238389==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b00c48844b at pc 0x5650d8035961 bp 0x7f751aaecc90 sp 0x7f751aaecc80 READ of size 1 at 0x60b00c48844b thread T193
#0 0x5650d8035960 in _sort__sym_cmp util/sort.c:310
#1 0x5650d8043744 in hist_entry__cmp util/hist.c:1286
#2 0x5650d8043951 in hists__findnew_entry util/hist.c:614
#3 0x5650d804568f in __hists__add_entry util/hist.c:754
#4 0x5650d8045bf9 in hists__add_entry util/hist.c:772
#5 0x5650d8045df1 in iter_add_single_normal_entry util/hist.c:997
#6 0x5650d8043326 in hist_entry_iter__add util/hist.c:1242
#7 0x5650d7ceeefe in perf_event__process_sample /home/matt/src/linux/tools/perf/builtin-top.c:845
#8 0x5650d7ceeefe in deliver_event /home/matt/src/linux/tools/perf/builtin-top.c:1208
#9 0x5650d7fdb51b in do_flush util/ordered-events.c:245
#10 0x5650d7fdb51b in __ordered_events__flush util/ordered-events.c:324
#11 0x5650d7ced743 in process_thread /home/matt/src/linux/tools/perf/builtin-top.c:1120
#12 0x7f757ef1f133 in start_thread nptl/pthread_create.c:442
#13 0x7f757ef9f7db in clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81When updating hist maps it's also necessary to update the hist symbol reference because the old one gets freed in map__put().
While this bug was probably introduced with 5c24b67aae72f54c ("perf
tools: Replace map->referenced & maps->removed_maps with map->refcnt"), the symbol objects were leaked until c087e9480cf33672 ("perf machine:
Fix refcount usage when processing PERF_RECORD_KSYMBOL") was merged so the bug was masked.
--- tools/perf/util/hist.c | 5 +++++ 1 file changed, 5 insertions(+)
tools/perf/util/hist.c +5 -0
@@ -634,6 +634,11 @@ static struct hist_entry *hists__findnew* the history counter to increment. */ if (he->ms.map != entry->ms.map) { +if (he->ms.sym) { +u64 addr = he->ms.sym->start; + he->ms.sym =map__find_symbol (entry->ms.map, addr); + } +map__put (he->ms.map); he->ms.map =map__get (entry->ms.map); }
Greg Kroah-Hartman
maintainerPATCH 576/798 nfsd: fix delegation_blocked() to block correctly for at least 30 seconds
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit 45bb63ed20e02ae146336412889fe5450316a84f upstream.
The pair of bloom filtered used by delegation_blocked() was intended to block delegations on given filehandles for between 30 and 60 seconds. A new filehandle would be recorded in the "new" bit set. That would then be switch to the "old" bit set between 0 and 30 seconds later, and it would remain as the "old" bit set for 30 seconds.
Unfortunately the code intended to clear the old bit set once it reached 30 seconds old, preparing it to be the next new bit set, instead cleared the *new* bit set before switching it to be the old bit set. This means that the "old" bit set is always empty and delegations are blocked between 0 and 30 seconds.
This patch updates bd->new before clearing the set with that index, instead of afterwards.
--- fs/nfsd/nfs4state.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/nfsd/nfs4state.c +3 -2
@@ -1090,7 +1090,8 @@ static void nfs4_free_deleg(struct nfs4_* When a delegation is recalled, the filehandle is stored in the "new" * filter. * Every 30 seconds we swap the filters and clear the "new" one, -* unless both are empty of course. +* unless both are empty of course. This results in delegations for a +* given filehandle being blocked for between 30 and 60 seconds. * * Each filter is 256 bits. We hash the filehandle to 32bit and use the * low 3 bytes as hash-table indices.
@@ -1119,9 +1120,9 @@ static int delegation_blocked(struct knfif (ktime_get_seconds () - bd->swap_time >30 ) { bd->entries -= bd->old_entries; bd->old_entries = bd->entries; + bd->new =1 -bd->new;memset (bd->set[bd->new],0 ,sizeof (bd->set[0 ])); - bd->new =1 -bd->new; bd->swap_time =ktime_get_seconds (); }spin_unlock (&blocked_delegations_lock);
Greg Kroah-Hartman
maintainerPATCH 577/798 nfsd: map the EBADMSG to nfserr_io to avoid warning
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Lingfeng <[email protected]>
commit 340e61e44c1d2a15c42ec72ade9195ad525fd048 upstream.
Ext4 will throw -EBADMSG through ext4_readdir when a checksum error occurs, resulting in the following WARNING.
Fix it by mapping EBADMSG to nfserr_io.
nfsd_buffered_readdir
iterate_dir // -EBADMSG -74
ext4_readdir // .iterate_shared
ext4_dx_readdir
ext4_htree_fill_tree
htree_dirblock_to_tree
ext4_read_dirblock
__ext4_read_dirblock
ext4_dirblock_csum_verify
warn_no_space_for_csum
__warn_no_space_for_csum
return ERR_PTR(-EFSBADCRC) // -EBADMSG -74
nfserrno // WARNING
[ 161.115610] ------------[ cut here ]------------ [ 161.116465] nfsd: non-standard errno: -74 [ 161.117315] WARNING: CPU: 1 PID: 780 at fs/nfsd/nfsproc.c:878 nfserrno+0x9d/0xd0 [ 161.118596] Modules linked in: [ 161.119243] CPU: 1 PID: 780 Comm: nfsd Not tainted 5.10.0-00014-g79679361fd5d #138 [ 161.120684] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qe mu.org 04/01/2014 [ 161.123601] RIP: 0010:nfserrno+0x9d/0xd0 [ 161.124676] Code: 0f 87 da 30 dd 00 83 e3 01 b8 00 00 00 05 75 d7 44 89 ee 48 c7 c7 c0 57 24 98 89 44 24 04 c6 05 ce 2b 61 03 01 e8 99 20 d8 00 <0f> 0b 8b 44 24 04 eb b5 4c 89 e6 48 c7 c7 a0 6d a4 99 e8 cc 15 33 [ 161.127797] RSP: 0018:ffffc90000e2f9c0 EFLAGS: 00010286 [ 161.128794] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 [ 161.130089] RDX: 1ffff1103ee16f6d RSI: 0000000000000008 RDI: fffff520001c5f2a [ 161.131379] RBP: 0000000000000022 R08: 0000000000000001 R09: ffff8881f70c1827 [ 161.132664] R10: ffffed103ee18304 R11: 0000000000000001 R12: 0000000000000021 [ 161.133949] R13: 00000000ffffffb6 R14: ffff8881317c0000 R15: ffffc90000e2fbd8 [ 161.135244] FS: 0000000000000000(0000) GS:ffff8881f7080000(0000) knlGS:0000000000000000 [ 161.136695] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 161.137761] CR2: 00007fcaad70b348 CR3: 0000000144256006 CR4: 0000000000770ee0 [ 161.139041] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 161.140291] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 161.141519] PKRU: 55555554 [ 161.142076] Call Trace: [ 161.142575] ? __warn+0x9b/0x140 [ 161.143229] ? nfserrno+0x9d/0xd0 [ 161.143872] ? report_bug+0x125/0x150 [ 161.144595] ? handle_bug+0x41/0x90 [ 161.145284] ? exc_invalid_op+0x14/0x70 [ 161.146009] ? asm_exc_invalid_op+0x12/0x20 [ 161.146816] ? nfserrno+0x9d/0xd0 [ 161.147487] nfsd_buffered_readdir+0x28b/0x2b0 [ 161.148333] ? nfsd4_encode_dirent_fattr+0x380/0x380 [ 161.149258] ? nfsd_buffered_filldir+0xf0/0xf0 [ 161.150093] ? wait_for_concurrent_writes+0x170/0x170 [ 161.151004] ? generic_file_llseek_size+0x48/0x160 [ 161.151895] nfsd_readdir+0x132/0x190 [ 161.152606] ? nfsd4_encode_dirent_fattr+0x380/0x380 [ 161.153516] ? nfsd_unlink+0x380/0x380 [ 161.154256] ? override_creds+0x45/0x60 [ 161.155006] nfsd4_encode_readdir+0x21a/0x3d0 [ 161.155850] ? nfsd4_encode_readlink+0x210/0x210 [ 161.156731] ? write_bytes_to_xdr_buf+0x97/0xe0 [ 161.157598] ? __write_bytes_to_xdr_buf+0xd0/0xd0 [ 161.158494] ? lock_downgrade+0x90/0x90 [ 161.159232] ? nfs4svc_decode_voidarg+0x10/0x10 [ 161.160092] nfsd4_encode_operation+0x15a/0x440 [ 161.160959] nfsd4_proc_compound+0x718/0xe90 [ 161.161818] nfsd_dispatch+0x18e/0x2c0 [ 161.162586] svc_process_common+0x786/0xc50 [ 161.163403] ? nfsd_svc+0x380/0x380 [ 161.164137] ? svc_printk+0x160/0x160 [ 161.164846] ? svc_xprt_do_enqueue.part.0+0x365/0x380 [ 161.165808] ? nfsd_svc+0x380/0x380 [ 161.166523] ? rcu_is_watching+0x23/0x40 [ 161.167309] svc_process+0x1a5/0x200 [ 161.168019] nfsd+0x1f5/0x380 [ 161.168663] ? nfsd_shutdown_threads+0x260/0x260 [ 161.169554] kthread+0x1c4/0x210 [ 161.170224] ? kthread_insert_work_sanity_check+0x80/0x80 [ 161.171246] ret_from_fork+0x1f/0x30
--- fs/nfsd/vfs.c | 1 + 1 file changed, 1 insertion(+)
fs/nfsd/vfs.c +1 -0
@@ -101,6 +101,7 @@ nfserrno (int errno) { nfserr_io, -EUCLEAN }, { nfserr_perm, -ENOKEY }, { nfserr_no_grace, -ENOGRACE}, + { nfserr_io, -EBADMSG }, };int i;
Greg Kroah-Hartman
maintainerPATCH 578/798 NFSD: Fix NFSv4s PUTPUBFH operation
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
commit 202f39039a11402dcbcd5fece8d9fa6be83f49ae upstream.
According to RFC 8881, all minor versions of NFSv4 support PUTPUBFH.
Replace the XDR decoder for PUTPUBFH with a "noop" since we no longer want the minorversion check, and PUTPUBFH has no arguments to decode. (Ideally nfsd4_decode_noop should really be called nfsd4_decode_void).
PUTPUBFH should now behave just like PUTROOTFH.
--- fs/nfsd/nfs4xdr.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-)
fs/nfsd/nfs4xdr.c +1 -9
@@ -1246,14 +1246,6 @@ nfsd4_decode_putfh(struct nfsd4_compound }static __be32 -nfsd4_decode_putpubfh (struct nfsd4_compoundargs *argp,union nfsd4_op_u *p) -{ -if (argp->minorversion ==0 ) -return nfs_ok; -return nfserr_notsupp; -} - -static __be32 nfsd4_decode_read (struct nfsd4_compoundargs *argp,union nfsd4_op_u *u) {struct nfsd4_read *read = &u->read;
@@ -2345,7 +2337,7 @@ static const nfsd4_dec nfsd4_dec_ops[] = [OP_OPEN_CONFIRM] = nfsd4_decode_open_confirm, [OP_OPEN_DOWNGRADE] = nfsd4_decode_open_downgrade, [OP_PUTFH] = nfsd4_decode_putfh, - [OP_PUTPUBFH] = nfsd4_decode_putpubfh, + [OP_PUTPUBFH] = nfsd4_decode_noop, [OP_PUTROOTFH] = nfsd4_decode_noop, [OP_READ] = nfsd4_decode_read, [OP_READDIR] = nfsd4_decode_readdir,
Greg Kroah-Hartman
maintainerPATCH 579/798 aoe: fix the potential use-after-free problem in more places
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chun-Yi Lee <[email protected]>
commit 6d6e54fc71ad1ab0a87047fd9c211e75d86084a3 upstream.
For fixing CVE-2023-6270, f98364e92662 ("aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts") makes tx() calling dev_put() instead of doing in aoecmd_cfg_pkts(). It avoids that the tx() runs into use-after-free.
Then Nicolai Stange found more places in aoe have potential use-after-free problem with tx(). e.g. revalidate(), aoecmd_ata_rw(), resend(), probe() and aoecmd_cfg_rsp(). Those functions also use aoenet_xmit() to push packet to tx queue. So they should also use dev_hold() to increase the refcnt of skb->dev.
On the other hand, moving dev_put() to tx() causes that the refcnt of skb->dev be reduced to a negative value, because corresponding dev_hold() are not called in revalidate(), aoecmd_ata_rw(), resend(), probe(), and aoecmd_cfg_rsp(). This patch fixed this issue.
--- drivers/block/aoe/aoecmd.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/block/aoe/aoecmd.c +12 -1
@@ -361,6 +361,7 @@ ata_rw_frameinit(struct frame *f) } ah->cmdstat =ATA_CMD_PIO_READ | writebit | extbit; +dev_hold (t->ifp->nd); skb->dev = t->ifp->nd; }
@@ -401,6 +402,8 @@ aoecmd_ata_rw(struct aoedev *d)__skb_queue_head_init (&queue);__skb_queue_tail (&queue, skb);aoenet_xmit (&queue); + }else { +dev_put (f->t->ifp->nd); }return 1 ; }
@@ -483,10 +486,13 @@ resend(struct aoedev *d, struct frame *fmemcpy (h->dst, t->addr,sizeof h->dst);memcpy (h->src, t->ifp->nd->dev_addr,sizeof h->src); +dev_hold (t->ifp->nd); skb->dev = t->ifp->nd; skb =skb_clone (skb,GFP_ATOMIC ); -if (skb ==NULL ) +if (skb ==NULL ) { +dev_put (t->ifp->nd);return ; + } f->sent =ktime_get ();__skb_queue_head_init (&queue);__skb_queue_tail (&queue, skb);
@@ -617,6 +623,8 @@ probe(struct aoetgt *t)__skb_queue_head_init (&queue);__skb_queue_tail (&queue, skb);aoenet_xmit (&queue); + }else { +dev_put (f->t->ifp->nd); } }
@@ -1395,6 +1403,7 @@ aoecmd_ata_id(struct aoedev *d) ah->cmdstat =ATA_CMD_ID_ATA ; ah->lba3 =0xa0 ; +dev_hold (t->ifp->nd); skb->dev = t->ifp->nd; d->rttavg =RTTAVG_INIT ;
@@ -1404,6 +1413,8 @@ aoecmd_ata_id(struct aoedev *d) skb =skb_clone (skb,GFP_ATOMIC );if (skb) f->sent =ktime_get (); +else +dev_put (t->ifp->nd);return skb; }
Greg Kroah-Hartman
maintainerPATCH 580/798 clk: rockchip: fix error for unknown clocks
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Reichel <[email protected]>
commit 12fd64babaca4dc09d072f63eda76ba44119816a upstream.
There is a clk == NULL check after the switch to check for unsupported clk types. Since clk is re-assigned in a loop, this check is useless right now for anything but the first round. Let's fix this up by assigning clk = NULL in the loop before the switch statement.
--- drivers/clk/rockchip/clk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/clk/rockchip/clk.c +2 -1
@@ -438,12 +438,13 @@ void rockchip_clk_register_branches(stru struct rockchip_clk_branch *list, unsigned int nr_clk) { -struct clk *clk =NULL ; +struct clk *clk;unsigned int idx;unsigned long flags;for (idx =0 ; idx < nr_clk; idx++, list++) { flags = list->flags; + clk =NULL ;/* catch simple muxes */ switch (list->branch_type) {
Greg Kroah-Hartman
maintainerPATCH 581/798 remoteproc: k3-r5: Fix error handling when power-up failed
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kiszka <[email protected]>
commit 9ab27eb5866ccbf57715cfdba4b03d57776092fb upstream.
By simply bailing out, the driver was violating its rule and internal assumptions that either both or no rproc should be initialized. E.g., this could cause the first core to be available but not the second one, leading to crashes on its shutdown later on while trying to dereference that second instance.
--- drivers/remoteproc/ti_k3_r5_remoteproc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/remoteproc/ti_k3_r5_remoteproc.c +2 -1
@@ -1324,7 +1324,7 @@ init_rmem:dev_err (dev,"Timed out waiting for %s core to power up!\n" , rproc->name); -return ret; + goto err_powerup; } }
@@ -1340,6 +1340,7 @@ err_split: } } +err_powerup:rproc_del (rproc); err_add:k3_r5_reserved_mem_exit (kproc);
Greg Kroah-Hartman
maintainerPATCH 582/798 clk: qcom: dispcc-sm8250: use CLK_SET_RATE_PARENT for branch clocks
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
commit 0e93c6320ecde0583de09f3fe801ce8822886fec upstream.
Add CLK_SET_RATE_PARENT for several branch clocks. Such clocks don't have a way to change the rate, so set the parent rate instead.
--- drivers/clk/qcom/dispcc-sm8250.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/clk/qcom/dispcc-sm8250.c +3 -0
@@ -837,6 +837,7 @@ static struct clk_branch disp_cc_mdss_dp &disp_cc_mdss_dp_link1_div_clk_src.clkr.hw, }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, },
@@ -872,6 +873,7 @@ static struct clk_branch disp_cc_mdss_dp &disp_cc_mdss_dp_link_div_clk_src.clkr.hw, }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, },
@@ -997,6 +999,7 @@ static struct clk_branch disp_cc_mdss_md &disp_cc_mdss_mdp_clk_src.clkr.hw, }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, },
Greg Kroah-Hartman
maintainerPATCH 583/798 media: sun4i_csi: Implement link validate for sun4i_csi subdev
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laurent Pinchart <[email protected]>
commit 2dc5d5d401f5c6cecd97800ffef82e8d17d228f0 upstream.
The sun4i_csi driver doesn't implement link validation for the subdev it registers, leaving the link between the subdev and its source unvalidated. Fix it, using the v4l2_subdev_link_validate() helper.
--- drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c +5 -0
@@ -40,6 +40,10 @@ static const struct media_entity_operati .link_validate = v4l2_subdev_link_validate, }; +static const struct media_entity_operations sun4i_csi_subdev_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; +static int sun4i_csi_notify_bound (struct v4l2_async_notifier *notifier,struct v4l2_subdev *subdev,struct v4l2_async_subdev *asd)
@@ -214,6 +218,7 @@ static int sun4i_csi_probe(struct platfov4l2_subdev_init (subdev, &sun4i_csi_subdev_ops); subdev->flags =V4L2_SUBDEV_FL_HAS_DEVNODE |V4L2_SUBDEV_FL_HAS_EVENTS ; subdev->entity.function =MEDIA_ENT_F_VID_IF_BRIDGE ; + subdev->entity.ops = &sun4i_csi_subdev_entity_ops; subdev->owner =THIS_MODULE ;snprintf (subdev->name,sizeof (subdev->name),"sun4i-csi-0" );v4l2_set_subdevdata (subdev, csi);
Greg Kroah-Hartman
maintainerPATCH 584/798 clk: qcom: gcc-sm8450: Do not turn off PCIe GDSCs during gdsc_disable()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manivannan Sadhasivam <[email protected]>
commit 889e1332310656961855c0dcedbb4dbe78e39d22 upstream.
With PWRSTS_OFF_ON, PCIe GDSCs are turned off during gdsc_disable(). This can happen during scenarios such as system suspend and breaks the resume of PCIe controllers from suspend.
So use PWRSTS_RET_ON to indicate the GDSC driver to not turn off the GDSCs during gdsc_disable() and allow the hardware to transition the GDSCs to retention when the parent domain enters low power state during system suspend.
--- drivers/clk/qcom/gcc-sm8450.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/qcom/gcc-sm8450.c +2 -2
@@ -2934,7 +2934,7 @@ static struct gdsc pcie_0_gdsc = { .pd = { .name = "pcie_0_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, };static struct gdsc pcie_1_gdsc = {
@@ -2942,7 +2942,7 @@ static struct gdsc pcie_1_gdsc = { .pd = { .name = "pcie_1_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, };static struct gdsc ufs_phy_gdsc = {
Greg Kroah-Hartman
maintainerPATCH 585/798 media: uapi/linux/cec.h: cec_msg_set_reply_to: zero flags
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil <[email protected]>
commit 599f6899051cb70c4e0aa9fd591b9ee220cb6f14 upstream.
The cec_msg_set_reply_to() helper function never zeroed the struct cec_msg flags field, this can cause unexpected behavior if flags was uninitialized to begin with.
--- include/uapi/linux/cec.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
include/uapi/linux/cec.h +5 -1
@@ -132,6 +132,8 @@ static inline void cec_msg_init(struct c* Set the msg destination to the orig initiator and the msg initiator to the * orig destination. Note that msg and orig may be the same pointer, in which * case the change is done in place. +* +* It also zeroes the reply, timeout and flags fields. */ static inline void cec_msg_set_reply_to (struct cec_msg *msg,struct cec_msg *orig)
@@ -139,7 +141,9 @@ static inline void cec_msg_set_reply_to(/* The destination becomes the initiator and vice versa */ msg->msg[0 ] = (cec_msg_destination (orig) <<4 ) |cec_msg_initiator (orig); - msg->reply = msg->timeout =0 ; + msg->reply =0 ; + msg->timeout =0 ; + msg->flags =0 ; }/**
Greg Kroah-Hartman
maintainerPATCH 586/798 clk: qcom: clk-rpmh: Fix overflow in BCM vote
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Tipton <[email protected]>
commit a4e5af27e6f6a8b0d14bc0d7eb04f4a6c7291586 upstream.
Valid frequencies may result in BCM votes that exceed the max HW value. Set vote ceiling to BCM_TCS_CMD_VOTE_MASK to ensure the votes aren't truncated, which can result in lower frequencies than desired.
--- drivers/clk/qcom/clk-rpmh.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/clk/qcom/clk-rpmh.c +2 -0
@@ -266,6 +266,8 @@ static int clk_rpmh_bcm_send_cmd(struct cmd_state =0 ; } + cmd_state =min (cmd_state,BCM_TCS_CMD_VOTE_MASK ); +if (c->last_sent_aggr_state != cmd_state) { cmd.addr = c->res_addr; cmd.data =BCM_TCS_CMD (1 , enable,0 , cmd_state);
Greg Kroah-Hartman
maintainerPATCH 587/798 clk: qcom: gcc-sm8150: De-register gcc_cpuss_ahb_clk_src
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satya Priya Kakitapalli <[email protected]>
commit bab0c7a0bc586e736b7cd2aac8e6391709a70ef2 upstream.
The branch clocks of gcc_cpuss_ahb_clk_src are marked critical and hence these clocks vote on XO blocking the suspend. De-register these clocks and its source as there is no rate setting happening on them.
--- drivers/clk/qcom/gcc-sc8180x.c | 63 ----------------------------------------- 1 file changed, 63 deletions(-)
drivers/clk/qcom/gcc-sc8180x.c +0 -63
@@ -261,28 +261,6 @@ static const struct clk_parent_data gcc_ { .hw = &gpll0_out_even.clkr.hw }, }; -static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = { -F (19200000 ,P_BI_TCXO ,1 ,0 ,0 ), -F (50000000 ,P_GPLL0_OUT_MAIN ,12 ,0 ,0 ), -F (100000000 ,P_GPLL0_OUT_MAIN ,6 ,0 ,0 ), - { } -}; - -static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { - .cmd_rcgr =0x48014 , - .mnd_width =0 , - .hid_width =5 , - .parent_map = gcc_parent_map_0, - .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_cpuss_ahb_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, -}; -static const struct freq_tbl ftbl_gcc_emac_ptp_clk_src[] = {F (19200000 ,P_BI_TCXO ,1 ,0 ,0 ),F (50000000 ,P_GPLL0_OUT_EVEN ,6 ,0 ,0 ),
@@ -1600,25 +1578,6 @@ static struct clk_branch gcc_cfg_noc_usb }, }; -/* For CPUSS functionality the AHB clock needs to be left enabled */ -static struct clk_branch gcc_cpuss_ahb_clk = { - .halt_reg =0x48000 , - .halt_check =BRANCH_HALT_VOTED , - .clkr = { - .enable_reg =0x52004 , - .enable_mask =BIT (21 ), - .hw.init = &(struct clk_init_data ){ - .name ="gcc_cpuss_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &gcc_cpuss_ahb_clk_src.clkr.hw - }, - .num_parents =1 , - .flags =CLK_IS_CRITICAL |CLK_SET_RATE_PARENT , - .ops = &clk_branch2_ops, - }, - }, -}; -static struct clk_branch gcc_cpuss_rbcpr_clk = { .halt_reg =0x48008 , .halt_check =BRANCH_HALT ,
@@ -3151,25 +3110,6 @@ static struct clk_branch gcc_sdcc4_apps_ }, }; -/* For CPUSS functionality the SYS NOC clock needs to be left enabled */ -static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = { - .halt_reg =0x4819c , - .halt_check =BRANCH_HALT_VOTED , - .clkr = { - .enable_reg =0x52004 , - .enable_mask =BIT (0 ), - .hw.init = &(struct clk_init_data ){ - .name ="gcc_sys_noc_cpuss_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &gcc_cpuss_ahb_clk_src.clkr.hw - }, - .num_parents =1 , - .flags =CLK_IS_CRITICAL |CLK_SET_RATE_PARENT , - .ops = &clk_branch2_ops, - }, - }, -}; -static struct clk_branch gcc_tsif_ahb_clk = { .halt_reg =0x36004 , .halt_check =BRANCH_HALT ,
@@ -4259,8 +4199,6 @@ static struct clk_regmap *gcc_sc8180x_cl [GCC_CFG_NOC_USB3_MP_AXI_CLK] = &gcc_cfg_noc_usb3_mp_axi_clk.clkr, [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, [GCC_CFG_NOC_USB3_SEC_AXI_CLK] = &gcc_cfg_noc_usb3_sec_axi_clk.clkr, - [GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr, - [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr, [GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr, [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr, [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr,
@@ -4397,7 +4335,6 @@ static struct clk_regmap *gcc_sc8180x_cl [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr, [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, [GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr, - [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr, [GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr, [GCC_TSIF_INACTIVITY_TIMERS_CLK] = &gcc_tsif_inactivity_timers_clk.clkr, [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr,
Greg Kroah-Hartman
maintainerPATCH 588/798 media: venus: fix use after free bug in venus_remove due to race condition
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zheng Wang <[email protected]>
commit c5a85ed88e043474161bbfe54002c89c1cb50ee2 upstream.
in venus_probe, core->work is bound with venus_sys_error_handler, which is used to handle error. The code use core->sys_err_done to make sync work. The core->work is started in venus_event_notify.
If we call venus_remove, there might be an unfished work. The possible sequence is as follows:
CPU0 CPU1
|venus_sys_error_handlervenus_remove |hfi_destroy |venus_hfi_destroy |
kfree(hdev); |
|hfi_reinit
|venus_hfi_queues_reinit
|//use hdevFix it by canceling the work in venus_remove.
--- drivers/media/platform/qcom/venus/core.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/platform/qcom/venus/core.c +1 -0
@@ -423,6 +423,7 @@ static int venus_remove(struct platform_struct device *dev = core->dev;int ret; +cancel_delayed_work_sync (&core->work); ret =pm_runtime_get_sync (dev);WARN_ON (ret <0 );
Greg Kroah-Hartman
maintainerPATCH 589/798 clk: qcom: gcc-sm8250: Do not turn off PCIe GDSCs during gdsc_disable()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manivannan Sadhasivam <[email protected]>
commit ade508b545c969c72cd68479f275a5dd640fd8b9 upstream.
With PWRSTS_OFF_ON, PCIe GDSCs are turned off during gdsc_disable(). This can happen during scenarios such as system suspend and breaks the resume of PCIe controllers from suspend.
So use PWRSTS_RET_ON to indicate the GDSC driver to not turn off the GDSCs during gdsc_disable() and allow the hardware to transition the GDSCs to retention when the parent domain enters low power state during system suspend.
--- drivers/clk/qcom/gcc-sm8250.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/qcom/gcc-sm8250.c +3 -3
@@ -3228,7 +3228,7 @@ static struct gdsc pcie_0_gdsc = { .pd = { .name = "pcie_0_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, };static struct gdsc pcie_1_gdsc = {
@@ -3236,7 +3236,7 @@ static struct gdsc pcie_1_gdsc = { .pd = { .name = "pcie_1_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, };static struct gdsc pcie_2_gdsc = {
@@ -3244,7 +3244,7 @@ static struct gdsc pcie_2_gdsc = { .pd = { .name = "pcie_2_gdsc", }, - .pwrsts = PWRSTS_OFF_ON, + .pwrsts = PWRSTS_RET_ON, };static struct gdsc ufs_card_gdsc = {
Greg Kroah-Hartman
maintainerPATCH 590/798 media: qcom: camss: Fix ordering of pm_runtime_enable
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan O'Donoghue <[email protected]>
commit a151766bd3688f6803e706c6433a7c8d3c6a6a94 upstream.
pm_runtime_enable() should happen prior to vfe_get() since vfe_get() calls pm_runtime_resume_and_get().
This is a basic race condition that doesn't show up for most users so is not widely reported. If you blacklist qcom-camss in modules.d and then subsequently modprobe the module post-boot it is possible to reliably show this error up.
The kernel log for this error looks like this:
qcom-camss ac5a000.camss: Failed to power up pipeline: -13
--- drivers/media/platform/qcom/camss/camss.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/media/platform/qcom/camss/camss.c +3 -2
@@ -1663,6 +1663,8 @@ static int camss_probe(struct platform_dv4l2_async_nf_init (&camss->notifier); +pm_runtime_enable (dev); + num_subdevs =camss_of_parse_ports (camss);if (num_subdevs <0 ) { ret = num_subdevs;
@@ -1700,8 +1702,6 @@ static int camss_probe(struct platform_d } } -pm_runtime_enable (dev); -return 0 ; err_register_subdevs:
@@ -1709,6 +1709,7 @@ err_register_subdevs: err_v4l2_device_unregister:v4l2_device_unregister (&camss->v4l2_dev);v4l2_async_nf_cleanup (&camss->notifier); +pm_runtime_disable (dev); err_genpd_cleanup:camss_genpd_cleanup (camss);
Greg Kroah-Hartman
maintainerPATCH 591/798 clk: qcom: gcc-sc8180x: Fix the sdcc2 and sdcc4 clocks freq table
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satya Priya Kakitapalli <[email protected]>
commit b8acaf2de8081371761ab4cf1e7a8ee4e7acc139 upstream.
Update the frequency tables of gcc_sdcc2_apps_clk and gcc_sdcc4_apps_clk as per the latest frequency plan.
--- drivers/clk/qcom/gcc-sc8180x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/clk/qcom/gcc-sc8180x.c +2 -3
@@ -895,7 +895,7 @@ static const struct freq_tbl ftbl_gcc_sdF (25000000 ,P_GPLL0_OUT_MAIN ,12 ,1 ,2 ),F (50000000 ,P_GPLL0_OUT_MAIN ,12 ,0 ,0 ),F (100000000 ,P_GPLL0_OUT_MAIN ,6 ,0 ,0 ), - F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(202000000, P_GPLL9_OUT_MAIN, 4, 0, 0), { } };
@@ -918,9 +918,8 @@ static const struct freq_tbl ftbl_gcc_sdF (400000 ,P_BI_TCXO ,12 ,1 ,4 ),F (9600000 ,P_BI_TCXO ,2 ,0 ,0 ),F (19200000 ,P_BI_TCXO ,1 ,0 ,0 ), -F (37500000 ,P_GPLL0_OUT_MAIN ,16 ,0 ,0 ),F (50000000 ,P_GPLL0_OUT_MAIN ,12 ,0 ,0 ), - F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), { } };
Greg Kroah-Hartman
maintainerPATCH 592/798 clk: qcom: clk-alpha-pll: Fix CAL_L_VAL override for LUCID EVO PLL
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ajit Pandey <[email protected]>
commit fff617979f97c773aaa9432c31cf62444b3bdbd4 upstream.
In LUCID EVO PLL CAL_L_VAL and L_VAL bitfields are part of single PLL_L_VAL register. Update for L_VAL bitfield values in PLL_L_VAL register using regmap_write() API in __alpha_pll_trion_set_rate callback will override LUCID EVO PLL initial configuration related to PLL_CAL_L_VAL bit fields in PLL_L_VAL register.
Observed random PLL lock failures during PLL enable due to such override in PLL calibration value. Use regmap_update_bits() with L_VAL bitfield mask instead of regmap_write() API to update only PLL_L_VAL bitfields in __alpha_pll_trion_set_rate callback.
--- drivers/clk/qcom/clk-alpha-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/clk-alpha-pll.c +1 -1
@@ -1581,7 +1581,7 @@ static int __alpha_pll_trion_set_rate(stif (ret <0 )return ret; -regmap_write (pll->clkr.regmap,PLL_L_VAL (pll), l); +regmap_update_bits (pll->clkr.regmap,PLL_L_VAL (pll),LUCID_EVO_PLL_L_VAL_MASK , l);regmap_write (pll->clkr.regmap,PLL_ALPHA_VAL (pll), a);/* Latch the PLL input */
Greg Kroah-Hartman
maintainerPATCH 593/798 smb: client: use actual path when queryfs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: wangrong <[email protected]>
commit a421e3fe0e6abe27395078f4f0cec5daf466caea upstream.
Due to server permission control, the client does not have access to the shared root directory, but can access subdirectories normally, so users usually mount the shared subdirectories directly. In this case, queryfs should use the actual path instead of the root directory to avoid the call returning an error (EACCES).
--- fs/smb/client/cifsfs.c | 13 ++++++++++++- fs/smb/client/cifsglob.h | 2 +- fs/smb/client/smb1ops.c | 2 +- fs/smb/client/smb2ops.c | 19 ++++++++++++------- 4 files changed, 26 insertions(+), 10 deletions(-)
fs/smb/client/cifsfs.c +12 -1
@@ -311,8 +311,17 @@ cifs_statfs(struct dentry *dentry, strucstruct TCP_Server_Info *server = tcon->ses->server;unsigned int xid;int rc =0 ; +const char *full_path; +void *page; xid =get_xid (); + page =alloc_dentry_path (); + + full_path =build_path_from_dentry (dentry, page); +if (IS_ERR (full_path)) { + rc =PTR_ERR (full_path); + goto statfs_out; + }if (le32_to_cpu (tcon->fsAttrInfo.MaxPathNameComponentLength) >0 ) buf->f_namelen =
@@ -328,8 +337,10 @@ cifs_statfs(struct dentry *dentry, struc buf->f_ffree =0 ;/* unlimited */ if (server->ops->queryfs) - rc = server->ops->queryfs (xid, tcon, cifs_sb, buf); + rc = server->ops->queryfs (xid, tcon, full_path, cifs_sb, buf); +statfs_out: +free_dentry_path (page);free_xid (xid);return rc; }
fs/smb/client/cifsglob.h +1 -1
@@ -432,7 +432,7 @@ struct smb_version_operations { __u16 net_fid, struct cifsInodeInfo *cifs_inode);/* query remote filesystem */ int (*queryfs)(const unsigned int ,struct cifs_tcon *, -struct cifs_sb_info *,struct kstatfs *); +const char *,struct cifs_sb_info *,struct kstatfs *);/* send mandatory brlock to the server */ int (*mand_lock)(const unsigned int ,struct cifsFileInfo *,__u64 ,__u64 ,__u32 ,int ,int ,bool );
fs/smb/client/smb1ops.c +1 -1
@@ -906,7 +906,7 @@ cifs_oplock_response(struct cifs_tcon *tstatic int cifs_queryfs (const unsigned int xid,struct cifs_tcon *tcon, -struct cifs_sb_info *cifs_sb,struct kstatfs *buf) +const char *path,struct cifs_sb_info *cifs_sb,struct kstatfs *buf) {int rc = -EOPNOTSUPP ;
fs/smb/client/smb2ops.c +12 -7
@@ -2677,7 +2677,7 @@ smb2_query_info_compound(const unsignedstatic int smb2_queryfs (const unsigned int xid,struct cifs_tcon *tcon, -struct cifs_sb_info *cifs_sb,struct kstatfs *buf) +const char *path,struct cifs_sb_info *cifs_sb,struct kstatfs *buf) {struct smb2_query_info_rsp *rsp;struct smb2_fs_full_size_info *info =NULL ;
@@ -2686,7 +2686,7 @@ smb2_queryfs(const unsigned int xid, strint rc; - rc = smb2_query_info_compound(xid, tcon, "", + rc = smb2_query_info_compound(xid, tcon, path, FILE_READ_ATTRIBUTES, FS_FULL_SIZE_INFORMATION, SMB2_O_INFO_FILESYSTEM,
@@ -2713,28 +2713,33 @@ qfs_exit:static int smb311_queryfs (const unsigned int xid,struct cifs_tcon *tcon, -struct cifs_sb_info *cifs_sb,struct kstatfs *buf) +const char *path,struct cifs_sb_info *cifs_sb,struct kstatfs *buf) {int rc; -__le16 srch_path =0 ;/* Null - open root of share */ +__le16 *utf16_path =NULL ;u8 oplock =SMB2_OPLOCK_LEVEL_NONE ;struct cifs_open_parms oparms;struct cifs_fid fid;if (!tcon->posix_extensions) -return smb2_queryfs (xid, tcon, cifs_sb, buf); +return smb2_queryfs (xid, tcon, path, cifs_sb, buf); oparms = (struct cifs_open_parms ) { .tcon = tcon, - .path ="" , + .path = path, .desired_access =FILE_READ_ATTRIBUTES , .disposition =FILE_OPEN , .create_options =cifs_create_options (cifs_sb,0 ), .fid = &fid, }; - rc =SMB2_open (xid, &oparms, &srch_path, &oplock,NULL ,NULL , + utf16_path =cifs_convert_path_to_utf16 (path, cifs_sb); +if (utf16_path ==NULL ) +return -ENOMEM ; + + rc =SMB2_open (xid, &oparms, utf16_path, &oplock,NULL ,NULL ,NULL ,NULL ); +kfree (utf16_path);if (rc)return rc;
Greg Kroah-Hartman
maintainerPATCH 594/798 iio: magnetometer: ak8975: Fix reading for ak099xx sensors
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Barnabás Czémán <[email protected]>
commit 129464e86c7445a858b790ac2d28d35f58256bbe upstream.
Move ST2 reading with overflow handling after measurement data reading.
ST2 register read have to be read after read measurment data, because it means end of the reading and realease the lock on the data. Remove ST2 read skip on interrupt based waiting because ST2 required to be read out at and of the axis read.
--- drivers/iio/magnetometer/ak8975.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)
drivers/iio/magnetometer/ak8975.c +16 -16
@@ -692,22 +692,8 @@ static int ak8975_start_read_axis(structif (ret <0 )return ret; -/* This will be executed only for non-interrupt based waiting case */ -if (ret & data->def->ctrl_masks[ST1_DRDY ]) { - ret =i2c_smbus_read_byte_data (client, - data->def->ctrl_regs[ST2 ]); -if (ret <0 ) { -dev_err (&client->dev,"Error in reading ST2\n" ); -return ret; - } -if (ret & (data->def->ctrl_masks[ST2_DERR ] | - data->def->ctrl_masks[ST2_HOFL ])) { -dev_err (&client->dev,"ST2 status error 0x%x\n" , ret); -return -EINVAL ; - } - } - -return 0 ; +/* Return with zero if the data is ready. */ +return !data->def->ctrl_regs[ST1_DRDY ]; }/* Retrieve raw flux value for one of the x, y, or z axis. */
@@ -734,6 +720,20 @@ static int ak8975_read_axis(struct iio_dif (ret <0 ) goto exit; +/* Read out ST2 for release lock on measurment data. */ + ret =i2c_smbus_read_byte_data (client, data->def->ctrl_regs[ST2 ]); +if (ret <0 ) { +dev_err (&client->dev,"Error in reading ST2\n" ); + goto exit; + } + +if (ret & (data->def->ctrl_masks[ST2_DERR ] | + data->def->ctrl_masks[ST2_HOFL ])) { +dev_err (&client->dev,"ST2 status error 0x%x\n" , ret); + ret = -EINVAL ; + goto exit; + } +mutex_unlock (&data->lock);pm_runtime_mark_last_busy (&data->client->dev);
Greg Kroah-Hartman
maintainerPATCH 595/798 gso: fix udp gso fraglist segmentation after pull from frag_list
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willem de Bruijn <[email protected]>
commit a1e40ac5b5e9077fe1f7ae0eb88034db0f9ae1ab upstream.
Detect gso fraglist skbs with corrupted geometry (see below) and pass these to skb_segment instead of skb_segment_list, as the first can segment them correctly.
Valid SKB_GSO_FRAGLIST skbs
- consist of two or more segments
- the head_skb holds the protocol headers plus first gso_size
- one or more frag_list skbs hold exactly one segment
- all but the last must be gso_size
Optional datapath hooks such as NAT and BPF (bpf_skb_pull_data) can modify these skbs, breaking these invariants.
In extreme cases they pull all data into skb linear. For UDP, this causes a NULL ptr deref in __udpv4_gso_segment_list_csum at udp_hdr(seg->next)->dest.
Detect invalid geometry due to pull, by checking head_skb size. Don't just drop, as this may blackhole a destination. Convert to be able to pass to regular skb_segment.
--- net/ipv4/udp_offload.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
net/ipv4/udp_offload.c +20 -2
@@ -289,8 +289,26 @@ struct sk_buff *__udp_gso_segment(structreturn NULL ; } -if (skb_shinfo (gso_skb)->gso_type &SKB_GSO_FRAGLIST ) -return __udp_gso_segment_list (gso_skb, features, is_ipv6); +if (skb_shinfo (gso_skb)->gso_type &SKB_GSO_FRAGLIST ) { +/* Detect modified geometry and pass those to skb_segment. */ +if (skb_pagelen (gso_skb) -sizeof (*uh) ==skb_shinfo (gso_skb)->gso_size) +return __udp_gso_segment_list (gso_skb, features, is_ipv6); + +/* Setup csum, as fraglist skips this in udp4_gro_receive. */ + gso_skb->csum_start =skb_transport_header (gso_skb) - gso_skb->head; + gso_skb->csum_offset = offsetof(struct udphdr , check); + gso_skb->ip_summed =CHECKSUM_PARTIAL ; + + uh =udp_hdr (gso_skb); +if (is_ipv6) + uh->check = ~udp_v6_check (gso_skb->len, + &ipv6_hdr (gso_skb)->saddr, + &ipv6_hdr (gso_skb)->daddr,0 ); +else + uh->check = ~udp_v4_check (gso_skb->len, +ip_hdr (gso_skb)->saddr, +ip_hdr (gso_skb)->daddr,0 ); + }skb_pull (gso_skb,sizeof (*uh));
Greg Kroah-Hartman
maintainerPATCH 596/798 tomoyo: fallback to realpath if symlinks pathname does not exist
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tetsuo Handa <[email protected]>
commit ada1986d07976d60bed5017aa38b7f7cf27883f7 upstream.
Alfred Agrell found that TOMOYO cannot handle execveat(AT_EMPTY_PATH) inside chroot environment where /dev and /proc are not mounted, for commit 51f39a1f0cea ("syscalls: implement execveat() system call") missed that TOMOYO tries to canonicalize argv[0] when the filename fed to the executed program as argv[0] is supplied using potentially nonexistent pathname.
Since "/dev/fd/<fd>" already lost symlink information used for obtaining that <fd>, it is too late to reconstruct symlink's pathname. Although <filename> part of "/dev/fd/<fd>/<filename>" might not be canonicalized, TOMOYO cannot use tomoyo_realpath_nofollow() when /dev or /proc is not mounted. Therefore, fallback to tomoyo_realpath_from_path() when tomoyo_realpath_nofollow() failed.
--- security/tomoyo/domain.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
security/tomoyo/domain.c +6 -3
@@ -723,10 +723,13 @@ int tomoyo_find_next_domain(struct linux ee->r.obj = &ee->obj; ee->obj.path1 = bprm->file->f_path;/* Get symlink's pathname of program. */ - retval = -ENOENT ; exename.name =tomoyo_realpath_nofollow (original_name); -if (!exename.name) - goto out; +if (!exename.name) { +/* Fallback to realpath if symlink's pathname does not exist. */ + exename.name =tomoyo_realpath_from_path (&bprm->file->f_path); +if (!exename.name) + goto out; + }tomoyo_fill_path_info (&exename); retry:/* Check 'aggregator' directive. */
Greg Kroah-Hartman
maintainerPATCH 597/798 net: stmmac: Fix zero-division error when disabling tc cbs
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: KhaiWenTan <[email protected]>
commit 675faf5a14c14a2be0b870db30a70764df81e2df upstream.
The commit b8c43360f6e4 ("net: stmmac: No need to calculate speed divider when offload is disabled") allows the "port_transmit_rate_kbps" to be set to a value of 0, which is then passed to the "div_s64" function when tc-cbs is disabled. This leads to a zero-division error.
When tc-cbs is disabled, the idleslope, sendslope, and credit values the credit values are not required to be configured. Therefore, adding a return statement after setting the txQ mode to DCB when tc-cbs is disabled would prevent a zero-division error.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +1 -0
@@ -396,6 +396,7 @@ static int tc_setup_cbs(struct stmmac_prreturn ret; priv->plat->tx_queues_cfg[queue].mode_to_use =MTL_QUEUE_DCB ; +return 0 ; }/* Final adjustments for HW */
Greg Kroah-Hartman
maintainerPATCH 598/798 rtc: at91sam9: fix OF node leak in probe() error path
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 73580e2ee6adfb40276bd420da3bb1abae204e10 upstream.
Driver is leaking an OF node reference obtained from of_parse_phandle_with_fixed_args().
--- drivers/rtc/rtc-at91sam9.c | 1 + 1 file changed, 1 insertion(+)
drivers/rtc/rtc-at91sam9.c +1 -0
@@ -368,6 +368,7 @@ static int at91_rtc_probe(struct platforreturn ret; rtc->gpbr =syscon_node_to_regmap (args.np); +of_node_put (args.np); rtc->gpbr_offset = args.args[0 ];if (IS_ERR (rtc->gpbr)) {dev_err (&pdev->dev,"failed to retrieve gpbr regmap, aborting.\n" );
Greg Kroah-Hartman
maintainerPATCH 599/798 Input: adp5589-keys - fix NULL pointer dereference
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sa <[email protected]>
commit fb5cc65f973661241e4a2b7390b429aa7b330c69 upstream.
We register a devm action to call adp5589_clear_config() and then pass the i2c client as argument so that we can call i2c_get_clientdata() in order to get our device object. However, i2c_set_clientdata() is only being set at the end of the probe function which means that we'll get a NULL pointer dereference in case the probe function fails early.
--- drivers/input/keyboard/adp5589-keys.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/input/keyboard/adp5589-keys.c +3 -6
@@ -936,10 +936,9 @@ static int adp5589_keypad_add(struct adpstatic void adp5589_clear_config (void *data) { -struct i2c_client *client = data; -struct adp5589_kpad *kpad =i2c_get_clientdata (client); +struct adp5589_kpad *kpad = data; -adp5589_write (client, kpad->var->reg (ADP5589_GENERAL_CFG ),0 ); +adp5589_write (kpad->client, kpad->var->reg (ADP5589_GENERAL_CFG ),0 ); } static int adp5589_probe(struct i2c_client *client,
@@ -983,7 +982,7 @@ static int adp5589_probe(struct i2c_clie } error =devm_add_action_or_reset (&client->dev, adp5589_clear_config, - client); + kpad);if (error)return error;
@@ -1010,8 +1009,6 @@ static int adp5589_probe(struct i2c_clieif (error)return error; -i2c_set_clientdata (client, kpad); -dev_info (&client->dev,"Rev.%d keypad, irq %d\n" , revid, client->irq);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 600/798 Input: adp5589-keys - fix adp5589_gpio_get_value()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sa <[email protected]>
commit c684771630e64bc39bddffeb65dd8a6612a6b249 upstream.
The adp5589 seems to have the same behavior as similar devices as explained in commit 910a9f5636f5 ("Input: adp5588-keys - get value from data out when dir is out").
Basically, when the gpio is set as output we need to get the value from ADP5589_GPO_DATA_OUT_A register instead of ADP5589_GPI_STATUS_A.
--- drivers/input/keyboard/adp5589-keys.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/input/keyboard/adp5589-keys.c +10 -3
@@ -391,10 +391,17 @@ static int adp5589_gpio_get_value(structstruct adp5589_kpad *kpad =gpiochip_get_data (chip);unsigned int bank = kpad->var->bank (kpad->gpiomap[off]);unsigned int bit = kpad->var->bit (kpad->gpiomap[off]); +int val; -return !!(adp5589_read (kpad->client, - kpad->var->reg (ADP5589_GPI_STATUS_A ) + bank) & - bit); +mutex_lock (&kpad->gpio_lock); +if (kpad->dir[bank] & bit) + val = kpad->dat_out[bank]; +else + val =adp5589_read (kpad->client, + kpad->var->reg (ADP5589_GPI_STATUS_A ) + bank); +mutex_unlock (&kpad->gpio_lock); + +return !!(val & bit); } static void adp5589_gpio_set_value(struct gpio_chip *chip,
Greg Kroah-Hartman
maintainerPATCH 601/798 cachefiles: fix dentry leak in cachefiles_open_file()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit da6ef2dffe6056aad3435e6cf7c6471c2a62187c upstream.
A dentry leak may be caused when a lookup cookie and a cull are concurrent:
P1 | P2
-----------------------------------------------------------cachefiles_lookup_cookie
cachefiles_look_up_object
lookup_one_positive_unlocked
// get dentry
cachefiles_cull
inode->i_flags |= S_KERNEL_FILE;
cachefiles_open_file
cachefiles_mark_inode_in_use
__cachefiles_mark_inode_in_use
can_use = false
if (!(inode->i_flags & S_KERNEL_FILE))
can_use = true
return false
return false
// Returns an error but doesn't put dentryAfter that the following WARNING will be triggered when the backend folder is umounted:
==================================================================
BUG: Dentry 000000008ad87947{i=7a,n=Dx_1_1.img} still in use (1) [unmount of ext4 sda]
WARNING: CPU: 4 PID: 359261 at fs/dcache.c:1767 umount_check+0x5d/0x70
CPU: 4 PID: 359261 Comm: umount Not tainted 6.6.0-dirty #25
RIP: 0010:umount_check+0x5d/0x70
Call Trace:
<TASK>
d_walk+0xda/0x2b0
do_one_tree+0x20/0x40
shrink_dcache_for_umount+0x2c/0x90
generic_shutdown_super+0x20/0x160
kill_block_super+0x1a/0x40
ext4_kill_sb+0x22/0x40
deactivate_locked_super+0x35/0x80
cleanup_mnt+0x104/0x160
==================================================================Whether cachefiles_open_file() returns true or false, the reference count obtained by lookup_positive_unlocked() in cachefiles_look_up_object() should be released.
Therefore release that reference count in cachefiles_look_up_object() to fix the above issue and simplify the code.
--- fs/cachefiles/namei.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
fs/cachefiles/namei.c +3 -4
@@ -593,14 +593,12 @@ static bool cachefiles_open_file(struct* write and readdir but not lookup or open). */ touch_atime (&file->f_path); -dput (dentry);return true; check_failed:fscache_cookie_lookup_negative (object->cookie);cachefiles_unmark_inode_in_use (object, file);fput (file); -dput (dentry);if (ret == -ESTALE )return cachefiles_create_file (object);return false;
@@ -609,7 +607,6 @@ error_fput:fput (file); error:cachefiles_do_unmark_inode_in_use (object,d_inode (dentry)); -dput (dentry);return false; }
@@ -652,7 +649,9 @@ bool cachefiles_look_up_object(struct ca goto new_file; } -if (!cachefiles_open_file (object, dentry)) + ret =cachefiles_open_file (object, dentry); +dput (dentry); +if (!ret)return false;_leave (" = t [%lu]" ,file_inode (object->file)->i_ino);
Greg Kroah-Hartman
maintainerPATCH 602/798 ACPI: resource: Add Asus Vivobook X1704VAP to irq1_level_low_skip_override[]
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit 2f80ce0b78c340e332f04a5801dee5e4ac8cfaeb upstream.
Like other Asus Vivobook models the X1704VAP has its keybopard IRQ (1) described as ActiveLow in the DSDT, which the kernel overrides to EdgeHigh which breaks the keyboard.
Add the X1704VAP to the irq1_level_low_skip_override[] quirk table to fix this.
--- drivers/acpi/resource.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/acpi/resource.c +7 -0
@@ -440,6 +440,13 @@ static const struct dmi_system_id asus_l }, }, { +/* Asus Vivobook X1704VAP */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"ASUSTeK COMPUTER INC." ), + DMI_MATCH(DMI_BOARD_NAME, "X1704VAP"), + }, + }, + { .ident ="Asus ExpertBook B1402CBA" , .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
Greg Kroah-Hartman
maintainerPATCH 603/798 ACPI: resource: Add Asus ExpertBook B2502CVA to irq1_level_low_skip_override[]
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit 056301e7c7c886f96d799edd36f3406cc30e1822 upstream.
Like other Asus ExpertBook models the B2502CVA has its keybopard IRQ (1) described as ActiveLow in the DSDT, which the kernel overrides to EdgeHigh which breaks the keyboard.
Add the B2502CVA to the irq1_level_low_skip_override[] quirk table to fix this.
--- drivers/acpi/resource.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/acpi/resource.c +7 -0
@@ -514,6 +514,13 @@ static const struct dmi_system_id mainge } }, { +/* Asus ExpertBook B2502CVA */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"ASUSTeK COMPUTER INC." ), + DMI_MATCH(DMI_BOARD_NAME, "B2502CVA"), + }, + }, + {/* TongFang GMxXGxx/TUXEDO Polaris 15 Gen5 AMD */ .matches = { DMI_MATCH(DMI_BOARD_NAME, "GMxXGxx"),
Greg Kroah-Hartman
maintainerPATCH 604/798 btrfs: fix a NULL pointer dereference when failed to start a new trasacntion
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit c3b47f49e83197e8dffd023ec568403bcdbb774b upstream.
[BUG]
Syzbot reported a NULL pointer dereference with the following crash:
FAULT_INJECTION: forcing a failure.
start_transaction+0x830/0x1670 fs/btrfs/transaction.c:676 prepare_to_relocate+0x31f/0x4c0 fs/btrfs/relocation.c:3642 relocate_block_group+0x169/0xd20 fs/btrfs/relocation.c:3678 ... BTRFS info (device loop0): balance: ended with status: -12 Oops: general protection fault, probably for non-canonical address 0xdffffc00000000cc: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000660-0x0000000000000667] RIP: 0010:btrfs_update_reloc_root+0x362/0xa80 fs/btrfs/relocation.c:926 Call Trace: <TASK> commit_fs_roots+0x2ee/0x720 fs/btrfs/transaction.c:1496 btrfs_commit_transaction+0xfaf/0x3740 fs/btrfs/transaction.c:2430 del_balance_item fs/btrfs/volumes.c:3678 [inline] reset_balance_state+0x25e/0x3c0 fs/btrfs/volumes.c:3742 btrfs_balance+0xead/0x10c0 fs/btrfs/volumes.c:4574 btrfs_ioctl_balance+0x493/0x7c0 fs/btrfs/ioctl.c:3673 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
[CAUSE]
The allocation failure happens at the start_transaction() inside prepare_to_relocate(), and during the error handling we call unset_reloc_control(), which makes fs_info->balance_ctl to be NULL.
Then we continue the error path cleanup in btrfs_balance() by calling reset_balance_state() which will call del_balance_item() to fully delete the balance item in the root tree.
However during the small window between set_reloc_contrl() and unset_reloc_control(), we can have a subvolume tree update and created a reloc_root for that subvolume.
Then we go into the final btrfs_commit_transaction() of del_balance_item(), and into btrfs_update_reloc_root() inside commit_fs_roots().
That function checks if fs_info->reloc_ctl is in the merge_reloc_tree stage, but since fs_info->reloc_ctl is NULL, it results a NULL pointer dereference.
[FIX]
Just add extra check on fs_info->reloc_ctl insidebtrfs_update_reloc_root(), before checkingfs_info->reloc_ctl->merge_reloc_tree.
That DEAD_RELOC_TREE handling is to prevent further modification to the reloc tree during merge stage, but since there is no reloc_ctl at all, we do not need to bother that.
--- fs/btrfs/relocation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/relocation.c +1 -1
@@ -921,7 +921,7 @@ int btrfs_update_reloc_root(struct btrfsbtrfs_grab_root (reloc_root);/* root->reloc_root will stay until current relocation finished */ -if (fs_info->reloc_ctl->merge_reloc_tree && +if (fs_info->reloc_ctl && fs_info->reloc_ctl->merge_reloc_tree &&btrfs_root_refs (root_item) ==0 ) {set_bit (BTRFS_ROOT_DEAD_RELOC_TREE , &root->state);/*
Greg Kroah-Hartman
maintainerPATCH 605/798 btrfs: send: fix invalid clone operation for file that got its size decreased
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit fa630df665aa9ddce3a96ce7b54e10a38e4d2a2b upstream.
During an incremental send we may end up sending an invalid clone operation, for the last extent of a file which ends at an unaligned offset that matches the final i_size of the file in the send snapshot, in case the file had its initial size (the size in the parent snapshot) decreased in the send snapshot. In this case the destination will fail to apply the clone operation because its end offset is not sector size aligned and it ends before the current size of the file.
Sending the truncate operation always happens when we finish processing an inode, after we process all its extents (and xattrs, names, etc). So fix this by ensuring the file has a valid size before we send a clone operation for an unaligned extent that ends at the final i_size of the file. The size we truncate to matches the start offset of the clone range but it could be any value between that start offset and the final size of the file since the clone operation will expand the i_size if the current size is smaller than the end offset. The start offset of the range was chosen because it's always sector size aligned and avoids a truncation into the middle of a page, which results in dirtying the page due to filling part of it with zeroes and then making the clone operation at the receiver trigger IO.
The following test reproduces the issue:
$ cat test.sh #!/bin/bash
DEV=/dev/sdi
MNT=/mnt/sdi
mkfs.btrfs -f $DEV
mount $DEV $MNT
# Create a file with a size of 256K + 5 bytes, having two extents, one
# with a size of 128K and another one with a size of 128K + 5 bytes.
last_ext_size=$((128 * 1024 + 5))
xfs_io -f -d -c "pwrite -S 0xab -b 128K 0 128K" \
-c "pwrite -S 0xcd -b $last_ext_size 128K $last_ext_size" \
$MNT/foo# Another file which we will later clone foo into, but initially with
# a larger size than foo. xfs_io -f -c "pwrite -S 0xef 0 1M" $MNT/bar
btrfs subvolume snapshot -r $MNT/ $MNT/snap1
# Now resize bar and clone foo into it.
xfs_io -c "truncate 0" \
-c "reflink $MNT/foo" $MNT/barbtrfs subvolume snapshot -r $MNT/ $MNT/snap2
rm -f /tmp/send-full /tmp/send-inc
btrfs send -f /tmp/send-full $MNT/snap1 btrfs send -p $MNT/snap1 -f /tmp/send-inc $MNT/snap2
umount $MNT
mkfs.btrfs -f $DEV
mount $DEV $MNT
btrfs receive -f /tmp/send-full $MNT
btrfs receive -f /tmp/send-inc $MNT
umount $MNT
Running it before this patch:
$ ./test.sh (...) At subvol snap1 At snapshot snap2 ERROR: failed to clone extents to bar: Invalid argument
A test case for fstests will be sent soon.
--- fs/btrfs/send.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
fs/btrfs/send.c +22 -1
@@ -5941,8 +5941,29 @@ static int send_write_or_clone(struct seif (ret <0 )return ret; -if (clone_root->offset + num_bytes == info.size) +if (clone_root->offset + num_bytes == info.size) { +/* +* The final size of our file matches the end offset, but it may +* be that its current size is larger, so we have to truncate it +* to any value between the start offset of the range and the +* final i_size, otherwise the clone operation is invalid +* because it's unaligned and it ends before the current EOF. +* We do this truncate to the final i_size when we finish +* processing the inode, but it's too late by then. And here we +* truncate to the start offset of the range because it's always +* sector size aligned while if it were the final i_size it +* would result in dirtying part of a page, filling part of a +* page with zeroes and then having the clone operation at the +* receiver trigger IO and wait for it due to the dirty page. +*/ +if (sctx->parent_root !=NULL ) { + ret =send_truncate (sctx, sctx->cur_ino, + sctx->cur_inode_gen, offset); +if (ret <0 ) +return ret; + } goto clone_data; + } write_data: ret =send_extent_data (sctx, path, offset, num_bytes);
Greg Kroah-Hartman
maintainerPATCH 606/798 btrfs: wait for fixup workers before stopping cleaner kthread during umount
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 41fd1e94066a815a7ab0a7025359e9b40e4b3576 upstream.
During unmount, at close_ctree(), we have the following steps in this order:
1) Park the cleaner kthread - this doesn't destroy the kthread, it basically halts its execution (wake ups against it work but do nothing);
2) We stop the cleaner kthread - this results in freeing the respective struct task_struct;
3) We call btrfs_stop_all_workers() which waits for any jobs running in all the work queues and then free the work queues.
Syzbot reported a case where a fixup worker resulted in a crash when doing a delayed iput on its inode while attempting to wake up the cleaner at btrfs_add_delayed_iput(), because the task_struct of the cleaner kthread was already freed. This can happen during unmount because we don't wait for any fixup workers still running before we call kthread_stop() against the cleaner kthread, which stops and free all its resources.
Fix this by waiting for any fixup workers at close_ctree() before we call kthread_stop() against the cleaner and run pending delayed iputs.
The stack traces reported by syzbot were the following:
BUG: KASAN: slab-use-after-free in __lock_acquire+0x77/0x2050 kernel/locking/lockdep.c:5065
Read of size 8 at addr ffff8880272a8a18 by task kworker/u8:3/52
CPU: 1 UID: 0 PID: 52 Comm: kworker/u8:3 Not tainted 6.12.0-rc1-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
Workqueue: btrfs-fixup btrfs_work_helper
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:377 [inline]
print_report+0x169/0x550 mm/kasan/report.c:488
kasan_report+0x143/0x180 mm/kasan/report.c:601
__lock_acquire+0x77/0x2050 kernel/locking/lockdep.c:5065
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5825
__raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
_raw_spin_lock_irqsave+0xd5/0x120 kernel/locking/spinlock.c:162
class_raw_spinlock_irqsave_constructor include/linux/spinlock.h:551 [inline]
try_to_wake_up+0xb0/0x1480 kernel/sched/core.c:4154
btrfs_writepage_fixup_worker+0xc16/0xdf0 fs/btrfs/inode.c:2842
btrfs_work_helper+0x390/0xc50 fs/btrfs/async-thread.c:314
process_one_work kernel/workqueue.c:3229 [inline]
process_scheduled_works+0xa63/0x1850 kernel/workqueue.c:3310
worker_thread+0x870/0xd30 kernel/workqueue.c:3391
kthread+0x2f0/0x390 kernel/kthread.c:389
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
</TASK>
Allocated by task 2:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
unpoison_slab_object mm/kasan/common.c:319 [inline]
__kasan_slab_alloc+0x66/0x80 mm/kasan/common.c:345
kasan_slab_alloc include/linux/kasan.h:247 [inline]
slab_post_alloc_hook mm/slub.c:4086 [inline]
slab_alloc_node mm/slub.c:4135 [inline]
kmem_cache_alloc_node_noprof+0x16b/0x320 mm/slub.c:4187
alloc_task_struct_node kernel/fork.c:180 [inline]
dup_task_struct+0x57/0x8c0 kernel/fork.c:1107
copy_process+0x5d1/0x3d50 kernel/fork.c:2206
kernel_clone+0x223/0x880 kernel/fork.c:2787
kernel_thread+0x1bc/0x240 kernel/fork.c:2849
create_kthread kernel/kthread.c:412 [inline]
kthreadd+0x60d/0x810 kernel/kthread.c:765
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
Freed by task 61:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:579
poison_slab_object mm/kasan/common.c:247 [inline]
__kasan_slab_free+0x59/0x70 mm/kasan/common.c:264
kasan_slab_free include/linux/kasan.h:230 [inline]
slab_free_hook mm/slub.c:2343 [inline]
slab_free mm/slub.c:4580 [inline]
kmem_cache_free+0x1a2/0x420 mm/slub.c:4682
put_task_struct include/linux/sched/task.h:144 [inline]
delayed_put_task_struct+0x125/0x300 kernel/exit.c:228
rcu_do_batch kernel/rcu/tree.c:2567 [inline]
rcu_core+0xaaa/0x17a0 kernel/rcu/tree.c:2823
handle_softirqs+0x2c5/0x980 kernel/softirq.c:554
__do_softirq kernel/softirq.c:588 [inline]
invoke_softirq kernel/softirq.c:428 [inline]
__irq_exit_rcu+0xf4/0x1c0 kernel/softirq.c:637
irq_exit_rcu+0x9/0x30 kernel/softirq.c:649
instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1037 [inline]
sysvec_apic_timer_interrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1037
asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:702
Last potentially related work creation:
kasan_save_stack+0x3f/0x60 mm/kasan/common.c:47
__kasan_record_aux_stack+0xac/0xc0 mm/kasan/generic.c:541
__call_rcu_common kernel/rcu/tree.c:3086 [inline]
call_rcu+0x167/0xa70 kernel/rcu/tree.c:3190
context_switch kernel/sched/core.c:5318 [inline]
__schedule+0x184b/0x4ae0 kernel/sched/core.c:6675
schedule_idle+0x56/0x90 kernel/sched/core.c:6793
do_idle+0x56a/0x5d0 kernel/sched/idle.c:354
cpu_startup_entry+0x42/0x60 kernel/sched/idle.c:424
start_secondary+0x102/0x110 arch/x86/kernel/smpboot.c:314
common_startup_64+0x13e/0x147
The buggy address belongs to the object at ffff8880272a8000
which belongs to the cache task_struct of size 7424
The buggy address is located 2584 bytes inside of
freed 7424-byte region [ffff8880272a8000, ffff8880272a9d00)
The buggy address belongs to the physical page:
page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x272a8
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0xfff00000000040(head|node=0|zone=1|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 00fff00000000040 ffff88801bafa500 dead000000000122 0000000000000000
raw: 0000000000000000 0000000080040004 00000001f5000000 0000000000000000
head: 00fff00000000040 ffff88801bafa500 dead000000000122 0000000000000000
head: 0000000000000000 0000000080040004 00000001f5000000 0000000000000000
head: 00fff00000000003 ffffea00009caa01 ffffffffffffffff 0000000000000000
head: 0000000000000008 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 2, tgid 2 (kthreadd), ts 71247381401, free_ts 71214998153
set_page_owner include/linux/page_owner.h:32 [inline]
post_alloc_hook+0x1f3/0x230 mm/page_alloc.c:1537
prep_new_page mm/page_alloc.c:1545 [inline]
get_page_from_freelist+0x3039/0x3180 mm/page_alloc.c:3457
__alloc_pages_noprof+0x256/0x6c0 mm/page_alloc.c:4733
alloc_pages_mpol_noprof+0x3e8/0x680 mm/mempolicy.c:2265
alloc_slab_page+0x6a/0x120 mm/slub.c:2413
allocate_slab+0x5a/0x2f0 mm/slub.c:2579
new_slab mm/slub.c:2632 [inline]
___slab_alloc+0xcd1/0x14b0 mm/slub.c:3819
__slab_alloc+0x58/0xa0 mm/slub.c:3909
__slab_alloc_node mm/slub.c:3962 [inline]
slab_alloc_node mm/slub.c:4123 [inline]
kmem_cache_alloc_node_noprof+0x1fe/0x320 mm/slub.c:4187
alloc_task_struct_node kernel/fork.c:180 [inline]
dup_task_struct+0x57/0x8c0 kernel/fork.c:1107
copy_process+0x5d1/0x3d50 kernel/fork.c:2206
kernel_clone+0x223/0x880 kernel/fork.c:2787
kernel_thread+0x1bc/0x240 kernel/fork.c:2849
create_kthread kernel/kthread.c:412 [inline]
kthreadd+0x60d/0x810 kernel/kthread.c:765
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
page last free pid 5230 tgid 5230 stack trace:
reset_page_owner include/linux/page_owner.h:25 [inline]
free_pages_prepare mm/page_alloc.c:1108 [inline]
free_unref_page+0xcd0/0xf00 mm/page_alloc.c:2638
discard_slab mm/slub.c:2678 [inline]
__put_partials+0xeb/0x130 mm/slub.c:3146
put_cpu_partial+0x17c/0x250 mm/slub.c:3221
__slab_free+0x2ea/0x3d0 mm/slub.c:4450
qlink_free mm/kasan/quarantine.c:163 [inline]
qlist_free_all+0x9a/0x140 mm/kasan/quarantine.c:179
kasan_quarantine_reduce+0x14f/0x170 mm/kasan/quarantine.c:286
__kasan_slab_alloc+0x23/0x80 mm/kasan/common.c:329
kasan_slab_alloc include/linux/kasan.h:247 [inline]
slab_post_alloc_hook mm/slub.c:4086 [inline]
slab_alloc_node mm/slub.c:4135 [inline]
kmem_cache_alloc_noprof+0x135/0x2a0 mm/slub.c:4142
getname_flags+0xb7/0x540 fs/namei.c:139
do_sys_openat2+0xd2/0x1d0 fs/open.c:1409
do_sys_open fs/open.c:1430 [inline]
__do_sys_openat fs/open.c:1446 [inline]
__se_sys_openat fs/open.c:1441 [inline]
__x64_sys_openat+0x247/0x2a0 fs/open.c:1441
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Memory state around the buggy address:
ffff8880272a8900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880272a8980: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff8880272a8a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8880272a8a80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880272a8b00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================--- fs/btrfs/disk-io.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
fs/btrfs/disk-io.c +11 -0
@@ -4642,6 +4642,17 @@ void __cold close_ctree(struct btrfs_fs_btrfs_cleanup_defrag_inodes (fs_info);/* +* Wait for any fixup workers to complete. +* If we don't wait for them here and they are still running by the time +* we call kthread_stop() against the cleaner kthread further below, we +* get an use-after-free on the cleaner because the fixup worker adds an +* inode to the list of delayed iputs and then attempts to wakeup the +* cleaner kthread, which was already stopped and destroyed. We parked +* already the cleaner, but below we run all pending delayed iputs. +*/ +btrfs_flush_workqueue (fs_info->fixup_workers); + +/* * After we parked the cleaner kthread, ordered extents may have * completed and created new delayed iputs. If one of the async reclaim * tasks is running and in the RUN_DELAYED_IPUTS flush state, then we
Greg Kroah-Hartman
maintainerPATCH 607/798 gpio: davinci: fix lazy disable
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emanuele Ghidoli <[email protected]>
commit 3360d41f4ac490282fddc3ccc0b58679aa5c065d upstream.
On a few platforms such as TI's AM69 device, disable_irq() fails to keep track of the interrupts that happen between disable_irq() and enable_irq() and those interrupts are missed. Use the ->irq_unmask() and ->irq_mask() methods instead of ->irq_enable() and ->irq_disable() to correctly keep track of edges when disable_irq is called.
This solves the issue of disable_irq() not working as expected on such platforms.
--- drivers/gpio/gpio-davinci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpio/gpio-davinci.c +4 -4
@@ -295,7 +295,7 @@ static int davinci_gpio_probe(struct pla* serve as EDMA event triggers. */ -static void gpio_irq_disable (struct irq_data *d) +static void gpio_irq_mask (struct irq_data *d) {struct davinci_gpio_regs __iomem *g =irq2regs (d);uintptr_t mask = (uintptr_t )irq_data_get_irq_handler_data (d);
@@ -304,7 +304,7 @@ static void gpio_irq_disable(struct irq_writel_relaxed (mask, &g->clr_rising); } -static void gpio_irq_enable (struct irq_data *d) +static void gpio_irq_unmask (struct irq_data *d) {struct davinci_gpio_regs __iomem *g =irq2regs (d);uintptr_t mask = (uintptr_t )irq_data_get_irq_handler_data (d);
@@ -330,8 +330,8 @@ static int gpio_irq_type(struct irq_datastatic struct irq_chip gpio_irqchip = { .name ="GPIO" , - .irq_enable = gpio_irq_enable, - .irq_disable = gpio_irq_disable, + .irq_unmask = gpio_irq_unmask, + .irq_mask = gpio_irq_mask, .irq_set_type = gpio_irq_type, .flags =IRQCHIP_SET_TYPE_MASKED |IRQCHIP_SKIP_SET_WAKE , };
Greg Kroah-Hartman
maintainerPATCH 608/798 Bluetooth: hci_event: Align BR/EDR JUST_WORKS paring with LE
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
commit b25e11f978b63cb7857890edb3a698599cddb10e upstream.
This aligned BR/EDR JUST_WORKS method with LE which since 92516cd97fd4 ("Bluetooth: Always request for user confirmation for Just Works") always request user confirmation with confirm_hint set since the likes of bluetoothd have dedicated policy around JUST_WORKS method (e.g. main.conf:JustWorksRepairing).
CVE: CVE-2024-8805
--- net/bluetooth/hci_event.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
net/bluetooth/hci_event.c +5 -8
@@ -5422,19 +5422,16 @@ static void hci_user_confirm_request_evt goto unlock; } -/* If no side requires MITM protection; auto-accept */ +/* If no side requires MITM protection; use JUST_CFM method */ if ((!loc_mitm || conn->remote_cap ==HCI_IO_NO_INPUT_OUTPUT ) && (!rem_mitm || conn->io_capability ==HCI_IO_NO_INPUT_OUTPUT )) { -/* If we're not the initiators request authorization to -* proceed from user space (mgmt_user_confirm with -* confirm_hint set to 1). The exception is if neither -* side had MITM or if the local IO capability is -* NoInputNoOutput, in which case we do auto-accept +/* If we're not the initiator of request authorization and the +* local IO capability is not NoInputNoOutput, use JUST_WORKS +* method (mgmt_user_confirm with confirm_hint set to 1). */ if (!test_bit (HCI_CONN_AUTH_PEND , &conn->flags) && - conn->io_capability !=HCI_IO_NO_INPUT_OUTPUT && - (loc_mitm || rem_mitm)) { + conn->io_capability !=HCI_IO_NO_INPUT_OUTPUT ) {bt_dev_dbg (hdev,"Confirming auto-accept as acceptor" ); confirm_hint =1 ; goto confirm;
Greg Kroah-Hartman
maintainerPATCH 609/798 ceph: fix cap ref leak via netfs init_request
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrick Donnelly <[email protected]>
commit ccda9910d8490f4fb067131598e4b2e986faa5a0 upstream.
Log recovered from a user's cluster:
<7>[ 5413.970692] ceph: get_cap_refs 00000000958c114b ret 1 got Fr
<7>[ 5413.970695] ceph: start_read 00000000958c114b, no cache cap
...
<7>[ 5473.934609] ceph: my wanted = Fr, used = Fr, dirty -
<7>[ 5473.934616] ceph: revocation: pAsLsXsFr -> pAsLsXs (revoking Fr)
<7>[ 5473.934632] ceph: __ceph_caps_issued 00000000958c114b cap 00000000f7784259 issued pAsLsXs
<7>[ 5473.934638] ceph: check_caps 10000000e68.fffffffffffffffe file_want - used Fr dirty - flushing - issued pAsLsXs revoking Fr retain pAsLsXsFsr AUTHONLY NOINVAL FLUSH_FORCEThe MDS subsequently complains that the kernel client is late releasing caps.
Approximately, a series of changes to this code by commits 49870056005c ("ceph: convert ceph_readpages to ceph_readahead"), 2de160417315 ("netfs: Change ->init_request() to return an error code") and a5c9dc445139 ("ceph: Make ceph_init_request() check caps on readahead") resulted in subtle resource cleanup to be missed. The main culprit is the change in error handling in 2de160417315 which meant that a failure in init_request() would no longer cause cleanup to be called. That would prevent the ceph_put_cap_refs() call which would cleanup the leaked cap ref.
--- fs/ceph/addr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/ceph/addr.c +4 -1
@@ -435,8 +435,11 @@ static int ceph_init_request(struct netf rreq->netfs_priv = priv; out: -if (ret <0 ) +if (ret <0 ) { +if (got) +ceph_put_cap_refs (ceph_inode (inode), got);kfree (priv); + }return ret; }
Greg Kroah-Hartman
maintainerPATCH 610/798 tracing/hwlat: Fix a race during cpuhp processing
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Li <[email protected]>
commit 2a13ca2e8abb12ee43ada8a107dadca83f140937 upstream.
The cpuhp online/offline processing race also exists in percpu-mode hwlat tracer in theory, apply the fix too. That is:
T1 | T2
[CPUHP_ONLINE] | cpu_device_down()
hwlat_hotplug_workfn() |
| cpus_write_lock()
| takedown_cpu(1)
| cpus_write_unlock()
[CPUHP_OFFLINE] |
cpus_read_lock() |
start_kthread(1) |
cpus_read_unlock() |--- kernel/trace/trace_hwlat.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/trace/trace_hwlat.c +2 -0
@@ -520,6 +520,8 @@ static void hwlat_hotplug_workfn(structif (!hwlat_busy || hwlat_data.thread_mode !=MODE_PER_CPU ) goto out_unlock; +if (!cpu_online (cpu)) + goto out_unlock;if (!cpumask_test_cpu (cpu, tr->tracing_cpumask)) goto out_unlock;
Greg Kroah-Hartman
maintainerPATCH 611/798 tracing/timerlat: Fix a race during cpuhp processing
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Li <[email protected]>
commit 829e0c9f0855f26b3ae830d17b24aec103f7e915 upstream.
There is another found exception that the "timerlat/1" thread was scheduled on CPU0, and lead to timer corruption finally:
``` ODEBUG: init active (active state 0) object: ffff888237c2e108 object type: hrtimer hint: timerlat_irq+0x0/0x220 WARNING: CPU: 0 PID: 426 at lib/debugobjects.c:518 debug_print_object+0x7d/0xb0 Modules linked in: CPU: 0 UID: 0 PID: 426 Comm: timerlat/1 Not tainted 6.11.0-rc7+ #45 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 RIP: 0010:debug_print_object+0x7d/0xb0 ... Call Trace: <TASK> ? __warn+0x7c/0x110 ? debug_print_object+0x7d/0xb0 ? report_bug+0xf1/0x1d0 ? prb_read_valid+0x17/0x20 ? handle_bug+0x3f/0x70 ? exc_invalid_op+0x13/0x60 ? asm_exc_invalid_op+0x16/0x20 ? debug_print_object+0x7d/0xb0 ? debug_print_object+0x7d/0xb0 ? __pfx_timerlat_irq+0x10/0x10 __debug_object_init+0x110/0x150 hrtimer_init+0x1d/0x60 timerlat_main+0xab/0x2d0 ? __pfx_timerlat_main+0x10/0x10 kthread+0xb7/0xe0 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x2d/0x40 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> ```
After tracing the scheduling event, it was discovered that the migration of the "timerlat/1" thread was performed during thread creation. Further analysis confirmed that it is because the CPU online processing for osnoise is implemented through workers, which is asynchronous with the offline processing. When the worker was scheduled to create a thread, the CPU may has already been removed from the cpu_online_mask during the offline process, resulting in the inability to select the right CPU:
T1 | T2
[CPUHP_ONLINE] | cpu_device_down()
osnoise_hotplug_workfn() |
| cpus_write_lock()
| takedown_cpu(1)
| cpus_write_unlock()
[CPUHP_OFFLINE] |
cpus_read_lock() |
start_kthread(1) |
cpus_read_unlock() |To fix this, skip online processing if the CPU is already offline.
--- kernel/trace/trace_osnoise.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/trace/trace_osnoise.c +2 -0
@@ -1813,6 +1813,8 @@ static void osnoise_hotplug_workfn(strucmutex_lock (&interface_lock);cpus_read_lock (); +if (!cpu_online (cpu)) + goto out_unlock;if (!cpumask_test_cpu (cpu, &osnoise_cpumask)) goto out_unlock;
Greg Kroah-Hartman
maintainerPATCH 612/798 close_range(): fix the logics in descriptor table trimming
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 678379e1d4f7443b170939525d3312cfc37bf86b upstream.
Cloning a descriptor table picks the size that would cover all currently opened files. That's fine for clone() and unshare(), but for close_range() there's an additional twist - we clone before we close, and it would be a shame to have
close_range(3, ~0U, CLOSE_RANGE_UNSHARE)
leave us with a huge descriptor table when we are not going to keep anything past stderr, just because some large file descriptor used to be open before our call has taken it out.
Unfortunately, it had been dealt with in an inherently racy way - sane_fdtable_size() gets a "don't copy anything past that" argument (passed via unshare_fd() and dup_fd()), close_range() decides how much should be trimmed and passes that to unshare_fd().
The problem is, a range that used to extend to the end of descriptor table back when close_range() had looked at it might very well have stuff grown after it by the time dup_fd() has allocated a new files_struct and started to figure out the capacity of fdtable to be attached to that.
That leads to interesting pathological cases; at the very least it's a QoI issue, since unshare(CLONE_FILES) is atomic in a sense that it takes a snapshot of descriptor table one might have observed at some point. Since CLOSE_RANGE_UNSHARE close_range() is supposed to be a combination of unshare(CLONE_FILES) with plain close_range(), ending up with a weird state that would never occur with unshare(2) is confusing, to put it mildly.
It's not hard to get rid of - all it takes is passing both ends of the range down to sane_fdtable_size(). There we are under ->files_lock, so the race is trivially avoided.
So we do the following:
* switch close_files() from calling unshare_fd() to callingdup_fd().
* undo the calling convention change done to unshare_fd() in60997c3d45d9 "close_range: add CLOSE_RANGE_UNSHARE"
* introduce struct fd_range, pass a pointer to that to dup_fd()
and sane_fdtable_size() instead of "trim everything past that point" they are currently getting. NULL means "we are not going to be punching any holes"; NR_OPEN_MAX is gone.
* make sane_fdtable_size() use find_last_bit() instead of
open-coding it; it's easier to follow that way.
* while we are at it, have dup_fd() report errors by returningERR_PTR(), no need to use a separate int *errorp argument.
--- fs/file.c | 93 +++++++++++++++++------------------------------- include/linux/fdtable.h | 8 ++-- kernel/fork.c | 30 ++++++--------- 3 files changed, 50 insertions(+), 81 deletions(-)
fs/file.c +33 -60
@@ -267,59 +267,45 @@ static inline void __clear_open_fd(unsig__clear_bit (fd /BITS_PER_LONG , fdt->full_fds_bits); } -static unsigned int count_open_files (struct fdtable *fdt) -{ -unsigned int size = fdt->max_fds; -unsigned int i; - -/* Find the last open fd */ -for (i = size /BITS_PER_LONG ; i >0 ; ) { -if (fdt->open_fds[--i]) -break ; - } - i = (i +1 ) *BITS_PER_LONG ; -return i; -} -/* * Note that a sane fdtable size always has to be a multiple of * BITS_PER_LONG, since we have bitmaps that are sized by this. * -* 'max_fds' will normally already be properly aligned, but it -* turns out that in the close_range() -> __close_range() -> -* unshare_fd() -> dup_fd() -> sane_fdtable_size() we can end -* up having a 'max_fds' value that isn't already aligned. -* -* Rather than make close_range() have to worry about this, -* just make that BITS_PER_LONG alignment be part of a sane -* fdtable size. Becuase that's really what it is. +* punch_hole is optional - when close_range() is asked to unshare +* and close, we don't need to copy descriptors in that range, so +* a smaller cloned descriptor table might suffice if the last +* currently opened descriptor falls into that range. */ -static unsigned int sane_fdtable_size (struct fdtable *fdt,unsigned int max_fds) +static unsigned int sane_fdtable_size (struct fdtable *fdt,struct fd_range *punch_hole) { -unsigned int count; +unsigned int last =find_last_bit (fdt->open_fds, fdt->max_fds); - count =count_open_files (fdt); -if (max_fds <NR_OPEN_DEFAULT ) - max_fds =NR_OPEN_DEFAULT ; -return ALIGN (min (count, max_fds),BITS_PER_LONG ); +if (last == fdt->max_fds) +return NR_OPEN_DEFAULT ; +if (punch_hole && punch_hole->to >= last && punch_hole->from <= last) { + last =find_last_bit (fdt->open_fds, punch_hole->from); +if (last == punch_hole->from) +return NR_OPEN_DEFAULT ; + } +return ALIGN (last +1 ,BITS_PER_LONG ); }/* -* Allocate a new files structure and copy contents from the -* passed in files structure. -* errorp will be valid only when the returned files_struct is NULL. +* Allocate a new descriptor table and copy contents from the passed in +* instance. Returns a pointer to cloned table on success, ERR_PTR() +* on failure. For 'punch_hole' see sane_fdtable_size(). */ -struct files_struct *dup_fd (struct files_struct *oldf,unsigned int max_fds,int *errorp) +struct files_struct *dup_fd (struct files_struct *oldf,struct fd_range *punch_hole) {struct files_struct *newf;struct file **old_fds, **new_fds;unsigned int open_files, i;struct fdtable *old_fdt, *new_fdt; +int error; - *errorp = -ENOMEM ; newf =kmem_cache_alloc (files_cachep,GFP_KERNEL );if (!newf) - goto out; +return ERR_PTR (-ENOMEM );atomic_set (&newf->count,1 );
@@ -336,7 +322,7 @@ struct files_struct *dup_fd(struct filesspin_lock (&oldf->file_lock); old_fdt =files_fdtable (oldf); - open_files =sane_fdtable_size (old_fdt, max_fds); + open_files =sane_fdtable_size (old_fdt, punch_hole);/* * Check whether we need to allocate a larger fd array and fd set.
@@ -349,14 +335,14 @@ struct files_struct *dup_fd(struct files new_fdt =alloc_fdtable (open_files -1 );if (!new_fdt) { - *errorp = -ENOMEM ; + error = -ENOMEM ; goto out_release; }/* beyond sysctl_nr_open; nothing to do */ if (unlikely (new_fdt->max_fds < open_files)) {__free_fdtable (new_fdt); - *errorp = -EMFILE ; + error = -EMFILE ; goto out_release; }
@@ -367,7 +353,7 @@ struct files_struct *dup_fd(struct files*/ spin_lock (&oldf->file_lock); old_fdt =files_fdtable (oldf); - open_files =sane_fdtable_size (old_fdt, max_fds); + open_files =sane_fdtable_size (old_fdt, punch_hole); }copy_fd_bitmaps (new_fdt, old_fdt, open_files /BITS_PER_LONG );
@@ -401,8 +387,7 @@ struct files_struct *dup_fd(struct files out_release:kmem_cache_free (files_cachep, newf); -out: -return NULL ; +return ERR_PTR (error); }static struct fdtable *close_files (struct files_struct * files)
@@ -734,37 +719,25 @@ int __close_range(unsigned fd, unsignedif (fd > max_fd)return -EINVAL ; -if (flags &CLOSE_RANGE_UNSHARE ) { -int ret; -unsigned int max_unshare_fds =NR_OPEN_MAX ; +if ((flags &CLOSE_RANGE_UNSHARE ) &&atomic_read (&cur_fds->count) >1 ) { +struct fd_range range = {fd, max_fd}, *punch_hole = ⦥/* * If the caller requested all fds to be made cloexec we always * copy all of the file descriptors since they still want to * use them. */ -if (!(flags &CLOSE_RANGE_CLOEXEC )) { -/* -* If the requested range is greater than the current -* maximum, we're closing everything so only copy all -* file descriptors beneath the lowest file descriptor. -*/ -rcu_read_lock (); -if (max_fd >=last_fd (files_fdtable (cur_fds))) - max_unshare_fds = fd; -rcu_read_unlock (); - } - - ret =unshare_fd (CLONE_FILES , max_unshare_fds, &fds); -if (ret) -return ret; +if (flags &CLOSE_RANGE_CLOEXEC ) + punch_hole =NULL ; + fds =dup_fd (cur_fds, punch_hole); +if (IS_ERR (fds)) +return PTR_ERR (fds);/* * We used to share our file descriptor table, and have now * created a private one, make sure we're using it below. */ -if (fds) -swap (cur_fds, fds); +swap (cur_fds, fds); }if (flags &CLOSE_RANGE_CLOEXEC )
include/linux/fdtable.h +4 -4
@@ -22,7 +22,6 @@* as this is the granularity returned by copy_fdset(). */ #define NR_OPEN_DEFAULT BITS_PER_LONG -#define NR_OPEN_MAX ~0Ustruct fdtable {unsigned int max_fds;
@@ -117,7 +116,10 @@ struct task_struct;void put_files_struct (struct files_struct *fs);int unshare_files (void ); -struct files_struct *dup_fd (struct files_struct *,unsigned ,int *) __latent_entropy; +struct fd_range { +unsigned int from, to; +}; +struct files_struct *dup_fd (struct files_struct *,struct fd_range *) __latent_entropy;void do_close_on_exec (struct files_struct *); int iterate_fd(struct files_struct *, unsigned, int (*)(const void *, struct file *, unsigned),
@@ -126,8 +128,6 @@ int iterate_fd(struct files_struct *, unextern int close_fd (unsigned int fd);extern int __close_range (unsigned int fd,unsigned int max_fd,unsigned int flags);extern struct file *close_fd_get_file (unsigned int fd); -extern int unshare_fd (unsigned long unshare_flags,unsigned int max_fds, -struct files_struct **new_fdp);extern struct kmem_cache *files_cachep;
kernel/fork.c +13 -17
@@ -1619,28 +1619,25 @@ static int copy_fs(unsigned long clone_fstatic int copy_files (unsigned long clone_flags,struct task_struct *tsk) {struct files_struct *oldf, *newf; -int error =0 ;/* * A background process may not have any files ... */ oldf = current->files;if (!oldf) - goto out; +return 0 ;if (clone_flags &CLONE_FILES ) {atomic_inc (&oldf->count); - goto out; +return 0 ; } - newf =dup_fd (oldf,NR_OPEN_MAX , &error); -if (!newf) - goto out; + newf =dup_fd (oldf,NULL ); +if (IS_ERR (newf)) +return PTR_ERR (newf); tsk->files = newf; - error =0 ; -out: -return error; +return 0 ; }static int copy_sighand (unsigned long clone_flags,struct task_struct *tsk)
@@ -3126,17 +3123,16 @@ static int unshare_fs(unsigned long unsh/* * Unshare file descriptor table if it is being shared */ -int unshare_fd (unsigned long unshare_flags,unsigned int max_fds, -struct files_struct **new_fdp) +static int unshare_fd (unsigned long unshare_flags,struct files_struct **new_fdp) {struct files_struct *fd = current->files; -int error =0 ;if ((unshare_flags &CLONE_FILES ) && (fd &&atomic_read (&fd->count) >1 )) { - *new_fdp =dup_fd (fd, max_fds, &error); -if (!*new_fdp) -return error; + fd =dup_fd (fd,NULL ); +if (IS_ERR (fd)) +return PTR_ERR (fd); + *new_fdp = fd; }return 0 ;
@@ -3194,7 +3190,7 @@ int ksys_unshare(unsigned long unshare_f err =unshare_fs (unshare_flags, &new_fs);if (err) goto bad_unshare_out; - err =unshare_fd (unshare_flags,NR_OPEN_MAX , &new_fd); + err =unshare_fd (unshare_flags, &new_fd);if (err) goto bad_unshare_cleanup_fs; err =unshare_userns (unshare_flags, &new_cred);
@@ -3286,7 +3282,7 @@ int unshare_files(void)struct files_struct *old, *copy =NULL ;int error; - error =unshare_fd (CLONE_FILES ,NR_OPEN_MAX , ©); + error =unshare_fd (CLONE_FILES , ©);if (error || !copy)return error;
Greg Kroah-Hartman
maintainerPATCH 613/798 drm/i915/gem: fix bitwise and logical AND mixup
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jani Nikula <[email protected]>
commit 394b52462020b6cceff1f7f47fdebd03589574f3 upstream.
CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND is an int, defaulting to 250. When the wakeref is non-zero, it's either -1 or a dynamically allocated pointer, depending on CONFIG_DRM_I915_DEBUG_RUNTIME_PM. It's likely that the code works by coincidence with the bitwise AND, but with CONFIG_DRM_I915_DEBUG_RUNTIME_PM=y, there's the off chance that the condition evaluates to false, and intel_wakeref_auto() doesn't get called. Switch to the intended logical AND.
v2: Use != to avoid clang -Wconstant-logical-operand (Nathan)
--- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i915/gem/i915_gem_ttm.c +1 -1
@@ -1058,7 +1058,7 @@ static vm_fault_t vm_fault_ttm(struct vmspin_unlock (&to_i915 (obj->base.dev)->runtime_pm.lmem_userfault_lock); } -if (wakeref &CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND ) +if (wakeref &&CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND !=0 )intel_wakeref_auto (&to_i915 (obj->base.dev)->runtime_pm.userfault_wakeref,msecs_to_jiffies_timeout (CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND ));
Greg Kroah-Hartman
maintainerPATCH 614/798 drm/sched: Add locking to drm_sched_entity_modify_sched
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tvrtko Ursulin <[email protected]>
commit 4286cc2c953983d44d248c9de1c81d3a9643345c upstream.
Without the locking amdgpu currently can race between amdgpu_ctx_set_entity_priority() (via drm_sched_entity_modify_sched()) and drm_sched_job_arm(), leading to the latter accesing potentially inconsitent entity->sched_list and entity->num_sched_list pair.
v2:
* Improve commit message. (Philipp)
--- drivers/gpu/drm/scheduler/sched_entity.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/scheduler/sched_entity.c +2 -0
@@ -110,8 +110,10 @@ void drm_sched_entity_modify_sched(struc {WARN_ON (!num_sched_list || !sched_list); +spin_lock (&entity->rq_lock); entity->sched_list = sched_list; entity->num_sched_list = num_sched_list; +spin_unlock (&entity->rq_lock); }EXPORT_SYMBOL (drm_sched_entity_modify_sched);
Greg Kroah-Hartman
maintainerPATCH 615/798 drm/amd/display: Fix system hang while resume with TBT monitor
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tom Chung <[email protected]>
commit 52d4e3fb3d340447dcdac0e14ff21a764f326907 upstream.
[Why]
Connected with a Thunderbolt monitor and do the suspend and the system may hang while resume.
The TBT monitor HPD will be triggered during the resume procedure and call the drm_client_modeset_probe() while
struct drm_connector connector->dev->master is NULL.
It will mess up the pipe topology after resume.
[How]
Skip the TBT monitor HPD during the resume procedure because we currently will probe the connectors after resume by default.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +6 -0
@@ -712,6 +712,12 @@ static void dmub_hpd_callback(struct amdreturn ; } +/* Skip DMUB HPD IRQ in suspend/resume. We will probe them later. */ +if (notify->type ==DMUB_NOTIFICATION_HPD && adev->in_suspend) { +DRM_INFO ("Skip DMUB HPD IRQ callback in suspend/resume\n" ); +return ; + } + link_index = notify->link_index; link = adev->dm.dc->links[link_index]; dev = adev->dm.ddev;
Greg Kroah-Hartman
maintainerPATCH 616/798 cpufreq: intel_pstate: Make hwp_notify_lock a raw spinlock
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
commit 8b4865cd904650cbed7f2407e653934c621b8127 upstream.
notify_hwp_interrupt() is called via sysvec_thermal() -> smp_thermal_vector() -> intel_thermal_interrupt() in hard irq context. For this reason it must not use a simple spin_lock that sleeps with PREEMPT_RT enabled. So convert it to a raw spinlock.
--- drivers/cpufreq/intel_pstate.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/cpufreq/intel_pstate.c +10 -10
@@ -1596,7 +1596,7 @@ static void intel_pstate_notify_work(struct work_struct *work)wrmsrl_on_cpu (cpudata->cpu,MSR_HWP_STATUS ,0 ); } -static DEFINE_SPINLOCK (hwp_notify_lock); +static DEFINE_RAW_SPINLOCK (hwp_notify_lock);static cpumask_t hwp_intr_enable_mask;void notify_hwp_interrupt (void )
@@ -1613,7 +1613,7 @@ void notify_hwp_interrupt(void)if (!(value &0x01 ))return ; -spin_lock_irqsave (&hwp_notify_lock, flags); +raw_spin_lock_irqsave (&hwp_notify_lock, flags);if (!cpumask_test_cpu (this_cpu, &hwp_intr_enable_mask)) goto ack_intr;
@@ -1637,13 +1637,13 @@ void notify_hwp_interrupt(void)schedule_delayed_work (&cpudata->hwp_notify_work,msecs_to_jiffies (10 )); -spin_unlock_irqrestore (&hwp_notify_lock, flags); +raw_spin_unlock_irqrestore (&hwp_notify_lock, flags);return ; ack_intr:wrmsrl_safe (MSR_HWP_STATUS ,0 ); -spin_unlock_irqrestore (&hwp_notify_lock, flags); +raw_spin_unlock_irqrestore (&hwp_notify_lock, flags); }static void intel_pstate_disable_hwp_interrupt (struct cpudata *cpudata)
@@ -1656,10 +1656,10 @@ static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata)/* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */ wrmsrl_on_cpu (cpudata->cpu,MSR_HWP_INTERRUPT ,0x00 ); -spin_lock_irqsave (&hwp_notify_lock, flags); +raw_spin_lock_irqsave (&hwp_notify_lock, flags);if (cpumask_test_and_clear_cpu (cpudata->cpu, &hwp_intr_enable_mask))cancel_delayed_work (&cpudata->hwp_notify_work); -spin_unlock_irqrestore (&hwp_notify_lock, flags); +raw_spin_unlock_irqrestore (&hwp_notify_lock, flags); }static void intel_pstate_enable_hwp_interrupt (struct cpudata *cpudata)
@@ -1668,10 +1668,10 @@ static void intel_pstate_enable_hwp_interrupt(struct cpudata *cpudata)if (boot_cpu_has (X86_FEATURE_HWP_NOTIFY )) {unsigned long flags; -spin_lock_irqsave (&hwp_notify_lock, flags); +raw_spin_lock_irqsave (&hwp_notify_lock, flags);INIT_DELAYED_WORK (&cpudata->hwp_notify_work, intel_pstate_notify_work);cpumask_set_cpu (cpudata->cpu, &hwp_intr_enable_mask); -spin_unlock_irqrestore (&hwp_notify_lock, flags); +raw_spin_unlock_irqrestore (&hwp_notify_lock, flags);/* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */ wrmsrl_on_cpu (cpudata->cpu,MSR_HWP_INTERRUPT ,0x01 );
@@ -3101,10 +3101,10 @@ static void intel_pstate_driver_cleanup(void)if (intel_pstate_driver == &intel_pstate)intel_pstate_clear_update_util_hook (cpu); -spin_lock (&hwp_notify_lock); +raw_spin_lock (&hwp_notify_lock);kfree (all_cpu_data[cpu]);WRITE_ONCE (all_cpu_data[cpu],NULL ); -spin_unlock (&hwp_notify_lock); +raw_spin_unlock (&hwp_notify_lock); } }cpus_read_unlock ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 617/798 kconfig: qconf: fix buffer overflow in debug links
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
[ Upstream commit 984ed20ece1c6c20789ece040cbff3eb1a388fa9 ]
If you enable "Option -> Show Debug Info" and click a link, the program terminates with the following error:
*** buffer overflow detected ***: terminated
The buffer overflow is caused by the following line:
strcat(data, "$");
The buffer needs one more byte to accommodate the additional character.
--- scripts/kconfig/qconf.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/kconfig/qconf.cc +1 -1
@@ -1172,7 +1172,7 @@ void ConfigInfoView::clicked(const QUrl &url) { QByteArray str = url.toEncoded(); const std::size_t count = str.size(); - char *data = new char[count + 1]; + char *data = new char[count + 2]; // '$' + '\0' struct symbol **result; struct menu *m = NULL;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 618/798 i2c: create debugfs entry per adapter
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wolfram Sang <[email protected]>
[ Upstream commit 73febd775bdbdb98c81255ff85773ac410ded5c4 ]
Two drivers already implement custom debugfs handling for their i2c_adapter and more will come. So, let the core create a debugfs directory per adapter and pass that to drivers for their debugfs files.
Stable-dep-of: 8d3cefaf6592 ("i2c: core: Lock address during client device instantiation")
--- drivers/i2c/i2c-core-base.c | 11 +++++++++++ include/linux/i2c.h | 2 ++ 2 files changed, 13 insertions(+)
drivers/i2c/i2c-core-base.c +11 -0
@@ -16,6 +16,7 @@#include <linux/acpi.h> #include <linux/clk/clk-conf.h> #include <linux/completion.h> +#include <linux/debugfs.h> #include <linux/delay.h> #include <linux/err.h> #include <linux/errno.h>
@@ -66,6 +67,8 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);static DEFINE_STATIC_KEY_FALSE (i2c_trace_msg_key);static bool is_registered; +static struct dentry *i2c_debugfs_root; +int i2c_transfer_trace_reg (void ) {static_branch_inc (&i2c_trace_msg_key);
@@ -1528,6 +1531,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap) goto out_list; } + adap->debugfs =debugfs_create_dir (dev_name (&adap->dev), i2c_debugfs_root); + res =i2c_setup_smbus_alert (adap);if (res) goto out_reg;
@@ -1567,6 +1572,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)return 0 ; out_reg: +debugfs_remove_recursive (adap->debugfs);init_completion (&adap->dev_released);device_unregister (&adap->dev);wait_for_completion (&adap->dev_released);
@@ -1768,6 +1774,8 @@ void i2c_del_adapter(struct i2c_adapter *adap)i2c_host_notify_irq_teardown (adap); +debugfs_remove_recursive (adap->debugfs); +/* wait until all references to the device are gone * * FIXME: This is old code and should ideally be replaced by an
@@ -2065,6 +2073,8 @@ static int __init i2c_init(void) is_registered = true; + i2c_debugfs_root =debugfs_create_dir ("i2c" ,NULL ); +#ifdef CONFIG_I2C_COMPAT i2c_adapter_compat_class =class_compat_register ("i2c-adapter" );if (!i2c_adapter_compat_class) {
@@ -2103,6 +2113,7 @@ static void __exit i2c_exit(void)#ifdef CONFIG_I2C_COMPAT class_compat_unregister (i2c_adapter_compat_class);#endif +debugfs_remove_recursive (i2c_debugfs_root);bus_unregister (&i2c_bus_type);tracepoint_synchronize_unregister (); }
include/linux/i2c.h +2 -0
@@ -750,6 +750,8 @@ struct i2c_adapter {struct irq_domain *host_notify_domain;struct regulator *bus_regulator; + +struct dentry *debugfs; };#define to_i2c_adapter (d) container_of(d, struct i2c_adapter, dev)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 619/798 i2c: core: Lock address during client device instantiation
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiner Kallweit <[email protected]>
[ Upstream commit 8d3cefaf659265aa82b0373a563fdb9d16a2b947 ]
Krzysztof reported an issue [0] which is caused by parallel attempts to instantiate the same I2C client device. This can happen if driver supports auto-detection, but certain devices are also instantiated explicitly.
The original change isn't actually wrong, it just revealed that I2C core isn't prepared yet to handle this scenario.
Calls to i2c_new_client_device() can be nested, therefore we can't use a simple mutex here. Parallel instantiation of devices at different addresses is ok, so we just have to prevent parallel instantiation at the same address. We can use a bitmap with one bit per 7-bit I2C client address, and atomic bit operations to set/check/clear bits.
Now a parallel attempt to instantiate a device at the same address will result in -EBUSY being returned, avoiding the "sysfs: cannot create duplicate filename" splash.
Note: This patch version includes small cosmetic changes to the Tested-by
version, only functional change is that address locking is supported for slave addresses too.
[0] https://lore.kernel.org/linux-i2c/[email protected]/T/#m12706546e8e2414d8f1a0dc61c53393f731685cc
--- drivers/i2c/i2c-core-base.c | 28 ++++++++++++++++++++++++++++ include/linux/i2c.h | 3 +++ 2 files changed, 31 insertions(+)
drivers/i2c/i2c-core-base.c +28 -0
@@ -919,6 +919,27 @@ int i2c_dev_irq_from_resources(const struct resource *resources,return 0 ; } +/* +* Serialize device instantiation in case it can be instantiated explicitly +* and by auto-detection +*/ +static int i2c_lock_addr (struct i2c_adapter *adap,unsigned short addr, +unsigned short flags) +{ +if (!(flags &I2C_CLIENT_TEN ) && +test_and_set_bit (addr, adap->addrs_in_instantiation)) +return -EBUSY ; + +return 0 ; +} + +static void i2c_unlock_addr (struct i2c_adapter *adap,unsigned short addr, +unsigned short flags) +{ +if (!(flags &I2C_CLIENT_TEN )) +clear_bit (addr, adap->addrs_in_instantiation); +} +/** * i2c_new_client_device - instantiate an i2c device * @adap: the adapter managing the device
@@ -966,6 +987,10 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf goto out_err_silent; } + status =i2c_lock_addr (adap, client->addr, client->flags); +if (status) + goto out_err_silent; +/* Check for address business */ status =i2c_check_addr_busy (adap,i2c_encode_flags_to_addr (client));if (status)
@@ -997,6 +1022,8 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *infdev_dbg (&adap->dev,"client [%s] registered with bus id %s\n" , client->name,dev_name (&client->dev)); +i2c_unlock_addr (adap, client->addr, client->flags); +return client; out_remove_swnode:
@@ -1008,6 +1035,7 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *infdev_err (&adap->dev,"Failed to register i2c client %s at 0x%02x (%d)\n" , client->name, client->addr, status); +i2c_unlock_addr (adap, client->addr, client->flags); out_err_silent:if (need_put)put_device (&client->dev);
include/linux/i2c.h +3 -0
@@ -752,6 +752,9 @@ struct i2c_adapter {struct regulator *bus_regulator;struct dentry *debugfs; + +/* 7bit address space */ +DECLARE_BITMAP (addrs_in_instantiation,1 <<7 ); };#define to_i2c_adapter (d) container_of(d, struct i2c_adapter, dev)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 620/798 i2c: xiic: Use devm_clk_get_enabled()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andi Shyti <[email protected]>
[ Upstream commit 8390dc7477e49e4acc9e553f385f4ff59d186efe ]
Replace the pair of functions, devm_clk_get() and clk_prepare_enable(), with a single function devm_clk_get_enabled().
Stable-dep-of: 0c8d604dea43 ("i2c: xiic: Fix pm_runtime_set_suspended() with runtime pm enabled")
--- drivers/i2c/busses/i2c-xiic.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-)
drivers/i2c/busses/i2c-xiic.c +7 -13
@@ -798,16 +798,11 @@ static int xiic_i2c_probe(struct platform_device *pdev)mutex_init (&i2c->lock); - i2c->clk =devm_clk_get (&pdev->dev,NULL ); + i2c->clk =devm_clk_get_enabled (&pdev->dev,NULL );if (IS_ERR (i2c->clk))return dev_err_probe (&pdev->dev,PTR_ERR (i2c->clk), -"input clock not found.\n" ); +"failed to enable input clock.\n" ); - ret =clk_prepare_enable (i2c->clk); -if (ret) { -dev_err (&pdev->dev,"Unable to enable clock.\n" ); -return ret; - } i2c->dev = &pdev->dev;pm_runtime_set_autosuspend_delay (i2c->dev,XIIC_PM_TIMEOUT );pm_runtime_use_autosuspend (i2c->dev);
@@ -819,7 +814,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)if (ret <0 ) {dev_err (&pdev->dev,"Cannot claim IRQ\n" ); - goto err_clk_dis; + goto err_pm_disable; } i2c->singlemaster =
@@ -840,14 +835,14 @@ static int xiic_i2c_probe(struct platform_device *pdev) ret =xiic_reinit (i2c);if (ret <0 ) {dev_err (&pdev->dev,"Cannot xiic_reinit\n" ); - goto err_clk_dis; + goto err_pm_disable; }/* add i2c adapter to i2c tree */ ret =i2c_add_adapter (&i2c->adap);if (ret) {xiic_deinit (i2c); - goto err_clk_dis; + goto err_pm_disable; }if (pdata) {
@@ -858,10 +853,10 @@ static int xiic_i2c_probe(struct platform_device *pdev)return 0 ; -err_clk_dis: +err_pm_disable:pm_runtime_set_suspended (&pdev->dev);pm_runtime_disable (&pdev->dev); -clk_disable_unprepare (i2c->clk); +return ret; }
@@ -879,7 +874,6 @@ static int xiic_i2c_remove(struct platform_device *pdev)xiic_deinit (i2c);pm_runtime_put_sync (i2c->dev); -clk_disable_unprepare (i2c->clk);pm_runtime_disable (&pdev->dev);pm_runtime_set_suspended (&pdev->dev);pm_runtime_dont_use_autosuspend (&pdev->dev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 621/798 i2c: xiic: Fix pm_runtime_set_suspended() with runtime pm enabled
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 0c8d604dea437b69a861479b413d629bc9b3da70 ]
It is not valid to call pm_runtime_set_suspended() for devices with runtime PM enabled because it returns -EAGAIN if it is enabled already and working. So, call pm_runtime_disable() before to fix it.
--- drivers/i2c/busses/i2c-xiic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-xiic.c +1 -1
@@ -854,8 +854,8 @@ static int xiic_i2c_probe(struct platform_device *pdev)return 0 ; err_pm_disable: -pm_runtime_set_suspended (&pdev->dev);pm_runtime_disable (&pdev->dev); +pm_runtime_set_suspended (&pdev->dev);return ret; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 622/798 dt-bindings: clock: exynos7885: Fix duplicated binding
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Virag <[email protected]>
[ Upstream commit abf3a3ea9acb5c886c8729191a670744ecd42024 ]
The numbering in Exynos7885's FSYS CMU bindings has 4 duplicated by accident, with the rest of the bindings continuing with 5.
Fix this by moving CLK_MOUT_FSYS_USB30DRD_USER to the end as 11.
Since CLK_MOUT_FSYS_USB30DRD_USER is not used in any device tree as of now, and there are no other clocks affected (maybe apart from CLK_MOUT_FSYS_MMC_SDIO_USER which the number was shared with, also not used in a device tree), this is the least impactful way to solve this problem.
--- include/dt-bindings/clock/exynos7885.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/dt-bindings/clock/exynos7885.h +2 -2
@@ -139,13 +139,13 @@#define CLK_MOUT_FSYS_MMC_CARD_USER 2#define CLK_MOUT_FSYS_MMC_EMBD_USER 3#define CLK_MOUT_FSYS_MMC_SDIO_USER 4 -#define CLK_MOUT_FSYS_USB30DRD_USER 4#define CLK_GOUT_MMC_CARD_ACLK 5#define CLK_GOUT_MMC_CARD_SDCLKIN 6#define CLK_GOUT_MMC_EMBD_ACLK 7#define CLK_GOUT_MMC_EMBD_SDCLKIN 8#define CLK_GOUT_MMC_SDIO_ACLK 9#define CLK_GOUT_MMC_SDIO_SDCLKIN 10 -#define FSYS_NR_CLK 11 +#define CLK_MOUT_FSYS_USB30DRD_USER 11 +#define FSYS_NR_CLK 12#endif /* _DT_BINDINGS_CLOCK_EXYNOS_7885_H */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 623/798 spi: bcm63xx: Fix missing pm_runtime_disable()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 265697288ec2160ca84707565d6641d46f69b0ff ]
The pm_runtime_disable() is missing in the remove function, fix it by using devm_pm_runtime_enable(), so the pm_runtime_disable() in the probe error path can also be removed.
--- drivers/spi/spi-bcm63xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/spi/spi-bcm63xx.c +4 -4
@@ -595,13 +595,15 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)bcm_spi_writeb (bs,SPI_INTR_CLEAR_ALL ,SPI_INT_STATUS ); -pm_runtime_enable (&pdev->dev); + ret =devm_pm_runtime_enable (&pdev->dev); +if (ret) + goto out_clk_disable;/* register and we are done */ ret =devm_spi_register_master (dev, master);if (ret) {dev_err (dev,"spi register failed\n" ); - goto out_pm_disable; + goto out_clk_disable; } dev_info(dev, "at %pr (irq %d, FIFOs size %d)\n",
@@ -609,8 +611,6 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)return 0 ; -out_pm_disable: -pm_runtime_disable (&pdev->dev); out_clk_disable:clk_disable_unprepare (clk); out_err:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 624/798 arm64: Add Cortex-715 CPU part definition
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anshuman Khandual <[email protected]>
[ Upstream commit 07e39e60bbf0ccd5f895568e1afca032193705c0 ]
Add the CPU Partnumbers for the new Arm designs.
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -82,6 +82,7 @@#define ARM_CPU_PART_CORTEX_A510 0xD46#define ARM_CPU_PART_CORTEX_A520 0xD80#define ARM_CPU_PART_CORTEX_A710 0xD47 +#define ARM_CPU_PART_CORTEX_A715 0xD4D#define ARM_CPU_PART_CORTEX_X2 0xD48#define ARM_CPU_PART_NEOVERSE_N2 0xD49#define ARM_CPU_PART_CORTEX_A78C 0xD4B
@@ -156,6 +157,7 @@#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)#define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520)#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) +#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715)#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 625/798 arm64: cputype: Add Neoverse-N3 definitions
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit 924725707d80bc2588cefafef76ff3f164d299bc ]
Add cputype definitions for Neoverse-N3. These will be used for errata detection in subsequent patches.
These values can be found in Table A-261 ("MIDR_EL1 bit descriptions") in issue 02 of the Neoverse-N3 TRM, which can be found at:
https://developer.arm.com/documentation/107997/0000/?lang=en
--- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/include/asm/cputype.h +2 -0
@@ -94,6 +94,7 @@#define ARM_CPU_PART_NEOVERSE_V3 0xD84#define ARM_CPU_PART_CORTEX_X925 0xD85#define ARM_CPU_PART_CORTEX_A725 0xD87 +#define ARM_CPU_PART_NEOVERSE_N3 0xD8E#define APM_CPU_PART_XGENE 0x000#define APM_CPU_VAR_POTENZA 0x00
@@ -169,6 +170,7 @@#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725) +#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 626/798 arm64: errata: Expand speculative SSBS workaround once more
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
[ Upstream commit 081eb7932c2b244f63317a982c5e3990e2c7fbdd ]
A number of Arm Ltd CPUs suffer from errata whereby an MSR to the SSBS special-purpose register does not affect subsequent speculative instructions, permitting speculative store bypassing for a window of time.
We worked around this for a number of CPUs in commits:
* 7187bb7d0b5c7dfa ("arm64: errata: Add workaround for Arm errata 3194386 and 3312417")
* 75b3c43eab594bfb ("arm64: errata: Expand speculative SSBS workaround")
* 145502cac7ea70b5 ("arm64: errata: Expand speculative SSBS workaround (again)")
Since then, a (hopefully final) batch of updates have been published, with two more affected CPUs. For the affected CPUs the existing mitigation is sufficient, as described in their respective Software Developer Errata Notice (SDEN) documents:
* Cortex-A715 (MP148) SDEN v15.0, erratum 3456084
https://developer.arm.com/documentation/SDEN-2148827/1500/
* Neoverse-N3 (MP195) SDEN v5.0, erratum 3456111
https://developer.arm.com/documentation/SDEN-3050973/0500/
Enable the existing mitigation by adding the relevant MIDRs to erratum_spec_ssbs_list, and update silicon-errata.rst and the Kconfig text accordingly.
--- Documentation/arm64/silicon-errata.rst | 4 ++++ arch/arm64/Kconfig | 2 ++ arch/arm64/kernel/cpu_errata.c | 2 ++ 3 files changed, 8 insertions(+)
Documentation/arm64/silicon-errata.rst +4 -0
@@ -135,6 +135,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
@@ -171,6 +173,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |
arch/arm64/Kconfig +2 -0
@@ -1012,6 +1012,7 @@ config ARM64_ERRATUM_3194386 * ARM Cortex-A78C erratum 3324346 * ARM Cortex-A78C erratum 3324347 * ARM Cortex-A710 erratam 3324338 + * ARM Cortex-A715 errartum 3456084 * ARM Cortex-A720 erratum 3456091 * ARM Cortex-A725 erratum 3456106 * ARM Cortex-X1 erratum 3324344
@@ -1022,6 +1023,7 @@ config ARM64_ERRATUM_3194386 * ARM Cortex-X925 erratum 3324334 * ARM Neoverse-N1 erratum 3324349 * ARM Neoverse N2 erratum 3324339 + * ARM Neoverse-N3 erratum 3456111 * ARM Neoverse-V1 erratum 3324341 * ARM Neoverse V2 erratum 3324336 * ARM Neoverse-V3 erratum 3312417
arch/arm64/kernel/cpu_errata.c +2 -0
@@ -442,6 +442,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {MIDR_ALL_VERSIONS (MIDR_CORTEX_A78 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_A78C ),MIDR_ALL_VERSIONS (MIDR_CORTEX_A710 ), +MIDR_ALL_VERSIONS (MIDR_CORTEX_A715 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_A720 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_A725 ), MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
@@ -452,6 +453,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {MIDR_ALL_VERSIONS (MIDR_CORTEX_X925 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N1 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N2 ), +MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N3 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V1 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_V2 ), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 627/798 io_uring/net: harden multishot termination case for recv
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
[ Upstream commit c314094cb4cfa6fc5a17f4881ead2dfebfa717a7 ]
If the recv returns zero, or an error, then it doesn't matter if more data has already been received for this buffer. A condition like that should terminate the multishot receive. Rather than pass in the collected return value, pass in whether to terminate or keep the recv going separately.
Note that this isn't a bug right now, as the only way to get there is via setting MSG_WAITALL with multishot receive. And if an application does that, then -EINVAL is returned anyway. But it seems like an easy bug to introduce, so let's make it a bit more explicit.
--- io_uring/net.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
io_uring/net.c +3 -1
@@ -893,6 +893,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)int ret, min_ret =0 ;bool force_nonblock = issue_flags &IO_URING_F_NONBLOCK ;size_t len = sr->len; +bool mshot_finished;if (!(req->flags &REQ_F_POLLED ) && (sr->flags &IORING_RECVSEND_POLL_FIRST ))
@@ -957,6 +958,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)req_set_fail (req); } + mshot_finished = ret <=0 ;if (ret >0 ) ret += sr->done_io;else if (sr->done_io)
@@ -968,7 +970,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)if (msg.msg_inq) cflags |=IORING_CQE_F_SOCK_NONEMPTY ; -if (!io_recv_finish (req, &ret, cflags, ret <=0 , issue_flags)) +if (!io_recv_finish (req, &ret, cflags, mshot_finished, issue_flags)) goto retry_multishot;return ret;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 628/798 uprobes: fix kernel info leak via "[uprobes]" vma
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleg Nesterov <[email protected]>
commit 34820304cc2cd1804ee1f8f3504ec77813d29c8e upstream.
xol_add_vma() maps the uninitialized page allocated by __create_xol_area() into userspace. On some architectures (x86) this memory is readable even without VM_READ, VM_EXEC results in the same pgprot_t as VM_EXEC|VM_READ, although this doesn't really matter, debugger can read this memory anyway.
--- kernel/events/uprobes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/uprobes.c +1 -1
@@ -1494,7 +1494,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr) area->xol_mapping.name ="[uprobes]" ; area->xol_mapping.pages = area->pages; - area->pages[0 ] =alloc_page (GFP_HIGHUSER ); + area->pages[0 ] =alloc_page (GFP_HIGHUSER | __GFP_ZERO);if (!area->pages[0 ]) goto free_bitmap; area->pages[1 ] =NULL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 629/798 mm: z3fold: deprecate CONFIG_Z3FOLD
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yosry Ahmed <[email protected]>
[ Upstream commit 7a2369b74abf76cd3e54c45b30f6addb497f831b ]
The z3fold compressed pages allocator is rarely used, most users use zsmalloc. The only disadvantage of zsmalloc in comparison is the dependency on MMU, and zbud is a more common option for !MMU as it was the default zswap allocator for a long time.
Historically, zsmalloc had worse latency than zbud and z3fold but offered better memory savings. This is no longer the case as shown by a simple recent analysis [1]. That analysis showed that z3fold does not have any advantage over zsmalloc or zbud considering both performance and memory usage. In a kernel build test on tmpfs in a limited cgroup, z3fold took 3% more time and used 1.8% more memory. The latency of zswap_load() was 7% higher, and that of zswap_store() was 10% higher. Zsmalloc is better in all metrics.
Moreover, z3fold apparently has latent bugs, which was made noticeable by a recent soft lockup bug report with z3fold [2]. Switching to zsmalloc not only fixed the problem, but also reduced the swap usage from 6~8G to 1~2G. Other users have also reported being bitten by mistakenly enabling z3fold.
Other than hurting users, z3fold is repeatedly causing wasted engineering effort. Apart from investigating the above bug, it came up in multiple development discussions (e.g. [3]) as something we need to handle, when there aren't any legit users (at least not intentionally).
The natural course of action is to deprecate z3fold, and remove in a few cycles if no objections are raised from active users. Next on the list should be zbud, as it offers marginal latency gains at the cost of huge memory waste when compared to zsmalloc. That one will need to wait until zsmalloc does not depend on MMU.
Rename the user-visible config option from CONFIG_Z3FOLD to CONFIG_Z3FOLD_DEPRECATED so that users with CONFIG_Z3FOLD=y get a new prompt with explanation during make oldconfig. Also, remove CONFIG_Z3FOLD=y from defconfigs.
[1]https://lore.kernel.org/lkml/CAJD7tkbRF6od-2x_L8-A1QL3=2Ww13sCj4S3i4bNndqF+3+_Vg@mail.gmail.com/ [2]https://lore.kernel.org/lkml/[email protected]/ [3]https://lore.kernel.org/lkml/CAJD7tkbnmeVugfunffSovJf9FAgy9rhBVt_tx=nxUveLUfqVsA@mail.gmail.com/
--- arch/loongarch/configs/loongson3_defconfig | 1 - mm/Kconfig | 25 ++++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-)
arch/loongarch/configs/loongson3_defconfig +0 -1
@@ -82,7 +82,6 @@ CONFIG_ZSWAP=y CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y CONFIG_ZPOOL=y CONFIG_ZBUD=y -CONFIG_Z3FOLD=y CONFIG_ZSMALLOC=m CONFIG_NET=y CONFIG_PACKET=y
mm/Kconfig +19 -6
@@ -132,12 +132,15 @@ config ZSWAP_ZPOOL_DEFAULT_ZBUD help Use the zbud allocator as the default allocator. -config ZSWAP_ZPOOL_DEFAULT_Z3FOLD - bool "z3fold" - select Z3FOLD +config ZSWAP_ZPOOL_DEFAULT_Z3FOLD_DEPRECATED + bool "z3foldi (DEPRECATED)" + select Z3FOLD_DEPRECATED help Use the z3fold allocator as the default allocator. + Deprecated and scheduled for removal in a few cycles, + see CONFIG_Z3FOLD_DEPRECATED. + config ZSWAP_ZPOOL_DEFAULT_ZSMALLOC bool "zsmalloc" select ZSMALLOC
@@ -149,7 +152,7 @@ config ZSWAP_ZPOOL_DEFAULT string depends on ZSWAP default "zbud" if ZSWAP_ZPOOL_DEFAULT_ZBUD - default "z3fold" if ZSWAP_ZPOOL_DEFAULT_Z3FOLD + default "z3fold" if ZSWAP_ZPOOL_DEFAULT_Z3FOLD_DEPRECATED default "zsmalloc" if ZSWAP_ZPOOL_DEFAULT_ZSMALLOC default ""
@@ -163,15 +166,25 @@ config ZBUD deterministic reclaim properties that make it preferable to a higher density approach when reclaim will be used. -config Z3FOLD - tristate "3:1 compression allocator (z3fold)" +config Z3FOLD_DEPRECATED + tristate "3:1 compression allocator (z3fold) (DEPRECATED)" depends on ZSWAP help + Deprecated and scheduled for removal in a few cycles. If you have + a good reason for using Z3FOLD over ZSMALLOC, please contact + [email protected] and the zswap maintainers. + A special purpose allocator for storing compressed pages. It is designed to store up to three compressed pages per physical page. It is a ZBUD derivative so the simplicity and determinism are still there. +config Z3FOLD + tristate + default y if Z3FOLD_DEPRECATED=y + default m if Z3FOLD_DEPRECATED=m + depends on Z3FOLD_DEPRECATED + config ZSMALLOC tristate prompt "N:1 compression allocator (zsmalloc)" if ZSWAP
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 630/798 drm/amd/display: Allow backlight to go below `AMDGPU_DM_DEFAULT_MIN_BACKLIGHT`
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
[ Upstream commit 87d749a6aab73d8069d0345afaa98297816cb220 ]
The issue with panel power savings compatibility below AMDGPU_DM_DEFAULT_MIN_BACKLIGHT happens at AMDGPU_DM_DEFAULT_MIN_BACKLIGHT as well.
That issue will be fixed separately, so don't prevent the backlight brightness from going that low.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -1
@@ -4077,7 +4077,7 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm,int spread = caps.max_input_signal - caps.min_input_signal;if (caps.max_input_signal >AMDGPU_DM_DEFAULT_MAX_BACKLIGHT || - caps.min_input_signal <AMDGPU_DM_DEFAULT_MIN_BACKLIGHT || + caps.min_input_signal <0 || spread >AMDGPU_DM_DEFAULT_MAX_BACKLIGHT || spread <AMDGPU_DM_MIN_SPREAD ) { DRM_DEBUG_KMS("DM: Invalid backlight caps: min=%d, max=%d\n",
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 631/798 build-id: require program headers to be right after ELF header
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Dobriyan <[email protected]>
[ Upstream commit 961a2851324561caed579764ffbee3db82b32829 ]
Neither ELF spec not ELF loader require program header to be placed right after ELF header, but build-id code very much assumes such placement:
See
find_get_page(vma->vm_file->f_mapping, 0);
line and checks against PAGE_SIZE.
Returns errors for now until someone rewrites build-id parser to be more inline with load_elf_binary().
Stable-dep-of: 905415ff3ffb ("lib/buildid: harden build ID parsing logic")
--- lib/buildid.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
lib/buildid.c +14 -0
@@ -73,6 +73,13 @@ static int get_build_id_32(const void *page_addr, unsigned char *build_id,Elf32_Phdr *phdr;int i; +/* +* FIXME +* Neither ELF spec nor ELF loader require that program headers +* start immediately after ELF header. +*/ +if (ehdr->e_phoff !=sizeof (Elf32_Ehdr)) +return -EINVAL ;/* only supports phdr that fits in one page */ if (ehdr->e_phnum > (PAGE_SIZE -sizeof (Elf32_Ehdr)) /sizeof (Elf32_Phdr))
@@ -98,6 +105,13 @@ static int get_build_id_64(const void *page_addr, unsigned char *build_id,Elf64_Phdr *phdr;int i; +/* +* FIXME +* Neither ELF spec nor ELF loader require that program headers +* start immediately after ELF header. +*/ +if (ehdr->e_phoff !=sizeof (Elf64_Ehdr)) +return -EINVAL ;/* only supports phdr that fits in one page */ if (ehdr->e_phnum > (PAGE_SIZE -sizeof (Elf64_Ehdr)) /sizeof (Elf64_Phdr))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 632/798 lib/buildid: harden build ID parsing logic
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrii Nakryiko <[email protected]>
[ Upstream commit 905415ff3ffb1d7e5afa62bacabd79776bd24606 ]
Harden build ID parsing logic, adding explicit READ_ONCE() where it's important to have a consistent value read and validated just once.
Also, as pointed out by Andi Kleen, we need to make sure that entire ELF note is within a page bounds, so move the overflow check up and add an extra note_size boundaries validation.
Fixes tag below points to the code that moved this code into lib/buildid.c, and then subsequently was used in perf subsystem, making this code exposed to perf_event_open() users in v5.12+.
--- lib/buildid.c | 76 +++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 32 deletions(-)
lib/buildid.c +44 -32
@@ -18,31 +18,37 @@ static int parse_build_id_buf(unsigned char *build_id,const void *note_start, Elf32_Word note_size) { - Elf32_Word note_offs = 0, new_offs; - -while (note_offs +sizeof (Elf32_Nhdr) < note_size) { -Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_offs); + const char note_name[] = "GNU"; +const size_t note_name_sz =sizeof (note_name); +u64 note_off =0 , new_off, name_sz, desc_sz; +const char *data; + +while (note_off +sizeof (Elf32_Nhdr) < note_size && + note_off +sizeof (Elf32_Nhdr) > note_off/* overflow */ ) { +Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_off); + + name_sz =READ_ONCE (nhdr->n_namesz); + desc_sz =READ_ONCE (nhdr->n_descsz); + + new_off = note_off +sizeof (Elf32_Nhdr); +if (check_add_overflow (new_off,ALIGN (name_sz,4 ), &new_off) || +check_add_overflow (new_off,ALIGN (desc_sz,4 ), &new_off) || + new_off > note_size) +break ;if (nhdr->n_type ==BUILD_ID && - nhdr->n_namesz ==sizeof ("GNU" ) && - !strcmp ((char *)(nhdr +1 ),"GNU" ) && - nhdr->n_descsz >0 && - nhdr->n_descsz <=BUILD_ID_SIZE_MAX ) { -memcpy (build_id, - note_start + note_offs + -ALIGN (sizeof ("GNU" ),4 ) +sizeof (Elf32_Nhdr), - nhdr->n_descsz); -memset (build_id + nhdr->n_descsz,0 , -BUILD_ID_SIZE_MAX - nhdr->n_descsz); + name_sz == note_name_sz && +memcmp (nhdr +1 , note_name, note_name_sz) ==0 && + desc_sz >0 && desc_sz <=BUILD_ID_SIZE_MAX ) { + data = note_start + note_off +ALIGN (note_name_sz,4 ); +memcpy (build_id, data, desc_sz); +memset (build_id + desc_sz,0 ,BUILD_ID_SIZE_MAX - desc_sz);if (size) - *size = nhdr->n_descsz; + *size = desc_sz;return 0 ; } - new_offs = note_offs +sizeof (Elf32_Nhdr) + -ALIGN (nhdr->n_namesz,4 ) +ALIGN (nhdr->n_descsz,4 ); -if (new_offs <= note_offs)/* overflow */ -break ; - note_offs = new_offs; + + note_off = new_off; }return -EINVAL ;
@@ -71,7 +77,7 @@ static int get_build_id_32(const void *page_addr, unsigned char *build_id, {Elf32_Ehdr *ehdr = (Elf32_Ehdr *)page_addr;Elf32_Phdr *phdr; -int i; +__u32 i, phnum;/* * FIXME
@@ -80,18 +86,19 @@ static int get_build_id_32(const void *page_addr, unsigned char *build_id,*/ if (ehdr->e_phoff !=sizeof (Elf32_Ehdr))return -EINVAL ; + + phnum =READ_ONCE (ehdr->e_phnum);/* only supports phdr that fits in one page */ -if (ehdr->e_phnum > - (PAGE_SIZE -sizeof (Elf32_Ehdr)) /sizeof (Elf32_Phdr)) +if (phnum > (PAGE_SIZE -sizeof (Elf32_Ehdr)) /sizeof (Elf32_Phdr))return -EINVAL ; phdr = (Elf32_Phdr *)(page_addr +sizeof (Elf32_Ehdr)); -for (i =0 ; i < ehdr->e_phnum; ++i) { +for (i =0 ; i < phnum; ++i) {if (phdr[i].p_type ==PT_NOTE && !parse_build_id (page_addr, build_id, size, - page_addr + phdr[i].p_offset, - phdr[i].p_filesz)) + page_addr +READ_ONCE (phdr[i].p_offset), +READ_ONCE (phdr[i].p_filesz)))return 0 ; }return -EINVAL ;
@@ -103,7 +110,7 @@ static int get_build_id_64(const void *page_addr, unsigned char *build_id, {Elf64_Ehdr *ehdr = (Elf64_Ehdr *)page_addr;Elf64_Phdr *phdr; -int i; +__u32 i, phnum;/* * FIXME
@@ -112,18 +119,19 @@ static int get_build_id_64(const void *page_addr, unsigned char *build_id,*/ if (ehdr->e_phoff !=sizeof (Elf64_Ehdr))return -EINVAL ; + + phnum =READ_ONCE (ehdr->e_phnum);/* only supports phdr that fits in one page */ -if (ehdr->e_phnum > - (PAGE_SIZE -sizeof (Elf64_Ehdr)) /sizeof (Elf64_Phdr)) +if (phnum > (PAGE_SIZE -sizeof (Elf64_Ehdr)) /sizeof (Elf64_Phdr))return -EINVAL ; phdr = (Elf64_Phdr *)(page_addr +sizeof (Elf64_Ehdr)); -for (i =0 ; i < ehdr->e_phnum; ++i) { +for (i =0 ; i < phnum; ++i) {if (phdr[i].p_type ==PT_NOTE && !parse_build_id (page_addr, build_id, size, - page_addr + phdr[i].p_offset, - phdr[i].p_filesz)) + page_addr +READ_ONCE (phdr[i].p_offset), +READ_ONCE (phdr[i].p_filesz)))return 0 ; }return -EINVAL ;
@@ -152,6 +160,10 @@ int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id, page =find_get_page (vma->vm_file->f_mapping,0 );if (!page)return -EFAULT ;/* page not mapped */ +if (!PageUptodate (page)) { +put_page (page); +return -EFAULT ; + } ret = -EINVAL ; page_addr =kmap_atomic (page);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 633/798 docs/zh_CN: Update the translation of delay-accounting to 6.1-rc8
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yanteng Si <[email protected]>
[ Upstream commit 6ab587e8e8b434ffc2decdd6db17dff0ef2b13ab ]
Update to commit f347c9d2697f ("filemap: make the accounting of thrashing more consistent").
Commit 662ce1dc9caf ("delayacct: track delays from write-protect copy").
Stable-dep-of: 3840cbe24cf0 ("sched: psi: fix bogus pressure spikes from aggregation race")
--- .../translations/zh_CN/accounting/delay-accounting.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
Documentation/translations/zh_CN/accounting/delay-accounting.rst +5 -2
@@ -17,8 +17,9 @@ a) 等待一个CPU(任务为可运行) b) 完成由该任务发起的块I/O同步请求 c) 页面交换 d) 内存回收 -e) 页缓存抖动 +e) 抖动 f) 直接规整 +g) 写保护复制 并将这些统计信息通过taskstats接口提供给用户空间。
@@ -42,7 +43,7 @@ f) 直接规整 include/uapi/linux/taskstats.h 其描述了延时计数相关字段。系统通常以计数器形式返回 CPU、同步块 I/O、交换、内存 -回收、页缓存抖动、直接规整等的累积延时。 +回收、页缓存抖动、直接规整、写保护复制等的累积延时。 取任务某计数器两个连续读数的差值,将得到任务在该时间间隔内等待对应资源的总延时。
@@ -100,6 +101,8 @@ getdelays命令的一般格式:: 0 0 0ms COMPACT count delay total delay average 0 0 0ms + WPCOPY count delay total delay average + 0 0 0ms 获取pid为1的IO计数,它只和-p一起使用:: # ./getdelays -i -p 1
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 634/798 delayacct: improve the average delay precision of getdelay tool to microsecond
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Yong <[email protected]>
[ Upstream commit eca7de7cdc382eb6e0d344c07b1449ed75f5b435 ]
Improve the average delay precision of getdelay tool to microsecond. When using the getdelay tool, it is sometimes found that the average delay except CPU is not 0, but display is 0, because the precison is too low. For example, see delay average of SWAP below when using ZRAM.
print delayacct stats ON
PID 32915
CPU count real total virtual total delay total delay average
339202 2793871936 9233585504 7951112 0.000ms
IO count delay total delay average
41 419296904 10ms
SWAP count delay total delay average
242589 1045792384 0msThis wrong display is misleading, so improve the millisecond precision of the average delay to microsecond just like CPU. Then user would get more accurate information of delay time.
Stable-dep-of: 3840cbe24cf0 ("sched: psi: fix bogus pressure spikes from aggregation race")
--- Documentation/accounting/delay-accounting.rst | 14 +++++------ .../zh_CN/accounting/delay-accounting.rst | 10 ++++---- tools/accounting/getdelays.c | 24 +++++++++---------- 3 files changed, 24 insertions(+), 24 deletions(-)
Documentation/accounting/delay-accounting.rst +7 -7
@@ -109,17 +109,17 @@ Get sum of delays, since system boot, for all pids with tgid 5:: CPU count real total virtual total delay total delay average 8 7000000 6872122 3382277 0.423ms IO count delay total delay average - 0 0 0ms + 0 0 0.000ms SWAP count delay total delay average - 0 0 0ms + 0 0 0.000ms RECLAIM count delay total delay average - 0 0 0ms + 0 0 0.000ms THRASHING count delay total delay average - 0 0 0ms + 0 0 0.000ms COMPACT count delay total delay average - 0 0 0ms - WPCOPY count delay total delay average - 0 0 0ms + 0 0 0.000ms + WPCOPY count delay total delay average + 0 0 0.000ms Get IO accounting for pid 1, it works only with -p::
Documentation/translations/zh_CN/accounting/delay-accounting.rst +5 -5
@@ -92,15 +92,15 @@ getdelays命令的一般格式:: CPU count real total virtual total delay total delay average 8 7000000 6872122 3382277 0.423ms IO count delay total delay average - 0 0 0ms + 0 0 0.000ms SWAP count delay total delay average - 0 0 0ms + 0 0 0.000ms RECLAIM count delay total delay average - 0 0 0ms + 0 0 0.000ms THRASHING count delay total delay average - 0 0 0ms + 0 0 0.000ms COMPACT count delay total delay average - 0 0 0ms + 0 0 0.000ms WPCOPY count delay total delay average 0 0 0ms
tools/accounting/getdelays.c +12 -12
@@ -198,17 +198,17 @@ static void print_delayacct(struct taskstats *t) printf("\n\nCPU %15s%15s%15s%15s%15s\n" " %15llu%15llu%15llu%15llu%15.3fms\n" "IO %15s%15s%15s\n" - " %15llu%15llu%15llums\n" + " %15llu%15llu%15.3fms\n" "SWAP %15s%15s%15s\n" - " %15llu%15llu%15llums\n" + " %15llu%15llu%15.3fms\n" "RECLAIM %12s%15s%15s\n" - " %15llu%15llu%15llums\n" + " %15llu%15llu%15.3fms\n" "THRASHING%12s%15s%15s\n" - " %15llu%15llu%15llums\n" + " %15llu%15llu%15.3fms\n" "COMPACT %12s%15s%15s\n" - " %15llu%15llu%15llums\n" + " %15llu%15llu%15.3fms\n" "WPCOPY %12s%15s%15s\n" - " %15llu%15llu%15llums\n", + " %15llu%15llu%15.3fms\n", "count", "real total", "virtual total", "delay total", "delay average", (unsigned long long)t->cpu_count,
@@ -219,27 +219,27 @@ static void print_delayacct(struct taskstats *t)"count" ,"delay total" ,"delay average" , (unsigned long long )t->blkio_count, (unsigned long long )t->blkio_delay_total, -average_ms (t->blkio_delay_total, t->blkio_count), +average_ms ((double )t->blkio_delay_total, t->blkio_count),"count" ,"delay total" ,"delay average" , (unsigned long long )t->swapin_count, (unsigned long long )t->swapin_delay_total, -average_ms (t->swapin_delay_total, t->swapin_count), +average_ms ((double )t->swapin_delay_total, t->swapin_count),"count" ,"delay total" ,"delay average" , (unsigned long long )t->freepages_count, (unsigned long long )t->freepages_delay_total, -average_ms (t->freepages_delay_total, t->freepages_count), +average_ms ((double )t->freepages_delay_total, t->freepages_count),"count" ,"delay total" ,"delay average" , (unsigned long long )t->thrashing_count, (unsigned long long )t->thrashing_delay_total, -average_ms (t->thrashing_delay_total, t->thrashing_count), +average_ms ((double )t->thrashing_delay_total, t->thrashing_count),"count" ,"delay total" ,"delay average" , (unsigned long long )t->compact_count, (unsigned long long )t->compact_delay_total, -average_ms (t->compact_delay_total, t->compact_count), +average_ms ((double )t->compact_delay_total, t->compact_count),"count" ,"delay total" ,"delay average" , (unsigned long long )t->wpcopy_count, (unsigned long long )t->wpcopy_delay_total, - average_ms(t->wpcopy_delay_total, t->wpcopy_count)); + average_ms((double)t->wpcopy_delay_total, t->wpcopy_count)); }static void task_context_switch_counts (struct taskstats *t)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 635/798 sched: psi: fix bogus pressure spikes from aggregation race
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Weiner <[email protected]>
[ Upstream commit 3840cbe24cf060ea05a585ca497814609f5d47d1 ]
Brandon reports sporadic, non-sensical spikes in cumulative pressure time (total=) when reading cpu.pressure at a high rate. This is due to a race condition between reader aggregation and tasks changing states.
While it affects all states and all resources captured by PSI, in practice it most likely triggers with CPU pressure, since scheduling events are so frequent compared to other resource events.
The race context is the live snooping of ongoing stalls during a pressure read. The read aggregates per-cpu records for stalls that have concluded, but will also incorporate ad-hoc the duration of any active state that hasn't been recorded yet. This is important to get timely measurements of ongoing stalls. Those ad-hoc samples are calculated on-the-fly up to the current time on that CPU; since the stall hasn't concluded, it's expected that this is the minimum amount of stall time that will enter the per-cpu records once it does.
The problem is that the path that concludes the state uses a CPU clock read that is not synchronized against aggregators; the clock is read outside of the seqlock protection. This allows aggregators to race and snoop a stall with a longer duration than will actually be recorded.
With the recorded stall time being less than the last snapshot remembered by the aggregator, a subsequent sample will underflow and observe a bogus delta value, resulting in an erratic jump in pressure.
Fix this by moving the clock read of the state change into the seqlock protection. This ensures no aggregation can snoop live stalls past the time that's recorded when the state concludes.
--- kernel/sched/psi.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-)
kernel/sched/psi.c +12 -14
@@ -777,13 +777,14 @@ static void record_times(struct psi_group_cpu *groupc, u64 now) }static void psi_group_change (struct psi_group *group,int cpu, -unsigned int clear,unsigned int set,u64 now, +unsigned int clear,unsigned int set,bool wake_clock) {struct psi_group_cpu *groupc;unsigned int t, m;enum psi_states s;u32 state_mask; +u64 now;lockdep_assert_rq_held (cpu_rq (cpu)); groupc =per_cpu_ptr (group->pcpu, cpu);
@@ -798,6 +799,7 @@ static void psi_group_change(struct psi_group *group, int cpu,* SOME and FULL time these may have resulted in. */ write_seqcount_begin (&groupc->seq); + now =cpu_clock (cpu);/* * Start with TSK_ONCPU, which doesn't have a corresponding
@@ -911,18 +913,15 @@ void psi_task_change(struct task_struct *task, int clear, int set) {int cpu =task_cpu (task);struct psi_group *group; -u64 now;if (!task->pid)return ;psi_flags_change (task, clear, set); - now =cpu_clock (cpu); - group =task_psi_group (task);do { -psi_group_change (group, cpu, clear, set, now, true); +psi_group_change (group, cpu, clear, set, true); }while ((group = group->parent)); }
@@ -931,7 +930,6 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next, {struct psi_group *group, *common =NULL ;int cpu =task_cpu (prev); -u64 now =cpu_clock (cpu);if (next->pid) {psi_flags_change (next,0 ,TSK_ONCPU );
@@ -948,7 +946,7 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next,break ; } -psi_group_change (group, cpu,0 ,TSK_ONCPU , now, true); +psi_group_change (group, cpu,0 ,TSK_ONCPU , true); }while ((group = group->parent)); }
@@ -986,7 +984,7 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next,do {if (group == common)break ; -psi_group_change (group, cpu, clear, set, now, wake_clock); +psi_group_change (group, cpu, clear, set, wake_clock); }while ((group = group->parent));/*
@@ -998,7 +996,7 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next,if ((prev->psi_flags ^ next->psi_flags) & ~TSK_ONCPU ) { clear &= ~TSK_ONCPU ;for (; group; group = group->parent) -psi_group_change (group, cpu, clear, set, now, wake_clock); +psi_group_change (group, cpu, clear, set, wake_clock); } } }
@@ -1009,8 +1007,8 @@ void psi_account_irqtime(struct rq *rq, struct task_struct *curr, struct task_stint cpu =task_cpu (curr);struct psi_group *group;struct psi_group_cpu *groupc; -u64 now, irq;s64 delta; +u64 irq;if (!curr->pid)return ;
@@ -1020,7 +1018,6 @@ void psi_account_irqtime(struct rq *rq, struct task_struct *curr, struct task_stif (prev &&task_psi_group (prev) == group)return ; - now =cpu_clock (cpu); irq =irq_time_read (cpu); delta = (s64)(irq - rq->psi_irq_time);if (delta <0 )
@@ -1028,12 +1025,15 @@ void psi_account_irqtime(struct rq *rq, struct task_struct *curr, struct task_st rq->psi_irq_time = irq; do { + u64 now; + if (!group->enabled) continue; groupc = per_cpu_ptr(group->pcpu, cpu); write_seqcount_begin(&groupc->seq); + now = cpu_clock(cpu); record_times(groupc, now); groupc->times[PSI_IRQ_FULL] += delta;
@@ -1232,11 +1232,9 @@ void psi_cgroup_restart(struct psi_group *group)for_each_possible_cpu (cpu) {struct rq *rq =cpu_rq (cpu);struct rq_flags rf; -u64 now;rq_lock_irq (rq, &rf); - now =cpu_clock (cpu); -psi_group_change (group, cpu,0 ,0 , now, true); +psi_group_change (group, cpu,0 ,0 , true);rq_unlock_irq (rq, &rf); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 636/798 clk: imx6ul: fix enet1 gate configuration
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
[ Upstream commit 5f82bfced6118450cb9ea3f12316568f6fac10ab ]
According to the "i.MX 6UltraLite Applications Processor Reference Manual, Rev. 2, 03/2017", BIT(13) is ENET1_125M_EN which is not controlling root of PLL6. It is controlling ENET1 separately.
So, instead of this picture (implementation before this patch):
fec1 <- enet_ref (divider) <---------------------------,
|- pll6_enet (gate)
fec2 <- enet2_ref_125m (gate) <- enet2_ref (divider) <-´
we should have this one (after this patch):
fec1 <- enet1_ref_125m (gate) <- enet1_ref (divider) <-,
|- pll6_enet
fec2 <- enet2_ref_125m (gate) <- enet2_ref (divider) <-´
With this fix, the RMII reference clock will be turned off, after setting network interface down on each separate interface
(ip l s dev eth0 down). Which was not working before, on system with both FECs enabled.
Stable-dep-of: 32c055ef563c ("clk: imx6ul: fix clock parent for IMX6UL_CLK_ENETx_REF_SEL")
--- drivers/clk/imx/clk-imx6ul.c | 7 ++++--- include/dt-bindings/clock/imx6ul-clock.h | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-)
drivers/clk/imx/clk-imx6ul.c +4 -3
@@ -176,7 +176,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) hws[IMX6UL_CLK_PLL3_USB_OTG ] =imx_clk_hw_gate ("pll3_usb_otg" ,"pll3_bypass" , base +0x10 ,13 ); hws[IMX6UL_CLK_PLL4_AUDIO ] =imx_clk_hw_gate ("pll4_audio" ,"pll4_bypass" , base +0x70 ,13 ); hws[IMX6UL_CLK_PLL5_VIDEO ] =imx_clk_hw_gate ("pll5_video" ,"pll5_bypass" , base +0xa0 ,13 ); - hws[IMX6UL_CLK_PLL6_ENET ] =imx_clk_hw_gate ("pll6_enet" ,"pll6_bypass" , base +0xe0 ,13 ); + hws[IMX6UL_CLK_PLL6_ENET ] =imx_clk_hw_fixed_factor ("pll6_enet" ,"pll6_bypass" ,1 ,1 ); hws[IMX6UL_CLK_PLL7_USB_HOST ] =imx_clk_hw_gate ("pll7_usb_host" ,"pll7_bypass" , base +0x20 ,13 );/*
@@ -205,12 +205,13 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) hws[IMX6UL_CLK_PLL3_PFD2 ] =imx_clk_hw_pfd ("pll3_pfd2_508m" ,"pll3_usb_otg" , base +0xf0 ,2 ); hws[IMX6UL_CLK_PLL3_PFD3 ] =imx_clk_hw_pfd ("pll3_pfd3_454m" ,"pll3_usb_otg" , base +0xf0 ,3 ); - hws[IMX6UL_CLK_ENET_REF ] =clk_hw_register_divider_table (NULL ,"enet_ref" ,"pll6_enet" ,0 , + hws[IMX6UL_CLK_ENET_REF ] =clk_hw_register_divider_table (NULL ,"enet1_ref" ,"pll6_enet" ,0 , base +0xe0 ,0 ,2 ,0 , clk_enet_ref_table, &imx_ccm_lock); hws[IMX6UL_CLK_ENET2_REF ] =clk_hw_register_divider_table (NULL ,"enet2_ref" ,"pll6_enet" ,0 , base +0xe0 ,2 ,2 ,0 , clk_enet_ref_table, &imx_ccm_lock); - hws[IMX6UL_CLK_ENET2_REF_125M ] =imx_clk_hw_gate ("enet_ref_125m" ,"enet2_ref" , base +0xe0 ,20 ); + hws[IMX6UL_CLK_ENET1_REF_125M ] =imx_clk_hw_gate ("enet1_ref_125m" ,"enet1_ref" , base +0xe0 ,13 ); + hws[IMX6UL_CLK_ENET2_REF_125M ] =imx_clk_hw_gate ("enet2_ref_125m" ,"enet2_ref" , base +0xe0 ,20 ); hws[IMX6UL_CLK_ENET_PTP_REF ] =imx_clk_hw_fixed_factor ("enet_ptp_ref" ,"pll6_enet" ,1 ,20 ); hws[IMX6UL_CLK_ENET_PTP ] =imx_clk_hw_gate ("enet_ptp" ,"enet_ptp_ref" , base +0xe0 ,21 );
include/dt-bindings/clock/imx6ul-clock.h +2 -1
@@ -256,7 +256,8 @@#define IMX6UL_CLK_GPIO4 247#define IMX6UL_CLK_GPIO5 248#define IMX6UL_CLK_MMDC_P1_IPG 249 +#define IMX6UL_CLK_ENET1_REF_125M 250 -#define IMX6UL_CLK_END 250 +#define IMX6UL_CLK_END 251#endif /* __DT_BINDINGS_CLOCK_IMX6UL_H */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 637/798 clk: imx6ul: add ethernet refclock mux support
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
[ Upstream commit 4e197ee880c24ecb63f7fe17449b3653bc64b03c ]
Add ethernet refclock mux support and set it to internal clock by default. This configuration will not affect existing boards.
clock tree before this patch:
fec1 <- enet1_ref_125m (gate) <- enet1_ref (divider) <-,
|- pll6_enet
fec2 <- enet2_ref_125m (gate) <- enet2_ref (divider) <-´
after this patch:
fec1 <- enet1_ref_sel(mux) <- enet1_ref_125m (gate) <- ...
`--<> enet1_ref_pad |- pll6_enet
fec2 <- enet2_ref_sel(mux) <- enet2_ref_125m (gate) <- ...
`--<> enet2_ref_pad
Stable-dep-of: 32c055ef563c ("clk: imx6ul: fix clock parent for IMX6UL_CLK_ENETx_REF_SEL")
--- drivers/clk/imx/clk-imx6ul.c | 26 +++++++++++++++++++++ include/dt-bindings/clock/imx6ul-clock.h | 6 ++++- include/linux/mfd/syscon/imx6q-iomuxc-gpr.h | 6 +++-- 3 files changed, 35 insertions(+), 3 deletions(-)
drivers/clk/imx/clk-imx6ul.c +26 -0
@@ -10,6 +10,7 @@#include <linux/err.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h>
@@ -94,6 +95,17 @@ static const struct clk_div_table video_div_table[] = { { } }; +static const char * enet1_ref_sels[] = {"enet1_ref_125m" ,"enet1_ref_pad" , }; +static const u32 enet1_ref_sels_table[] = {IMX6UL_GPR1_ENET1_TX_CLK_DIR , +IMX6UL_GPR1_ENET1_CLK_SEL }; +static const u32 enet1_ref_sels_table_mask =IMX6UL_GPR1_ENET1_TX_CLK_DIR | +IMX6UL_GPR1_ENET1_CLK_SEL ; +static const char * enet2_ref_sels[] = {"enet2_ref_125m" ,"enet2_ref_pad" , }; +static const u32 enet2_ref_sels_table[] = {IMX6UL_GPR1_ENET2_TX_CLK_DIR , +IMX6UL_GPR1_ENET2_CLK_SEL }; +static const u32 enet2_ref_sels_table_mask =IMX6UL_GPR1_ENET2_TX_CLK_DIR | +IMX6UL_GPR1_ENET2_CLK_SEL ; +static u32 share_count_asrc;static u32 share_count_audio;static u32 share_count_sai1;
@@ -472,6 +484,17 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)/* mask handshake of mmdc */ imx_mmdc_mask_handshake (base,0 ); + hws[IMX6UL_CLK_ENET1_REF_PAD ] =imx_obtain_fixed_of_clock (ccm_node,"enet1_ref_pad" ,0 ); + + hws[IMX6UL_CLK_ENET1_REF_SEL ] =imx_clk_gpr_mux ("enet1_ref_sel" ,"fsl,imx6ul-iomuxc-gpr" , +IOMUXC_GPR1 , enet1_ref_sels,ARRAY_SIZE (enet1_ref_sels), + enet1_ref_sels_table, enet1_ref_sels_table_mask); + hws[IMX6UL_CLK_ENET2_REF_PAD ] =imx_obtain_fixed_of_clock (ccm_node,"enet2_ref_pad" ,0 ); + + hws[IMX6UL_CLK_ENET2_REF_SEL ] =imx_clk_gpr_mux ("enet2_ref_sel" ,"fsl,imx6ul-iomuxc-gpr" , +IOMUXC_GPR1 , enet2_ref_sels,ARRAY_SIZE (enet2_ref_sels), + enet2_ref_sels_table, enet2_ref_sels_table_mask); +imx_check_clk_hws (hws,IMX6UL_CLK_END );of_clk_add_hw_provider (np, of_clk_hw_onecell_get, clk_hw_data);
@@ -516,6 +539,9 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)clk_set_parent (hws[IMX6ULL_CLK_EPDC_PRE_SEL ]->clk, hws[IMX6UL_CLK_PLL3_PFD2 ]->clk);clk_set_parent (hws[IMX6UL_CLK_ENFC_SEL ]->clk, hws[IMX6UL_CLK_PLL2_PFD2 ]->clk); + +clk_set_parent (hws[IMX6UL_CLK_ENET1_REF_SEL ]->clk, hws[IMX6UL_CLK_ENET_REF ]->clk); +clk_set_parent (hws[IMX6UL_CLK_ENET2_REF_SEL ]->clk, hws[IMX6UL_CLK_ENET2_REF ]->clk); }CLK_OF_DECLARE (imx6ul,"fsl,imx6ul-ccm" , imx6ul_clocks_init);
include/dt-bindings/clock/imx6ul-clock.h +5 -1
@@ -257,7 +257,11 @@#define IMX6UL_CLK_GPIO5 248#define IMX6UL_CLK_MMDC_P1_IPG 249#define IMX6UL_CLK_ENET1_REF_125M 250 +#define IMX6UL_CLK_ENET1_REF_SEL 251 +#define IMX6UL_CLK_ENET1_REF_PAD 252 +#define IMX6UL_CLK_ENET2_REF_SEL 253 +#define IMX6UL_CLK_ENET2_REF_PAD 254 -#define IMX6UL_CLK_END 251 +#define IMX6UL_CLK_END 255#endif /* __DT_BINDINGS_CLOCK_IMX6UL_H */
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h +4 -2
@@ -451,8 +451,10 @@#define IMX6SX_GPR12_PCIE_RX_EQ_2 (0x2 << 0)/* For imx6ul iomux gpr register field define */ -#define IMX6UL_GPR1_ENET1_CLK_DIR (0x1 << 17) -#define IMX6UL_GPR1_ENET2_CLK_DIR (0x1 << 18) +#define IMX6UL_GPR1_ENET2_TX_CLK_DIR BIT(18) +#define IMX6UL_GPR1_ENET1_TX_CLK_DIR BIT(17) +#define IMX6UL_GPR1_ENET2_CLK_SEL BIT(14) +#define IMX6UL_GPR1_ENET1_CLK_SEL BIT(13)#define IMX6UL_GPR1_ENET1_CLK_OUTPUT (0x1 << 17)#define IMX6UL_GPR1_ENET2_CLK_OUTPUT (0x1 << 18)#define IMX6UL_GPR1_ENET_CLK_DIR (0x3 << 17)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 638/798 clk: imx6ul: retain early UART clocks during kernel init
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Stein <[email protected]>
[ Upstream commit 912d7af473f163ccdeb02aaabc3534177936b86c ]
Make sure to keep UART clocks enabled during kernel init if earlyprintk or earlycon are active.
Stable-dep-of: 32c055ef563c ("clk: imx6ul: fix clock parent for IMX6UL_CLK_ENETx_REF_SEL")
--- drivers/clk/imx/clk-imx6ul.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/clk/imx/clk-imx6ul.c +2 -0
@@ -542,6 +542,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)clk_set_parent (hws[IMX6UL_CLK_ENET1_REF_SEL ]->clk, hws[IMX6UL_CLK_ENET_REF ]->clk);clk_set_parent (hws[IMX6UL_CLK_ENET2_REF_SEL ]->clk, hws[IMX6UL_CLK_ENET2_REF ]->clk); + +imx_register_uart_clocks (); }CLK_OF_DECLARE (imx6ul,"fsl,imx6ul-ccm" , imx6ul_clocks_init);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 639/798 clk: imx6ul: fix clock parent for IMX6UL_CLK_ENETx_REF_SEL
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michel Alex <[email protected]>
[ Upstream commit 32c055ef563c3a4a73a477839f591b1b170bde8e ]
Commit 4e197ee880c24ecb63f7fe17449b3653bc64b03c ("clk: imx6ul: add ethernet refclock mux support") sets the internal clock as default ethernet clock.
Since IMX6UL_CLK_ENET_REF cannot be parent for IMX6UL_CLK_ENET1_REF_SEL, the call to clk_set_parent() fails. IMX6UL_CLK_ENET1_REF_125M is the correct parent and shall be used instead.
Same applies for IMX6UL_CLK_ENET2_REF_SEL, for which IMX6UL_CLK_ENET2_REF_125M is the correct parent.
--- drivers/clk/imx/clk-imx6ul.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/imx/clk-imx6ul.c +2 -2
@@ -540,8 +540,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)clk_set_parent (hws[IMX6UL_CLK_ENFC_SEL ]->clk, hws[IMX6UL_CLK_PLL2_PFD2 ]->clk); -clk_set_parent (hws[IMX6UL_CLK_ENET1_REF_SEL ]->clk, hws[IMX6UL_CLK_ENET_REF ]->clk); -clk_set_parent (hws[IMX6UL_CLK_ENET2_REF_SEL ]->clk, hws[IMX6UL_CLK_ENET2_REF ]->clk); +clk_set_parent (hws[IMX6UL_CLK_ENET1_REF_SEL ]->clk, hws[IMX6UL_CLK_ENET1_REF_125M ]->clk); +clk_set_parent (hws[IMX6UL_CLK_ENET2_REF_SEL ]->clk, hws[IMX6UL_CLK_ENET2_REF_125M ]->clk);imx_register_uart_clocks (); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 640/798 media: i2c: imx335: Enable regulator supplies
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kieran Bingham <[email protected]>
[ Upstream commit fea91ee73b7cd19f08017221923d789f984abc54 ]
Provide support for enabling and disabling regulator supplies to control power to the camera sensor.
While updating the power on function, document that a sleep is represented as 'T4' in the datasheet power on sequence.
Stable-dep-of: 99d30e2fdea4 ("media: imx335: Fix reset-gpio handling")
--- drivers/media/i2c/imx335.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-)
drivers/media/i2c/imx335.c +34 -2
@@ -75,6 +75,12 @@ struct imx335_reg_list {const struct imx335_reg *regs; }; +static const char *const imx335_supply_name[] = { +"avdd" ,/* Analog (2.9V) supply */ +"ovdd" ,/* Digital I/O (1.8V) supply */ +"dvdd" ,/* Digital Core (1.2V) supply */ +}; +/** * struct imx335_mode - imx335 sensor mode structure * @width: Frame width
@@ -108,6 +114,7 @@ struct imx335_mode {* @sd: V4L2 sub-device * @pad: Media pad. Only one pad supported * @reset_gpio: Sensor reset gpio +* @supplies: Regulator supplies to handle power control * @inclk: Sensor input clock * @ctrl_handler: V4L2 control handler * @link_freq_ctrl: Pointer to link frequency control
@@ -127,6 +134,8 @@ struct imx335 {struct v4l2_subdev sd;struct media_pad pad;struct gpio_desc *reset_gpio; +struct regulator_bulk_data supplies[ARRAY_SIZE (imx335_supply_name)]; +struct clk *inclk;struct v4l2_ctrl_handler ctrl_handler;struct v4l2_ctrl *link_freq_ctrl;
@@ -790,6 +799,17 @@ static int imx335_parse_hw_config(struct imx335 *imx335)return PTR_ERR (imx335->reset_gpio); } +for (i =0 ; i <ARRAY_SIZE (imx335_supply_name); i++) + imx335->supplies[i].supply = imx335_supply_name[i]; + + ret =devm_regulator_bulk_get (imx335->dev, +ARRAY_SIZE (imx335_supply_name), + imx335->supplies); +if (ret) { +dev_err (imx335->dev,"Failed to get regulators\n" ); +return ret; + } +/* Get sensor input clock */ imx335->inclk =devm_clk_get (imx335->dev,NULL );if (IS_ERR (imx335->inclk)) {
@@ -868,6 +888,17 @@ static int imx335_power_on(struct device *dev)struct imx335 *imx335 =to_imx335 (sd);int ret; + ret =regulator_bulk_enable (ARRAY_SIZE (imx335_supply_name), + imx335->supplies); +if (ret) { +dev_err (dev,"%s: failed to enable regulators\n" , + __func__); +return ret; + } + +usleep_range (500 ,550 );/* Tlow */ + +/* Set XCLR */ gpiod_set_value_cansleep (imx335->reset_gpio,1 ); ret =clk_prepare_enable (imx335->inclk);
@@ -876,12 +907,13 @@ static int imx335_power_on(struct device *dev) goto error_reset; } -usleep_range (20 ,22 ); +usleep_range (20 ,22 );/* T4 */ return 0 ; error_reset:gpiod_set_value_cansleep (imx335->reset_gpio,0 ); +regulator_bulk_disable (ARRAY_SIZE (imx335_supply_name), imx335->supplies);return ret; }
@@ -898,8 +930,8 @@ static int imx335_power_off(struct device *dev)struct imx335 *imx335 =to_imx335 (sd);gpiod_set_value_cansleep (imx335->reset_gpio,0 ); -clk_disable_unprepare (imx335->inclk); +regulator_bulk_disable (ARRAY_SIZE (imx335_supply_name), imx335->supplies);return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 641/798 media: imx335: Fix reset-gpio handling
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Umang Jain <[email protected]>
[ Upstream commit 99d30e2fdea4086be4e66e2deb10de854b547ab8 ]
Rectify the logical value of reset-gpio so that it is set to 0 (disabled) during power-on and to 1 (enabled) during power-off.
Set the reset-gpio to GPIO_OUT_HIGH at initialization time to make sure it starts off in reset. Also drop the "Set XCLR" comment which is not-so-informative.
The existing usage of imx335 had reset-gpios polarity inverted (GPIO_ACTIVE_HIGH) in their device-tree sources. With this patch included, those DTS will not be able to stream imx335 anymore. The reset-gpio polarity will need to be rectified in the device-tree sources as shown in [1] example, in order to get imx335 functional again (as it remains in reset prior to this fix).
--- drivers/media/i2c/imx335.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/media/i2c/imx335.c +4 -5
@@ -792,7 +792,7 @@ static int imx335_parse_hw_config(struct imx335 *imx335)/* Request optional reset pin */ imx335->reset_gpio =devm_gpiod_get_optional (imx335->dev,"reset" , -GPIOD_OUT_LOW ); +GPIOD_OUT_HIGH );if (IS_ERR (imx335->reset_gpio)) {dev_err (imx335->dev,"failed to get reset gpio %ld" ,PTR_ERR (imx335->reset_gpio));
@@ -898,8 +898,7 @@ static int imx335_power_on(struct device *dev)usleep_range (500 ,550 );/* Tlow */ -/* Set XCLR */ -gpiod_set_value_cansleep (imx335->reset_gpio,1 ); +gpiod_set_value_cansleep (imx335->reset_gpio,0 ); ret =clk_prepare_enable (imx335->inclk);if (ret) {
@@ -912,7 +911,7 @@ static int imx335_power_on(struct device *dev)return 0 ; error_reset: -gpiod_set_value_cansleep (imx335->reset_gpio,0 ); +gpiod_set_value_cansleep (imx335->reset_gpio,1 );regulator_bulk_disable (ARRAY_SIZE (imx335_supply_name), imx335->supplies);return ret;
@@ -929,7 +928,7 @@ static int imx335_power_off(struct device *dev)struct v4l2_subdev *sd =dev_get_drvdata (dev);struct imx335 *imx335 =to_imx335 (sd); -gpiod_set_value_cansleep (imx335->reset_gpio,0 ); +gpiod_set_value_cansleep (imx335->reset_gpio,1 );clk_disable_unprepare (imx335->inclk);regulator_bulk_disable (ARRAY_SIZE (imx335_supply_name), imx335->supplies);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 642/798 remoteproc: k3-r5: Acquire mailbox handle during probe routine
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Beleswar Padhi <[email protected]>
[ Upstream commit f3f11cfe890733373ddbb1ce8991ccd4ee5e79e1 ]
Acquire the mailbox handle during device probe and do not release handle in stop/detach routine or error paths. This removes the redundant requests for mbox handle later during rproc start/attach. This also allows to defer remoteproc driver's probe if mailbox is not probed yet.
Stable-dep-of: 8fa052c29e50 ("remoteproc: k3-r5: Delay notification of wakeup event")
--- drivers/remoteproc/ti_k3_r5_remoteproc.c | 78 +++++++++--------------- 1 file changed, 30 insertions(+), 48 deletions(-)
drivers/remoteproc/ti_k3_r5_remoteproc.c +30 -48
@@ -189,6 +189,10 @@ static void k3_r5_rproc_mbox_callback(struct mbox_client *client, void *data)const char *name = kproc->rproc->name;u32 msg =omap_mbox_message (data); +/* Do not forward message from a detached core */ +if (kproc->rproc->state ==RPROC_DETACHED ) +return ; +dev_dbg (dev,"mbox msg: 0x%x\n" , msg);switch (msg) {
@@ -224,6 +228,10 @@ static void k3_r5_rproc_kick(struct rproc *rproc, int vqid)mbox_msg_t msg = (mbox_msg_t )vqid;int ret; +/* Do not forward message to a detached core */ +if (kproc->rproc->state ==RPROC_DETACHED ) +return ; +/* send the index of the triggered virtqueue in the mailbox payload */ ret =mbox_send_message (kproc->mbox, (void *)msg);if (ret <0 )
@@ -394,12 +402,9 @@ static int k3_r5_rproc_request_mbox(struct rproc *rproc) client->knows_txdone = false; kproc->mbox =mbox_request_channel (client,0 ); -if (IS_ERR (kproc->mbox)) { - ret = -EBUSY ; -dev_err (dev,"mbox_request_channel failed: %ld\n" , -PTR_ERR (kproc->mbox)); -return ret; - } +if (IS_ERR (kproc->mbox)) +return dev_err_probe (dev,PTR_ERR (kproc->mbox), +"mbox_request_channel failed\n" );/* * Ping the remote processor, this is only for sanity-sake for now;
@@ -547,10 +552,6 @@ static int k3_r5_rproc_start(struct rproc *rproc)u32 boot_addr;int ret; - ret =k3_r5_rproc_request_mbox (rproc); -if (ret) -return ret; - boot_addr = rproc->bootaddr;/* TODO: add boot_addr sanity checking */ dev_dbg (dev,"booting R5F core using boot addr = 0x%x\n" , boot_addr);
@@ -559,7 +560,7 @@ static int k3_r5_rproc_start(struct rproc *rproc) core = kproc->core; ret =ti_sci_proc_set_config (core->tsp, boot_addr,0 ,0 );if (ret) - goto put_mbox; +return ret;/* unhalt/run all applicable cores */ if (cluster->mode ==CLUSTER_MODE_LOCKSTEP ) {
@@ -575,13 +576,12 @@ static int k3_r5_rproc_start(struct rproc *rproc)if (core != core0 && core0->rproc->state ==RPROC_OFFLINE ) {dev_err (dev,"%s: can not start core 1 before core 0\n" , __func__); - ret = -EPERM ; - goto put_mbox; +return -EPERM ; } ret =k3_r5_core_run (core);if (ret) - goto put_mbox; +return ret; }return 0 ;
@@ -591,8 +591,6 @@ static int k3_r5_rproc_start(struct rproc *rproc)if (k3_r5_core_halt (core))dev_warn (core->dev,"core halt back failed\n" ); } -put_mbox: -mbox_free_channel (kproc->mbox);return ret; }
@@ -653,8 +651,6 @@ static int k3_r5_rproc_stop(struct rproc *rproc) goto out; } -mbox_free_channel (kproc->mbox); -return 0 ; unroll_core_halt:
@@ -669,42 +665,22 @@ static int k3_r5_rproc_stop(struct rproc *rproc)/* * Attach to a running R5F remote processor (IPC-only mode) * -* The R5F attach callback only needs to request the mailbox, the remote -* processor is already booted, so there is no need to issue any TI-SCI -* commands to boot the R5F cores in IPC-only mode. This callback is invoked -* only in IPC-only mode. +* The R5F attach callback is a NOP. The remote processor is already booted, and +* all required resources have been acquired during probe routine, so there is +* no need to issue any TI-SCI commands to boot the R5F cores in IPC-only mode. +* This callback is invoked only in IPC-only mode and exists because +* rproc_validate() checks for its existence. */ -static int k3_r5_rproc_attach (struct rproc *rproc) -{ -struct k3_r5_rproc *kproc = rproc->priv; -struct device *dev = kproc->dev; -int ret; - - ret =k3_r5_rproc_request_mbox (rproc); -if (ret) -return ret; - -dev_info (dev,"R5F core initialized in IPC-only mode\n" ); -return 0 ; -} +static int k3_r5_rproc_attach (struct rproc *rproc) {return 0 ; }/* * Detach from a running R5F remote processor (IPC-only mode) * -* The R5F detach callback performs the opposite operation to attach callback -* and only needs to release the mailbox, the R5F cores are not stopped and -* will be left in booted state in IPC-only mode. This callback is invoked -* only in IPC-only mode. +* The R5F detach callback is a NOP. The R5F cores are not stopped and will be +* left in booted state in IPC-only mode. This callback is invoked only in +* IPC-only mode and exists for sanity sake. */ -static int k3_r5_rproc_detach (struct rproc *rproc) -{ -struct k3_r5_rproc *kproc = rproc->priv; -struct device *dev = kproc->dev; - -mbox_free_channel (kproc->mbox); -dev_info (dev,"R5F core deinitialized in IPC-only mode\n" ); -return 0 ; -} +static int k3_r5_rproc_detach (struct rproc *rproc) {return 0 ; }/* * This function implements the .get_loaded_rsc_table() callback and is used
@@ -1273,6 +1249,10 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev) kproc->rproc = rproc; core->rproc = rproc; + ret =k3_r5_rproc_request_mbox (rproc); +if (ret) +return ret; + ret =k3_r5_rproc_configure_mode (kproc);if (ret <0 ) goto err_config;
@@ -1388,6 +1368,8 @@ static void k3_r5_cluster_rproc_exit(void *data) } } +mbox_free_channel (kproc->mbox); +rproc_del (rproc);k3_r5_reserved_mem_exit (kproc);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 643/798 remoteproc: k3-r5: Delay notification of wakeup event
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Udit Kumar <[email protected]>
[ Upstream commit 8fa052c29e509f3e47d56d7fc2ca28094d78c60a ]
Few times, core1 was scheduled to boot first before core0, which leads to error:
'k3_r5_rproc_start: can not start core 1 before core 0'.
This was happening due to some scheduling between prepare and start callback. The probe function waits for event, which is getting triggered by prepare callback. To avoid above condition move event trigger to start instead of prepare callback.
--- drivers/remoteproc/ti_k3_r5_remoteproc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/remoteproc/ti_k3_r5_remoteproc.c +3 -2
@@ -464,8 +464,6 @@ static int k3_r5_rproc_prepare(struct rproc *rproc) ret);return ret; } - core->released_from_reset = true; -wake_up_interruptible (&cluster->core_transition);/* * Newer IP revisions like on J7200 SoCs support h/w auto-initialization
@@ -582,6 +580,9 @@ static int k3_r5_rproc_start(struct rproc *rproc) ret =k3_r5_core_run (core);if (ret)return ret; + + core->released_from_reset = true; +wake_up_interruptible (&cluster->core_transition); }return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 644/798 dt-bindings: clock: qcom: Add missing UFS QREF clocks
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manivannan Sadhasivam <[email protected]>
[ Upstream commit 26447dad8119fd084d7c6f167c3026700b701666 ]
Add missing QREF clocks for UFS MEM and UFS CARD controllers.
Stable-dep-of: 648b4bde0aca ("dt-bindings: clock: qcom: Add GPLL9 support on gcc-sc8180x")
--- include/dt-bindings/clock/qcom,gcc-sc8180x.h | 2 ++ 1 file changed, 2 insertions(+)
include/dt-bindings/clock/qcom,gcc-sc8180x.h +2 -0
@@ -246,6 +246,8 @@#define GCC_PCIE_3_CLKREF_CLK 236#define GCC_USB3_PRIM_CLKREF_CLK 237#define GCC_USB3_SEC_CLKREF_CLK 238 +#define GCC_UFS_MEM_CLKREF_EN 239 +#define GCC_UFS_CARD_CLKREF_EN 240#define GCC_EMAC_BCR 0#define GCC_GPU_BCR 1
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 645/798 dt-bindings: clock: qcom: Add GPLL9 support on gcc-sc8180x
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satya Priya Kakitapalli <[email protected]>
[ Upstream commit 648b4bde0aca2980ebc0b90cdfbb80d222370c3d ]
Add the missing GPLL9 which is required for the gcc sdcc2 clock.
--- include/dt-bindings/clock/qcom,gcc-sc8180x.h | 1 + 1 file changed, 1 insertion(+)
include/dt-bindings/clock/qcom,gcc-sc8180x.h +1 -0
@@ -248,6 +248,7 @@#define GCC_USB3_SEC_CLKREF_CLK 238#define GCC_UFS_MEM_CLKREF_EN 239#define GCC_UFS_CARD_CLKREF_EN 240 +#define GPLL9 241#define GCC_EMAC_BCR 0#define GCC_GPU_BCR 1
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 646/798 clk: samsung: exynos7885: do not define number of clocks in bindings
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit ef4923c8e0523d83b7cd4918760e03b03b2b08ad ]
Number of clocks supported by Linux drivers might vary - sometimes we add new clocks, not exposed previously. Therefore these numbers of clocks should not be in the bindings, as that prevents changing them.
Define number of clocks per each clock controller inside the driver directly.
Stable-dep-of: 217a5f23c290 ("clk: samsung: exynos7885: Update CLKS_NR_FSYS after bindings fix")
--- drivers/clk/samsung/clk-exynos7885.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/clk/samsung/clk-exynos7885.c +10 -4
@@ -17,6 +17,12 @@#include "clk.h" #include "clk-exynos-arm64.h" +/* NOTE: Must be equal to the last clock ID increased by one */ +#define CLKS_NR_TOP (CLK_GOUT_FSYS_USB30DRD + 1) +#define CLKS_NR_CORE (CLK_GOUT_TREX_P_CORE_PCLK_P_CORE + 1) +#define CLKS_NR_PERI (CLK_GOUT_WDT1_PCLK + 1) +#define CLKS_NR_FSYS (CLK_GOUT_MMC_SDIO_SDCLKIN + 1) +/* ---- CMU_TOP ------------------------------------------------------------- */ /* Register Offset definitions for CMU_TOP (0x12060000) */
@@ -334,7 +340,7 @@ static const struct samsung_cmu_info top_cmu_info __initconst = { .nr_div_clks = ARRAY_SIZE(top_div_clks), .gate_clks = top_gate_clks, .nr_gate_clks = ARRAY_SIZE(top_gate_clks), - .nr_clk_ids = TOP_NR_CLK, + .nr_clk_ids = CLKS_NR_TOP, .clk_regs = top_clk_regs, .nr_clk_regs = ARRAY_SIZE(top_clk_regs), };
@@ -553,7 +559,7 @@ static const struct samsung_cmu_info peri_cmu_info __initconst = { .nr_mux_clks = ARRAY_SIZE(peri_mux_clks), .gate_clks = peri_gate_clks, .nr_gate_clks = ARRAY_SIZE(peri_gate_clks), - .nr_clk_ids = PERI_NR_CLK, + .nr_clk_ids = CLKS_NR_PERI, .clk_regs = peri_clk_regs, .nr_clk_regs = ARRAY_SIZE(peri_clk_regs), .clk_name = "dout_peri_bus",
@@ -662,7 +668,7 @@ static const struct samsung_cmu_info core_cmu_info __initconst = { .nr_div_clks = ARRAY_SIZE(core_div_clks), .gate_clks = core_gate_clks, .nr_gate_clks = ARRAY_SIZE(core_gate_clks), - .nr_clk_ids = CORE_NR_CLK, + .nr_clk_ids = CLKS_NR_CORE, .clk_regs = core_clk_regs, .nr_clk_regs = ARRAY_SIZE(core_clk_regs), .clk_name = "dout_core_bus",
@@ -744,7 +750,7 @@ static const struct samsung_cmu_info fsys_cmu_info __initconst = { .nr_mux_clks = ARRAY_SIZE(fsys_mux_clks), .gate_clks = fsys_gate_clks, .nr_gate_clks = ARRAY_SIZE(fsys_gate_clks), - .nr_clk_ids = FSYS_NR_CLK, + .nr_clk_ids = CLKS_NR_FSYS, .clk_regs = fsys_clk_regs, .nr_clk_regs = ARRAY_SIZE(fsys_clk_regs), .clk_name = "dout_fsys_bus",
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 647/798 clk: samsung: exynos7885: Update CLKS_NR_FSYS after bindings fix
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Virag <[email protected]>
[ Upstream commit 217a5f23c290c349ceaa37a6f2c014ad4c2d5759 ]
Update CLKS_NR_FSYS to the proper value after a fix in DT bindings. This should always be the last clock in a CMU + 1.
--- drivers/clk/samsung/clk-exynos7885.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/samsung/clk-exynos7885.c +1 -1
@@ -21,7 +21,7 @@#define CLKS_NR_TOP (CLK_GOUT_FSYS_USB30DRD + 1)#define CLKS_NR_CORE (CLK_GOUT_TREX_P_CORE_PCLK_P_CORE + 1)#define CLKS_NR_PERI (CLK_GOUT_WDT1_PCLK + 1) -#define CLKS_NR_FSYS (CLK_GOUT_MMC_SDIO_SDCLKIN + 1) +#define CLKS_NR_FSYS (CLK_MOUT_FSYS_USB30DRD_USER + 1)/* ---- CMU_TOP ------------------------------------------------------------- */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 648/798 r8169: Fix spelling mistake: "tx_underun" -> "tx_underrun"
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Colin Ian King <[email protected]>
[ Upstream commit 8df9439389a44fb2cc4ef695e08d6a8870b1616c ]
There is a spelling mistake in the struct field tx_underun, rename it to tx_underrun.
Stable-dep-of: ced8e8b8f40a ("r8169: add tally counter fields added with RTL8125")
--- drivers/net/ethernet/realtek/r8169_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/realtek/r8169_main.c +2 -2
@@ -563,7 +563,7 @@ struct rtl8169_counters {__le64 rx_broadcast;__le32 rx_multicast;__le16 tx_aborted; -__le16 tx_underun; +__le16 tx_underrun; };struct rtl8169_tc_offsets {
@@ -1710,7 +1710,7 @@ static void rtl8169_get_ethtool_stats(struct net_device *dev, data[9 ] =le64_to_cpu (counters->rx_broadcast); data[10 ] =le32_to_cpu (counters->rx_multicast); data[11 ] =le16_to_cpu (counters->tx_aborted); - data[12 ] =le16_to_cpu (counters->tx_underun); + data[12 ] =le16_to_cpu (counters->tx_underrun); }static void rtl8169_get_strings (struct net_device *dev,u32 stringset,u8 *data)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 649/798 r8169: add tally counter fields added with RTL8125
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiner Kallweit <[email protected]>
[ Upstream commit ced8e8b8f40accfcce4a2bbd8b150aa76d5eff9a ]
RTL8125 added fields to the tally counter, what may result in the chip dma'ing these new fields to unallocated memory. Therefore make sure that the allocated memory area is big enough to hold all of the tally counter values, even if we use only parts of it.
--- drivers/net/ethernet/realtek/r8169_main.c | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+)
drivers/net/ethernet/realtek/r8169_main.c +27 -0
@@ -564,6 +564,33 @@ struct rtl8169_counters {__le32 rx_multicast;__le16 tx_aborted;__le16 tx_underrun; +/* new since RTL8125 */ +__le64 tx_octets; +__le64 rx_octets; +__le64 rx_multicast64; +__le64 tx_unicast64; +__le64 tx_broadcast64; +__le64 tx_multicast64; +__le32 tx_pause_on; +__le32 tx_pause_off; +__le32 tx_pause_all; +__le32 tx_deferred; +__le32 tx_late_collision; +__le32 tx_all_collision; +__le32 tx_aborted32; +__le32 align_errors32; +__le32 rx_frame_too_long; +__le32 rx_runt; +__le32 rx_pause_on; +__le32 rx_pause_off; +__le32 rx_pause_all; +__le32 rx_unknown_opcode; +__le32 rx_mac_error; +__le32 tx_underrun32; +__le32 rx_mac_missed; +__le32 rx_tcam_dropped; +__le32 tdu; +__le32 rdu; };struct rtl8169_tc_offsets {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 650/798 clk: qcom: gcc-sc8180x: Add GPLL9 support
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satya Priya Kakitapalli <[email protected]>
[ Upstream commit 818a2f8d5e4ad2c1e39a4290158fe8e39a744c70 ]
Add the missing GPLL9 pll and fix the gcc_parents_7 data to use the correct pll hw.
--- drivers/clk/qcom/gcc-sc8180x.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
drivers/clk/qcom/gcc-sc8180x.c +19 -1
@@ -143,6 +143,23 @@ static struct clk_alpha_pll gpll7 = { }, }; +static struct clk_alpha_pll gpll9 = { + .offset =0x1c000 , + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION ], + .clkr = { + .enable_reg =0x52000 , + .enable_mask =BIT (9 ), + .hw.init = &(const struct clk_init_data ) { + .name ="gpll9" , + .parent_data = &(const struct clk_parent_data ) { + .fw_name ="bi_tcxo" , + }, + .num_parents =1 , + .ops = &clk_alpha_pll_fixed_trion_ops, + }, + }, +}; +static const struct parent_map gcc_parent_map_0[] = { {P_BI_TCXO ,0 }, {P_GPLL0_OUT_MAIN ,1 },
@@ -242,7 +259,7 @@ static const struct parent_map gcc_parent_map_7[] = {static const struct clk_parent_data gcc_parents_7[] = { { .fw_name ="bi_tcxo" , }, { .hw = &gpll0.clkr.hw }, - { .name ="gppl9" }, + { .hw = &gpll9.clkr.hw }, { .hw = &gpll4.clkr.hw }, { .hw = &gpll0_out_even.clkr.hw }, };
@@ -4420,6 +4437,7 @@ static struct clk_regmap *gcc_sc8180x_clocks[] = { [GPLL1] = &gpll1.clkr, [GPLL4] = &gpll4.clkr, [GPLL7] = &gpll7.clkr, + [GPLL9] = &gpll9.clkr, };static const struct qcom_reset_map gcc_sc8180x_resets[] = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 651/798 ACPI: battery: Simplify battery hook locking
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit 86309cbed26139e1caae7629dcca1027d9a28e75 ]
Move the conditional locking from __battery_hook_unregister() into battery_hook_unregister() and rename the low-level function to simplify the locking during battery hook removal.
Stable-dep-of: 76959aff14a0 ("ACPI: battery: Fix possible crash when unregistering a battery hook")
--- drivers/acpi/battery.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/acpi/battery.c +9 -9
@@ -692,27 +692,27 @@ static LIST_HEAD(acpi_battery_list);static LIST_HEAD (battery_hook_list);static DEFINE_MUTEX (hook_mutex); -static void __battery_hook_unregister (struct acpi_battery_hook *hook,int lock) +static void battery_hook_unregister_unlocked (struct acpi_battery_hook *hook) {struct acpi_battery *battery; +/* * In order to remove a hook, we first need to * de-register all the batteries that are registered. */ -if (lock) -mutex_lock (&hook_mutex);list_for_each_entry (battery, &acpi_battery_list, list) { hook->remove_battery (battery->bat); }list_del (&hook->list); -if (lock) -mutex_unlock (&hook_mutex); +pr_info ("extension unregistered: %s\n" , hook->name); }void battery_hook_unregister (struct acpi_battery_hook *hook) { -__battery_hook_unregister (hook,1 ); +mutex_lock (&hook_mutex); +battery_hook_unregister_unlocked (hook); +mutex_unlock (&hook_mutex); }EXPORT_SYMBOL_GPL (battery_hook_unregister);
@@ -738,7 +738,7 @@ void battery_hook_register(struct acpi_battery_hook *hook)* hooks. */ pr_err ("extension failed to load: %s" , hook->name); -__battery_hook_unregister (hook,0 ); +battery_hook_unregister_unlocked (hook); goto end; } }
@@ -775,7 +775,7 @@ static void battery_hook_add_battery(struct acpi_battery *battery)*/ pr_err ("error in extension, unloading: %s" , hook_node->name); -__battery_hook_unregister (hook_node,0 ); +battery_hook_unregister_unlocked (hook_node); } }mutex_unlock (&hook_mutex);
@@ -808,7 +808,7 @@ static void __exit battery_hook_exit(void)* need to remove the hooks. */ list_for_each_entry_safe (hook, ptr, &battery_hook_list, list) { -__battery_hook_unregister (hook,1 ); +battery_hook_unregister (hook); }mutex_destroy (&hook_mutex); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 652/798 ACPI: battery: Fix possible crash when unregistering a battery hook
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit 76959aff14a0012ad6b984ec7686d163deccdc16 ]
When a battery hook returns an error when adding a new battery, then the battery hook is automatically unregistered.
However the battery hook provider cannot know that, so it will later call battery_hook_unregister() on the already unregistered battery hook, resulting in a crash.
Fix this by using the list head to mark already unregistered battery hooks as already being unregistered so that they can be ignored by battery_hook_unregister().
--- drivers/acpi/battery.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/acpi/battery.c +9 -3
@@ -703,7 +703,7 @@ static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook)list_for_each_entry (battery, &acpi_battery_list, list) { hook->remove_battery (battery->bat); } -list_del (&hook->list); +list_del_init (&hook->list);pr_info ("extension unregistered: %s\n" , hook->name); }
@@ -711,7 +711,14 @@ static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook)void battery_hook_unregister (struct acpi_battery_hook *hook) {mutex_lock (&hook_mutex); -battery_hook_unregister_unlocked (hook); +/* +* Ignore already unregistered battery hooks. This might happen +* if a battery hook was previously unloaded due to an error when +* adding a new battery. +*/ +if (!list_empty (&hook->list)) +battery_hook_unregister_unlocked (hook); +mutex_unlock (&hook_mutex); }EXPORT_SYMBOL_GPL (battery_hook_unregister);
@@ -721,7 +728,6 @@ void battery_hook_register(struct acpi_battery_hook *hook)struct acpi_battery *battery;mutex_lock (&hook_mutex); -INIT_LIST_HEAD (&hook->list);list_add (&hook->list, &battery_hook_list);/* * Now that the driver is registered, we need
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 653/798 Revert "arm64: dts: qcom: sm8250: switch UFS QMP PHY to new style of bindings"
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sumit Semwal <[email protected]>
This reverts commit cf9c7b34b90b622254b236a9a43737b6059a1c14.
This commit breaks UFS on RB5 in the 6.1 LTS kernels. The original patch author suggests that this is not a stable kernel patch, hence reverting it.
This was reported during testing with 6.1.103 / 5.15.165 LTS kernels merged in the respective Android Common Kernel branches.
--- arch/arm64/boot/dts/qcom/sm8250.dtsi | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
arch/arm64/boot/dts/qcom/sm8250.dtsi +14 -6
@@ -2125,7 +2125,7 @@ "jedec,ufs-2.0"; reg = <0 0x01d84000 0 0x3000>; interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>; - phys = <&ufs_mem_phy>; + phys = <&ufs_mem_phy_lanes>; phy-names = "ufsphy"; lanes-per-direction = <2>; #reset-cells = <1>;
@@ -2169,8 +2169,10 @@ ufs_mem_phy: phy@1d87000 { compatible = "qcom,sm8250-qmp-ufs-phy"; - reg = <0 0x01d87000 0 0x1000>; - + reg = <0 0x01d87000 0 0x1c0>; + #address-cells = <2>; + #size-cells = <2>; + ranges; clock-names = "ref", "ref_aux"; clocks = <&rpmhcc RPMH_CXO_CLK>,
@@ -2178,12 +2180,18 @@ resets = <&ufs_mem_hc 0>; reset-names = "ufsphy"; + status = "disabled"; power-domains = <&gcc UFS_PHY_GDSC>; - #phy-cells = <0>; - - status = "disabled"; + ufs_mem_phy_lanes: phy@1d87400 { + reg = <0 0x01d87400 0 0x16c>, + <0 0x01d87600 0 0x200>, + <0 0x01d87c00 0 0x200>, + <0 0x01d87800 0 0x16c>, + <0 0x01d87a00 0 0x200>; + #phy-cells = <0>; + }; }; ipa_virt: interconnect@1e00000 {
Greg Kroah-Hartman
maintainerPATCH 654/798 erofs: get rid of erofs_inode_datablocks()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
commit 4efdec36dc9907628e590a68193d6d8e5e74d032 upstream.
erofs_inode_datablocks() has the only one caller, let's just get rid of it entirely. No logic changes.
Stable-dep-of: 9ed50b8231e3 ("erofs: fix incorrect symlink detection in fast symlink")
[ Gao Xiang: apply this to 6.6.y to avoid further backport twists
due to obsoleted EROFS_BLKSIZ. ]
---
Obsoleted EROFS_BLKSIZ impedes efforts to backport
9ed50b8231e3 ("erofs: fix incorrect symlink detection in fast symlink") 9e2f9d34dd12 ("erofs: handle overlapped pclusters out of crafted images properly")
To avoid further bugfix conflicts due to random EROFS_BLKSIZs around the whole codebase, just backport the dependencies for 6.1.y.
fs/erofs/internal.h | 6 ------ fs/erofs/namei.c | 18 +++++------------- 2 files changed, 5 insertions(+), 19 deletions(-)
fs/erofs/internal.h +0 -6
@@ -347,12 +347,6 @@ static inline erofs_off_t erofs_iloc(str (EROFS_I (inode)->nid << sbi->islotbits); } -static inline unsigned long erofs_inode_datablocks (struct inode *inode) -{ -/* since i_size cannot be changed */ -return DIV_ROUND_UP (inode->i_size,EROFS_BLKSIZ ); -} -static inline unsigned int erofs_bitrange (unsigned int value,unsigned int bit,unsigned int bits) {
fs/erofs/namei.c +5 -13
@@ -5,7 +5,6 @@* Copyright (C) 2022, Alibaba Cloud */ #include "xattr.h" -#include <trace/events/erofs.h> struct erofs_qstr {
@@ -87,19 +86,13 @@ static struct erofs_dirent *find_target_return ERR_PTR (-ENOENT ); } -static void *find_target_block_classic (struct erofs_buf *target, -struct inode *dir, -struct erofs_qstr *name, -int *_ndirents) +static void *erofs_find_target_block (struct erofs_buf *target, +struct inode *dir,struct erofs_qstr *name,int *_ndirents) { -unsigned int startprfx, endprfx; -int head, back; +int head =0 , back =DIV_ROUND_UP (dir->i_size,EROFS_BLKSIZ ) -1 ; +unsigned int startprfx =0 , endprfx =0 ;void *candidate =ERR_PTR (-ENOENT ); - startprfx = endprfx =0 ; - head =0 ; - back =erofs_inode_datablocks (dir) -1 ; -while (head <= back) {const int mid = head + (back - head) /2 ;struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
@@ -180,8 +173,7 @@ int erofs_namei(struct inode *dir, const qn.end = name->name + name->len; ndirents =0 ; - - de =find_target_block_classic (&buf, dir, &qn, &ndirents); + de =erofs_find_target_block (&buf, dir, &qn, &ndirents);if (IS_ERR (de))return PTR_ERR (de);
Greg Kroah-Hartman
maintainerPATCH 655/798 erofs: get rid of z_erofs_do_map_blocks() forward declaration
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
commit 999f2f9a63f475192d837a2b8595eb0962984d21 upstream.
The code can be neater without forward declarations. Let's get rid of z_erofs_do_map_blocks() forward declaration.
Stable-dep-of: 9ed50b8231e3 ("erofs: fix incorrect symlink detection in fast symlink")
[ Gao Xiang: apply this to 6.6.y to avoid further backport twists
due to obsoleted EROFS_BLKSIZ. ]
--- fs/erofs/zmap.c | 242 +++++++++++++++++++++++++++----------------------------- 1 file changed, 119 insertions(+), 123 deletions(-)
fs/erofs/zmap.c +119 -123
@@ -7,10 +7,6 @@#include <asm/unaligned.h> #include <trace/events/erofs.h> -static int z_erofs_do_map_blocks (struct inode *inode, -struct erofs_map_blocks *map, -int flags); -int z_erofs_fill_inode (struct inode *inode) {struct erofs_inode *const vi =EROFS_I (inode);
@@ -29,125 +25,6 @@ int z_erofs_fill_inode(struct inode *inoreturn 0 ; } -static int z_erofs_fill_inode_lazy (struct inode *inode) -{ -struct erofs_inode *const vi =EROFS_I (inode); -struct super_block *const sb = inode->i_sb; -int err, headnr; -erofs_off_t pos; -struct erofs_buf buf = __EROFS_BUF_INITIALIZER; -void *kaddr; -struct z_erofs_map_header *h; - -if (test_bit (EROFS_I_Z_INITED_BIT , &vi->flags)) { -/* -* paired with smp_mb() at the end of the function to ensure -* fields will only be observed after the bit is set. -*/ -smp_mb (); -return 0 ; - } - -if (wait_on_bit_lock (&vi->flags,EROFS_I_BL_Z_BIT ,TASK_KILLABLE )) -return -ERESTARTSYS ; - - err =0 ; -if (test_bit (EROFS_I_Z_INITED_BIT , &vi->flags)) - goto out_unlock; - - pos =ALIGN (erofs_iloc (inode) + vi->inode_isize + vi->xattr_isize,8 ); - kaddr =erofs_read_metabuf (&buf, sb,erofs_blknr (pos),EROFS_KMAP ); -if (IS_ERR (kaddr)) { - err =PTR_ERR (kaddr); - goto out_unlock; - } - - h = kaddr +erofs_blkoff (pos); -/* -* if the highest bit of the 8-byte map header is set, the whole file -* is stored in the packed inode. The rest bits keeps z_fragmentoff. -*/ -if (h->h_clusterbits >>Z_EROFS_FRAGMENT_INODE_BIT ) { - vi->z_advise =Z_EROFS_ADVISE_FRAGMENT_PCLUSTER ; - vi->z_fragmentoff =le64_to_cpu (*(__le64 *)h) ^ (1ULL <<63 ); - vi->z_tailextent_headlcn =0 ; - goto done; - } - vi->z_advise =le16_to_cpu (h->h_advise); - vi->z_algorithmtype[0 ] = h->h_algorithmtype &15 ; - vi->z_algorithmtype[1 ] = h->h_algorithmtype >>4 ; - - headnr =0 ; -if (vi->z_algorithmtype[0 ] >=Z_EROFS_COMPRESSION_MAX || - vi->z_algorithmtype[++headnr] >=Z_EROFS_COMPRESSION_MAX ) { -erofs_err (sb,"unknown HEAD%u format %u for nid %llu, please upgrade kernel" , - headnr +1 , vi->z_algorithmtype[headnr], vi->nid); - err = -EOPNOTSUPP ; - goto out_put_metabuf; - } - - vi->z_logical_clusterbits =LOG_BLOCK_SIZE + (h->h_clusterbits &7 ); -if (!erofs_sb_has_big_pcluster (EROFS_SB (sb)) && - vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 | -Z_EROFS_ADVISE_BIG_PCLUSTER_2 )) { -erofs_err (sb,"per-inode big pcluster without sb feature for nid %llu" , - vi->nid); - err = -EFSCORRUPTED ; - goto out_put_metabuf; - } -if (vi->datalayout ==EROFS_INODE_FLAT_COMPRESSION && - !(vi->z_advise &Z_EROFS_ADVISE_BIG_PCLUSTER_1 ) ^ - !(vi->z_advise &Z_EROFS_ADVISE_BIG_PCLUSTER_2 )) { -erofs_err (sb,"big pcluster head1/2 of compact indexes should be consistent for nid %llu" , - vi->nid); - err = -EFSCORRUPTED ; - goto out_put_metabuf; - } - -if (vi->z_advise &Z_EROFS_ADVISE_INLINE_PCLUSTER ) { -struct erofs_map_blocks map = { - .buf = __EROFS_BUF_INITIALIZER - }; - - vi->z_idata_size =le16_to_cpu (h->h_idata_size); - err =z_erofs_do_map_blocks (inode, &map, -EROFS_GET_BLOCKS_FINDTAIL ); -erofs_put_metabuf (&map.buf); - -if (!map.m_plen || -erofs_blkoff (map.m_pa) + map.m_plen >EROFS_BLKSIZ ) { -erofs_err (sb,"invalid tail-packing pclustersize %llu" , - map.m_plen); - err = -EFSCORRUPTED ; - } -if (err <0 ) - goto out_put_metabuf; - } - -if (vi->z_advise &Z_EROFS_ADVISE_FRAGMENT_PCLUSTER && - !(h->h_clusterbits >>Z_EROFS_FRAGMENT_INODE_BIT )) { -struct erofs_map_blocks map = { - .buf = __EROFS_BUF_INITIALIZER - }; - - vi->z_fragmentoff =le32_to_cpu (h->h_fragmentoff); - err =z_erofs_do_map_blocks (inode, &map, -EROFS_GET_BLOCKS_FINDTAIL ); -erofs_put_metabuf (&map.buf); -if (err <0 ) - goto out_put_metabuf; - } -done: -/* paired with smp_mb() at the beginning of the function */ -smp_mb (); -set_bit (EROFS_I_Z_INITED_BIT , &vi->flags); -out_put_metabuf: -erofs_put_metabuf (&buf); -out_unlock: -clear_and_wake_up_bit (EROFS_I_BL_Z_BIT , &vi->flags); -return err; -} -struct z_erofs_maprecorder {struct inode *inode;struct erofs_map_blocks *map;
@@ -732,6 +609,125 @@ unmap_out:return err; } +static int z_erofs_fill_inode_lazy (struct inode *inode) +{ +struct erofs_inode *const vi =EROFS_I (inode); +struct super_block *const sb = inode->i_sb; +int err, headnr; +erofs_off_t pos; +struct erofs_buf buf = __EROFS_BUF_INITIALIZER; +void *kaddr; +struct z_erofs_map_header *h; + +if (test_bit (EROFS_I_Z_INITED_BIT , &vi->flags)) { +/* +* paired with smp_mb() at the end of the function to ensure +* fields will only be observed after the bit is set. +*/ +smp_mb (); +return 0 ; + } + +if (wait_on_bit_lock (&vi->flags,EROFS_I_BL_Z_BIT ,TASK_KILLABLE )) +return -ERESTARTSYS ; + + err =0 ; +if (test_bit (EROFS_I_Z_INITED_BIT , &vi->flags)) + goto out_unlock; + + pos =ALIGN (erofs_iloc (inode) + vi->inode_isize + vi->xattr_isize,8 ); + kaddr =erofs_read_metabuf (&buf, sb,erofs_blknr (pos),EROFS_KMAP ); +if (IS_ERR (kaddr)) { + err =PTR_ERR (kaddr); + goto out_unlock; + } + + h = kaddr +erofs_blkoff (pos); +/* +* if the highest bit of the 8-byte map header is set, the whole file +* is stored in the packed inode. The rest bits keeps z_fragmentoff. +*/ +if (h->h_clusterbits >>Z_EROFS_FRAGMENT_INODE_BIT ) { + vi->z_advise =Z_EROFS_ADVISE_FRAGMENT_PCLUSTER ; + vi->z_fragmentoff =le64_to_cpu (*(__le64 *)h) ^ (1ULL <<63 ); + vi->z_tailextent_headlcn =0 ; + goto done; + } + vi->z_advise =le16_to_cpu (h->h_advise); + vi->z_algorithmtype[0 ] = h->h_algorithmtype &15 ; + vi->z_algorithmtype[1 ] = h->h_algorithmtype >>4 ; + + headnr =0 ; +if (vi->z_algorithmtype[0 ] >=Z_EROFS_COMPRESSION_MAX || + vi->z_algorithmtype[++headnr] >=Z_EROFS_COMPRESSION_MAX ) { +erofs_err (sb,"unknown HEAD%u format %u for nid %llu, please upgrade kernel" , + headnr +1 , vi->z_algorithmtype[headnr], vi->nid); + err = -EOPNOTSUPP ; + goto out_put_metabuf; + } + + vi->z_logical_clusterbits =LOG_BLOCK_SIZE + (h->h_clusterbits &7 ); +if (!erofs_sb_has_big_pcluster (EROFS_SB (sb)) && + vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 | +Z_EROFS_ADVISE_BIG_PCLUSTER_2 )) { +erofs_err (sb,"per-inode big pcluster without sb feature for nid %llu" , + vi->nid); + err = -EFSCORRUPTED ; + goto out_put_metabuf; + } +if (vi->datalayout ==EROFS_INODE_FLAT_COMPRESSION && + !(vi->z_advise &Z_EROFS_ADVISE_BIG_PCLUSTER_1 ) ^ + !(vi->z_advise &Z_EROFS_ADVISE_BIG_PCLUSTER_2 )) { +erofs_err (sb,"big pcluster head1/2 of compact indexes should be consistent for nid %llu" , + vi->nid); + err = -EFSCORRUPTED ; + goto out_put_metabuf; + } + +if (vi->z_advise &Z_EROFS_ADVISE_INLINE_PCLUSTER ) { +struct erofs_map_blocks map = { + .buf = __EROFS_BUF_INITIALIZER + }; + + vi->z_idata_size =le16_to_cpu (h->h_idata_size); + err =z_erofs_do_map_blocks (inode, &map, +EROFS_GET_BLOCKS_FINDTAIL ); +erofs_put_metabuf (&map.buf); + +if (!map.m_plen || +erofs_blkoff (map.m_pa) + map.m_plen >EROFS_BLKSIZ ) { +erofs_err (sb,"invalid tail-packing pclustersize %llu" , + map.m_plen); + err = -EFSCORRUPTED ; + } +if (err <0 ) + goto out_put_metabuf; + } + +if (vi->z_advise &Z_EROFS_ADVISE_FRAGMENT_PCLUSTER && + !(h->h_clusterbits >>Z_EROFS_FRAGMENT_INODE_BIT )) { +struct erofs_map_blocks map = { + .buf = __EROFS_BUF_INITIALIZER + }; + + vi->z_fragmentoff =le32_to_cpu (h->h_fragmentoff); + err =z_erofs_do_map_blocks (inode, &map, +EROFS_GET_BLOCKS_FINDTAIL ); +erofs_put_metabuf (&map.buf); +if (err <0 ) + goto out_put_metabuf; + } +done: +/* paired with smp_mb() at the beginning of the function */ +smp_mb (); +set_bit (EROFS_I_Z_INITED_BIT , &vi->flags); +out_put_metabuf: +erofs_put_metabuf (&buf); +out_unlock: +clear_and_wake_up_bit (EROFS_I_BL_Z_BIT , &vi->flags); +return err; +} +int z_erofs_map_blocks_iter (struct inode *inode,struct erofs_map_blocks *map,int flags) {
Greg Kroah-Hartman
maintainerPATCH 656/798 erofs: avoid hardcoded blocksize for subpage block support
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jingbo Xu <[email protected]>
commit 3acea5fc335420ba7ef53947cf2d98d07fac39f7 upstream.
As the first step of converting hardcoded blocksize to that specified in on-disk superblock, convert all call sites of hardcoded blocksize to sb->s_blocksize except for:
1) use sbi->blkszbits instead of sb->s_blocksize in erofs_superblock_csum_verify() since sb->s_blocksize has not been updated with the on-disk blocksize yet when the function is called.
2) use inode->i_blkbits instead of sb->s_blocksize in erofs_bread(), since the inode operated on may be an anonymous inode in fscache mode. Currently the anonymous inode is allocated from an anonymous mount maintained in erofs, while in the near future we may allocate anonymous inodes from a generic API directly and thus have no access to the anonymous inode's i_sb. Thus we keep the block size in i_blkbits for anonymous inodes in fscache mode.
Be noted that this patch only gets rid of the hardcoded blocksize, in preparation for actually setting the on-disk block size in the following patch. The hard limit of constraining the block size to PAGE_SIZE still exists until the next patch.
Stable-dep-of: 9ed50b8231e3 ("erofs: fix incorrect symlink detection in fast symlink") [ Gao Xiang: apply this to 6.6.y to avoid further backport twists
due to obsoleted EROFS_BLKSIZ. ]
--- fs/erofs/data.c | 50 +++++++++++++++++++++++-------------------- fs/erofs/decompressor.c | 6 ++--- fs/erofs/decompressor_lzma.c | 4 +-- fs/erofs/dir.c | 22 ++++++++---------- fs/erofs/fscache.c | 7 +++--- fs/erofs/inode.c | 20 +++++++++-------- fs/erofs/internal.h | 20 ++++++----------- fs/erofs/namei.c | 14 ++++++------ fs/erofs/super.c | 27 +++++++++++++---------- fs/erofs/xattr.c | 40 ++++++++++++++++------------------ fs/erofs/xattr.h | 10 ++++---- fs/erofs/zdata.c | 16 +++++++------ fs/erofs/zmap.c | 29 ++++++++++++------------ include/trace/events/erofs.h | 4 +-- 14 files changed, 137 insertions(+), 132 deletions(-)
fs/erofs/data.c +27 -23
@@ -29,11 +29,15 @@ void erofs_put_metabuf(struct erofs_buf buf->page =NULL ; } +/* +* Derive the block size from inode->i_blkbits to make compatible with +* anonymous inode in fscache mode. +*/ void *erofs_bread (struct erofs_buf *buf,struct inode *inode,erofs_blk_t blkaddr,enum erofs_kmap_type type) { +erofs_off_t offset = (erofs_off_t )blkaddr << inode->i_blkbits;struct address_space *const mapping = inode->i_mapping; -erofs_off_t offset =blknr_to_addr (blkaddr);pgoff_t index = offset >>PAGE_SHIFT ;struct page *page = buf->page;struct folio *folio;
@@ -84,33 +88,32 @@ static int erofs_map_blocks_flatmode(strerofs_blk_t nblocks, lastblk;u64 offset = map->m_la;struct erofs_inode *vi =EROFS_I (inode); +struct super_block *sb = inode->i_sb;bool tailendpacking = (vi->datalayout ==EROFS_INODE_FLAT_INLINE ); - nblocks =DIV_ROUND_UP (inode->i_size,EROFS_BLKSIZ ); + nblocks =erofs_iblks (inode); lastblk = nblocks - tailendpacking;/* there is no hole in flatmode */ map->m_flags =EROFS_MAP_MAPPED ; -if (offset <blknr_to_addr (lastblk)) { - map->m_pa =blknr_to_addr (vi->raw_blkaddr) + map->m_la; - map->m_plen =blknr_to_addr (lastblk) - offset; +if (offset <erofs_pos (sb, lastblk)) { + map->m_pa =erofs_pos (sb, vi->raw_blkaddr) + map->m_la; + map->m_plen =erofs_pos (sb, lastblk) - offset; }else if (tailendpacking) { map->m_pa =erofs_iloc (inode) + vi->inode_isize + - vi->xattr_isize +erofs_blkoff (offset); + vi->xattr_isize +erofs_blkoff (sb, offset); map->m_plen = inode->i_size - offset;/* inline data should be located in the same meta block */ -if (erofs_blkoff (map->m_pa) + map->m_plen >EROFS_BLKSIZ ) { -erofs_err (inode->i_sb, -"inline data cross block boundary @ nid %llu" , +if (erofs_blkoff (sb, map->m_pa) + map->m_plen > sb->s_blocksize) { +erofs_err (sb,"inline data cross block boundary @ nid %llu" , vi->nid);DBG_BUGON (1 );return -EFSCORRUPTED ; } map->m_flags |=EROFS_MAP_META ; }else { -erofs_err (inode->i_sb, -"internal error @ nid: %llu (size %llu), m_la 0x%llx" , +erofs_err (sb,"internal error @ nid: %llu (size %llu), m_la 0x%llx" , vi->nid, inode->i_size, map->m_la);DBG_BUGON (1 );return -EIO ;
@@ -154,29 +157,29 @@ int erofs_map_blocks(struct inode *inode pos =ALIGN (erofs_iloc (inode) + vi->inode_isize + vi->xattr_isize, unit) + unit * chunknr; - kaddr =erofs_read_metabuf (&buf, sb,erofs_blknr (pos),EROFS_KMAP ); + kaddr =erofs_read_metabuf (&buf, sb,erofs_blknr (sb, pos),EROFS_KMAP );if (IS_ERR (kaddr)) { err =PTR_ERR (kaddr); goto out; } map->m_la = chunknr << vi->chunkbits; map->m_plen =min_t (erofs_off_t,1UL << vi->chunkbits, -roundup (inode->i_size - map->m_la,EROFS_BLKSIZ )); +round_up (inode->i_size - map->m_la, sb->s_blocksize));/* handle block map */ if (!(vi->chunkformat &EROFS_CHUNK_FORMAT_INDEXES )) { -__le32 *blkaddr = kaddr +erofs_blkoff (pos); +__le32 *blkaddr = kaddr +erofs_blkoff (sb, pos);if (le32_to_cpu (*blkaddr) ==EROFS_NULL_ADDR ) { map->m_flags =0 ; }else { - map->m_pa =blknr_to_addr (le32_to_cpu (*blkaddr)); + map->m_pa =erofs_pos (sb,le32_to_cpu (*blkaddr)); map->m_flags =EROFS_MAP_MAPPED ; } goto out_unlock; }/* parse chunk indexes */ - idx = kaddr +erofs_blkoff (pos); + idx = kaddr +erofs_blkoff (sb, pos);switch (le32_to_cpu (idx->blkaddr)) {case EROFS_NULL_ADDR : map->m_flags =0 ;
@@ -184,7 +187,7 @@ int erofs_map_blocks(struct inode *inodedefault : map->m_deviceid =le16_to_cpu (idx->device_id) &EROFS_SB (sb)->device_id_mask; - map->m_pa =blknr_to_addr (le32_to_cpu (idx->blkaddr)); + map->m_pa =erofs_pos (sb,le32_to_cpu (idx->blkaddr)); map->m_flags =EROFS_MAP_MAPPED ;break ; }
@@ -228,8 +231,8 @@ int erofs_map_dev(struct super_block *sbif (!dif->mapped_blkaddr)continue ; - startoff =blknr_to_addr (dif->mapped_blkaddr); - length =blknr_to_addr (dif->blocks); + startoff =erofs_pos (sb, dif->mapped_blkaddr); + length =erofs_pos (sb, dif->blocks);if (map->m_pa >= startoff && map->m_pa < startoff + length) {
@@ -250,6 +253,7 @@ static int erofs_iomap_begin(struct inod unsigned int flags, struct iomap *iomap, struct iomap *srcmap) { int ret; +struct super_block *sb = inode->i_sb;struct erofs_map_blocks map;struct erofs_map_dev mdev;
@@ -264,7 +268,7 @@ static int erofs_iomap_begin(struct inod .m_deviceid = map.m_deviceid, .m_pa = map.m_pa, }; - ret =erofs_map_dev (inode->i_sb, &mdev); + ret =erofs_map_dev (sb, &mdev);if (ret)return ret;
@@ -290,11 +294,11 @@ static int erofs_iomap_begin(struct inodstruct erofs_buf buf = __EROFS_BUF_INITIALIZER; iomap->type =IOMAP_INLINE ; - ptr =erofs_read_metabuf (&buf, inode->i_sb, -erofs_blknr (mdev.m_pa),EROFS_KMAP ); + ptr =erofs_read_metabuf (&buf, sb, +erofs_blknr (sb, mdev.m_pa),EROFS_KMAP );if (IS_ERR (ptr))return PTR_ERR (ptr); - iomap->inline_data = ptr +erofs_blkoff (mdev.m_pa); + iomap->inline_data = ptr +erofs_blkoff (sb, mdev.m_pa); iomap->private = buf.base; }else { iomap->type =IOMAP_MAPPED ;
fs/erofs/decompressor.c +3 -3
@@ -42,7 +42,7 @@ static int z_erofs_load_lz4_config(strucif (!sbi->lz4.max_pclusterblks) { sbi->lz4.max_pclusterblks =1 ;/* reserved case */ }else if (sbi->lz4.max_pclusterblks > -Z_EROFS_PCLUSTER_MAX_SIZE /EROFS_BLKSIZ ) { +erofs_blknr (sb,Z_EROFS_PCLUSTER_MAX_SIZE )) {erofs_err (sb,"too large lz4 pclusterblks %u" , sbi->lz4.max_pclusterblks);return -EINVAL ;
@@ -221,13 +221,13 @@ static int z_erofs_lz4_decompress_mem(st support_0padding = true; ret =z_erofs_fixup_insize (rq, headpage + rq->pageofs_in, min_t(unsigned int, rq->inputsize, -EROFS_BLKSIZ - rq->pageofs_in)); + rq->sb->s_blocksize - rq->pageofs_in));if (ret) {kunmap_local (headpage);return ret; } may_inplace = !((rq->pageofs_in + rq->inputsize) & - (EROFS_BLKSIZ -1 )); + (rq->sb->s_blocksize -1 )); } inputmargin = rq->pageofs_in;
fs/erofs/decompressor_lzma.c +2 -2
@@ -166,8 +166,8 @@ int z_erofs_lzma_decompress(struct z_ero/* 1. get the exact LZMA compressed size */ kin =kmap (*rq->in); err =z_erofs_fixup_insize (rq, kin + rq->pageofs_in, - min_t(unsigned int, rq->inputsize, -EROFS_BLKSIZ - rq->pageofs_in)); + min_t(unsigned int, rq->inputsize, + rq->sb->s_blocksize - rq->pageofs_in));if (err) {kunmap (*rq->in);return err;
fs/erofs/dir.c +10 -12
@@ -67,9 +67,11 @@ static int erofs_readdir(struct file *f, {struct inode *dir =file_inode (f);struct erofs_buf buf = __EROFS_BUF_INITIALIZER; +struct super_block *sb = dir->i_sb; +unsigned long bsz = sb->s_blocksize;const size_t dirsize =i_size_read (dir); -unsigned int i = ctx->pos /EROFS_BLKSIZ ; -unsigned int ofs = ctx->pos %EROFS_BLKSIZ ; +unsigned int i =erofs_blknr (sb, ctx->pos); +unsigned int ofs =erofs_blkoff (sb, ctx->pos);int err =0 ;bool initial = true;
@@ -79,32 +81,28 @@ static int erofs_readdir(struct file *f, de =erofs_bread (&buf, dir, i,EROFS_KMAP );if (IS_ERR (de)) { -erofs_err (dir->i_sb, -"fail to readdir of logical block %u of nid %llu" , +erofs_err (sb,"fail to readdir of logical block %u of nid %llu" , i,EROFS_I (dir)->nid); err =PTR_ERR (de);break ; } nameoff =le16_to_cpu (de->nameoff); -if (nameoff <sizeof (struct erofs_dirent ) || - nameoff >=EROFS_BLKSIZ ) { -erofs_err (dir->i_sb, -"invalid de[0].nameoff %u @ nid %llu" , +if (nameoff <sizeof (struct erofs_dirent ) || nameoff >= bsz) { +erofs_err (sb,"invalid de[0].nameoff %u @ nid %llu" , nameoff,EROFS_I (dir)->nid); err = -EFSCORRUPTED ;break ; } - maxsize = min_t(unsigned int, - dirsize - ctx->pos + ofs,EROFS_BLKSIZ ); + maxsize = min_t(unsigned int, dirsize - ctx->pos + ofs, bsz);/* search dirents at the arbitrary position */ if (initial) { initial = false; ofs =roundup (ofs,sizeof (struct erofs_dirent )); - ctx->pos =blknr_to_addr (i) + ofs; + ctx->pos =erofs_pos (sb, i) + ofs;if (ofs >= nameoff) goto skip_this; }
@@ -114,7 +112,7 @@ static int erofs_readdir(struct file *f,if (err)break ; skip_this: - ctx->pos =blknr_to_addr (i) + maxsize; + ctx->pos =erofs_pos (sb, i) + maxsize; ++i; ofs =0 ; }
fs/erofs/fscache.c +4 -3
@@ -282,8 +282,8 @@ static int erofs_fscache_data_read(strucvoid *src;/* For tail packing layout, the offset may be non-zero. */ - offset =erofs_blkoff (map.m_pa); - blknr =erofs_blknr (map.m_pa); + offset =erofs_blkoff (sb, map.m_pa); + blknr =erofs_blknr (sb, map.m_pa); size = map.m_llen; src =erofs_read_metabuf (&buf, sb, blknr,EROFS_KMAP );
@@ -333,7 +333,7 @@ static int erofs_fscache_read_folio(strubool unlock;int ret; -DBG_BUGON (folio_size (folio) !=EROFS_BLKSIZ ); +DBG_BUGON (folio_size (folio) !=PAGE_SIZE ); ret =erofs_fscache_data_read (folio_mapping (folio),folio_pos (folio),folio_size (folio), &unlock);
@@ -529,6 +529,7 @@ struct erofs_fscache *erofs_fscache_acquset_nlink (inode,1 ); inode->i_size =OFFSET_MAX ; inode->i_mapping->a_ops = &erofs_fscache_meta_aops; + inode->i_blkbits =EROFS_SB (sb)->blkszbits;mapping_set_gfp_mask (inode->i_mapping,GFP_NOFS ); ctx->inode = inode;
fs/erofs/inode.c +11 -9
@@ -23,8 +23,8 @@ static void *erofs_read_inode(struct erounsigned int ifmt;int err; - blkaddr =erofs_blknr (inode_loc); - *ofs =erofs_blkoff (inode_loc); + blkaddr =erofs_blknr (sb, inode_loc); + *ofs =erofs_blkoff (sb, inode_loc);erofs_dbg ("%s, reading inode nid %llu at %u of blkaddr %u" , __func__, vi->nid, *ofs, blkaddr);
@@ -58,11 +58,11 @@ static void *erofs_read_inode(struct erocase EROFS_INODE_LAYOUT_EXTENDED : vi->inode_isize =sizeof (struct erofs_inode_extended );/* check if the extended inode acrosses block boundary */ -if (*ofs + vi->inode_isize <=EROFS_BLKSIZ ) { +if (*ofs + vi->inode_isize <= sb->s_blocksize) { *ofs += vi->inode_isize; die = (struct erofs_inode_extended *)dic; }else { -const unsigned int gotten =EROFS_BLKSIZ - *ofs; +const unsigned int gotten = sb->s_blocksize - *ofs; copied =kmalloc (vi->inode_isize,GFP_NOFS );if (!copied) {
@@ -176,7 +176,7 @@ static void *erofs_read_inode(struct ero err = -EOPNOTSUPP ; goto err_out; } - vi->chunkbits =LOG_BLOCK_SIZE + + vi->chunkbits = sb->s_blocksize_bits + (vi->chunkformat &EROFS_CHUNK_FORMAT_BLKBITS_MASK ); } inode->i_mtime.tv_sec = inode->i_ctime.tv_sec;
@@ -189,11 +189,12 @@ static void *erofs_read_inode(struct ero (vi->datalayout ==EROFS_INODE_FLAT_PLAIN || vi->datalayout == EROFS_INODE_CHUNK_BASED)) inode->i_flags |= S_DAX; +if (!nblks)/* measure inode.i_blocks as generic filesystems */ - inode->i_blocks =roundup (inode->i_size,EROFS_BLKSIZ ) >>9 ; + inode->i_blocks =round_up (inode->i_size, sb->s_blocksize) >>9 ;else - inode->i_blocks = nblks <<LOG_SECTORS_PER_BLOCK ; + inode->i_blocks = nblks << (sb->s_blocksize_bits -9 );return kaddr; bogusimode:
@@ -211,11 +212,12 @@ static int erofs_fill_symlink(struct ino unsigned int m_pofs) {struct erofs_inode *vi =EROFS_I (inode); +unsigned int bsz =i_blocksize (inode);char *lnk;/* if it cannot be handled with fast symlink scheme */ if (vi->datalayout !=EROFS_INODE_FLAT_INLINE || - inode->i_size >=EROFS_BLKSIZ || inode->i_size <0 ) { + inode->i_size >= bsz || inode->i_size <0 ) { inode->i_op = &erofs_symlink_iops;return 0 ; }
@@ -226,7 +228,7 @@ static int erofs_fill_symlink(struct ino m_pofs += vi->xattr_isize;/* inline symlink data shouldn't cross block boundary */ -if (m_pofs + inode->i_size >EROFS_BLKSIZ ) { +if (m_pofs + inode->i_size > bsz) {kfree (lnk); erofs_err(inode->i_sb, "inline data cross block boundary @ nid %llu",
fs/erofs/internal.h +7 -13
@@ -145,8 +145,8 @@ struct erofs_sb_info {#endif u16 device_id_mask;/* valid bits of device id to be used */ -/* inode slot unit size in bit shift */ -unsigned char islotbits; +unsigned char islotbits;/* inode slot unit size in bit shift */ +unsigned char blkszbits;u32 sb_size;/* total superblock size */ u32 build_time_nsec;
@@ -241,13 +241,6 @@ static inline int erofs_wait_on_workgrou/* we strictly follow PAGE_SIZE and no buffer head yet */ #define LOG_BLOCK_SIZE PAGE_SHIFT - -#undef LOG_SECTORS_PER_BLOCK -#define LOG_SECTORS_PER_BLOCK (PAGE_SHIFT - 9) - -#undef SECTORS_PER_BLOCK -#define SECTORS_PER_BLOCK (1 << SECTORS_PER_BLOCK) -#define EROFS_BLKSIZ (1 << LOG_BLOCK_SIZE)#if (EROFS_BLKSIZ %4096 || !EROFS_BLKSIZ )
@@ -269,9 +262,10 @@ struct erofs_buf {#define ROOT_NID (sb) ((sb)->root_nid) -#define erofs_blknr (addr) ((addr) / EROFS_BLKSIZ) -#define erofs_blkoff (addr) ((addr) % EROFS_BLKSIZ) -#define blknr_to_addr (nr) ((erofs_off_t)(nr) * EROFS_BLKSIZ) +#define erofs_blknr (sb, addr) ((addr) >> (sb)->s_blocksize_bits) +#define erofs_blkoff (sb, addr) ((addr) & ((sb)->s_blocksize - 1)) +#define erofs_pos (sb, blk) ((erofs_off_t)(blk) << (sb)->s_blocksize_bits) +#define erofs_iblks (i) (round_up((i)->i_size, i_blocksize(i)) >> (i)->i_blkbits)#define EROFS_FEATURE_FUNCS (name, compat, feature) \ static inline bool erofs_sb_has_##name(struct erofs_sb_info *sbi) \
@@ -343,7 +337,7 @@ static inline erofs_off_t erofs_iloc(str {struct erofs_sb_info *sbi =EROFS_I_SB (inode); -return blknr_to_addr (sbi->meta_blkaddr) + +return erofs_pos (inode->i_sb, sbi->meta_blkaddr) + (EROFS_I (inode)->nid << sbi->islotbits); }
fs/erofs/namei.c +7 -7
@@ -89,7 +89,8 @@ static struct erofs_dirent *find_target_static void *erofs_find_target_block (struct erofs_buf *target,struct inode *dir,struct erofs_qstr *name,int *_ndirents) { -int head =0 , back =DIV_ROUND_UP (dir->i_size,EROFS_BLKSIZ ) -1 ; +unsigned int bsz =i_blocksize (dir); +int head =0 , back =erofs_iblks (dir) -1 ;unsigned int startprfx =0 , endprfx =0 ;void *candidate =ERR_PTR (-ENOENT );
@@ -100,8 +101,7 @@ static void *erofs_find_target_block(str de =erofs_bread (&buf, dir, mid,EROFS_KMAP );if (!IS_ERR (de)) { -const int nameoff =nameoff_from_disk (de->nameoff, -EROFS_BLKSIZ ); +const int nameoff =nameoff_from_disk (de->nameoff, bsz);const int ndirents = nameoff /sizeof (*de);int diff;unsigned int matched;
@@ -121,11 +121,10 @@ static void *erofs_find_target_block(str dname.name = (u8 *)de + nameoff;if (ndirents ==1 ) - dname.end = (u8 *)de +EROFS_BLKSIZ ; + dname.end = (u8 *)de + bsz;else dname.end = (u8 *)de + -nameoff_from_disk (de[1 ].nameoff, -EROFS_BLKSIZ ); +nameoff_from_disk (de[1 ].nameoff, bsz);/* string comparison without already matched prefix */ diff =erofs_dirnamecmp (name, &dname, &matched);
@@ -178,7 +177,8 @@ int erofs_namei(struct inode *dir, constreturn PTR_ERR (de);if (ndirents) - de =find_target_dirent (&qn, (u8 *)de,EROFS_BLKSIZ , ndirents); + de =find_target_dirent (&qn, (u8 *)de,i_blocksize (dir), + ndirents);if (!IS_ERR (de)) { *nid =le64_to_cpu (de->nid);
fs/erofs/super.c +16 -11
@@ -53,18 +53,21 @@ void _erofs_info(struct super_block *sb,static int erofs_superblock_csum_verify (struct super_block *sb,void *sbdata) { +size_t len =1 <<EROFS_SB (sb)->blkszbits;struct erofs_super_block *dsb;u32 expected_crc, crc; - dsb =kmemdup (sbdata +EROFS_SUPER_OFFSET , -EROFS_BLKSIZ -EROFS_SUPER_OFFSET ,GFP_KERNEL ); +if (len >EROFS_SUPER_OFFSET ) + len -=EROFS_SUPER_OFFSET ; + + dsb =kmemdup (sbdata +EROFS_SUPER_OFFSET , len,GFP_KERNEL );if (!dsb)return -ENOMEM ; expected_crc =le32_to_cpu (dsb->checksum); dsb->checksum =0 ;/* to allow for x86 boot sectors and other oddities. */ - crc =crc32c (~0 , dsb,EROFS_BLKSIZ -EROFS_SUPER_OFFSET ); + crc =crc32c (~0 , dsb, len);kfree (dsb);if (crc != expected_crc) {
@@ -133,11 +136,11 @@ void *erofs_read_metadata(struct super_bint len, i, cnt; *offset =round_up (*offset,4 ); - ptr =erofs_read_metabuf (buf, sb,erofs_blknr (*offset),EROFS_KMAP ); + ptr =erofs_read_metabuf (buf, sb,erofs_blknr (sb, *offset),EROFS_KMAP );if (IS_ERR (ptr))return ptr; - len =le16_to_cpu (*(__le16 *)&ptr[erofs_blkoff (*offset)]); + len =le16_to_cpu (*(__le16 *)&ptr[erofs_blkoff (sb, *offset)]);if (!len) len =U16_MAX +1 ; buffer =kmalloc (len,GFP_KERNEL );
@@ -147,14 +150,15 @@ void *erofs_read_metadata(struct super_b *lengthp = len;for (i =0 ; i < len; i += cnt) { - cnt =min (EROFS_BLKSIZ - (int )erofs_blkoff (*offset), len - i); - ptr =erofs_read_metabuf (buf, sb,erofs_blknr (*offset), + cnt =min_t (int, sb->s_blocksize -erofs_blkoff (sb, *offset), + len - i); + ptr =erofs_read_metabuf (buf, sb,erofs_blknr (sb, *offset),EROFS_KMAP );if (IS_ERR (ptr)) {kfree (buffer);return ptr; } -memcpy (buffer + i, ptr +erofs_blkoff (*offset), cnt); +memcpy (buffer + i, ptr +erofs_blkoff (sb, *offset), cnt); *offset += cnt; }return buffer;
@@ -180,10 +184,10 @@ static int erofs_init_device(struct erofstruct block_device *bdev;void *ptr; - ptr =erofs_read_metabuf (buf, sb,erofs_blknr (*pos),EROFS_KMAP ); + ptr =erofs_read_metabuf (buf, sb,erofs_blknr (sb, *pos),EROFS_KMAP );if (IS_ERR (ptr))return PTR_ERR (ptr); - dis = ptr +erofs_blkoff (*pos); + dis = ptr +erofs_blkoff (sb, *pos);if (!dif->path) {if (!dis->tag[0 ]) {
@@ -672,6 +676,7 @@ static int erofs_fc_fill_super(struct su sbi->domain_id = ctx->domain_id; ctx->domain_id =NULL ; + sbi->blkszbits =PAGE_SHIFT ;if (erofs_is_fscache_mode (sb)) { sb->s_blocksize =EROFS_BLKSIZ ; sb->s_blocksize_bits =LOG_BLOCK_SIZE ;
@@ -1007,7 +1012,7 @@ static int erofs_statfs(struct dentry *d id =huge_encode_dev (sb->s_bdev->bd_dev); buf->f_type = sb->s_magic; - buf->f_bsize =EROFS_BLKSIZ ; + buf->f_bsize = sb->s_blocksize; buf->f_blocks = sbi->total_blocks; buf->f_bfree = buf->f_bavail =0 ;
fs/erofs/xattr.c +19 -21
@@ -68,8 +68,8 @@ static int init_inode_xattrs(struct inod } it.buf = __EROFS_BUF_INITIALIZER; - it.blkaddr =erofs_blknr (erofs_iloc (inode) + vi->inode_isize); - it.ofs =erofs_blkoff (erofs_iloc (inode) + vi->inode_isize); + it.blkaddr =erofs_blknr (sb,erofs_iloc (inode) + vi->inode_isize); + it.ofs =erofs_blkoff (sb,erofs_iloc (inode) + vi->inode_isize);/* read in shared xattr array (non-atomic, see kmalloc below) */ it.kaddr =erofs_read_metabuf (&it.buf, sb, it.blkaddr,EROFS_KMAP );
@@ -92,9 +92,9 @@ static int init_inode_xattrs(struct inod it.ofs +=sizeof (struct erofs_xattr_ibody_header );for (i =0 ; i < vi->xattr_shared_count; ++i) { -if (it.ofs >=EROFS_BLKSIZ ) { +if (it.ofs >= sb->s_blocksize) {/* cannot be unaligned */ -DBG_BUGON (it.ofs !=EROFS_BLKSIZ ); +DBG_BUGON (it.ofs != sb->s_blocksize); it.kaddr =erofs_read_metabuf (&it.buf, sb, ++it.blkaddr,EROFS_KMAP );
@@ -139,15 +139,15 @@ struct xattr_iter_handlers {static inline int xattr_iter_fixup (struct xattr_iter *it) { -if (it->ofs <EROFS_BLKSIZ ) +if (it->ofs < it->sb->s_blocksize)return 0 ; - it->blkaddr +=erofs_blknr (it->ofs); + it->blkaddr +=erofs_blknr (it->sb, it->ofs); it->kaddr =erofs_read_metabuf (&it->buf, it->sb, it->blkaddr,EROFS_KMAP_ATOMIC );if (IS_ERR (it->kaddr))return PTR_ERR (it->kaddr); - it->ofs =erofs_blkoff (it->ofs); + it->ofs =erofs_blkoff (it->sb, it->ofs);return 0 ; }
@@ -165,8 +165,8 @@ static int inline_xattr_iter_begin(struc inline_xattr_ofs = vi->inode_isize + xattr_header_sz; - it->blkaddr =erofs_blknr (erofs_iloc (inode) + inline_xattr_ofs); - it->ofs =erofs_blkoff (erofs_iloc (inode) + inline_xattr_ofs); + it->blkaddr =erofs_blknr (it->sb,erofs_iloc (inode) + inline_xattr_ofs); + it->ofs =erofs_blkoff (it->sb,erofs_iloc (inode) + inline_xattr_ofs); it->kaddr =erofs_read_metabuf (&it->buf, inode->i_sb, it->blkaddr,EROFS_KMAP_ATOMIC );if (IS_ERR (it->kaddr))
@@ -222,8 +222,8 @@ static int xattr_foreach(struct xattr_it processed =0 ;while (processed < entry.e_name_len) { -if (it->ofs >=EROFS_BLKSIZ ) { -DBG_BUGON (it->ofs >EROFS_BLKSIZ ); +if (it->ofs >= it->sb->s_blocksize) { +DBG_BUGON (it->ofs > it->sb->s_blocksize); err =xattr_iter_fixup (it);if (err)
@@ -231,7 +231,7 @@ static int xattr_foreach(struct xattr_it it->ofs =0 ; } - slice = min_t(unsigned int, EROFS_BLKSIZ - it->ofs, + slice = min_t(unsigned int, it->sb->s_blocksize - it->ofs, entry.e_name_len - processed);/* handle name */
@@ -257,8 +257,8 @@ static int xattr_foreach(struct xattr_it }while (processed < value_sz) { -if (it->ofs >=EROFS_BLKSIZ ) { -DBG_BUGON (it->ofs >EROFS_BLKSIZ ); +if (it->ofs >= it->sb->s_blocksize) { +DBG_BUGON (it->ofs > it->sb->s_blocksize); err =xattr_iter_fixup (it);if (err)
@@ -266,7 +266,7 @@ static int xattr_foreach(struct xattr_it it->ofs =0 ; } - slice = min_t(unsigned int, EROFS_BLKSIZ - it->ofs, + slice = min_t(unsigned int, it->sb->s_blocksize - it->ofs, value_sz - processed); op->value (it, processed, it->kaddr + it->ofs, slice); it->ofs += slice;
@@ -352,15 +352,14 @@ static int shared_getxattr(struct inode {struct erofs_inode *const vi =EROFS_I (inode);struct super_block *const sb = inode->i_sb; -struct erofs_sb_info *const sbi =EROFS_SB (sb);unsigned int i;int ret = -ENOATTR ;for (i =0 ; i < vi->xattr_shared_count; ++i) {erofs_blk_t blkaddr = -xattrblock_addr (sbi, vi->xattr_shared_xattrs[i]); +xattrblock_addr (sb, vi->xattr_shared_xattrs[i]); - it->it.ofs =xattrblock_offset (sbi, vi->xattr_shared_xattrs[i]); + it->it.ofs =xattrblock_offset (sb, vi->xattr_shared_xattrs[i]); it->it.kaddr =erofs_read_metabuf (&it->it.buf, sb, blkaddr,EROFS_KMAP_ATOMIC );if (IS_ERR (it->it.kaddr))
@@ -564,15 +563,14 @@ static int shared_listxattr(struct listxstruct inode *const inode =d_inode (it->dentry);struct erofs_inode *const vi =EROFS_I (inode);struct super_block *const sb = inode->i_sb; -struct erofs_sb_info *const sbi =EROFS_SB (sb);unsigned int i;int ret =0 ;for (i =0 ; i < vi->xattr_shared_count; ++i) {erofs_blk_t blkaddr = -xattrblock_addr (sbi, vi->xattr_shared_xattrs[i]); +xattrblock_addr (sb, vi->xattr_shared_xattrs[i]); - it->it.ofs =xattrblock_offset (sbi, vi->xattr_shared_xattrs[i]); + it->it.ofs =xattrblock_offset (sb, vi->xattr_shared_xattrs[i]); it->it.kaddr =erofs_read_metabuf (&it->it.buf, sb, blkaddr,EROFS_KMAP_ATOMIC );if (IS_ERR (it->it.kaddr))
fs/erofs/xattr.h +5 -5
@@ -19,21 +19,21 @@ static inline unsigned int inlinexattr_hsizeof (u32) *EROFS_I (inode)->xattr_shared_count; } -static inline erofs_blk_t xattrblock_addr (struct erofs_sb_info *sbi, +static inline erofs_blk_t xattrblock_addr (struct super_block *sb,unsigned int xattr_id) {#ifdef CONFIG_EROFS_FS_XATTR -return sbi->xattr_blkaddr + - xattr_id *sizeof (__u32) /EROFS_BLKSIZ ; +return EROFS_SB (sb)->xattr_blkaddr + + xattr_id *sizeof (__u32) / sb->s_blocksize;#else return 0 ;#endif } -static inline unsigned int xattrblock_offset (struct erofs_sb_info *sbi, +static inline unsigned int xattrblock_offset (struct super_block *sb,unsigned int xattr_id) { -return (xattr_id *sizeof (__u32)) %EROFS_BLKSIZ ; +return (xattr_id *sizeof (__u32)) % sb->s_blocksize; }#ifdef CONFIG_EROFS_FS_XATTR
fs/erofs/zdata.c +9 -7
@@ -766,6 +766,7 @@ static int z_erofs_read_fragment(struct struct page *page, unsigned int pageofs, unsigned int len) { + struct super_block *sb = inode->i_sb;struct inode *packed_inode =EROFS_I_SB (inode)->packed_inode;struct erofs_buf buf = __EROFS_BUF_INITIALIZER;u8 *src, *dst;
@@ -777,16 +778,16 @@ static int z_erofs_read_fragment(struct pos +=EROFS_I (inode)->z_fragmentoff;for (i =0 ; i < len; i += cnt) { cnt = min_t(unsigned int, len - i, -EROFS_BLKSIZ -erofs_blkoff (pos)); + sb->s_blocksize -erofs_blkoff (sb, pos)); src =erofs_bread (&buf, packed_inode, -erofs_blknr (pos),EROFS_KMAP ); +erofs_blknr (sb, pos),EROFS_KMAP );if (IS_ERR (src)) {erofs_put_metabuf (&buf);return PTR_ERR (src); } dst =kmap_local_page (page); -memcpy (dst + pageofs + i, src +erofs_blkoff (pos), cnt); +memcpy (dst + pageofs + i, src +erofs_blkoff (sb, pos), cnt);kunmap_local (dst); pos += cnt; }
@@ -841,7 +842,8 @@ repeat:void *mp; mp =erofs_read_metabuf (&fe->map.buf, inode->i_sb, -erofs_blknr (map->m_pa),EROFS_NO_KMAP ); +erofs_blknr (inode->i_sb, map->m_pa), +EROFS_NO_KMAP );if (IS_ERR (mp)) { err =PTR_ERR (mp); erofs_err(inode->i_sb,
@@ -1526,11 +1528,11 @@ static void z_erofs_submit_queue(struct/* no device id here, thus it will always succeed */ mdev = (struct erofs_map_dev ) { - .m_pa =blknr_to_addr (pcl->obj.index), + .m_pa =erofs_pos (sb, pcl->obj.index), }; (void )erofs_map_dev (sb, &mdev); - cur =erofs_blknr (mdev.m_pa); + cur =erofs_blknr (sb, mdev.m_pa); end = cur + pcl->pclusterpages; do {
@@ -1564,7 +1566,7 @@ submit_bio_retry: last_bdev = mdev.m_bdev; bio->bi_iter.bi_sector = (sector_t )cur << -LOG_SECTORS_PER_BLOCK ; + (sb->s_blocksize_bits -9 ); bio->bi_private = q[JQ_SUBMIT ];if (f->readahead) bio->bi_opf |=REQ_RAHEAD ;
fs/erofs/zmap.c +15 -14
@@ -18,7 +18,7 @@ int z_erofs_fill_inode(struct inode *ino vi->z_advise =0 ; vi->z_algorithmtype[0 ] =0 ; vi->z_algorithmtype[1 ] =0 ; - vi->z_logical_clusterbits =LOG_BLOCK_SIZE ; + vi->z_logical_clusterbits = inode->i_sb->s_blocksize_bits;set_bit (EROFS_I_Z_INITED_BIT , &vi->flags); } inode->i_mapping->a_ops = &z_erofs_aops;
@@ -53,13 +53,13 @@ static int legacy_load_cluster_from_diskunsigned int advise, type; m->kaddr =erofs_read_metabuf (&m->map->buf, inode->i_sb, -erofs_blknr (pos),EROFS_KMAP_ATOMIC ); +erofs_blknr (inode->i_sb, pos),EROFS_KMAP_ATOMIC );if (IS_ERR (m->kaddr))return PTR_ERR (m->kaddr); m->nextpackoff = pos +sizeof (struct z_erofs_vle_decompressed_index ); m->lcn = lcn; - di = m->kaddr +erofs_blkoff (pos); + di = m->kaddr +erofs_blkoff (inode->i_sb, pos); advise =le16_to_cpu (di->di_advise); type = (advise >> Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT) &
@@ -160,7 +160,7 @@ static int unpack_compacted_index(struct (vcnt << amortizedshift); big_pcluster = vi->z_advise &Z_EROFS_ADVISE_BIG_PCLUSTER_1 ; encodebits = ((vcnt << amortizedshift) -sizeof (__le32)) *8 / vcnt; - eofs =erofs_blkoff (pos); + eofs =erofs_blkoff (m->inode->i_sb, pos); base =round_down (eofs, vcnt << amortizedshift); in = m->kaddr + base;
@@ -252,7 +252,7 @@ static int compacted_load_cluster_from_dstruct erofs_inode *const vi =EROFS_I (inode);const erofs_off_t ebase =sizeof (struct z_erofs_map_header ) +ALIGN (erofs_iloc (inode) + vi->inode_isize + vi->xattr_isize,8 ); -const unsigned int totalidx =DIV_ROUND_UP (inode->i_size,EROFS_BLKSIZ ); +unsigned int totalidx =erofs_iblks (inode);unsigned int compacted_4b_initial, compacted_2b;unsigned int amortizedshift;erofs_off_t pos;
@@ -290,7 +290,7 @@ static int compacted_load_cluster_from_d out: pos += lcn * (1 << amortizedshift); m->kaddr =erofs_read_metabuf (&m->map->buf, inode->i_sb, -erofs_blknr (pos),EROFS_KMAP_ATOMIC ); +erofs_blknr (inode->i_sb, pos),EROFS_KMAP_ATOMIC );if (IS_ERR (m->kaddr))return PTR_ERR (m->kaddr);return unpack_compacted_index (m, amortizedshift, pos, lookahead);
@@ -360,6 +360,7 @@ static int z_erofs_extent_lookback(strucstatic int z_erofs_get_extent_compressedlen (struct z_erofs_maprecorder *m,unsigned int initial_lcn) { +struct super_block *sb = m->inode->i_sb;struct erofs_inode *const vi =EROFS_I (m->inode);struct erofs_map_blocks *const map = m->map;const unsigned int lclusterbits = vi->z_logical_clusterbits;
@@ -406,7 +407,7 @@ static int z_erofs_get_extent_compressed* if the 1st NONHEAD lcluster is actually PLAIN or HEAD type * rather than CBLKCNT, it's a 1 lcluster-sized pcluster. */ - m->compressedblks =1 << (lclusterbits -LOG_BLOCK_SIZE ); + m->compressedblks =1 << (lclusterbits - sb->s_blocksize_bits);break ;case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD :if (m->delta[0 ] !=1 )
@@ -422,7 +423,7 @@ static int z_erofs_get_extent_compressedreturn -EFSCORRUPTED ; } out: - map->m_plen = (u64 )m->compressedblks <<LOG_BLOCK_SIZE ; + map->m_plen =erofs_pos (sb, m->compressedblks);return 0 ; err_bonus_cblkcnt: erofs_err(m->inode->i_sb,
@@ -565,7 +566,7 @@ static int z_erofs_do_map_blocks(struct }else if (fragment && m.lcn == vi->z_tailextent_headlcn) { map->m_flags |=EROFS_MAP_FRAGMENT ; }else { - map->m_pa =blknr_to_addr (m.pblk); + map->m_pa =erofs_pos (inode->i_sb, m.pblk); err =z_erofs_get_extent_compressedlen (&m, initial_lcn);if (err) goto unmap_out;
@@ -595,7 +596,7 @@ static int z_erofs_do_map_blocks(structif ((flags &EROFS_GET_BLOCKS_FIEMAP ) || ((flags &EROFS_GET_BLOCKS_READMORE ) && map->m_algorithmformat ==Z_EROFS_COMPRESSION_LZMA && - map->m_llen >=EROFS_BLKSIZ )) { + map->m_llen >=i_blocksize (inode))) { err =z_erofs_get_extent_decompressedlen (&m);if (!err) map->m_flags |=EROFS_MAP_FULL_MAPPED ;
@@ -636,13 +637,13 @@ static int z_erofs_fill_inode_lazy(struc goto out_unlock; pos =ALIGN (erofs_iloc (inode) + vi->inode_isize + vi->xattr_isize,8 ); - kaddr =erofs_read_metabuf (&buf, sb,erofs_blknr (pos),EROFS_KMAP ); + kaddr =erofs_read_metabuf (&buf, sb,erofs_blknr (sb, pos),EROFS_KMAP );if (IS_ERR (kaddr)) { err =PTR_ERR (kaddr); goto out_unlock; } - h = kaddr +erofs_blkoff (pos); + h = kaddr +erofs_blkoff (sb, pos);/* * if the highest bit of the 8-byte map header is set, the whole file * is stored in the packed inode. The rest bits keeps z_fragmentoff.
@@ -666,7 +667,7 @@ static int z_erofs_fill_inode_lazy(struc goto out_put_metabuf; } - vi->z_logical_clusterbits =LOG_BLOCK_SIZE + (h->h_clusterbits &7 ); + vi->z_logical_clusterbits = sb->s_blocksize_bits + (h->h_clusterbits &7 );if (!erofs_sb_has_big_pcluster (EROFS_SB (sb)) && vi->z_advise & (Z_EROFS_ADVISE_BIG_PCLUSTER_1 |Z_EROFS_ADVISE_BIG_PCLUSTER_2 )) {
@@ -695,7 +696,7 @@ static int z_erofs_fill_inode_lazy(strucerofs_put_metabuf (&map.buf);if (!map.m_plen || -erofs_blkoff (map.m_pa) + map.m_plen >EROFS_BLKSIZ ) { +erofs_blkoff (sb, map.m_pa) + map.m_plen > sb->s_blocksize) {erofs_err (sb,"invalid tail-packing pclustersize %llu" , map.m_plen); err = -EFSCORRUPTED ;
include/trace/events/erofs.h +2 -2
@@ -66,8 +66,8 @@ TRACE_EVENT(erofs_fill_inode,TP_fast_assign ( __entry->dev = inode->i_sb->s_dev; __entry->nid =EROFS_I (inode)->nid; - __entry->blkaddr =erofs_blknr (erofs_iloc (inode)); - __entry->ofs =erofs_blkoff (erofs_iloc (inode)); + __entry->blkaddr =erofs_blknr (inode->i_sb,erofs_iloc (inode)); + __entry->ofs =erofs_blkoff (inode->i_sb,erofs_iloc (inode)); ), TP_printk("dev = (%d,%d), nid = %llu, blkaddr %u ofs %u",
Greg Kroah-Hartman
maintainerPATCH 657/798 erofs: set block size to the on-disk block size
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jingbo Xu <[email protected]>
commit d3c4bdcc756e60b95365c66ff58844ce75d1c8f8 upstream.
Set the block size to that specified in on-disk superblock.
Also remove the hard constraint of PAGE_SIZE block size for the uncompressed device backend. This constraint is temporarily remained for compressed device and fscache backend, as there is more work needed to handle the condition where the block size is not equal to PAGE_SIZE.
It is worth noting that the on-disk block size is read prior to erofs_superblock_csum_verify(), as the read block size is needed in the latter.
Besides, later we are going to make erofs refer to tar data blobs (which is 512-byte aligned) for OCI containers, where the block size is 512 bytes. In this case, the 512-byte block size may not be adequate for a directory to contain enough dirents. To fix this, we are also going to introduce directory block size independent on the block size.
Due to we have already supported block size smaller than PAGE_SIZE now, disable all these images with such separated directory block size until we supported this feature later.
Stable-dep-of: 9ed50b8231e3 ("erofs: fix incorrect symlink detection in fast symlink") [ Gao Xiang: apply this to 6.6.y to avoid further backport twists
due to obsoleted EROFS_BLKSIZ. ]
--- fs/erofs/erofs_fs.h | 5 +++-- fs/erofs/inode.c | 3 ++- fs/erofs/internal.h | 10 +--------- fs/erofs/super.c | 45 +++++++++++++++++++++++++++++---------------- 4 files changed, 35 insertions(+), 28 deletions(-)
fs/erofs/erofs_fs.h +3 -2
@@ -53,7 +53,7 @@ struct erofs_super_block {__le32 magic;/* file system magic number */ __le32 checksum;/* crc32c(super_block) */ __le32 feature_compat; -__u8 blkszbits;/* support block_size == PAGE_SIZE only */ +__u8 blkszbits;/* filesystem block size in bit shift */ __u8 sb_extslots;/* superblock size = 128 + sb_extslots * 16 */ __le16 root_nid;/* nid of root directory */
@@ -75,7 +75,8 @@ struct erofs_super_block { }__packed u1;__le16 extra_devices;/* # of devices besides the primary device */ __le16 devt_slotoff;/* startoff = devt_slotoff * devt_slotsize */ -__u8 reserved[6 ]; +__u8 dirblkbits;/* directory block size in bit shift */ +__u8 reserved[5 ];__le64 packed_nid;/* nid of the special packed inode */ __u8 reserved2[24 ]; };
fs/erofs/inode.c +2 -1
@@ -291,7 +291,8 @@ static int erofs_fill_inode(struct inode }if (erofs_inode_is_data_compressed (vi->datalayout)) { -if (!erofs_is_fscache_mode (inode->i_sb)) +if (!erofs_is_fscache_mode (inode->i_sb) && + inode->i_sb->s_blocksize_bits ==PAGE_SHIFT ) err =z_erofs_fill_inode (inode);else err = -EOPNOTSUPP ;
fs/erofs/internal.h +1 -9
@@ -146,7 +146,7 @@ struct erofs_sb_info {u16 device_id_mask;/* valid bits of device id to be used */ unsigned char islotbits;/* inode slot unit size in bit shift */ -unsigned char blkszbits; +unsigned char blkszbits;/* filesystem block size in bit shift */ u32 sb_size;/* total superblock size */ u32 build_time_nsec;
@@ -239,14 +239,6 @@ static inline int erofs_wait_on_workgrou VAL != EROFS_LOCKED_MAGIC); } -/* we strictly follow PAGE_SIZE and no buffer head yet */ -#define LOG_BLOCK_SIZE PAGE_SHIFT -#define EROFS_BLKSIZ (1 << LOG_BLOCK_SIZE) - -#if (EROFS_BLKSIZ %4096 || !EROFS_BLKSIZ ) -#error erofs cannot be used in this platform -#endif -enum erofs_kmap_type {EROFS_NO_KMAP ,/* don't map the buffer */ EROFS_KMAP ,/* use kmap() to map the buffer */
fs/erofs/super.c +29 -16
89 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 658/798 erofs: fix incorrect symlink detection in fast symlink
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
commit 9ed50b8231e37b1ae863f5dec8153b98d9f389b4 upstream.
Fast symlink can be used if the on-disk symlink data is stored in the same block as the on-disk inode, so we don’t need to trigger another I/O for symlink data. However, currently fs correction could be reported _incorrectly_ if inode xattrs are too large.
In fact, these should be valid images although they cannot be handled as fast symlinks.
Many thanks to Colin for reporting this!
--- fs/erofs/inode.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-)
fs/erofs/inode.c +6 -14
@@ -212,12 +212,14 @@ static int erofs_fill_symlink(struct ino unsigned int m_pofs) {struct erofs_inode *vi =EROFS_I (inode); -unsigned int bsz =i_blocksize (inode); +loff_t off;char *lnk; -/* if it cannot be handled with fast symlink scheme */ -if (vi->datalayout !=EROFS_INODE_FLAT_INLINE || - inode->i_size >= bsz || inode->i_size <0 ) { + m_pofs += vi->xattr_isize; +/* check if it cannot be handled with fast symlink scheme */ +if (vi->datalayout !=EROFS_INODE_FLAT_INLINE || inode->i_size <0 || +check_add_overflow (m_pofs, inode->i_size, &off) || + off >i_blocksize (inode)) { inode->i_op = &erofs_symlink_iops;return 0 ; }
@@ -226,16 +228,6 @@ static int erofs_fill_symlink(struct inoif (!lnk)return -ENOMEM ; - m_pofs += vi->xattr_isize; -/* inline symlink data shouldn't cross block boundary */ -if (m_pofs + inode->i_size > bsz) { -kfree (lnk); -erofs_err (inode->i_sb, -"inline data cross block boundary @ nid %llu" , - vi->nid); -DBG_BUGON (1 ); -return -EFSCORRUPTED ; - }memcpy (lnk, kaddr + m_pofs, inode->i_size); lnk[inode->i_size] ='\0' ;
Greg Kroah-Hartman
maintainerPATCH 659/798 vhost/scsi: null-ptr-dereference in vhost_scsi_get_req()
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoran Zhang <[email protected]>
commit 221af82f606d928ccef19a16d35633c63026f1be upstream.
Since commit 3f8ca2e115e5 ("vhost/scsi: Extract common handling code from control queue handler") a null pointer dereference bug can be triggered when guest sends an SCSI AN request.
In vhost_scsi_ctl_handle_vq(), vc.target is assigned with &v_req.tmf.lun[1] within a switch-case block and is then passed to vhost_scsi_get_req() which extracts vc->req and tpg. However, for a VIRTIO_SCSI_T_AN_* request, tpg is not required, so vc.target is set to NULL in this branch. Later, in vhost_scsi_get_req(), vc->target is dereferenced without being checked, leading to a null pointer dereference bug. This bug can be triggered from guest.
When this bug occurs, the vhost_worker process is killed while holding vq->mutex and the corresponding tpg will remain occupied indefinitely.
Below is the KASAN report:
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 1 PID: 840 Comm: poc Not tainted 6.10.0+ #1 Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:vhost_scsi_get_req+0x165/0x3a0 Code: 00 fc ff df 48 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 2b 02 00 00 48 b8 00 00 00 00 00 fc ff df 4d 8b 65 30 4c 89 e2 48 c1 ea 03 <0f> b6 04 02 4c 89 e2 83 e2 07 38 d0 7f 08 84 c0 0f 85 be 01 00 00 RSP: 0018:ffff888017affb50 EFLAGS: 00010246 RAX: dffffc0000000000 RBX: ffff88801b000000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff888017affcb8 RBP: ffff888017affb80 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: ffff888017affc88 R14: ffff888017affd1c R15: ffff888017993000 FS: 000055556e076500(0000) GS:ffff88806b100000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000200027c0 CR3: 0000000010ed0004 CR4: 0000000000370ef0 Call Trace: <TASK> ? show_regs+0x86/0xa0 ? die_addr+0x4b/0xd0 ? exc_general_protection+0x163/0x260 ? asm_exc_general_protection+0x27/0x30 ? vhost_scsi_get_req+0x165/0x3a0 vhost_scsi_ctl_handle_vq+0x2a4/0xca0 ? __pfx_vhost_scsi_ctl_handle_vq+0x10/0x10 ? __switch_to+0x721/0xeb0 ? __schedule+0xda5/0x5710 ? __kasan_check_write+0x14/0x30 ? _raw_spin_lock+0x82/0xf0 vhost_scsi_ctl_handle_kick+0x52/0x90 vhost_run_work_list+0x134/0x1b0 vhost_task_fn+0x121/0x350 ... </TASK> ---[ end trace 0000000000000000 ]---
Let's add a check in vhost_scsi_get_req.
Message-Id: <[email protected]>
--- drivers/vhost/scsi.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-)
drivers/vhost/scsi.c +14 -11
@@ -905,20 +905,23 @@ vhost_scsi_get_req(struct vhost_virtqueu/* virtio-scsi spec requires byte 0 of the lun to be 1 */ vq_err (vq,"Illegal virtio-scsi lun: %u\n" , *vc->lunp); }else { -struct vhost_scsi_tpg **vs_tpg, *tpg; +struct vhost_scsi_tpg **vs_tpg, *tpg =NULL ; - vs_tpg =vhost_vq_get_backend (vq);/* validated at handler entry */ - - tpg =READ_ONCE (vs_tpg[*vc->target]); -if (unlikely (!tpg)) { -vq_err (vq,"Target 0x%x does not exist\n" , *vc->target); - }else { -if (tpgp) - *tpgp = tpg; - ret =0 ; +if (vc->target) { +/* validated at handler entry */ + vs_tpg =vhost_vq_get_backend (vq); + tpg =READ_ONCE (vs_tpg[*vc->target]); +if (unlikely (!tpg)) { +vq_err (vq,"Target 0x%x does not exist\n" , *vc->target); + goto out; + } } - } +if (tpgp) + *tpgp = tpg; + ret =0 ; + } +out:return ret; }
Greg Kroah-Hartman
maintainerPATCH 660/798 perf report: Fix segfault when sym sort key is not used
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
commit 9af2efee41b27a0f386fb5aa95d8d0b4b5d9fede upstream.
The fields in the hist_entry are filled on-demand which means they only have meaningful values when relevant sort keys are used.
So if neither of 'dso' nor 'sym' sort keys are used, the map/symbols in the hist entry can be garbage. So it shouldn't access it unconditionally.
I got a segfault, when I wanted to see cgroup profiles.
$ sudo perf record -a --all-cgroups --synth=cgroup true
$ sudo perf report -s cgroup
Program received signal SIGSEGV, Segmentation fault. 0x00005555557a8d90 in map__dso (map=0x0) at util/map.h:48
48 return RC_CHK_ACCESS(map)->dso;
(gdb) bt
#0 0x00005555557a8d90 in map__dso (map=0x0) at util/map.h:48
#1 0x00005555557aa39b in map__load (map=0x0) at util/map.c:344
#2 0x00005555557aa592 in map__find_symbol (map=0x0, addr=140736115941088) at util/map.c:385
#3 0x00005555557ef000 in hists__findnew_entry (hists=0x555556039d60, entry=0x7fffffffa4c0, al=0x7fffffffa8c0, sample_self=true)
at util/hist.c:644
#4 0x00005555557ef61c in __hists__add_entry (hists=0x555556039d60, al=0x7fffffffa8c0, sym_parent=0x0, bi=0x0, mi=0x0, ki=0x0,
block_info=0x0, sample=0x7fffffffaa90, sample_self=true, ops=0x0) at util/hist.c:761
#5 0x00005555557ef71f in hists__add_entry (hists=0x555556039d60, al=0x7fffffffa8c0, sym_parent=0x0, bi=0x0, mi=0x0, ki=0x0,
sample=0x7fffffffaa90, sample_self=true) at util/hist.c:779
#6 0x00005555557f00fb in iter_add_single_normal_entry (iter=0x7fffffffa900, al=0x7fffffffa8c0) at util/hist.c:1015
#7 0x00005555557f09a7 in hist_entry_iter__add (iter=0x7fffffffa900, al=0x7fffffffa8c0, max_stack_depth=127, arg=0x7fffffffbce0)
at util/hist.c:1260
#8 0x00005555555ba7ce in process_sample_event (tool=0x7fffffffbce0, event=0x7ffff7c14128, sample=0x7fffffffaa90, evsel=0x555556039ad0,
machine=0x5555560388e8) at builtin-report.c:334
#9 0x00005555557b30c8 in evlist__deliver_sample (evlist=0x555556039010, tool=0x7fffffffbce0, event=0x7ffff7c14128,
sample=0x7fffffffaa90, evsel=0x555556039ad0, machine=0x5555560388e8) at util/session.c:1232
#10 0x00005555557b32bc in machines__deliver_event (machines=0x5555560388e8, evlist=0x555556039010, event=0x7ffff7c14128,
sample=0x7fffffffaa90, tool=0x7fffffffbce0, file_offset=110888, file_path=0x555556038ff0 "perf.data") at util/session.c:1271
#11 0x00005555557b3848 in perf_session__deliver_event (session=0x5555560386d0, event=0x7ffff7c14128, tool=0x7fffffffbce0,
file_offset=110888, file_path=0x555556038ff0 "perf.data") at util/session.c:1354
#12 0x00005555557affaf in ordered_events__deliver_event (oe=0x555556038e60, event=0x555556135aa0) at util/session.c:132
#13 0x00005555557bb605 in do_flush (oe=0x555556038e60, show_progress=false) at util/ordered-events.c:245
#14 0x00005555557bb95c in __ordered_events__flush (oe=0x555556038e60, how=OE_FLUSH__ROUND, timestamp=0) at util/ordered-events.c:324
#15 0x00005555557bba46 in ordered_events__flush (oe=0x555556038e60, how=OE_FLUSH__ROUND) at util/ordered-events.c:342
#16 0x00005555557b1b3b in perf_event__process_finished_round (tool=0x7fffffffbce0, event=0x7ffff7c15bb8, oe=0x555556038e60)
at util/session.c:780
#17 0x00005555557b3b27 in perf_session__process_user_event (session=0x5555560386d0, event=0x7ffff7c15bb8, file_offset=117688,
file_path=0x555556038ff0 "perf.data") at util/session.c:1406As you can see the entry->ms.map was NULL even if he->ms.map has a value. This is because 'sym' sort key is not given, so it cannot assume whether he->ms.sym and entry->ms.sym is the same. I only checked the 'sym' sort key here as it implies 'dso' behavior (so maps are the same).
--- tools/perf/util/hist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/hist.c +1 -1
@@ -633,7 +633,7 @@ static struct hist_entry *hists__findnew* mis-adjust symbol addresses when computing * the history counter to increment. */ -if (he->ms.map != entry->ms.map) { +if (hists__has (hists, sym) && he->ms.map != entry->ms.map) {if (he->ms.sym) {u64 addr = he->ms.sym->start; he->ms.sym =map__find_symbol (entry->ms.map, addr);
Greg Kroah-Hartman
maintainerPATCH 661/798 fsdax: dax_unshare_iter() should return a valid length
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shiyang Ruan <[email protected]>
commit 388bc034d91d480efa88abc5c8d6e6c8a878b1ab upstream.
The copy_mc_to_kernel() will return 0 if it executed successfully. Then the return value should be set to the length it copied.
--- fs/dax.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/dax.c +3 -2
@@ -1247,8 +1247,9 @@ static s64 dax_unshare_iter(struct iomapif (ret <0 ) goto out_unlock; - ret =copy_mc_to_kernel (daddr, saddr, length); -if (ret) +if (copy_mc_to_kernel (daddr, saddr, length) ==0 ) + ret = length; +else ret = -EIO ; out_unlock:
Greg Kroah-Hartman
maintainerPATCH 662/798 clk: imx6ul: fix "failed to get parent" error
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
commit f420f47e56c67587d9bc8f94267327b6fb214c1d upstream.
On some configuration we may get following error:
[ 0.000000] imx:clk-gpr-mux: failed to get parent (-EINVAL)
This happens if selector is configured to not supported value. To avoid this warnings add dummy parents for not supported values.
--- drivers/clk/imx/clk-imx6ul.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/clk/imx/clk-imx6ul.c +6 -4
@@ -95,14 +95,16 @@ static const struct clk_div_table video_ { } }; -static const char * enet1_ref_sels[] = {"enet1_ref_125m" ,"enet1_ref_pad" , }; +static const char * enet1_ref_sels[] = {"enet1_ref_125m" ,"enet1_ref_pad" ,"dummy" ,"dummy" };static const u32 enet1_ref_sels_table[] = {IMX6UL_GPR1_ENET1_TX_CLK_DIR , -IMX6UL_GPR1_ENET1_CLK_SEL }; +IMX6UL_GPR1_ENET1_CLK_SEL ,0 , +IMX6UL_GPR1_ENET1_TX_CLK_DIR |IMX6UL_GPR1_ENET1_CLK_SEL };static const u32 enet1_ref_sels_table_mask =IMX6UL_GPR1_ENET1_TX_CLK_DIR |IMX6UL_GPR1_ENET1_CLK_SEL ; -static const char * enet2_ref_sels[] = {"enet2_ref_125m" ,"enet2_ref_pad" , }; +static const char * enet2_ref_sels[] = {"enet2_ref_125m" ,"enet2_ref_pad" ,"dummy" ,"dummy" };static const u32 enet2_ref_sels_table[] = {IMX6UL_GPR1_ENET2_TX_CLK_DIR , -IMX6UL_GPR1_ENET2_CLK_SEL }; +IMX6UL_GPR1_ENET2_CLK_SEL ,0 , +IMX6UL_GPR1_ENET2_TX_CLK_DIR |IMX6UL_GPR1_ENET2_CLK_SEL };static const u32 enet2_ref_sels_table_mask =IMX6UL_GPR1_ENET2_TX_CLK_DIR |IMX6UL_GPR1_ENET2_CLK_SEL ;
Greg Kroah-Hartman
maintainerPATCH 663/798 fsdax: unshare: zero destination if srcmap is HOLE or UNWRITTEN
In reply to Greg Kroah-Hartman6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shiyang Ruan <[email protected]>
commit 13dd4e04625f600e5affb1b3f0b6c35268ab839b upstream.
unshare copies data from source to destination. But if the source is HOLE or UNWRITTEN extents, we should zero the destination, otherwise the HOLE or UNWRITTEN part will be user-visible old data of the new allocated extent.
Found by running generic/649 while mounting with -o dax=always on pmem.
--- fs/dax.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
fs/dax.c +8 -3
@@ -1234,15 +1234,20 @@ static s64 dax_unshare_iter(struct iomap/* don't bother with blocks that are not shared to start with */ if (!(iomap->flags &IOMAP_F_SHARED ))return length; -/* don't bother with holes or unwritten extents */ -if (srcmap->type ==IOMAP_HOLE || srcmap->type ==IOMAP_UNWRITTEN ) -return length; id =dax_read_lock (); ret =dax_iomap_direct_access (iomap, pos, length, &daddr,NULL );if (ret <0 ) goto out_unlock; +/* zero the distance if srcmap is HOLE or UNWRITTEN */ +if (srcmap->flags &IOMAP_F_SHARED || srcmap->type ==IOMAP_UNWRITTEN ) { +memset (daddr,0 , length); +dax_flush (iomap->dax_dev, daddr, length); + ret = length; + goto out_unlock; + } + ret =dax_iomap_direct_access (srcmap, pos, length, &saddr,NULL );if (ret <0 ) goto out_unlock;