6.11.3-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainerPATCH 367/558 perf/core: Fix small negative period being ignored
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luo Gengkun <[email protected]>
commit 62c0b1061593d7012292f781f11145b2d46f43ab upstream.
In perf_adjust_period, we will first calculate period, and then use this period to calculate delta. However, when delta is less than 0, there will be a deviation compared to when delta is greater than or equal to 0. For example, when delta is in the range of [-14,-1], the range of delta = delta + 7 is between [-7,6], so the final value of delta/8 is 0. Therefore, the impact of -1 and -2 will be ignored. This is unacceptable when the target period is very short, because we will lose a lot of samples.
Here are some tests and analyzes:
before:
# perf record -e cs -F 1000 ./a.out [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.022 MB perf.data (518 samples) ]
# perf script ... a.out 396 257.956048: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.957891: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.959730: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.961545: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.963355: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.965163: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.966973: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.968785: 23 cs: ffffffff81f4eeec schedul> a.out 396 257.970593: 23 cs: ffffffff81f4eeec schedul> ...
after:
# perf record -e cs -F 1000 ./a.out [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.058 MB perf.data (1466 samples) ]
# perf script ... a.out 395 59.338813: 11 cs: ffffffff81f4eeec schedul> a.out 395 59.339707: 12 cs: ffffffff81f4eeec schedul> a.out 395 59.340682: 13 cs: ffffffff81f4eeec schedul> a.out 395 59.341751: 13 cs: ffffffff81f4eeec schedul> a.out 395 59.342799: 12 cs: ffffffff81f4eeec schedul> a.out 395 59.343765: 11 cs: ffffffff81f4eeec schedul> a.out 395 59.344651: 11 cs: ffffffff81f4eeec schedul> a.out 395 59.345539: 12 cs: ffffffff81f4eeec schedul> a.out 395 59.346502: 13 cs: ffffffff81f4eeec schedul> ...
test.c
int main() {
for (int i = 0; i < 20000; i++)
usleep(10);
return 0;
}# time ./a.out real 0m1.583s user 0m0.040s sys 0m0.298s
The above results were tested on x86-64 qemu with KVM enabled using test.c as test program. Ideally, we should have around 1500 samples, but the previous algorithm had only about 500, whereas the modified algorithm now has about 1400. Further more, the new version shows 1 sample per 0.001s, while the previous one is 1 sample per 0.002s.This indicates that the new algorithm is more sensitive to small negative values compared to old algorithm.
--- kernel/events/core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/events/core.c +5 -1
@@ -4097,7 +4097,11 @@ static void perf_adjust_period(struct pe period =perf_calculate_period (event, nsec, count); delta = (s64)(period - hwc->sample_period); - delta = (delta +7 ) /8 ;/* low pass filter */ +if (delta >=0 ) + delta +=7 ; +else + delta -=7 ; + delta /=8 ;/* low pass filter */ sample_period = hwc->sample_period + delta;
Greg Kroah-Hartman
maintainerPATCH 368/558 drm/v3d: Prevent out of bounds access in performance query extensions
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tvrtko Ursulin <[email protected]>
commit f32b5128d2c440368b5bf3a7a356823e235caabb upstream.
Check that the number of perfmons userspace is passing in the copy and reset extensions is not greater than the internal kernel storage where the ids will be copied into.
--- drivers/gpu/drm/v3d/v3d_submit.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/v3d/v3d_submit.c +6 -0
@@ -671,6 +671,9 @@ v3d_get_cpu_reset_performance_params(strif (reset.nperfmons >V3D_MAX_PERFMONS )return -EINVAL ; +if (reset.nperfmons >V3D_MAX_PERFMONS ) +return -EINVAL ; + job->job_type =V3D_CPU_JOB_TYPE_RESET_PERFORMANCE_QUERY ; job->performance_query.queries = kvmalloc_array(reset.count,
@@ -753,6 +756,9 @@ v3d_get_cpu_copy_performance_query_paramreturn -EINVAL ;if (copy.nperfmons >V3D_MAX_PERFMONS ) +return -EINVAL ; + +if (copy.nperfmons >V3D_MAX_PERFMONS )return -EINVAL ; job->job_type =V3D_CPU_JOB_TYPE_COPY_PERFORMANCE_QUERY ;
Greg Kroah-Hartman
maintainerPATCH 369/558 parisc: Fix itlb miss handler for 64-bit programs
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 9542130937e9dc707dd7c6b7af73326437da2d50 upstream.
For an itlb miss when executing code above 4 Gb on ILP64 adjust the iasq/iaoq in the same way isr/ior was adjusted. This fixes signal delivery for the 64-bit static test program from
http://ftp.parisc-linux.org/src/64bit.tar.gz. Note that signals are handled by the signal trampoline code in the 64-bit VDSO which is mapped into high userspace memory region above 4GB for 64-bit processes.
--- arch/parisc/kernel/entry.S | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
arch/parisc/kernel/entry.S +2 -4
@@ -1051,8 +1051,7 @@ ENTRY_CFI(intr_save) /* for os_hpmc */ STREG %r16, PT_ISR(%r29) STREG %r17, PT_IOR(%r29) -#if 0 && defined(CONFIG_64BIT) - /* Revisit when we have 64-bit code above 4Gb */ +#if defined(CONFIG_64BIT) b,n intr_save2 skip_save_ior:
@@ -1060,8 +1059,7 @@ skip_save_ior: * need to adjust iasq/iaoq here in the same way we adjusted isr/ior * above. */ - extrd,u,* %r8,PSW_W_BIT,1,%r1 - cmpib,COND(=),n 1,%r1,intr_save2 + bb,COND(>=),n %r8,PSW_W_BIT,intr_save2 LDREG PT_IASQ0(%r29), %r16 LDREG PT_IAOQ0(%r29), %r17 /* adjust iasq/iaoq */
Greg Kroah-Hartman
maintainerPATCH 370/558 drm/mediatek: ovl_adaptor: Add missing of_node_put()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <[email protected]>
commit 5beb6fba25db235b52eab34bde8112f07bb31d75 upstream.
Error paths that exit for_each_child_of_node() need to call of_node_put() to decerement the child refcount and avoid memory leaks.
Add the missing of_node_put().
--- drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c +3 -1
@@ -523,8 +523,10 @@ static int ovl_adaptor_comp_init(struct } comp_pdev =of_find_device_by_node (node); -if (!comp_pdev) +if (!comp_pdev) { +of_node_put (node);return -EPROBE_DEFER ; + } priv->ovl_adaptor_comp[id] = &comp_pdev->dev;
Greg Kroah-Hartman
maintainerPATCH 371/558 drm: Consistently use struct drm_mode_rect for FB_DAMAGE_CLIPS
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
commit 8b0d2f61545545ab5eef923ed6e59fc3be2385e0 upstream.
FB_DAMAGE_CLIPS is a plane property for damage handling. Its UAPI should only use UAPI types. Hence replace struct drm_rect with struct drm_mode_rect in drm_atomic_plane_set_property(). Both types are identical in practice, so there's no change in behavior.
--- drivers/gpu/drm/drm_atomic_uapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/drm_atomic_uapi.c +1 -1
@@ -543,7 +543,7 @@ static int drm_atomic_plane_set_property &state->fb_damage_clips, val,-1 , -sizeof (struct drm_rect ), +sizeof (struct drm_mode_rect ), &replaced);return ret; }else if (property == plane->scaling_filter_property) {
Greg Kroah-Hartman
maintainerPATCH 372/558 ALSA: hda/tas2781: Add new quirk for Lenovo Y990 Laptop
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baojun Xu <[email protected]>
commit 49f5ee951f11f4d6a124f00f71b2590507811a55 upstream.
Add new vendor_id and subsystem_id in quirk for Lenovo Y990 Laptop.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -10892,6 +10892,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x17aa ,0x38cd ,"Y790 VECO DUAL" ,ALC287_FIXUP_TAS2781_I2C ),SND_PCI_QUIRK (0x17aa ,0x38d2 ,"Lenovo Yoga 9 14IMH9" ,ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN ),SND_PCI_QUIRK (0x17aa ,0x38d7 ,"Lenovo Yoga 9 14IMH9" ,ALC287_FIXUP_YOGA9_14IMH9_BASS_SPK_PIN ), +SND_PCI_QUIRK (0x17aa ,0x38df ,"Y990 YG DUAL" ,ALC287_FIXUP_TAS2781_I2C ),SND_PCI_QUIRK (0x17aa ,0x38f9 ,"Thinkbook 16P Gen5" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x17aa ,0x38fa ,"Thinkbook 16P Gen5" ,ALC287_FIXUP_CS35L41_I2C_2 ), SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Greg Kroah-Hartman
maintainerPATCH 373/558 ALSA: core: add isascii() check to card ID generator
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaroslav Kysela <[email protected]>
commit d278a9de5e1837edbe57b2f1f95a104ff6c84846 upstream.
The card identifier should contain only safe ASCII characters. The isalnum() returns true also for characters for non-ASCII characters.
--- sound/core/init.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
sound/core/init.c +10 -4
@@ -654,13 +654,19 @@ void snd_card_free(struct snd_card *card }EXPORT_SYMBOL (snd_card_free); +/* check, if the character is in the valid ASCII range */ +static inline bool safe_ascii_char (char c) +{ +return isascii (c) &&isalnum (c); +} +/* retrieve the last word of shortname or longname */ static const char *retrieve_id_from_card_name (const char *name) {const char *spos = name;while (*name) { -if (isspace (*name) &&isalnum (name[1 ])) +if (isspace (*name) &&safe_ascii_char (name[1 ])) spos = name +1 ; name++; }
@@ -687,12 +693,12 @@ static void copy_valid_id_string(struct {char *id = card->id; -while (*nid && !isalnum (*nid)) +while (*nid && !safe_ascii_char (*nid)) nid++;if (isdigit (*nid)) *id++ =isalpha (*src) ? *src :'D' ;while (*nid && (size_t )(id - card->id) <sizeof (card->id) -1 ) { -if (isalnum (*nid)) +if (safe_ascii_char (*nid)) *id++ = *nid; nid++; }
@@ -787,7 +793,7 @@ static ssize_t id_store(struct device *dfor (idx =0 ; idx < copy; idx++) { c = buf[idx]; -if (!isalnum (c) && c !='_' && c !='-' ) +if (!safe_ascii_char (c) && c !='_' && c !='-' )return -EINVAL ; }memcpy (buf1, buf, copy);
Greg Kroah-Hartman
maintainerPATCH 374/558 ALSA: usb-audio: Add delay quirk for VIVO USB-C HEADSET
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lianqin Hu <[email protected]>
commit 73385f3e0d8088b715ae8f3f66d533c482a376ab upstream.
Audio control requests that sets sampling frequency sometimes fail on this card. Adding delay between control messages eliminates that problem.
--- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
sound/usb/quirks.c +2 -0
@@ -2279,6 +2279,8 @@ static const struct usb_audio_quirk_flag QUIRK_FLAG_GENERIC_IMPLICIT_FB),DEVICE_FLG (0x2b53 ,0x0031 ,/* Fiero SC-01 (firmware v1.1.0) */ QUIRK_FLAG_GENERIC_IMPLICIT_FB ), +DEVICE_FLG (0x2d95 ,0x8011 ,/* VIVO USB-C HEADSET */ +QUIRK_FLAG_CTL_MSG_DELAY_1M ),DEVICE_FLG (0x2d95 ,0x8021 ,/* VIVO USB-C-XE710 HEADSET */ QUIRK_FLAG_CTL_MSG_DELAY_1M ), DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */
Greg Kroah-Hartman
maintainerPATCH 375/558 ALSA: usb-audio: Add native DSD support for Luxman D-08u
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Lalinsky <[email protected]>
commit 6b0bde5d8d4078ca5feec72fd2d828f0e5cf115d upstream.
Add native DSD support for Luxman D-08u DAC, by adding the PID/VID 1852:5062. This makes DSD playback work, and also sound quality when playing PCM files is improved, crackling sounds are gone.
--- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
sound/usb/quirks.c +2 -0
@@ -2221,6 +2221,8 @@ static const struct usb_audio_quirk_flag QUIRK_FLAG_DISABLE_AUTOSUSPEND),DEVICE_FLG (0x17aa ,0x104d ,/* Lenovo ThinkStation P620 Internal Speaker + Front Headset */ QUIRK_FLAG_DISABLE_AUTOSUSPEND ), +DEVICE_FLG (0x1852 ,0x5062 ,/* Luxman D-08u */ +QUIRK_FLAG_ITF_USB_DSD_DAC |QUIRK_FLAG_CTL_MSG_DELAY ),DEVICE_FLG (0x1852 ,0x5065 ,/* Luxman DA-06 */ QUIRK_FLAG_ITF_USB_DSD_DAC |QUIRK_FLAG_CTL_MSG_DELAY ), DEVICE_FLG(0x1901, 0x0191, /* GE B850V3 CP2114 audio interface */
Greg Kroah-Hartman
maintainerPATCH 376/558 ALSA: line6: add hw monitor volume control to POD HD500X
In reply to Greg Kroah-Hartman6.11-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 377/558 ALSA: hda/realtek: fix mute/micmute LED for HP mt645 G8
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolai Afanasenkov <[email protected]>
commit cb2deca056d579fe008c8d0a4ceb04d2b368fe42 upstream.
The HP Elite mt645 G8 Mobile Thin Client uses an ALC236 codec and needs the ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF quirk to enable the mute and micmute LED functionality.
This patch adds the system ID of the HP Elite mt645 G8 to the alc269_fixup_tbl in patch_realtek.c to enable the required quirk.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -10529,6 +10529,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x8ca2 ,"HP ZBook Power" ,ALC236_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8ca4 ,"HP ZBook Fury" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x8ca7 ,"HP ZBook Fury" ,ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED ), +SND_PCI_QUIRK (0x103c ,0x8caf ,"HP Elite mt645 G8 Mobile Thin Client" ,ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF ),SND_PCI_QUIRK (0x103c ,0x8cbd ,"HP Pavilion Aero Laptop 13-bg0xxx" ,ALC245_FIXUP_HP_X360_MUTE_LEDS ),SND_PCI_QUIRK (0x103c ,0x8cdd ,"HP Spectre" ,ALC287_FIXUP_CS35L41_I2C_2 ), SND_PCI_QUIRK(0x103c, 0x8cde, "HP Spectre", ALC287_FIXUP_CS35L41_I2C_2),
Greg Kroah-Hartman
maintainerPATCH 378/558 ALSA: hda/realtek: Add quirk for Huawei MateBook 13 KLV-WX9
In reply to Greg Kroah-Hartman6.11-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
@@ -10930,6 +10930,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1854 ,0x048a ,"LG gram 17 (17ZD90R)" ,ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS ),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 379/558 ALSA: hda/realtek: Add a quirk for HP Pavilion 15z-ec200
In reply to Greg Kroah-Hartman6.11-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
@@ -10388,6 +10388,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 380/558 ext4: no need to continue when the number of entries is 1
In reply to Greg Kroah-Hartman6.11-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
@@ -2001,7 +2001,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 381/558 ext4: correct encrypted dentry name hash when not casefolded
In reply to Greg Kroah-Hartman6.11-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 382/558 ext4: fix slab-use-after-free in ext4_split_extent_at()
In reply to Greg Kroah-Hartman6.11-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
@@ -3230,6 +3230,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 ) {
@@ -3282,7 +3301,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 383/558 ext4: propagate errors from ext4_find_extent() in ext4_insert_range()
In reply to Greg Kroah-Hartman6.11-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
@@ -5553,6 +5553,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 384/558 ext4: fix incorrect tid assumption in ext4_fc_mark_ineligible()
In reply to Greg Kroah-Hartman6.11-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 385/558 ext4: dax: fix overflowing extents beyond inode size when partially writing
In reply to Greg Kroah-Hartman6.11-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
@@ -334,10 +334,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
@@ -586,7 +586,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:
@@ -670,7 +670,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 386/558 ext4: fix incorrect tid assumption in __jbd2_log_wait_for_space()
In reply to Greg Kroah-Hartman6.11-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
@@ -79,9 +79,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) {
@@ -89,7 +92,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 387/558 ext4: drop ppath from ext4_ext_replay_update_ex() to avoid double-free
In reply to Greg Kroah-Hartman6.11-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
@@ -5899,7 +5899,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;
@@ -5915,30 +5915,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 388/558 ext4: aovid use-after-free in ext4_ext_insert_extent()
In reply to Greg Kroah-Hartman6.11-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 389/558 ext4: fix double brelse() the buffer of the extents path
In reply to Greg Kroah-Hartman6.11-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 390/558 ext4: fix timer use-after-free on failed mount
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiaxi Shen <[email protected]>
commit 0ce160c5bdb67081a62293028dc85758a8efb22a upstream.
Syzbot has found an ODEBUG bug in ext4_fill_super
The del_timer_sync function cancels the s_err_report timer, which reminds about filesystem errors daily. We should guarantee the timer is no longer active before kfree(sbi).
When filesystem mounting fails, the flow goes to failed_mount3, where an error occurs when ext4_stop_mmpd is called, causing a read I/O failure. This triggers the ext4_handle_error function that ultimately re-arms the timer,
leaving the s_err_report timer active before kfree(sbi) is called.
Fix the issue by canceling the s_err_report timer after calling ext4_stop_mmpd.
--- fs/ext4/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/super.c +1 -1
@@ -5635,8 +5635,8 @@ failed_mount3a: failed_mount3:/* flush s_sb_upd_work before sbi destroy */ flush_work (&sbi->s_sb_upd_work); -del_timer_sync (&sbi->s_err_report);ext4_stop_mmpd (sbi); +del_timer_sync (&sbi->s_err_report);ext4_group_desc_free (sbi); failed_mount:if (sbi->s_chksum_driver)
Greg Kroah-Hartman
maintainerPATCH 391/558 ext4: fix access to uninitialised lock in fc replay path
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
commit 23dfdb56581ad92a9967bcd720c8c23356af74c1 upstream.
The following kernel trace can be triggered with fstest generic/629 when executed against a filesystem with fast-commit feature enabled:
INFO: trying to register non-static key.
The code is fine but needs lockdep annotation, or maybe you didn't initialize this object before use? turning off the locking correctness validator.
CPU: 0 PID: 866 Comm: mount Not tainted 6.10.0+ #11 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-3-gd478f380-prebuilt.qemu.org 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x66/0x90 register_lock_class+0x759/0x7d0 __lock_acquire+0x85/0x2630 ? __find_get_block+0xb4/0x380 lock_acquire+0xd1/0x2d0 ? __ext4_journal_get_write_access+0xd5/0x160 _raw_spin_lock+0x33/0x40 ? __ext4_journal_get_write_access+0xd5/0x160 __ext4_journal_get_write_access+0xd5/0x160 ext4_reserve_inode_write+0x61/0xb0 __ext4_mark_inode_dirty+0x79/0x270 ? ext4_ext_replay_set_iblocks+0x2f8/0x450 ext4_ext_replay_set_iblocks+0x330/0x450 ext4_fc_replay+0x14c8/0x1540 ? jread+0x88/0x2e0 ? rcu_is_watching+0x11/0x40 do_one_pass+0x447/0xd00 jbd2_journal_recover+0x139/0x1b0 jbd2_journal_load+0x96/0x390 ext4_load_and_init_journal+0x253/0xd40 ext4_fill_super+0x2cc6/0x3180
...
In the replay path there's an attempt to lock sbi->s_bdev_wb_lock in function ext4_check_bdev_write_error(). Unfortunately, at this point this spinlock has not been initialized yet. Moving it's initialization to an earlier point in __ext4_fill_super() fixes this splat.
--- fs/ext4/super.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ext4/super.c +2 -1
@@ -5334,6 +5334,8 @@ static int __ext4_fill_super(struct fs_cINIT_LIST_HEAD (&sbi->s_orphan);/* unlinked but open files */ mutex_init (&sbi->s_orphan_lock); +spin_lock_init (&sbi->s_bdev_wb_lock); +ext4_fast_commit_init (sb); sb->s_root =NULL ;
@@ -5555,7 +5557,6 @@ static int __ext4_fill_super(struct fs_c* Save the original bdev mapping's wb_err value which could be * used to detect the metadata async write error. */ -spin_lock_init (&sbi->s_bdev_wb_lock);errseq_check_and_advance (&sb->s_bdev->bd_mapping->wb_err, &sbi->s_bdev_wb_err);EXT4_SB (sb)->s_mount_state |=EXT4_ORPHAN_FS ;
Greg Kroah-Hartman
maintainerPATCH 392/558 ext4: update orig_path in ext4_find_extent()
In reply to Greg Kroah-Hartman6.11-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:
@@ -3249,7 +3251,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 393/558 ext4: fix incorrect tid assumption in ext4_wait_for_tail_page_commit()
In reply to Greg Kroah-Hartman6.11-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
@@ -5279,8 +5279,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 );/*
@@ -5305,12 +5306,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 394/558 ext4: fix incorrect tid assumption in jbd2_journal_shrink_checkpoint_list()
In reply to Greg Kroah-Hartman6.11-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
@@ -410,6 +410,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);
@@ -429,8 +430,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;
@@ -460,7 +463,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 395/558 ext4: fix fast commit inode enqueueing during a full journal commit
In reply to Greg Kroah-Hartman6.11-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
@@ -1295,8 +1295,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
@@ -740,9 +740,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 396/558 ext4: use handle to mark fc as ineligible in __track_dentry_update()
In reply to Greg Kroah-Hartman6.11-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 397/558 ext4: mark fc as ineligible using an handle in ext4_xattr_set()
In reply to Greg Kroah-Hartman6.11-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
@@ -2559,6 +2559,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))
@@ -2566,7 +2568,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 398/558 ext4: fix off by one issue in alloc_flex_gd()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 6121258c2b33ceac3d21f6a221452692c465df88 upstream.
Wesley reported an issue:
==================================================================
EXT4-fs (dm-5): resizing filesystem from 7168 to 786432 blocks
------------[ cut here ]------------ kernel BUG at fs/ext4/resize.c:324! CPU: 9 UID: 0 PID: 3576 Comm: resize2fs Not tainted 6.11.0+ #27 RIP: 0010:ext4_resize_fs+0x1212/0x12d0 Call Trace: __ext4_ioctl+0x4e0/0x1800 ext4_ioctl+0x12/0x20 __x64_sys_ioctl+0x99/0xd0 x64_sys_call+0x1206/0x20d0 do_syscall_64+0x72/0x110 entry_SYSCALL_64_after_hwframe+0x76/0x7e ==================================================================
While reviewing the patch, Honza found that when adjusting resize_bg in alloc_flex_gd(), it was possible for flex_gd->resize_bg to be bigger than flexbg_size.
The reproduction of the problem requires the following:
o_group = flexbg_size * 2 * n;
o_size = (o_group + 1) * group_size;
n_group: [o_group + flexbg_size, o_group + flexbg_size * 2) o_size = (n_group + 1) * group_size;
Take n=0,flexbg_size=16 as an example:
last:15 |o---------------|--------------n-| o_group:0 resize to n_group:30
The corresponding reproducer is:
img=test.img
rm -f $img
truncate -s 600M $img
mkfs.ext4 -F $img -b 1024 -G 16 8M
dev=losetup -f --show $img
mkdir -p /tmp/test
mount $dev /tmp/test
resize2fs $dev 248M
Delete the problematic plus 1 to fix the issue, and add a WARN_ON_ONCE() to prevent the issue from happening again.
[ Note: another reproucer which this commit fixes is:
img=test.img rm -f $img truncate -s 25MiB $img mkfs.ext4 -b 4096 -E nodiscard,lazy_itable_init=0,lazy_journal_init=0 $img truncate -s 3GiB $img dev=`losetup -f --show $img` mkdir -p /tmp/test mount $dev /tmp/test resize2fs $dev 3G umount $dev losetup -d $dev
-- TYT ]
--- fs/ext4/resize.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
fs/ext4/resize.c +10 -8
@@ -230,8 +230,8 @@ struct ext4_new_flex_group_data {#define MAX_RESIZE_BG 16384/* -* alloc_flex_gd() allocates a ext4_new_flex_group_data with size of -* @flexbg_size. +* alloc_flex_gd() allocates an ext4_new_flex_group_data that satisfies the +* resizing from @o_group to @n_group, its size is typically @flexbg_size. * * Returns NULL on failure otherwise address of the allocated structure. */
@@ -239,25 +239,27 @@ static struct ext4_new_flex_group_data * ext4_group_t o_group, ext4_group_t n_group) {ext4_group_t last_group; +unsigned int max_resize_bg;struct ext4_new_flex_group_data *flex_gd; flex_gd =kmalloc (sizeof (*flex_gd),GFP_NOFS );if (flex_gd ==NULL ) goto out3; -if (unlikely (flexbg_size >MAX_RESIZE_BG )) - flex_gd->resize_bg =MAX_RESIZE_BG ; -else - flex_gd->resize_bg = flexbg_size; + max_resize_bg =umin (flexbg_size,MAX_RESIZE_BG ); + flex_gd->resize_bg = max_resize_bg;/* Avoid allocating large 'groups' array if not needed */ last_group = o_group | (flex_gd->resize_bg -1 );if (n_group <= last_group) - flex_gd->resize_bg =1 <<fls (n_group - o_group +1 ); + flex_gd->resize_bg =1 <<fls (n_group - o_group);else if (n_group - last_group < flex_gd->resize_bg) - flex_gd->resize_bg =1 <<max (fls (last_group - o_group +1 ), + flex_gd->resize_bg =1 <<max (fls (last_group - o_group),fls (n_group - last_group)); +if (WARN_ON_ONCE (flex_gd->resize_bg > max_resize_bg)) + flex_gd->resize_bg = max_resize_bg; + flex_gd->groups =kmalloc_array (flex_gd->resize_bg,sizeof (struct ext4_new_group_data ),GFP_NOFS );
Greg Kroah-Hartman
maintainerPATCH 399/558 drm/xe: Generate oob before compiling anything
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas De Marchi <[email protected]>
commit ea74bf9ccba9ae80fc0766c07c4abaef927e9e63 upstream.
Instead of keep adding more dependencies as WAs are needed in different places of the driver, just add a rule with all the objects so the code generation happens before anything else.
While at it, group lines related to wa_oob in the Makefile.
v2: Prefix $(obj) when declaring dependency
--- drivers/gpu/drm/xe/Makefile | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-)
drivers/gpu/drm/xe/Makefile +4 -20
@@ -12,34 +12,15 @@ subdir-ccflags-$(CONFIG_DRM_XE_WERROR) + subdir-ccflags-y += -I$(obj) -I$(src) # generated sources -hostprogs := xe_gen_wa_oob +hostprogs := xe_gen_wa_oob generated_oob := $(obj)/generated/xe_wa_oob.c $(obj)/generated/xe_wa_oob.h - quiet_cmd_wa_oob = GEN $(notdir $(generated_oob)) cmd_wa_oob = mkdir -p $(@D); $^ $(generated_oob) - $(obj)/generated/%_wa_oob.c $(obj)/generated/%_wa_oob.h: $(obj)/xe_gen_wa_oob \ $(src)/xe_wa_oob.rules $(call cmd,wa_oob) -uses_generated_oob := \ - $(obj)/xe_ggtt.o \ - $(obj)/xe_device.o \ - $(obj)/xe_gsc.o \ - $(obj)/xe_gt.o \ - $(obj)/xe_guc.o \ - $(obj)/xe_guc_ads.o \ - $(obj)/xe_guc_pc.o \ - $(obj)/xe_migrate.o \ - $(obj)/xe_pat.o \ - $(obj)/xe_ring_ops.o \ - $(obj)/xe_vm.o \ - $(obj)/xe_wa.o \ - $(obj)/xe_ttm_stolen_mgr.o - -$(uses_generated_oob): $(generated_oob) - # Please keep these build lists sorted! # core driver code
@@ -322,3 +303,6 @@ quiet_cmd_hdrtest = HDRTEST $(patsubst % $(obj)/%.hdrtest: $(src)/%.h FORCE $(call if_changed_dep,hdrtest) + +uses_generated_oob := $(addprefix $(obj)/, $(xe-y)) +$(uses_generated_oob): $(obj)/generated/xe_wa_oob.h
Greg Kroah-Hartman
maintainerPATCH 400/558 parisc: Fix 64-bit userspace syscall path
In reply to Greg Kroah-Hartman6.11-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
@@ -243,10 +243,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
@@ -379,10 +379,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
@@ -1327,6 +1327,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 401/558 parisc: Allow mmap(MAP_STACK) memory to automatically expand upwards
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
commit 5d698966fa7b452035c44c937d704910bf3440dd upstream.
When userspace allocates memory with mmap() in order to be used for stack, allow this memory region to automatically expand upwards up until the current maximum process stack size.
The fault handler checks if the VM_GROWSUP bit is set in the vm_flags field of a memory area before it allows it to expand.
This patch modifies the parisc specific code only.
A RFC for a generic patch to modify mmap() for all architectures was sent to the mailing list but did not get enough Acks.
--- arch/parisc/include/asm/mman.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
arch/parisc/include/asm/mman.h +14 -0
@@ -11,4 +11,18 @@ static inline bool arch_memory_deny_writ }#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported +static inline unsigned long arch_calc_vm_flag_bits (unsigned long flags) +{ +/* +* The stack on parisc grows upwards, so if userspace requests memory +* for a stack, mark it with VM_GROWSUP so that the stack expansion in +* the fault handler will work. +*/ +if (flags &MAP_STACK ) +return VM_GROWSUP ; + +return 0 ; +} +#define arch_calc_vm_flag_bits (flags) arch_calc_vm_flag_bits(flags) +#endif /* __ASM_MMAN_H__ */
Greg Kroah-Hartman
maintainerPATCH 402/558 parisc: Fix stack start for ADDR_NO_RANDOMIZE personality
In reply to Greg Kroah-Hartman6.11-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
@@ -811,7 +811,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 403/558 drm/rockchip: vop: clear DMA stop bit on RK3066
In reply to Greg Kroah-Hartman6.11-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
@@ -1583,6 +1583,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
@@ -122,6 +122,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
@@ -466,6 +466,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 404/558 of: address: Report error on resource bounds overflow
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
commit 000f6d588a8f3d128f89351058dc04d38e54a327 upstream.
The members "start" and "end" of struct resource are of type "resource_size_t" which can be 32bit wide.
Values read from OF however are always 64bit wide.
Avoid silently truncating the value and instead return an error value.
This can happen on real systems when the DT was created for a PAE-enabled kernel and a non-PAE kernel is actually running. For example with an arm defconfig and "qemu-system-arm -M virt".
--- drivers/of/address.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/of/address.c +5 -0
@@ -8,6 +8,7 @@#include <linux/logic_pio.h> #include <linux/module.h> #include <linux/of_address.h> +#include <linux/overflow.h> #include <linux/pci.h> #include <linux/pci_regs.h> #include <linux/sizes.h>
@@ -1061,7 +1062,11 @@ static int __of_address_to_resource(struif (of_mmio_is_nonposted (dev)) flags |=IORESOURCE_MEM_NONPOSTED ; +if (overflows_type (taddr, r->start)) +return -EOVERFLOW ; r->start = taddr; +if (overflows_type (taddr + size -1 , r->end)) +return -EOVERFLOW ; r->end = taddr + size -1 ; r->flags = flags; r->name = name ? name : dev->full_name;
Greg Kroah-Hartman
maintainerPATCH 405/558 of/irq: Support #msi-cells=<0> in of_msi_get_domain
In reply to Greg Kroah-Hartman6.11-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
@@ -716,8 +716,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). */
@@ -725,33 +724,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 406/558 drm: omapdrm: Add missing check for alloc_ordered_workqueue
In reply to Greg Kroah-Hartman6.11-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
@@ -695,6 +695,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);
@@ -753,6 +757,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 407/558 resource: fix region_intersects() vs add_memory_driver_managed()
In reply to Greg Kroah-Hartman6.11-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
@@ -540,20 +540,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 408/558 lib/buildid: harden build ID parsing logic
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrii Nakryiko <[email protected]>
commit 905415ff3ffb1d7e5afa62bacabd79776bd24606 upstream.
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 cconst 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 *p {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 *p*/ 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 *p {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 *p*/ 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 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_local_page (page);
Greg Kroah-Hartman
maintainerPATCH 409/558 jbd2: stop waiting for space when jbd2_cleanup_journal_tail() returns error
In reply to Greg Kroah-Hartman6.11-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
@@ -89,8 +89,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 410/558 jbd2: correctly compare tids with tid_geq function in jbd2_fc_begin_commit
In reply to Greg Kroah-Hartman6.11-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
@@ -710,7 +710,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 411/558 mm: krealloc: consider spare memory for __GFP_ZERO
In reply to Greg Kroah-Hartman6.11-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
@@ -1273,6 +1273,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 412/558 ocfs2: fix the la space leak when unmounting an ocfs2 volume
In reply to Greg Kroah-Hartman6.11-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
@@ -1002,6 +1002,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 413/558 ocfs2: fix uninit-value in ocfs2_get_block()
In reply to Greg Kroah-Hartman6.11-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 414/558 ocfs2: reserve space for inline xattr before attaching reflink tree
In reply to Greg Kroah-Hartman6.11-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>
@@ -4155,8 +4156,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;
@@ -4182,6 +4184,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) {
@@ -4189,7 +4211,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
@@ -6520,16 +6520,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 415/558 ocfs2: cancel dqi_sync_work before freeing oinfo
In reply to Greg Kroah-Hartman6.11-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
@@ -692,7 +692,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 ;
@@ -700,6 +700,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;
@@ -712,6 +713,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 ) {
@@ -782,10 +784,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 416/558 ocfs2: remove unreasonable unlock in ocfs2_read_blocks
In reply to Greg Kroah-Hartman6.11-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 417/558 ocfs2: fix null-ptr-deref when journal load failed.
In reply to Greg Kroah-Hartman6.11-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
@@ -1055,7 +1055,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*
@@ -1074,9 +1074,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 418/558 ocfs2: fix possible null-ptr-deref in ocfs2_set_buffer_uptodate
In reply to Greg Kroah-Hartman6.11-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 419/558 scripts/gdb: fix timerlist parsing issue
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuan-Ying Lee <[email protected]>
commit a633a4b8001a7f2a12584f267a3280990d9ababa upstream.
Patch series "Fix some GDB command error and add some GDB commands", v3.
Fix some GDB command errors and add some useful GDB commands.
This patch (of 5):
Commit 7988e5ae2be7 ("tick: Split nohz and highres features from nohz_mode") and commit 7988e5ae2be7 ("tick: Split nohz and highres features from nohz_mode") move 'tick_stopped' and 'nohz_mode' to flags field which will break the gdb lx-mounts command:
(gdb) lx-timerlist
Python Exception <class 'gdb.error'>: There is no member named nohz_mode. Error occurred in Python: There is no member named nohz_mode.
(gdb) lx-timerlist
Python Exception <class 'gdb.error'>: There is no member named tick_stopped. Error occurred in Python: There is no member named tick_stopped.
We move 'tick_stopped' and 'nohz_mode' to flags field instead.
--- scripts/gdb/linux/timerlist.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-)
scripts/gdb/linux/timerlist.py +16 -15
@@ -87,21 +87,22 @@ def print_cpu(hrtimer_bases, cpu, max_cl text += "\n" if constants.LX_CONFIG_TICK_ONESHOT: - fmts = [(" .{} : {}", 'nohz_mode'), - (" .{} : {} nsecs", 'last_tick'), - (" .{} : {}", 'tick_stopped'), - (" .{} : {}", 'idle_jiffies'), - (" .{} : {}", 'idle_calls'), - (" .{} : {}", 'idle_sleeps'), - (" .{} : {} nsecs", 'idle_entrytime'), - (" .{} : {} nsecs", 'idle_waketime'), - (" .{} : {} nsecs", 'idle_exittime'), - (" .{} : {} nsecs", 'idle_sleeptime'), - (" .{}: {} nsecs", 'iowait_sleeptime'), - (" .{} : {}", 'last_jiffies'), - (" .{} : {}", 'next_timer'), - (" .{} : {} nsecs", 'idle_expires')] - text += "\n".join([s.format(f, ts[f]) for s, f in fmts]) + TS_FLAG_STOPPED = 1 << 1 + TS_FLAG_NOHZ = 1 << 4 + text += f" .{'nohz':15s}: {int(bool(ts['flags'] & TS_FLAG_NOHZ))}\n" + text += f" .{'last_tick':15s}: {ts['last_tick']}\n" + text += f" .{'tick_stopped':15s}: {int(bool(ts['flags'] & TS_FLAG_STOPPED))}\n" + text += f" .{'idle_jiffies':15s}: {ts['idle_jiffies']}\n" + text += f" .{'idle_calls':15s}: {ts['idle_calls']}\n" + text += f" .{'idle_sleeps':15s}: {ts['idle_sleeps']}\n" + text += f" .{'idle_entrytime':15s}: {ts['idle_entrytime']} nsecs\n" + text += f" .{'idle_waketime':15s}: {ts['idle_waketime']} nsecs\n" + text += f" .{'idle_exittime':15s}: {ts['idle_exittime']} nsecs\n" + text += f" .{'idle_sleeptime':15s}: {ts['idle_sleeptime']} nsecs\n" + text += f" .{'iowait_sleeptime':15s}: {ts['iowait_sleeptime']} nsecs\n" + text += f" .{'last_jiffies':15s}: {ts['last_jiffies']}\n" + text += f" .{'next_timer':15s}: {ts['next_timer']}\n" + text += f" .{'idle_expires':15s}: {ts['idle_expires']} nsecs\n" text += "\njiffies: {}\n".format(jiffies) text += "\n"
Greg Kroah-Hartman
maintainerPATCH 420/558 scripts/gdb: add iteration function for rbtree
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuan-Ying Lee <[email protected]>
commit 0c77e103c45fa1b119f5d3bb4625eee081c1a6cf upstream.
Add inorder iteration function for rbtree usage.
This is a preparation patch for the next patch to fix the gdb mounts issue.
--- scripts/gdb/linux/rbtree.py | 12 ++++++++++++ 1 file changed, 12 insertions(+)
scripts/gdb/linux/rbtree.py +12 -0
@@ -9,6 +9,18 @@ from linux import utils rb_root_type = utils.CachedType("struct rb_root") rb_node_type = utils.CachedType("struct rb_node") +def rb_inorder_for_each(root): + def inorder(node): + if node: + yield from inorder(node['rb_left']) + yield node + yield from inorder(node['rb_right']) + + yield from inorder(root['rb_node']) + +def rb_inorder_for_each_entry(root, gdbtype, member): + for node in rb_inorder_for_each(root): + yield utils.container_of(node, gdbtype, member) def rb_first(root): if root.type == rb_root_type.get_type():
Greg Kroah-Hartman
maintainerPATCH 421/558 scripts/gdb: fix lx-mounts command error
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuan-Ying Lee <[email protected]>
commit 4b183f613924ad536be2f8bd12b307e9c5a96bf6 upstream.
(gdb) lx-mounts
mount super_block devname pathname fstype options
Python Exception <class 'gdb.error'>: There is no member named list. Error occurred in Python: There is no member named list.
We encounter the above issue after commit 2eea9ce4310d ("mounts: keep list of mounts in an rbtree"). The commit move a mount from list into rbtree.
So we can instead use rbtree to iterate all mounts information.
--- scripts/gdb/linux/proc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
scripts/gdb/linux/proc.py +2 -2
@@ -18,6 +18,7 @@ from linux import utils from linux import tasks from linux import lists from linux import vfs +from linux import rbtree from struct import *
@@ -172,8 +173,7 @@ values of that process namespace""" gdb.write("{:^18} {:^15} {:>9} {} {} options\n".format( "mount", "super_block", "devname", "pathname", "fstype")) - for mnt in lists.list_for_each_entry(namespace['list'], - mount_ptr_type, "mnt_list"): + for mnt in rbtree.rb_inorder_for_each_entry(namespace['mounts'], mount_ptr_type, "mnt_node"): devname = mnt['mnt_devname'].string() devname = devname if devname else "none"
Greg Kroah-Hartman
maintainerPATCH 422/558 arm64: fix selection of HAVE_DYNAMIC_FTRACE_WITH_ARGS
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
commit b3d6121eaeb22aee8a02f46706745b1968cc0292 upstream.
The Kconfig logic to select HAVE_DYNAMIC_FTRACE_WITH_ARGS is incorrect, and HAVE_DYNAMIC_FTRACE_WITH_ARGS may be selected when it is not supported by the combination of clang and GNU LD, resulting in link-time errors:
aarch64-linux-gnu-ld: .init.data has both ordered [__patchable_function_entries' in init/main.o] and unordered [.meminit.data' in mm/sparse.o] sections
aarch64-linux-gnu-ld: final link failed: bad value
... which can be seen when building with CC=clang using a binutils version older than 2.36.
We originally fixed that in commit:
45bd8951806eb5e8 ("arm64: Improve HAVE_DYNAMIC_FTRACE_WITH_REGS selection for clang")
... by splitting the "select HAVE_DYNAMIC_FTRACE_WITH_ARGS" statement into separete CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS and GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS options which individually select HAVE_DYNAMIC_FTRACE_WITH_ARGS.
Subsequently we accidentally re-introduced the common "select HAVE_DYNAMIC_FTRACE_WITH_ARGS" statement in commit:
26299b3f6ba26bfc ("ftrace: arm64: move from REGS to ARGS")
... then we removed it again in commit:
68a63a412d18bd2e ("arm64: Fix build with CC=clang, CONFIG_FTRACE=y and CONFIG_STACK_TRACER=y")
... then we accidentally re-introduced it again in commit:
2aa6ac03516d078c ("arm64: ftrace: Add direct call support")
Fix this for the third time by keeping the unified select statement and making this depend onf either GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS or CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS. This is more consistent with usual style and less likely to go wrong in future.
--- arch/arm64/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
arch/arm64/Kconfig +2 -3
@@ -196,7 +196,8 @@ config ARM64 select HAVE_DMA_CONTIGUOUS select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_ARGS \ - if $(cc-option,-fpatchable-function-entry=2) + if (GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS || \ + CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS) select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS \ if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \
@@ -269,12 +270,10 @@ config CLANG_SUPPORTS_DYNAMIC_FTRACE_WIT def_bool CC_IS_CLANG # https://github.com/ClangBuiltLinux/linux/issues/1507 depends on AS_IS_GNU || (AS_IS_LLVM && (LD_IS_LLD || LD_VERSION >= 23600)) - select HAVE_DYNAMIC_FTRACE_WITH_ARGS config GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS def_bool CC_IS_GCC depends on $(cc-option,-fpatchable-function-entry=2) - select HAVE_DYNAMIC_FTRACE_WITH_ARGS config 64BIT def_bool y
Greg Kroah-Hartman
maintainerPATCH 423/558 arm64: Subscribe Microsoft Azure Cobalt 100 to erratum 3194386
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Easwar Hariharan <[email protected]>
commit 3eddb108abe3de6723cc4b77e8558ce1b3047987 upstream.
Add the Microsoft Azure Cobalt 100 CPU to the list of CPUs suffering from erratum 3194386 added in commit 75b3c43eab59 ("arm64: errata:
Expand speculative SSBS workaround")
--- Documentation/arch/arm64/silicon-errata.rst | 2 ++ arch/arm64/kernel/cpu_errata.c | 1 + 2 files changed, 3 insertions(+)
Documentation/arch/arm64/silicon-errata.rst +2 -0
@@ -289,3 +289,5 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Microsoft | Azure Cobalt 100| #2253138 | ARM64_ERRATUM_2253138 | +----------------+-----------------+-----------------+-----------------------------+ +| Microsoft | Azure Cobalt 100| #3324339 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+
arch/arm64/kernel/cpu_errata.c +1 -0
@@ -447,6 +447,7 @@ static const struct midr_range erratum_sMIDR_ALL_VERSIONS (MIDR_CORTEX_X3 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_X4 ),MIDR_ALL_VERSIONS (MIDR_CORTEX_X925 ), +MIDR_ALL_VERSIONS (MIDR_MICROSOFT_AZURE_COBALT_100 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N1 ),MIDR_ALL_VERSIONS (MIDR_NEOVERSE_N2 ), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
Greg Kroah-Hartman
maintainerPATCH 424/558 drm/xe: fix UAF around queue destruction
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Auld <[email protected]>
commit 2d2be279f1ca9e7288282d4214f16eea8a727cdb upstream.
We currently do stuff like queuing the final destruction step on a random system wq, which will outlive the driver instance. With bad timing we can teardown the driver with one or more work workqueue still being alive leading to various UAF splats. Add a fini step to ensure user queues are properly torn down. At this point GuC should already be nuked so queue itself should no longer be referenced from hw pov.
v2 (Matt B)
- Looks much safer to use a waitqueue and then just wait for the xa_array to become empty before triggering the drain.
--- drivers/gpu/drm/xe/xe_device.c | 6 +++++- drivers/gpu/drm/xe/xe_device_types.h | 3 +++ drivers/gpu/drm/xe/xe_guc_submit.c | 26 +++++++++++++++++++++++++- drivers/gpu/drm/xe/xe_guc_types.h | 2 ++ 4 files changed, 35 insertions(+), 2 deletions(-)
drivers/gpu/drm/xe/xe_device.c +5 -1
@@ -285,6 +285,9 @@ static void xe_device_destroy(struct drmif (xe->unordered_wq)destroy_workqueue (xe->unordered_wq); +if (xe->destroy_wq) +destroy_workqueue (xe->destroy_wq); +ttm_device_fini (&xe->ttm); }
@@ -350,8 +353,9 @@ struct xe_device *xe_device_create(struc xe->preempt_fence_wq =alloc_ordered_workqueue ("xe-preempt-fence-wq" ,0 ); xe->ordered_wq =alloc_ordered_workqueue ("xe-ordered-wq" ,0 ); xe->unordered_wq =alloc_workqueue ("xe-unordered-wq" ,0 ,0 ); + xe->destroy_wq =alloc_workqueue ("xe-destroy-wq" ,0 ,0 );if (!xe->ordered_wq || !xe->unordered_wq || - !xe->preempt_fence_wq) { + !xe->preempt_fence_wq || !xe->destroy_wq) {/* * Cleanup done in xe_device_destroy via * drmm_add_action_or_reset register above
drivers/gpu/drm/xe/xe_device_types.h +3 -0
@@ -392,6 +392,9 @@ struct xe_device {/** @unordered_wq: used to serialize unordered work, mostly display */ struct workqueue_struct *unordered_wq; +/** @destroy_wq: used to serialize user destroy work, like queue */ +struct workqueue_struct *destroy_wq; +/** @tiles: device tiles */ struct xe_tile tiles[XE_MAX_TILES_PER_DEVICE ];
drivers/gpu/drm/xe/xe_guc_submit.c +25 -1
@@ -276,10 +276,26 @@ static struct workqueue_struct *get_subm }#endif +static void xe_guc_submit_fini (struct xe_guc *guc) +{ +struct xe_device *xe =guc_to_xe (guc); +struct xe_gt *gt =guc_to_gt (guc); +int ret; + + ret =wait_event_timeout (guc->submission_state.fini_wq, +xa_empty (&guc->submission_state.exec_queue_lookup), +HZ *5 ); + +drain_workqueue (xe->destroy_wq); + +xe_gt_assert (gt, ret); +} +static void guc_submit_fini (struct drm_device *drm,void *arg) {struct xe_guc *guc = arg; +xe_guc_submit_fini (guc);xa_destroy (&guc->submission_state.exec_queue_lookup);free_submit_wq (guc); }
@@ -351,6 +367,8 @@ int xe_guc_submit_init(struct xe_guc *guxa_init (&guc->submission_state.exec_queue_lookup); +init_waitqueue_head (&guc->submission_state.fini_wq); +primelockdep (guc);return drmm_add_action_or_reset (&xe->drm, guc_submit_fini, guc);
@@ -367,6 +385,9 @@ static void __release_guc_id(struct xe_gxe_guc_id_mgr_release_locked (&guc->submission_state.idm, q->guc->id, q->width); + +if (xa_empty (&guc->submission_state.exec_queue_lookup)) +wake_up (&guc->submission_state.fini_wq); }static int alloc_guc_id (struct xe_guc *guc,struct xe_exec_queue *q)
@@ -1267,13 +1288,16 @@ static void __guc_exec_queue_fini_async(static void guc_exec_queue_fini_async (struct xe_exec_queue *q) { +struct xe_guc *guc =exec_queue_to_guc (q); +struct xe_device *xe =guc_to_xe (guc); +INIT_WORK (&q->guc->fini_async, __guc_exec_queue_fini_async);/* We must block on kernel engines so slabs are empty on driver unload */ if (q->flags &EXEC_QUEUE_FLAG_PERMANENT ||exec_queue_wedged (q))__guc_exec_queue_fini_async (&q->guc->fini_async);else -queue_work (system_wq, &q->guc->fini_async); +queue_work (xe->destroy_wq, &q->guc->fini_async); }static void __guc_exec_queue_fini (struct xe_guc *guc,struct xe_exec_queue *q)
drivers/gpu/drm/xe/xe_guc_types.h +2 -0
@@ -81,6 +81,8 @@ struct xe_guc {#endif /** @submission_state.enabled: submission is enabled */ bool enabled; +/** @submission_state.fini_wq: submit fini wait queue */ +wait_queue_head_t fini_wq; } submission_state;/** @hwconfig: Hardware config state */ struct {
Greg Kroah-Hartman
maintainerPATCH 425/558 drm/xe/oa: Dont reset OAC_CONTEXT_ENABLE on OA stream close
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: José Roberto de Souza <[email protected]>
commit 8135f1c09dd2eecee7cb637f7ec9a29e57300eb8 upstream.
Mesa testing on Xe2+ revealed that when OA metrics are collected for an exec_queue, after the OA stream is closed, future batch buffers submitted on that exec_queue do not complete. Not resetting OAC_CONTEXT_ENABLE on OA stream close resolves these hangs and should not have any adverse effects.
v2: Make the change that we don't reset the bit clearer (Ashutosh)
Also make the same fix for OAC as OAR (Ashutosh)
Bspec: 60314
--- drivers/gpu/drm/xe/xe_oa.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/gpu/drm/xe/xe_oa.c +3 -6
@@ -709,8 +709,7 @@ static int xe_oa_configure_oar_context(struct xe_oa_stream *stream, bool enable) {RING_CONTEXT_CONTROL (stream->hwe->mmio_base), regs_offset +CTX_CONTEXT_CONTROL , -_MASKED_FIELD (CTX_CTRL_OAC_CONTEXT_ENABLE , - enable ?CTX_CTRL_OAC_CONTEXT_ENABLE :0 ) + _MASKED_BIT_ENABLE(CTX_CTRL_OAC_CONTEXT_ENABLE), }, };struct xe_oa_reg reg_lri = {OAR_OACONTROL , oacontrol };
@@ -742,10 +741,8 @@ static int xe_oa_configure_oac_context(struct xe_oa_stream *stream, bool enable) {RING_CONTEXT_CONTROL (stream->hwe->mmio_base), regs_offset +CTX_CONTEXT_CONTROL , -_MASKED_FIELD (CTX_CTRL_OAC_CONTEXT_ENABLE , - enable ?CTX_CTRL_OAC_CONTEXT_ENABLE :0 ) | -_MASKED_FIELD (CTX_CTRL_RUN_ALONE , - enable ? CTX_CTRL_RUN_ALONE : 0), +_MASKED_BIT_ENABLE (CTX_CTRL_OAC_CONTEXT_ENABLE ) | + _MASKED_FIELD(CTX_CTRL_RUN_ALONE, enable ? CTX_CTRL_RUN_ALONE : 0), }, };struct xe_oa_reg reg_lri = {OAC_OACONTROL , oacontrol };
Signature · 1 line
2.46.2
Greg Kroah-Hartman
maintainerPATCH 426/558 sched/deadline: Comment sched_dl_entity::dl_server variable
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Bristot de Oliveira <[email protected]>
commit f23c042ce34ba265cf3129d530702b5d218e3f4b upstream.
Add an explanation for the newly added variable.
--- include/linux/sched.h | 2 ++ 1 file changed, 2 insertions(+)
include/linux/sched.h +2 -0
@@ -639,6 +639,8 @@ struct sched_dl_entity {* * @dl_overrun tells if the task asked to be informed about runtime * overruns. +* +* @dl_server tells if this is a server entity. */ unsigned int dl_throttled : 1; unsigned int dl_yielded : 1;
Greg Kroah-Hartman
maintainerPATCH 427/558 sched/core: Add clearing of ->dl_server in put_prev_task_balance()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joel Fernandes (Google) <[email protected]>
commit c245910049d04fbfa85bb2f5acd591c24e9907c7 upstream.
Paths using put_prev_task_balance() need to do a pick shortly after. Make sure they also clear the ->dl_server on prev as a part of that.
--- kernel/sched/core.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
kernel/sched/core.c +8 -8
@@ -5789,6 +5789,14 @@ static void put_prev_task_balance(struct#endif put_prev_task (rq, prev); + +/* +* We've updated @prev and no longer need the server link, clear it. +* Must be done before ->pick_next_task() because that can (re)set +* ->dl_server. +*/ +if (prev->dl_server) + prev->dl_server =NULL ; }/*
@@ -5832,14 +5840,6 @@ __pick_next_task(struct rq *rq, struct t restart:put_prev_task_balance (rq, prev, rf); -/* -* We've updated @prev and no longer need the server link, clear it. -* Must be done before ->pick_next_task() because that can (re)set -* ->dl_server. -*/ -if (prev->dl_server) - prev->dl_server =NULL ; -for_each_class (class) { p = class->pick_next_task (rq);if (p)
Greg Kroah-Hartman
maintainerPATCH 428/558 sched/core: Clear prev->dl_server in CFS pick fast path
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Youssef Esmat <[email protected]>
commit a741b82423f41501e301eb6f9820b45ca202e877 upstream.
In case the previous pick was a DL server pick, ->dl_server might be set. Clear it in the fast path as well.
--- kernel/sched/core.c | 7 +++++++ 1 file changed, 7 insertions(+)
kernel/sched/core.c +7 -0
@@ -5828,6 +5828,13 @@ __pick_next_task(struct rq *rq, struct t }/* +* This is a normal CFS pick, but the previous could be a DL pick. +* Clear it as previous is no longer picked. +*/ +if (prev->dl_server) + prev->dl_server =NULL ; + +/* * This is the fast path; it cannot be a DL server pick; * therefore even if @p == @prev, ->dl_server must be NULL. */
Greg Kroah-Hartman
maintainerPATCH 429/558 sched: psi: fix bogus pressure spikes from aggregation race
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Weiner <[email protected]>
commit 3840cbe24cf060ea05a585ca497814609f5d47d1 upstream.
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
@@ -769,12 +769,13 @@ static void record_times(struct psi_grou }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;u32 state_mask; +u64 now;lockdep_assert_rq_held (cpu_rq (cpu)); groupc =per_cpu_ptr (group->pcpu, cpu);
@@ -789,6 +790,7 @@ static void psi_group_change(struct psi_* 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
@@ -899,18 +901,15 @@ void psi_task_change(struct task_struct {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)); }
@@ -919,7 +918,6 @@ void psi_task_switch(struct task_struct {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 );
@@ -936,7 +934,7 @@ void psi_task_switch(struct task_structbreak ; } -psi_group_change (group, cpu,0 ,TSK_ONCPU , now, true); +psi_group_change (group, cpu,0 ,TSK_ONCPU , true); }while ((group = group->parent)); }
@@ -974,7 +972,7 @@ void psi_task_switch(struct task_structdo {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));/*
@@ -986,7 +984,7 @@ void psi_task_switch(struct task_structif ((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); } } }
@@ -997,8 +995,8 @@ void psi_account_irqtime(struct rq *rq,int cpu =task_cpu (curr);struct psi_group *group;struct psi_group_cpu *groupc; -u64 now, irq;s64 delta; +u64 irq;if (static_branch_likely (&psi_disabled))return ;
@@ -1011,7 +1009,6 @@ void psi_account_irqtime(struct rq *rq,if (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 )
@@ -1019,12 +1016,15 @@ void psi_account_irqtime(struct rq *rq, 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;
@@ -1223,11 +1223,9 @@ void psi_cgroup_restart(struct psi_groupfor_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); } }
Greg Kroah-Hartman
maintainerPATCH 430/558 riscv: define ILLEGAL_POINTER_VALUE for 64bit
In reply to Greg Kroah-Hartman6.11-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
@@ -319,6 +319,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 431/558 exfat: fix memory leak in exfat_load_bitmap()
In reply to Greg Kroah-Hartman6.11-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
@@ -91,11 +91,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);
@@ -103,6 +100,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 432/558 perf python: Disable -Wno-cast-function-type-mismatch if present on clang
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit 00dc514612fe98cfa117193b9df28f15e7c9db9c upstream.
The -Wcast-function-type-mismatch option was introduced in clang 19 and its enabled by default, since we use -Werror, and python bindings do casts that are valid but trips this warning, disable it if present.
--- tools/perf/util/setup.py | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/util/setup.py +2 -0
@@ -63,6 +63,8 @@ cflags = getenv('CFLAGS', '').split() cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter', '-Wno-redundant-decls' ] if cc_is_clang: cflags += ["-Wno-unused-command-line-argument" ] + if clang_has_option("-Wno-cast-function-type-mismatch"): + cflags += ["-Wno-cast-function-type-mismatch" ] else: cflags += ['-Wno-cast-function-type' ]
Re: [PATCH 6.11 432/558] perf python: Disable -Wno-cast-function-type-mismatch if present on clang
Quoted 34 lines · Greg Kroah-Hartman
6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit
00dc514612fe98cfa117193b9df28f15e7c9db9cupstream.The -Wcast-function-type-mismatch option was introduced in clang 19 and its enabled by default, since we use -Werror, and python bindings do casts that are valid but trips this warning, disable it if present.
Closes https://lore.kernel.org/all/CA+icZUXoJ6BS3GMhJHV3aZWyb5Cz2haFneX0C5pUMUUhG-UVKQ@mail.gmail.com open hereReported-by Sedat Dilek <[email protected]>Tested-by Sedat Dilek <[email protected]>Cc Ian Rogers <[email protected]>Cc Ingo Molnar <[email protected]>Cc Namhyung Kim <[email protected]>Cc Nathan Chancellor <[email protected]>Cc Peter Zijlstra <[email protected]>Cc [email protected] # To allow building with the upcoming clang 19Link https://lore.kernel.org/lkml/CA+icZUVtHn8X1Tb_Y__c-WswsO0K8U9uy3r2MzKXwTA5THtL7w@mail.gmail.com open hereSigned-off-by Arnaldo Carvalho de Melo <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- tools/perf/util/setup.py | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/util/setup.py cflags = getenv('CFLAGS', '').split() · line 70
Quoted 8 lines
tools/perf/util/setup.py +2
-0@@ -63,6 +63,8 @@ cflags = getenv('CFLAGS', '').split() cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter', '-Wno-redundant-decls' ] if cc_is_clang: cflags += ["-Wno-unused-command-line-argument" ] + if clang_has_option("-Wno-cast-function-type-mismatch"): + cflags += ["-Wno-cast-function-type-mismatch" ] else: cflags += ['-Wno-cast-function-type' ]
( I already responded to a stable-commits email sent to me, but here might be better. )
Hi Greg,
You need both patches:
upstream 00dc514612fe98cfa117193b9df28f15e7c9db9c
"perf python: Disable -Wno-cast-function-type-mismatch if present on clang" ^^ You have only this one - sets only the warning flag
upstream b81162302001f41157f6e93654aaccc30e817e2a "perf python: Allow checking for the existence of warning" ^^ Add this please to all stable trees affected, Thanks.
Explanations in [1] and initial report in [2].
Thanks.
BR,
-sed@-
[1] https://lore.kernel.org/all/CA+icZUUfk6bMCo+JXUy=5g-4qt20rDNR3b=HC9Ln_47UozXEDQ@mail.gmail.com/
[2] https://lore.kernel.org/all/CA+icZUXoJ6BS3GMhJHV3aZWyb5Cz2haFneX0C5pUMUUhG-UVKQ@mail.gmail.com/
Greg Kroah-Hartman
maintainerRe: [PATCH 6.11 432/558] perf python: Disable -Wno-cast-function-type-mismatch if present on clang
Quoted 56 lines · Sedat Dilek
Quoted 34 lines · Greg Kroah-Hartman
6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit
00dc514612fe98cfa117193b9df28f15e7c9db9cupstream.The -Wcast-function-type-mismatch option was introduced in clang 19 and its enabled by default, since we use -Werror, and python bindings do casts that are valid but trips this warning, disable it if present.
Closes https://lore.kernel.org/all/CA+icZUXoJ6BS3GMhJHV3aZWyb5Cz2haFneX0C5pUMUUhG-UVKQ@mail.gmail.com open hereReported-by Sedat Dilek <[email protected]>Tested-by Sedat Dilek <[email protected]>Cc Ian Rogers <[email protected]>Cc Ingo Molnar <[email protected]>Cc Namhyung Kim <[email protected]>Cc Nathan Chancellor <[email protected]>Cc Peter Zijlstra <[email protected]>Cc [email protected] # To allow building with the upcoming clang 19Link https://lore.kernel.org/lkml/CA+icZUVtHn8X1Tb_Y__c-WswsO0K8U9uy3r2MzKXwTA5THtL7w@mail.gmail.com open hereSigned-off-by Arnaldo Carvalho de Melo <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- tools/perf/util/setup.py | 2 ++ 1 file changed, 2 insertions(+)tools/perf/util/setup.py cflags = getenv('CFLAGS', '').split() · line 70
Quoted 8 lines
tools/perf/util/setup.py +2
-0@@ -63,6 +63,8 @@ cflags = getenv('CFLAGS', '').split() cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter', '-Wno-redundant-decls' ] if cc_is_clang: cflags += ["-Wno-unused-command-line-argument" ] + if clang_has_option("-Wno-cast-function-type-mismatch"): + cflags += ["-Wno-cast-function-type-mismatch" ] else: cflags += ['-Wno-cast-function-type' ]( I already responded to a stable-commits email sent to me, but here might be better. )
Hi Greg,
You need both patches:
upstream
00dc514612fe98cfa117193b9df28f15e7c9db9c
"perf python: Disable -Wno-cast-function-type-mismatch if present on clang" ^^ You have only this one - sets only the warning flag
Quoted 5 lines
upstream
b81162302001f41157f6e93654aaccc30e817e2a"perf python: Allow checking for the existence of warning" ^^ Add this please to all stable trees affected, Thanks.Explanations in [1] and initial report in [2].
Thanks, now queued up!
greg k-h
Re: [PATCH 6.11 432/558] perf python: Disable -Wno-cast-function-type-mismatch if present on clang
Quoted 62 lines · Greg Kroah-Hartman
Quoted 60 lines · Sedat Dilek
Quoted 34 lines · Greg Kroah-Hartman
6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit
00dc514612fe98cfa117193b9df28f15e7c9db9cupstream.The -Wcast-function-type-mismatch option was introduced in clang 19 and its enabled by default, since we use -Werror, and python bindings do casts that are valid but trips this warning, disable it if present.
Closes https://lore.kernel.org/all/CA+icZUXoJ6BS3GMhJHV3aZWyb5Cz2haFneX0C5pUMUUhG-UVKQ@mail.gmail.com open hereReported-by Sedat Dilek <[email protected]>Tested-by Sedat Dilek <[email protected]>Cc Ian Rogers <[email protected]>Cc Ingo Molnar <[email protected]>Cc Namhyung Kim <[email protected]>Cc Nathan Chancellor <[email protected]>Cc Peter Zijlstra <[email protected]>Cc [email protected] # To allow building with the upcoming clang 19Link https://lore.kernel.org/lkml/CA+icZUVtHn8X1Tb_Y__c-WswsO0K8U9uy3r2MzKXwTA5THtL7w@mail.gmail.com open hereSigned-off-by Arnaldo Carvalho de Melo <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- tools/perf/util/setup.py | 2 ++ 1 file changed, 2 insertions(+)tools/perf/util/setup.py cflags = getenv('CFLAGS', '').split() · line 70
Quoted 8 lines
tools/perf/util/setup.py +2
-0@@ -63,6 +63,8 @@ cflags = getenv('CFLAGS', '').split() cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter', '-Wno-redundant-decls' ] if cc_is_clang: cflags += ["-Wno-unused-command-line-argument" ] + if clang_has_option("-Wno-cast-function-type-mismatch"): + cflags += ["-Wno-cast-function-type-mismatch" ] else: cflags += ['-Wno-cast-function-type' ]( I already responded to a stable-commits email sent to me, but here might be better. )
Hi Greg,
You need both patches:
upstream
00dc514612fe98cfa117193b9df28f15e7c9db9c
"perf python: Disable -Wno-cast-function-type-mismatch if present on clang" ^^ You have only this one - sets only the warning flagupstream
b81162302001f41157f6e93654aaccc30e817e2a"perf python: Allow checking for the existence of warning" ^^ Add this please to all stable trees affected, Thanks.
Quoted 5 lines
Quoted 1 line
Explanations in [1] and initial report in [2].
Thanks, now queued up!
greg k-h
Cool, that will be a nice stable-linux version 6.11.3 for us!
-sed@-
Greg Kroah-Hartman
maintainerPATCH 433/558 perf hist: Update hist symbol when updating maps
In reply to Greg Kroah-Hartman6.11-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
@@ -637,6 +637,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 434/558 nfsd: fix delegation_blocked() to block correctly for at least 30 seconds
In reply to Greg Kroah-Hartman6.11-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
@@ -1077,7 +1077,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.
@@ -1106,9 +1107,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 435/558 nfsd: map the EBADMSG to nfserr_io to avoid warning
In reply to Greg Kroah-Hartman6.11-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
@@ -100,6 +100,7 @@ nfserrno (int errno) { nfserr_io, -EUCLEAN }, { nfserr_perm, -ENOKEY }, { nfserr_no_grace, -ENOGRACE}, + { nfserr_io, -EBADMSG }, };int i;
Greg Kroah-Hartman
maintainerPATCH 436/558 NFSD: Fix NFSv4s PUTPUBFH operation
In reply to Greg Kroah-Hartman6.11-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;
@@ -2374,7 +2366,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 437/558 i3c: master: svc: Fix use after free vulnerability in svc_i3c_master Driver Due to Race Condition
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kaixin Wang <[email protected]>
commit 61850725779709369c7e907ae8c7c75dc7cec4f3 upstream.
In the svc_i3c_master_probe function, &master->hj_work is bound with svc_i3c_master_hj_work, &master->ibi_work is bound with svc_i3c_master_ibi_work. And svc_i3c_master_ibi_work can start the hj_work, svc_i3c_master_irq_handler can start the ibi_work.
If we remove the module which will call svc_i3c_master_remove to make cleanup, it will free master->base through i3c_master_unregister while the work mentioned above will be used. The sequence of operations that may lead to a UAF bug is as follows:
CPU0 CPU1
| svc_i3c_master_hj_work
svc_i3c_master_remove |
i3c_master_unregister(&master->base)|
device_unregister(&master->dev) |
device_release |
//free master->base |
| i3c_master_do_daa(&master->base)
| //use master->baseFix it by ensuring that the work is canceled before proceeding with the cleanup in svc_i3c_master_remove.
--- drivers/i3c/master/svc-i3c-master.c | 1 + 1 file changed, 1 insertion(+)
drivers/i3c/master/svc-i3c-master.c +1 -0
@@ -1775,6 +1775,7 @@ static void svc_i3c_master_remove(struct {struct svc_i3c_master *master =platform_get_drvdata (pdev); +cancel_work_sync (&master->hj_work);i3c_master_unregister (&master->base);pm_runtime_dont_use_autosuspend (&pdev->dev);
Greg Kroah-Hartman
maintainerPATCH 438/558 sysctl: avoid spurious permanent empty tables
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <[email protected]>
commit 559d4c6a9d3b60f239493239070eb304edaea594 upstream.
The test if a table is a permanently empty one, inspects the address of the registered ctl_table argument.
However as sysctl_mount_point is an empty array and does not occupy and space it can end up sharing an address with another object in memory. If that other object itself is a "struct ctl_table" then registering that table will fail as it's incorrectly recognized as permanently empty.
Avoid this issue by adding a dummy element to the array so that is not empty anymore.
Explicitly register the table with zero elements as otherwise the dummy element would be recognized as a sentinel element which would lead to a runtime warning from the sysctl core.
While the issue seems not being encountered at this time, this seems mostly to be due to luck.
Also a future change, constifying sysctl_mount_point and root_table, can reliably trigger this issue on clang 18.
Given that empty arrays are non-standard in the first place it seems prudent to avoid them if possible.
--- fs/proc/proc_sysctl.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
fs/proc/proc_sysctl.c +8 -3
@@ -29,8 +29,13 @@ static const struct inode_operations prostatic const struct file_operations proc_sys_dir_file_operations;static const struct inode_operations proc_sys_dir_operations; -/* Support for permanently empty directories */ -static struct ctl_table sysctl_mount_point[] = { }; +/* +* Support for permanently empty directories. +* Must be non-empty to avoid sharing an address with other tables. +*/ +static struct ctl_table sysctl_mount_point[] = { + { } +};/** * register_sysctl_mount_point() - registers a sysctl mount point
@@ -42,7 +47,7 @@ static struct ctl_table sysctl_mount_poi*/ struct ctl_table_header *register_sysctl_mount_point (const char *path) { -return register_sysctl (path, sysctl_mount_point); +return register_sysctl_sz (path, sysctl_mount_point,0 ); }EXPORT_SYMBOL (register_sysctl_mount_point);
Greg Kroah-Hartman
maintainerPATCH 439/558 RDMA/mana_ib: use the correct page table index based on hardware page size
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <[email protected]>
commit 9e517a8e9d9a303bf9bde35e5c5374795544c152 upstream.
MANA hardware uses 4k page size. When calculating the page table index, it should use the hardware page size, not the system page size.
--- drivers/infiniband/hw/mana/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/mana/main.c +1 -1
@@ -383,7 +383,7 @@ static int mana_ib_gd_create_dma_region( create_req->length = umem->length; create_req->offset_in_page =ib_umem_dma_offset (umem, page_sz); - create_req->gdma_page_type =order_base_2 (page_sz) -PAGE_SHIFT ; + create_req->gdma_page_type =order_base_2 (page_sz) -MANA_PAGE_SHIFT ; create_req->page_count = num_pages_total; ibdev_dbg(&dev->ib_dev, "size_dma_region %lu num_pages_total %lu\n",
Greg Kroah-Hartman
maintainerPATCH 440/558 RDMA/mana_ib: use the correct page size for mapping user-mode doorbell page
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <[email protected]>
commit 4a3b99bc04e501b816db78f70064e26a01257910 upstream.
When mapping doorbell page from user-mode, the driver should use the system page size as this memory is allocated via mmap() from user-mode.
--- drivers/infiniband/hw/mana/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/infiniband/hw/mana/main.c +3 -3
@@ -511,13 +511,13 @@ int mana_ib_mmap(struct ib_ucontext *ibcPAGE_SHIFT ; prot =pgprot_writecombine (vma->vm_page_prot); - ret =rdma_user_mmap_io (ibcontext, vma, pfn, gc->db_page_size, prot, + ret =rdma_user_mmap_io (ibcontext, vma, pfn,PAGE_SIZE , prot,NULL );if (ret)ibdev_dbg (ibdev,"can't rdma_user_mmap_io ret %d\n" , ret);else -ibdev_dbg (ibdev,"mapped I/O pfn 0x%llx page_size %u, ret %d\n" , - pfn, gc->db_page_size, ret); +ibdev_dbg (ibdev,"mapped I/O pfn 0x%llx page_size %lu, ret %d\n" , + pfn,PAGE_SIZE , ret);return ret; }
Greg Kroah-Hartman
maintainerPATCH 441/558 drivers/perf: riscv: Align errno for unsupported perf event
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pu Lehui <[email protected]>
commit c625154993d0d24a962b1830cd5ed92adda2cf86 upstream.
RISC-V perf driver does not yet support PERF_TYPE_BREAKPOINT. It would be more appropriate to return -EOPNOTSUPP or -ENOENT for this type in pmu_sbi_event_map. Considering that other implementations return -ENOENT for unsupported perf types, let's synchronize this behavior. Due to this reason, a riscv bpf testcases perf_skip fail. Meanwhile, align that behavior to the rest of proper place.
--- drivers/perf/riscv_pmu_legacy.c | 4 ++-- drivers/perf/riscv_pmu_sbi.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/perf/riscv_pmu_legacy.c +2 -2
@@ -22,13 +22,13 @@ static int pmu_legacy_ctr_get_idx(structstruct perf_event_attr *attr = &event->attr;if (event->attr.type !=PERF_TYPE_HARDWARE ) -return -EOPNOTSUPP ; +return -ENOENT ;if (attr->config ==PERF_COUNT_HW_CPU_CYCLES )return RISCV_PMU_LEGACY_CYCLE ;else if (attr->config ==PERF_COUNT_HW_INSTRUCTIONS )return RISCV_PMU_LEGACY_INSTRET ;else -return -EOPNOTSUPP ; +return -ENOENT ; }/* For legacy config & counter index are same */
drivers/perf/riscv_pmu_sbi.c +2 -2
@@ -309,7 +309,7 @@ static void pmu_sbi_check_event(struct s ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0); }else if (ret.error ==SBI_ERR_NOT_SUPPORTED ) {/* This event cannot be monitored by any counter */ - edata->event_idx = -EINVAL ; + edata->event_idx = -ENOENT ; } }
@@ -543,7 +543,7 @@ static int pmu_sbi_event_map(struct perf }break ;default : - ret = -EINVAL ; + ret = -ENOENT ;break ; }
Greg Kroah-Hartman
maintainerPATCH 442/558 riscv: Fix kernel stack size when KASAN is enabled
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandre Ghiti <[email protected]>
commit cfb10de18538e383dbc4f3ce7f477ce49287ff3d upstream.
We use Kconfig to select the kernel stack size, doubling the default size if KASAN is enabled.
But that actually only works if KASAN is selected from the beginning, meaning that if KASAN config is added later (for example using menuconfig), CONFIG_THREAD_SIZE_ORDER won't be updated, keeping the default size, which is not enough for KASAN as reported in [1].
So fix this by moving the logic to compute the right kernel stack into a header.
--- arch/riscv/Kconfig | 3 +-- arch/riscv/include/asm/thread_info.h | 7 ++++++- 2 files changed, 7 insertions(+), 3 deletions(-)
arch/riscv/Kconfig +1 -2
@@ -763,8 +763,7 @@ config IRQ_STACKS config THREAD_SIZE_ORDER int "Kernel stack size (in power-of-two numbers of page size)" if VMAP_STACK && EXPERT range 0 4 - default 1 if 32BIT && !KASAN - default 3 if 64BIT && KASAN + default 1 if 32BIT default 2 help Specify the Pages of thread stack size (from 4KB to 64KB), which also
arch/riscv/include/asm/thread_info.h +6 -1
@@ -13,7 +13,12 @@#include <linux/sizes.h> /* thread information allocation */ -#define THREAD_SIZE_ORDER CONFIG_THREAD_SIZE_ORDER +#ifdef CONFIG_KASAN +#define KASAN_STACK_ORDER 1 +#else +#define KASAN_STACK_ORDER 0 +#endif +#define THREAD_SIZE_ORDER (CONFIG_THREAD_SIZE_ORDER + KASAN_STACK_ORDER)#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)/*
Greg Kroah-Hartman
maintainerPATCH 443/558 aoe: fix the potential use-after-free problem in more places
In reply to Greg Kroah-Hartman6.11-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 444/558 media: imx335: Fix reset-gpio handling
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Umang Jain <[email protected]>
commit 99d30e2fdea4086be4e66e2deb10de854b547ab8 upstream.
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
@@ -997,7 +997,7 @@ static int imx335_parse_hw_config(struct/* 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\n" ,PTR_ERR (imx335->reset_gpio));
@@ -1110,8 +1110,7 @@ static int imx335_power_on(struct deviceusleep_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) {
@@ -1124,7 +1123,7 @@ static int imx335_power_on(struct devicereturn 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;
@@ -1141,7 +1140,7 @@ static int imx335_power_off(struct devicstruct 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);
Greg Kroah-Hartman
maintainerPATCH 445/558 media: ov5675: Fix power on/off delay timings
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan O'Donoghue <[email protected]>
commit 719ec29fceda2f19c833d2784b1574638320400f upstream.
The ov5675 specification says that the gap between XSHUTDN deassert and the first I2C transaction should be a minimum of 8192 XVCLK cycles.
Right now we use a usleep_rage() that gives a sleep time of between about 430 and 860 microseconds.
On the Lenovo X13s we have observed that in about 1/20 cases the current timing is too tight and we start transacting before the ov5675's reset cycle completes, leading to I2C bus transaction failures.
The reset racing is sometimes triggered at initial chip probe but, more usually on a subsequent power-off/power-on cycle e.g.
[ 71.451662] ov5675 24-0010: failed to write reg 0x0103. error = -5 [ 71.451686] ov5675 24-0010: failed to set plls
The current quiescence period we have is too tight. Instead of expressing the post reset delay in terms of the current XVCLK this patch converts the power-on and power-off delays to the maximum theoretical delay @ 6 MHz with an additional buffer.
1.365 milliseconds on the power-on path is 1.5 milliseconds with grace. 85.3 microseconds on the power-off path is 90 microseconds with grace.
--- drivers/media/i2c/ov5675.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/media/i2c/ov5675.c +6 -6
@@ -972,12 +972,10 @@ static int ov5675_set_stream(struct v4l2static int ov5675_power_off (struct device *dev) { -/* 512 xvclk cycles after the last SCCB transation or MIPI frame end */ -u32 delay_us =DIV_ROUND_UP (512 ,OV5675_XVCLK_19_2 /1000 /1000 );struct v4l2_subdev *sd =dev_get_drvdata (dev);struct ov5675 *ov5675 =to_ov5675 (sd); -usleep_range (delay_us, delay_us *2 ); +usleep_range (90 ,100 );clk_disable_unprepare (ov5675->xvclk);gpiod_set_value_cansleep (ov5675->reset_gpio,1 );
@@ -988,7 +986,6 @@ static int ov5675_power_off(struct devicstatic int ov5675_power_on (struct device *dev) { -u32 delay_us =DIV_ROUND_UP (8192 ,OV5675_XVCLK_19_2 /1000 /1000 );struct v4l2_subdev *sd =dev_get_drvdata (dev);struct ov5675 *ov5675 =to_ov5675 (sd);int ret;
@@ -1014,8 +1011,11 @@ static int ov5675_power_on(struct devicegpiod_set_value_cansleep (ov5675->reset_gpio,0 ); -/* 8192 xvclk cycles prior to the first SCCB transation */ -usleep_range (delay_us, delay_us *2 ); +/* Worst case quiesence gap is 1.365 milliseconds @ 6MHz XVCLK +* Add an additional threshold grace period to ensure reset +* completion before initiating our first I2C transaction. +*/ +usleep_range (1500 ,1600 );return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 446/558 clk: rockchip: fix error for unknown clocks
In reply to Greg Kroah-Hartman6.11-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
@@ -450,12 +450,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 447/558 leds: pca9532: Remove irrelevant blink configuration error message
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bastien Curutchet <[email protected]>
commit 2aad93b6de0d874038d3d7958be05011284cd6b9 upstream.
The update_hw_blink() function prints an error message when hardware is not able to handle a blink configuration on its own. IMHO, this isn't a 'real' error since the software fallback is used afterwards.
Remove the error messages to avoid flooding the logs with unnecessary messages.
--- drivers/leds/leds-pca9532.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/leds/leds-pca9532.c +2 -3
@@ -215,8 +215,7 @@ static int pca9532_update_hw_blink(struct pca9532_led *led,if (other->state ==PCA9532_PWM1 ) {if (other->ldev.blink_delay_on != delay_on || other->ldev.blink_delay_off != delay_off) { -dev_err (&led->client->dev, -"HW can handle only one blink configuration at a time\n" ); +/* HW can handle only one blink configuration at a time */ return -EINVAL ; } }
@@ -224,7 +223,7 @@ static int pca9532_update_hw_blink(struct pca9532_led *led, psc = ((delay_on + delay_off) *PCA9532_PWM_PERIOD_DIV -1 ) /1000 ;if (psc >U8_MAX ) { -dev_err (&led->client->dev,"Blink period too long to be handled by hardware\n" ); +/* Blink period too long to be handled by hardware */ return -EINVAL ; }
Signature · 1 line
2.46.2
Greg Kroah-Hartman
maintainerPATCH 448/558 remoteproc: k3-r5: Fix error handling when power-up failed
In reply to Greg Kroah-Hartman6.11-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
@@ -1332,7 +1332,7 @@ init_rmem:dev_err (dev,"Timed out waiting for %s core to power up!\n" , rproc->name); -return ret; + goto err_powerup; } }
@@ -1348,6 +1348,7 @@ err_split: } } +err_powerup:rproc_del (rproc); err_add:k3_r5_reserved_mem_exit (kproc);
Greg Kroah-Hartman
maintainerPATCH 449/558 gfs2: fix double destroy_workqueue error
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Sun <[email protected]>
commit 6cb9df81a2c462b89d2f9611009ab43ae8717841 upstream.
When gfs2_fill_super() fails, destroy_workqueue() is called within gfs2_gl_hash_clear(), and the subsequent code path calls destroy_workqueue() on the same work queue again.
This issue can be fixed by setting the work queue pointer to NULL after the first destroy_workqueue() call and checking for a NULL pointer before attempting to destroy the work queue again.
--- fs/gfs2/glock.c | 1 + fs/gfs2/ops_fstype.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
fs/gfs2/glock.c +1 -0
@@ -2249,6 +2249,7 @@ void gfs2_gl_hash_clear(struct gfs2_sbdgfs2_free_dead_glocks (sdp);glock_hash_walk (dump_glock_func, sdp);destroy_workqueue (sdp->sd_glock_wq); + sdp->sd_glock_wq =NULL ; }static const char *state2str (unsigned state)
fs/gfs2/ops_fstype.c +2 -1
@@ -1307,7 +1307,8 @@ fail_debug: fail_delete_wq:destroy_workqueue (sdp->sd_delete_wq); fail_glock_wq: -destroy_workqueue (sdp->sd_glock_wq); +if (sdp->sd_glock_wq) +destroy_workqueue (sdp->sd_glock_wq); fail_free:free_sbd (sdp); sb->s_fs_info =NULL ;
Greg Kroah-Hartman
maintainerPATCH 450/558 media: videobuf2: Drop minimum allocation requirement of 2 buffers
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laurent Pinchart <[email protected]>
commit e5700c9037727d5a69a677d6dba25010b485d65b upstream.
When introducing the ability for drivers to indicate the minimum number of buffers they require an application to allocate, commit 6662edcd32cc ("media: videobuf2: Add min_reqbufs_allocation field to vb2_queue structure") also introduced a global minimum of 2 buffers. It turns out this breaks the Renesas R-Car VSP test suite, where a test that allocates a single buffer fails when two buffers are used.
One may consider debatable whether test suite failures without failures in production use cases should be considered as a regression, but operation with a single buffer is a valid use case. While full frame rate can't be maintained, memory-to-memory devices can still be used with a decent efficiency, and requiring applications to allocate multiple buffers for single-shot use cases with capture devices would just waste memory.
For those reasons, fix the regression by dropping the global minimum of buffers. Individual drivers can still set their own minimum.
--- drivers/media/common/videobuf2/videobuf2-core.c | 7 ------- 1 file changed, 7 deletions(-)
drivers/media/common/videobuf2/videobuf2-core.c +0 -7
@@ -2602,13 +2602,6 @@ int vb2_core_queue_init(struct vb2_queuereturn -EINVAL ;/* -* The minimum requirement is 2: one buffer is used -* by the hardware while the other is being processed by userspace. -*/ -if (q->min_reqbufs_allocation <2 ) - q->min_reqbufs_allocation =2 ; - -/* * If the driver needs 'min_queued_buffers' in the queue before * calling start_streaming() then the minimum requirement is * 'min_queued_buffers + 1' to keep at least one buffer available
Greg Kroah-Hartman
maintainerPATCH 451/558 clk: qcom: dispcc-sm8250: use CLK_SET_RATE_PARENT for branch clocks
In reply to Greg Kroah-Hartman6.11-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
@@ -849,6 +849,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, }, },
@@ -884,6 +885,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, }, },
@@ -1009,6 +1011,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 452/558 media: sun4i_csi: Implement link validate for sun4i_csi subdev
In reply to Greg Kroah-Hartman6.11-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
@@ -39,6 +39,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_connection *asd)
@@ -214,6 +218,7 @@ static int sun4i_csi_probe(struct platfo subdev->internal_ops = &sun4i_csi_subdev_internal_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 453/558 clk: qcom: gcc-sm8450: Do not turn off PCIe GDSCs during gdsc_disable()
In reply to Greg Kroah-Hartman6.11-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
@@ -2974,7 +2974,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 = {
@@ -2982,7 +2982,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 454/558 media: uapi/linux/cec.h: cec_msg_set_reply_to: zero flags
In reply to Greg Kroah-Hartman6.11-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 455/558 dt-bindings: clock: qcom: Add GPLL9 support on gcc-sc8180x
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satya Priya Kakitapalli <[email protected]>
commit 648b4bde0aca2980ebc0b90cdfbb80d222370c3d upstream.
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
Greg Kroah-Hartman
maintainerPATCH 456/558 clk: qcom: gcc-sc8180x: Register QUPv3 RCGs for DFS on sc8180x
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satya Priya Kakitapalli <[email protected]>
commit 1fc8c02e1d80463ce1b361d82b83fc43bb92d964 upstream.
QUPv3 clocks support DFS on sc8180x platform but currently the code changes for it are missing from the driver, this results in not populating all the DFS supported frequencies and returns incorrect frequency when the clients request for them. Hence add the DFS registration for QUPv3 RCGs.
--- drivers/clk/qcom/gcc-sc8180x.c | 350 ++++++++++++++++++++++++----------------- 1 file changed, 210 insertions(+), 140 deletions(-)
drivers/clk/qcom/gcc-sc8180x.c +210 -140
@@ -609,19 +609,29 @@ static const struct freq_tbl ftbl_gcc_qu { } }; +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { + .name ="gcc_qupv3_wrap0_s0_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, +}; +static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { .cmd_rcgr =0x17148 , .mnd_width =16 , .hid_width =5 , .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap0_s0_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { + .name ="gcc_qupv3_wrap0_s1_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
@@ -630,13 +640,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap0_s1_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { + .name ="gcc_qupv3_wrap0_s2_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
@@ -645,13 +657,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap0_s2_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { + .name ="gcc_qupv3_wrap0_s3_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
@@ -660,13 +674,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap0_s3_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { + .name ="gcc_qupv3_wrap0_s4_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
@@ -675,13 +691,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap0_s4_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { + .name ="gcc_qupv3_wrap0_s5_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
@@ -690,13 +708,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap0_s5_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = { + .name ="gcc_qupv3_wrap0_s6_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
@@ -705,13 +725,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap0_s6_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = { + .name ="gcc_qupv3_wrap0_s7_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
@@ -720,13 +742,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap0_s7_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .name ="gcc_qupv3_wrap1_s0_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
@@ -735,13 +759,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap1_s0_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .name ="gcc_qupv3_wrap1_s1_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
@@ -750,13 +776,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap1_s1_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { + .name ="gcc_qupv3_wrap1_s2_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
@@ -765,13 +793,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap1_s2_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { + .name ="gcc_qupv3_wrap1_s3_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
@@ -780,13 +810,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap1_s3_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .name ="gcc_qupv3_wrap1_s4_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
@@ -795,13 +827,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap1_s4_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .name ="gcc_qupv3_wrap1_s5_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
@@ -810,13 +844,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap1_s5_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = { + .name ="gcc_qupv3_wrap2_s0_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = {
@@ -825,13 +861,15 @@ static struct clk_rcg2 gcc_qupv3_wrap2_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap2_s0_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap2_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = { + .name ="gcc_qupv3_wrap2_s1_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = {
@@ -840,28 +878,33 @@ static struct clk_rcg2 gcc_qupv3_wrap2_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap2_s1_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap2_s1_clk_src_init, }; +static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = { + .name ="gcc_qupv3_wrap2_s2_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = { .cmd_rcgr =0x1e3a8 , .mnd_width =16 , .hid_width =5 , .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap2_s2_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap2_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = { + .name ="gcc_qupv3_wrap2_s3_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = {
@@ -870,13 +913,15 @@ static struct clk_rcg2 gcc_qupv3_wrap2_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap2_s3_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap2_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = { + .name ="gcc_qupv3_wrap2_s4_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = {
@@ -885,13 +930,15 @@ static struct clk_rcg2 gcc_qupv3_wrap2_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap2_s4_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap2_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s5_clk_src_init = { + .name ="gcc_qupv3_wrap2_s5_clk_src" , + .parent_data = gcc_parents_0, + .num_parents =ARRAY_SIZE (gcc_parents_0), + .flags =CLK_SET_RATE_PARENT , + .ops = &clk_rcg2_ops, };static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = {
@@ -900,13 +947,7 @@ static struct clk_rcg2 gcc_qupv3_wrap2_s .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="gcc_qupv3_wrap2_s5_clk_src" , - .parent_data = gcc_parents_0, - .num_parents =ARRAY_SIZE (gcc_parents_0), - .flags =CLK_SET_RATE_PARENT , - .ops = &clk_rcg2_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap2_s5_clk_src_init, };static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
@@ -4561,6 +4602,29 @@ static const struct qcom_reset_map gcc_s [GCC_VIDEO_AXI1_CLK_BCR] = { .reg = 0xb028, .bit = 2, .udelay = 150 }, }; +static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { +DEFINE_RCG_DFS (gcc_qupv3_wrap0_s0_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap0_s1_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap0_s2_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap0_s3_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap0_s4_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap0_s5_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap0_s6_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap0_s7_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap1_s0_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap1_s1_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap1_s2_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap1_s3_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap1_s4_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap1_s5_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap2_s0_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap2_s1_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap2_s2_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap2_s3_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap2_s4_clk_src), +DEFINE_RCG_DFS (gcc_qupv3_wrap2_s5_clk_src), +}; +static struct gdsc *gcc_sc8180x_gdscs[] = { [EMAC_GDSC ] = &emac_gdsc, [PCIE_0_GDSC ] = &pcie_0_gdsc,
@@ -4602,6 +4666,7 @@ MODULE_DEVICE_TABLE(of, gcc_sc8180x_matcstatic int gcc_sc8180x_probe (struct platform_device *pdev) {struct regmap *regmap; +int ret; regmap =qcom_cc_map (pdev, &gcc_sc8180x_desc);if (IS_ERR (regmap))
@@ -4623,6 +4688,11 @@ static int gcc_sc8180x_probe(struct platregmap_update_bits (regmap,0x4d110 ,0x3 ,0x3 );regmap_update_bits (regmap,0x71028 ,0x3 ,0x3 ); + ret =qcom_cc_register_rcg_dfs (regmap, gcc_dfs_clocks, +ARRAY_SIZE (gcc_dfs_clocks)); +if (ret) +return ret; +return qcom_cc_really_probe (&pdev->dev, &gcc_sc8180x_desc, regmap); }
Greg Kroah-Hartman
maintainerPATCH 457/558 clk: qcom: clk-rpmh: Fix overflow in BCM vote
In reply to Greg Kroah-Hartman6.11-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
@@ -263,6 +263,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 458/558 clk: samsung: exynos7885: Update CLKS_NR_FSYS after bindings fix
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Virag <[email protected]>
commit 217a5f23c290c349ceaa37a6f2c014ad4c2d5759 upstream.
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
@@ -20,7 +20,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 ------------------------------------------------------------- */
Greg Kroah-Hartman
maintainerPATCH 459/558 clk: qcom: gcc-sm8150: De-register gcc_cpuss_ahb_clk_src
In reply to Greg Kroah-Hartman6.11-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
@@ -260,28 +260,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 ),
@@ -1640,25 +1618,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 ,
@@ -3191,25 +3150,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 ,
@@ -4325,8 +4265,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,
@@ -4463,7 +4401,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 460/558 media: venus: fix use after free bug in venus_remove due to race condition
In reply to Greg Kroah-Hartman6.11-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
@@ -430,6 +430,7 @@ static void venus_remove(struct platformstruct 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 461/558 clk: qcom: gcc-sm8250: Do not turn off PCIe GDSCs during gdsc_disable()
In reply to Greg Kroah-Hartman6.11-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
@@ -3226,7 +3226,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 = {
@@ -3234,7 +3234,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 = {
@@ -3242,7 +3242,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 462/558 media: qcom: camss: Remove use_count guard in stop_streaming
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan O'Donoghue <[email protected]>
commit 25f18cb1b673220b76a86ebef8e7fb79bd303b27 upstream.
The use_count check was introduced so that multiple concurrent Raw Data Interfaces RDIs could be driven by different virtual channels VCs on the CSIPHY input driving the video pipeline.
This is an invalid use of use_count though as use_count pertains to the number of times a video entity has been opened by user-space not the number of active streams.
If use_count and stream-on count don't agree then stop_streaming() will break as is currently the case and has become apparent when using CAMSS with libcamera's released softisp 0.3.
The use of use_count like this is a bit hacky and right now breaks regular usage of CAMSS for a single stream case. Stopping qcam results in the splat below, and then it cannot be started again and any attempts to do so fails with -EBUSY.
[ 1265.509831] WARNING: CPU: 5 PID: 919 at drivers/media/common/videobuf2/videobuf2-core.c:2183 __vb2_queue_cancel+0x230/0x2c8 [videobuf2_common] ... [ 1265.510630] Call trace: [ 1265.510636] __vb2_queue_cancel+0x230/0x2c8 [videobuf2_common] [ 1265.510648] vb2_core_streamoff+0x24/0xcc [videobuf2_common] [ 1265.510660] vb2_ioctl_streamoff+0x5c/0xa8 [videobuf2_v4l2] [ 1265.510673] v4l_streamoff+0x24/0x30 [videodev] [ 1265.510707] __video_do_ioctl+0x190/0x3f4 [videodev] [ 1265.510732] video_usercopy+0x304/0x8c4 [videodev] [ 1265.510757] video_ioctl2+0x18/0x34 [videodev] [ 1265.510782] v4l2_ioctl+0x40/0x60 [videodev] ... [ 1265.510944] videobuf2_common: driver bug: stop_streaming operation is leaving buffer 0 in active state [ 1265.511175] videobuf2_common: driver bug: stop_streaming operation is leaving buffer 1 in active state [ 1265.511398] videobuf2_common: driver bug: stop_streaming operation is leaving buffer 2 in active st
One CAMSS specific way to handle multiple VCs on the same RDI might be:
- Reference count each pipeline enable for CSIPHY, CSID, VFE and RDIx.
- The video buffers are already associated with msm_vfeN_rdiX so release video buffers when told to do so by stop_streaming.
- Only release the power-domains for the CSIPHY, CSID and VFE when their internal refcounts drop.
Either way refusing to release video buffers based on use_count is erroneous and should be reverted. The silicon enabling code for selecting VCs is perfectly fine. Its a "known missing feature" that concurrent VCs won't work with CAMSS right now.
Initial testing with this code didn't show an error but, SoftISP and "real" usage with Google Hangouts breaks the upstream code pretty quickly, we need to do a partial revert and take another pass at VCs.
This commit partially reverts commit 89013969e232 ("media: camss: sm8250:
Pipeline starting and stopping for multiple virtual channels")
--- drivers/media/platform/qcom/camss/camss-video.c | 6 ------ 1 file changed, 6 deletions(-)
drivers/media/platform/qcom/camss/camss-video.c +0 -6
@@ -297,12 +297,6 @@ static void video_stop_streaming(struct ret =v4l2_subdev_call (subdev, video, s_stream,0 ); -if (entity->use_count >1 ) { -/* Don't stop if other instances of the pipeline are still running */ -dev_dbg (video->camss->dev,"Video pipeline still used, don't stop streaming.\n" ); -return ; - } -if (ret) {dev_err (video->camss->dev,"Video pipeline stop failed: %d\n" , ret);return ;
Greg Kroah-Hartman
maintainerPATCH 463/558 clk: qcom: gcc-sc8180x: Add GPLL9 support
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satya Priya Kakitapalli <[email protected]>
commit 818a2f8d5e4ad2c1e39a4290158fe8e39a744c70 upstream.
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
@@ -142,6 +142,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 },
@@ -241,7 +258,7 @@ static const struct parent_map gcc_parenstatic 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 }, };
@@ -4489,6 +4506,7 @@ static struct clk_regmap *gcc_sc8180x_cl [GPLL1] = &gpll1.clkr, [GPLL4] = &gpll4.clkr, [GPLL7] = &gpll7.clkr, + [GPLL9] = &gpll9.clkr, };static const struct qcom_reset_map gcc_sc8180x_resets[] = {
Greg Kroah-Hartman
maintainerPATCH 464/558 media: qcom: camss: Fix ordering of pm_runtime_enable
In reply to Greg Kroah-Hartman6.11-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
@@ -2283,6 +2283,8 @@ static int camss_probe(struct platform_dv4l2_async_nf_init (&camss->notifier, &camss->v4l2_dev); +pm_runtime_enable (dev); + num_subdevs =camss_of_parse_ports (camss);if (num_subdevs <0 ) { ret = num_subdevs;
@@ -2323,8 +2325,6 @@ static int camss_probe(struct platform_d } } -pm_runtime_enable (dev); -return 0 ; err_register_subdevs:
@@ -2332,6 +2332,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 465/558 clk: qcom: gcc-sc8180x: Fix the sdcc2 and sdcc4 clocks freq table
In reply to Greg Kroah-Hartman6.11-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
@@ -952,7 +952,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), { } };
@@ -975,9 +975,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 466/558 clk: qcom: clk-alpha-pll: Fix CAL_L_VAL override for LUCID EVO PLL
In reply to Greg Kroah-Hartman6.11-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
@@ -1713,7 +1713,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 467/558 drm/amd/display: avoid set dispclk to 0
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charlene Liu <[email protected]>
commit c36df0f5f5e5acec5d78f23c4725cc500df28843 upstream.
[why]
set dispclk to 0 cause stability issue.
--- drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +1 -0
@@ -766,6 +766,7 @@ static const struct dc_debug_options deb .disable_dmub_reallow_idle = false, .static_screen_wait_frames = 2, .notify_dpia_hr_bw = true, + .min_disp_clk_khz = 50000, };static const struct dc_panel_config panel_config_defaults = {
Greg Kroah-Hartman
maintainerPATCH 468/558 smb: client: use actual path when queryfs
In reply to Greg Kroah-Hartman6.11-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
@@ -313,8 +313,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 =
@@ -330,8 +339,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
@@ -482,7 +482,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
@@ -909,7 +909,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
@@ -2836,7 +2836,7 @@ out_free_path:static 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 ;
@@ -2845,7 +2845,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,
@@ -2873,28 +2873,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 469/558 smb3: fix incorrect mode displayed for read-only files
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve French <[email protected]>
commit 2f3017e7cc7515e0110a3733d8dca84de2a1d23d upstream.
Commands like "chmod 0444" mark a file readonly via the attribute flag (when mapping of mode bits into the ACL are not set, or POSIX extensions are not negotiated), but they were not reported correctly for stat of directories (they were reported ok for files and for "ls"). See example below:
root:~# ls /mnt2 -l
total 12
drwxr-xr-x 2 root root 0 Sep 21 18:03 normaldir
-rwxr-xr-x 1 root root 0 Sep 21 23:24 normalfile
dr-xr-xr-x 2 root root 0 Sep 21 17:55 readonly-dir
-r-xr-xr-x 1 root root 209716224 Sep 21 18:15 readonly-file
root:~# stat -c %a /mnt2/readonly-dir
755
root:~# stat -c %a /mnt2/readonly-file
555This fixes the stat of directories when ATTR_READONLY is set (in cases where the mode can not be obtained other ways).
root:~# stat -c %a /mnt2/readonly-dir
555--- fs/smb/client/inode.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
fs/smb/client/inode.c +11 -8
@@ -800,10 +800,6 @@ static void cifs_open_info_to_fattr(stru fattr->cf_mode =S_IFREG | cifs_sb->ctx->file_mode; fattr->cf_dtype =DT_REG ; -/* clear write bits if ATTR_READONLY is set */ -if (fattr->cf_cifsattrs &ATTR_READONLY ) - fattr->cf_mode &= ~(S_IWUGO ); -/* * Don't accept zero nlink from non-unix servers unless * delete is pending. Instead mark it as unknown.
@@ -816,6 +812,10 @@ static void cifs_open_info_to_fattr(stru } } +/* clear write bits if ATTR_READONLY is set */ +if (fattr->cf_cifsattrs &ATTR_READONLY ) + fattr->cf_mode &= ~(S_IWUGO ); + out_reparse:if (S_ISLNK (fattr->cf_mode)) {if (likely (data->symlink_target))
@@ -1233,11 +1233,14 @@ handle_mnt_opt: __func__, rc); goto out; } - } - -/* fill in remaining high mode bits e.g. SUID, VTX */ -if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_UNX_EMUL ) + }else if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_UNX_EMUL ) +/* fill in remaining high mode bits e.g. SUID, VTX */ cifs_sfu_mode (fattr, full_path, cifs_sb, xid); +else if (!(tcon->posix_extensions)) +/* clear write bits if ATTR_READONLY is set */ +if (fattr->cf_cifsattrs &ATTR_READONLY ) + fattr->cf_mode &= ~(S_IWUGO ); +/* check for Minshall+French symlinks */ if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_MF_SYMLINKS ) {
Greg Kroah-Hartman
maintainerPATCH 470/558 iio: magnetometer: ak8975: Fix reading for ak099xx sensors
In reply to Greg Kroah-Hartman6.11-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 471/558 iio: pressure: bmp280: Fix regmap for BMP280 device
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasileios Amoiridis <[email protected]>
commit b9065b0250e1705935445ede0a18c1850afe7b75 upstream.
Up to now, the BMP280 device is using the regmap of the BME280 which has registers that exist only in the BME280 device.
--- drivers/iio/pressure/bmp280-core.c | 2 - drivers/iio/pressure/bmp280-regmap.c | 45 ++++++++++++++++++++++++++++++++--- drivers/iio/pressure/bmp280.h | 1 3 files changed, 44 insertions(+), 4 deletions(-)
drivers/iio/pressure/bmp280-core.c +1 -1
@@ -882,7 +882,7 @@ const struct bmp280_chip_info bme280_chi .id_reg = BMP280_REG_ID, .chip_id = bme280_chip_ids, .num_chip_id = ARRAY_SIZE(bme280_chip_ids), - .regmap_config = &bmp280_regmap_config, + .regmap_config = &bme280_regmap_config, .start_up_time = 2000, .channels = bmp280_channels, .num_channels = 3,
drivers/iio/pressure/bmp280-regmap.c +42 -3
78 lines not on this page · raw message
drivers/iio/pressure/bmp280.h +1 -0
@@ -464,6 +464,7 @@ extern const struct bmp280_chip_info bmp/* Regmap configurations */ extern const struct regmap_config bmp180_regmap_config;extern const struct regmap_config bmp280_regmap_config; +extern const struct regmap_config bme280_regmap_config;extern const struct regmap_config bmp380_regmap_config;extern const struct regmap_config bmp580_regmap_config;
Greg Kroah-Hartman
maintainerPATCH 472/558 iio: pressure: bmp280: Fix waiting time for BMP3xx configuration
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasileios Amoiridis <[email protected]>
commit 262a6634bcc4f0c1c53d13aa89882909f281a6aa upstream.
According to the datasheet, both pressure and temperature can go up to oversampling x32. With this option, the maximum measurement time is not 80ms (this is for press x32 and temp x2), but it is 130ms nominal (calculated from table 3.9.2) and since most of the maximum values are around +15%, it is configured to 150ms.
--- drivers/iio/pressure/bmp280-core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/iio/pressure/bmp280-core.c +4 -3
@@ -1272,10 +1272,11 @@ static int bmp380_chip_config(struct bmp }/* * Waits for measurement before checking configuration error -* flag. Selected longest measure time indicated in -* section 3.9.1 in the datasheet. +* flag. Selected longest measurement time, calculated from +* formula in datasheet section 3.9.2 with an offset of ~+15% +* as it seen as well in table 3.9.1. */ -msleep (80 ); +msleep (150 );/* Check config error flag */ ret =regmap_read (data->regmap,BMP380_REG_ERROR , &tmp);
Greg Kroah-Hartman
maintainerPATCH 473/558 vrf: revert "vrf: Remove unnecessary RCU-bh critical section"
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willem de Bruijn <[email protected]>
commit b04c4d9eb4f25b950b33218e33b04c94e7445e51 upstream.
This reverts commit 504fc6f4f7f681d2a03aa5f68aad549d90eab853.
dev_queue_xmit_nit is expected to be called with BH disabled. __dev_queue_xmit has the following:
/* Disable soft irqs for various locks below. Also
* stops preemption for RCU.
*/
rcu_read_lock_bh();VRF must follow this invariant. The referenced commit removed this protection. Which triggered a lockdep warning:
================================
WARNING: inconsistent lock state
6.11.0 #1 Tainted: G W
--------------------------------
inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
btserver/134819 [HC0[0]:SC0[0]:HE1:SE1] takes:
ffff8882da30c118 (rlock-AF_PACKET){+.?.}-{2:2}, at: tpacket_rcv+0x863/0x3b30
{IN-SOFTIRQ-W} state was registered at:
lock_acquire+0x19a/0x4f0
_raw_spin_lock+0x27/0x40
packet_rcv+0xa33/0x1320
__netif_receive_skb_core.constprop.0+0xcb0/0x3a90
__netif_receive_skb_list_core+0x2c9/0x890
netif_receive_skb_list_internal+0x610/0xcc0
[...]
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(rlock-AF_PACKET);
<Interrupt>
lock(rlock-AF_PACKET);
*** DEADLOCK ***
Call Trace:
<TASK>
dump_stack_lvl+0x73/0xa0
mark_lock+0x102e/0x16b0
__lock_acquire+0x9ae/0x6170
lock_acquire+0x19a/0x4f0
_raw_spin_lock+0x27/0x40
tpacket_rcv+0x863/0x3b30
dev_queue_xmit_nit+0x709/0xa40
vrf_finish_direct+0x26e/0x340 [vrf]
vrf_l3_out+0x5f4/0xe80 [vrf]
__ip_local_out+0x51e/0x7a0
[...]--- drivers/net/vrf.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/vrf.c +2 -0
@@ -607,7 +607,9 @@ static void vrf_finish_direct(struct sk_eth_zero_addr (eth->h_dest); eth->h_proto = skb->protocol; +rcu_read_lock_bh ();dev_queue_xmit_nit (skb, vrf_dev); +rcu_read_unlock_bh ();skb_pull (skb,ETH_HLEN ); }
Greg Kroah-Hartman
maintainerPATCH 474/558 net: gso: fix tcp fraglist segmentation after pull from frag_list
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <[email protected]>
commit 17bd3bd82f9f79f3feba15476c2b2c95a9b11ff8 upstream.
Detect tcp 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 TCP, this causes a NULL ptr deref in __tcpv4_gso_segment_list_csum at tcp_hdr(seg->next).
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.
Approach and description based on a patch by Willem de Bruijn.
--- net/ipv4/tcp_offload.c | 10 ++++++++-- net/ipv6/tcpv6_offload.c | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-)
net/ipv4/tcp_offload.c +8 -2
@@ -101,8 +101,14 @@ static struct sk_buff *tcp4_gso_segment(if (!pskb_may_pull (skb,sizeof (struct tcphdr )))return ERR_PTR (-EINVAL ); -if (skb_shinfo (skb)->gso_type &SKB_GSO_FRAGLIST ) -return __tcp4_gso_segment_list (skb, features); +if (skb_shinfo (skb)->gso_type &SKB_GSO_FRAGLIST ) { +struct tcphdr *th =tcp_hdr (skb); + +if (skb_pagelen (skb) - th->doff *4 ==skb_shinfo (skb)->gso_size) +return __tcp4_gso_segment_list (skb, features); + + skb->ip_summed =CHECKSUM_NONE ; + }if (unlikely (skb->ip_summed !=CHECKSUM_PARTIAL )) {const struct iphdr *iph =ip_hdr (skb);
net/ipv6/tcpv6_offload.c +8 -2
@@ -159,8 +159,14 @@ static struct sk_buff *tcp6_gso_segment(if (!pskb_may_pull (skb,sizeof (*th)))return ERR_PTR (-EINVAL ); -if (skb_shinfo (skb)->gso_type &SKB_GSO_FRAGLIST ) -return __tcp6_gso_segment_list (skb, features); +if (skb_shinfo (skb)->gso_type &SKB_GSO_FRAGLIST ) { +struct tcphdr *th =tcp_hdr (skb); + +if (skb_pagelen (skb) - th->doff *4 ==skb_shinfo (skb)->gso_size) +return __tcp6_gso_segment_list (skb, features); + + skb->ip_summed =CHECKSUM_NONE ; + }if (unlikely (skb->ip_summed !=CHECKSUM_PARTIAL )) {const struct ipv6hdr *ipv6h =ipv6_hdr (skb);
Greg Kroah-Hartman
maintainerPATCH 475/558 gso: fix udp gso fraglist segmentation after pull from frag_list
In reply to Greg Kroah-Hartman6.11-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
@@ -296,8 +296,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 476/558 tomoyo: fallback to realpath if symlinks pathname does not exist
In reply to Greg Kroah-Hartman6.11-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 477/558 kselftests: mm: fix wrong __NR_userfaultfd value
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Usama Anjum <[email protected]>
commit f30beffd977e98c33550bbeb6f278d157ff54844 upstream.
grep -rnIF "#define __NR_userfaultfd" tools/include/uapi/asm-generic/unistd.h:681:#define __NR_userfaultfd 282 arch/x86/include/generated/uapi/asm/unistd_32.h:374:#define __NR_userfaultfd 374 arch/x86/include/generated/uapi/asm/unistd_64.h:327:#define __NR_userfaultfd 323 arch/x86/include/generated/uapi/asm/unistd_x32.h:282:#define __NR_userfaultfd (__X32_SYSCALL_BIT + 323) arch/arm/include/generated/uapi/asm/unistd-eabi.h:347:#define __NR_userfaultfd (__NR_SYSCALL_BASE + 388) arch/arm/include/generated/uapi/asm/unistd-oabi.h:359:#define __NR_userfaultfd (__NR_SYSCALL_BASE + 388) include/uapi/asm-generic/unistd.h:681:#define __NR_userfaultfd 282
The number is dependent on the architecture. The above data shows that:
x86 374x86_64 323
The value of __NR_userfaultfd was changed to 282 when asm-generic/unistd.h was included. It makes the test to fail every time as the correct number of this syscall on x86_64 is 323. Fix the header to asm/unistd.h.
--- tools/testing/selftests/mm/pagemap_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/mm/pagemap_ioctl.c +1 -1
@@ -15,7 +15,7 @@#include <sys/ioctl.h> #include <sys/stat.h> #include <math.h> -#include <asm-generic/unistd.h> +#include <asm/unistd.h> #include <pthread.h> #include <sys/resource.h> #include <assert.h>
Signature · 1 line
2.46.2
Greg Kroah-Hartman
maintainerPATCH 478/558 net: stmmac: Fix zero-division error when disabling tc cbs
In reply to Greg Kroah-Hartman6.11-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 479/558 rtc: at91sam9: fix OF node leak in probe() error path
In reply to Greg Kroah-Hartman6.11-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 480/558 mm/filemap: fix filemap_get_folios_contig THP panic
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve Sistare <[email protected]>
commit c225c4f6056b46a8a5bf2ed35abf17a2d6887691 upstream.
Patch series "memfd-pin huge page fixes".
Fix multiple bugs that occur when using memfd_pin_folios with hugetlb pages and THP. The hugetlb bugs only bite when the page is not yet faulted in when memfd_pin_folios is called. The THP bug bites when the starting offset passed to memfd_pin_folios is not huge page aligned. See the commit messages for details.
This patch (of 5):
memfd_pin_folios on memory backed by THP panics if the requested start offset is not huge page aligned:
BUG: kernel NULL pointer dereference, address: 0000000000000036 RIP: 0010:filemap_get_folios_contig+0xdf/0x290 RSP: 0018:ffffc9002092fbe8 EFLAGS: 00010202 RAX: 0000000000000002 RBX: 0000000000000002 RCX: 0000000000000002
The fault occurs here, because xas_load returns a folio with value 2:
filemap_get_folios_contig()
for (folio = xas_load(&xas); folio && xas.xa_index <= end;
folio = xas_next(&xas)) {
...
if (!folio_try_get(folio)) <-- BOOM"2" is an xarray sibling entry. We get it because memfd_pin_folios does not round the indices passed to filemap_get_folios_contig to huge page boundaries for THP, so we load from the middle of a huge page range see a sibling. (It does round for hugetlbfs, at the is_file_hugepages test).
To fix, if the folio is a sibling, then return the next index as the starting point for the next call to filemap_get_folios_contig.
--- mm/filemap.c | 4 ++++ 1 file changed, 4 insertions(+)
mm/filemap.c +4 -0
@@ -2181,6 +2181,10 @@ unsigned filemap_get_folios_contig(strucif (xa_is_value (folio)) goto update_start; +/* If we landed in the middle of a THP, continue at its end. */ +if (xa_is_sibling (folio)) + goto update_start; +if (!folio_try_get (folio)) goto retry;
Greg Kroah-Hartman
maintainerPATCH 481/558 mm/hugetlb: fix memfd_pin_folios free_huge_pages leak
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve Sistare <[email protected]>
commit c56b6f3d801d7ec8965993342bdd9e2972b6cb8e upstream.
memfd_pin_folios followed by unpin_folios fails to restore free_huge_pages if the pages were not already faulted in, because the folio refcount for pages created by memfd_alloc_folio never goes to 0. memfd_pin_folios needs another folio_put to undo the folio_try_get below:
memfd_alloc_folio()
alloc_hugetlb_folio_nodemask()
dequeue_hugetlb_folio_nodemask()
dequeue_hugetlb_folio_node_exact()
folio_ref_unfreeze(folio, 1); ; adds 1 refcount
folio_try_get() ; adds 1 refcount
hugetlb_add_to_page_cache() ; adds 512 refcount (on x86)
With the fix, after memfd_pin_folios + unpin_folios, the refcount for the (unfaulted) page is 512, which is correct, as the refcount for a faulted unpinned page is 513.
--- mm/gup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
mm/gup.c +3 -1
@@ -3618,7 +3618,7 @@ long memfd_pin_folios(struct file *memfdpgoff_t start_idx, end_idx, next_idx;struct folio *folio =NULL ;struct folio_batch fbatch; -struct hstate *h; +struct hstate *h =NULL ;long ret = -EINVAL ;if (start <0 || start > end || !max_folios)
@@ -3662,6 +3662,8 @@ long memfd_pin_folios(struct file *memfd &fbatch);if (folio) {folio_put (folio); +if (h) +folio_put (folio); folio =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 482/558 mm/hugetlb: fix memfd_pin_folios resv_huge_pages leak
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve Sistare <[email protected]>
commit 26a8ea80929c518bdec5e53a5776f95919b7c88e upstream.
memfd_pin_folios followed by unpin_folios leaves resv_huge_pages elevated if the pages were not already faulted in. During a normal page fault, resv_huge_pages is consumed here:
hugetlb_fault()
alloc_hugetlb_folio()
dequeue_hugetlb_folio_vma()
dequeue_hugetlb_folio_nodemask()
dequeue_hugetlb_folio_node_exact()
free_huge_pages--
resv_huge_pages--
During memfd_pin_folios, the page is created by calling alloc_hugetlb_folio_nodemask instead of alloc_hugetlb_folio, and resv_huge_pages is not modified:
memfd_alloc_folio()
alloc_hugetlb_folio_nodemask()
dequeue_hugetlb_folio_nodemask()
dequeue_hugetlb_folio_node_exact()
free_huge_pages--
alloc_hugetlb_folio_nodemask has other callers that must not modify resv_huge_pages. Therefore, to fix, define an alternate version of alloc_hugetlb_folio_nodemask for this call site that adjusts resv_huge_pages.
--- include/linux/hugetlb.h | 10 ++++++++++ mm/hugetlb.c | 17 +++++++++++++++++ mm/memfd.c | 9 ++++----- 3 files changed, 31 insertions(+), 5 deletions(-)
include/linux/hugetlb.h +10 -0
@@ -695,6 +695,9 @@ struct folio *alloc_hugetlb_folio(structstruct folio *alloc_hugetlb_folio_nodemask (struct hstate *h,int preferred_nid,nodemask_t *nmask,gfp_t gfp_mask,bool allow_alloc_fallback); +struct folio *alloc_hugetlb_folio_reserve (struct hstate *h,int preferred_nid, +nodemask_t *nmask,gfp_t gfp_mask); +int hugetlb_add_to_page_cache (struct folio *folio,struct address_space *mapping,pgoff_t idx); void restore_reserve_on_error(struct hstate *h, struct vm_area_struct *vma,
@@ -1060,6 +1063,13 @@ static inline struct folio *alloc_hugetl {return NULL ; } + +static inline struct folio * +alloc_hugetlb_folio_reserve (struct hstate *h,int preferred_nid, +nodemask_t *nmask,gfp_t gfp_mask) +{ +return NULL ; +}static inline struct folio * alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid,
mm/hugetlb.c +17 -0
@@ -2564,6 +2564,23 @@ struct folio *alloc_buddy_hugetlb_folio_return folio; } +struct folio *alloc_hugetlb_folio_reserve (struct hstate *h,int preferred_nid, +nodemask_t *nmask,gfp_t gfp_mask) +{ +struct folio *folio; + +spin_lock_irq (&hugetlb_lock); + folio =dequeue_hugetlb_folio_nodemask (h, gfp_mask, preferred_nid, + nmask); +if (folio) { +VM_BUG_ON (!h->resv_huge_pages); + h->resv_huge_pages--; + } + +spin_unlock_irq (&hugetlb_lock); +return folio; +} +/* folio migration callback function */ struct folio *alloc_hugetlb_folio_nodemask (struct hstate *h,int preferred_nid,nodemask_t *nmask,gfp_t gfp_mask,bool allow_alloc_fallback)
mm/memfd.c +4 -5
@@ -82,11 +82,10 @@ struct folio *memfd_alloc_folio(struct f gfp_mask =htlb_alloc_mask (hstate_file (memfd)); gfp_mask &= ~(__GFP_HIGHMEM | __GFP_MOVABLE); - folio =alloc_hugetlb_folio_nodemask (hstate_file (memfd), -numa_node_id (), -NULL , - gfp_mask, - false); + folio =alloc_hugetlb_folio_reserve (hstate_file (memfd), +numa_node_id (), +NULL , + gfp_mask);if (folio &&folio_try_get (folio)) { err = hugetlb_add_to_page_cache(folio, memfd->f_mapping,
Greg Kroah-Hartman
maintainerPATCH 483/558 mm/gup: fix memfd_pin_folios hugetlb page allocation
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve Sistare <[email protected]>
commit 9289f020da47ef04b28865589eeee3d56d4bafea upstream.
When memfd_pin_folios -> memfd_alloc_folio creates a hugetlb page, the index is wrong. The subsequent call to filemap_get_folios_contig thus cannot find it, and fails, and memfd_pin_folios loops forever. To fix, adjust the index for the huge_page_order.
memfd_alloc_folio also forgets to unlock the folio, so the next touch of the page calls hugetlb_fault which blocks forever trying to take the lock. Unlock it.
--- mm/memfd.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
mm/memfd.c +7 -3
@@ -79,10 +79,13 @@ struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx)* alloc from. Also, the folio will be pinned for an indefinite * amount of time, so it is not expected to be migrated away. */ - gfp_mask =htlb_alloc_mask (hstate_file (memfd)); - gfp_mask &= ~(__GFP_HIGHMEM | __GFP_MOVABLE); +struct hstate *h =hstate_file (memfd); - folio =alloc_hugetlb_folio_reserve (hstate_file (memfd), + gfp_mask =htlb_alloc_mask (h); + gfp_mask &= ~(__GFP_HIGHMEM | __GFP_MOVABLE); + idx >>=huge_page_order (h); + + folio =alloc_hugetlb_folio_reserve (h,numa_node_id (),NULL , gfp_mask);
@@ -95,6 +98,7 @@ struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx)free_huge_folio (folio);return ERR_PTR (err); } +folio_unlock (folio);return folio; }return ERR_PTR (-ENOMEM );
Signature · 1 line
2.46.2
Greg Kroah-Hartman
maintainerPATCH 484/558 mm/gup: fix memfd_pin_folios alloc race panic
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve Sistare <[email protected]>
commit ce645b9fdc78ec5d28067286e92871ddae6817d5 upstream.
If memfd_pin_folios tries to create a hugetlb page, but someone else already did, then folio gets the value -EEXIST here:
folio = memfd_alloc_folio(memfd, start_idx);
if (IS_ERR(folio)) {
ret = PTR_ERR(folio);
if (ret != -EEXIST)
goto err;then on the next trip through the "while start_idx" loop we panic here:
if (folio) {
folio_put(folio);To fix, set the folio to NULL on error.
--- mm/gup.c | 1 + 1 file changed, 1 insertion(+)
mm/gup.c +1 -0
@@ -3705,6 +3705,7 @@ long memfd_pin_folios(struct file *memfd ret =PTR_ERR (folio);if (ret != -EEXIST ) goto err; + folio =NULL ; } } }
Greg Kroah-Hartman
maintainerPATCH 485/558 mm/hugetlb: simplify refs in memfd_alloc_folio
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve Sistare <[email protected]>
commit dc677b5f3765cfd0944c8873d1ea57f1a3439676 upstream.
The folio_try_get in memfd_alloc_folio is not necessary. Delete it, and delete the matching folio_put in memfd_pin_folios. This also avoids leaking a ref if the memfd_alloc_folio call to hugetlb_add_to_page_cache fails. That error path is also broken in a second way -- when its folio_put causes the ref to become 0, it will implicitly call free_huge_folio, but then the path *explicitly* calls free_huge_folio. Delete the latter.
This is a continuation of the fix
"mm/hugetlb: fix memfd_pin_folios free_huge_pages leak"
--- mm/gup.c | 4 +--- mm/memfd.c | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-)
mm/gup.c +1 -3
@@ -3618,7 +3618,7 @@ long memfd_pin_folios(struct file *memfdpgoff_t start_idx, end_idx, next_idx;struct folio *folio =NULL ;struct folio_batch fbatch; -struct hstate *h =NULL ; +struct hstate *h;long ret = -EINVAL ;if (start <0 || start > end || !max_folios)
@@ -3662,8 +3662,6 @@ long memfd_pin_folios(struct file *memfd &fbatch);if (folio) {folio_put (folio); -if (h) -folio_put (folio); folio =NULL ; }
mm/memfd.c +1 -2
@@ -89,13 +89,12 @@ struct folio *memfd_alloc_folio(struct fnuma_node_id (),NULL , gfp_mask); -if (folio &&folio_try_get (folio)) { +if (folio) { err =hugetlb_add_to_page_cache (folio, memfd->f_mapping, idx);if (err) {folio_put (folio); -free_huge_folio (folio);return ERR_PTR (err); }folio_unlock (folio);
Greg Kroah-Hartman
maintainerPATCH 486/558 Input: adp5589-keys - fix NULL pointer dereference
In reply to Greg Kroah-Hartman6.11-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 487/558 Input: adp5589-keys - fix adp5589_gpio_get_value()
In reply to Greg Kroah-Hartman6.11-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 488/558 HID: bpf: fix cfi stubs for hid_bpf_ops
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Tissoires <[email protected]>
commit acd5f76fd5292c91628e04da83e8b78c986cfa2b upstream.
With the introduction of commit e42ac1418055 ("bpf: Check unsupported ops from the bpf_struct_ops's cfi_stubs"), a HID-BPF struct_ops containing a .hid_hw_request() or a .hid_hw_output_report() was failing to load as the cfi stubs were not defined.
Fix that by defining those simple static functions and restore HID-BPF functionality.
This was detected with the HID selftests suddenly failing on Linus' tree.
--- drivers/hid/bpf/hid_bpf_struct_ops.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/hid/bpf/hid_bpf_struct_ops.c +14 -0
@@ -276,9 +276,23 @@ static int __hid_bpf_rdesc_fixup(struct hid_bpf_ctx *ctx)return 0 ; } +static int __hid_bpf_hw_request (struct hid_bpf_ctx *ctx,unsigned char reportnum, +enum hid_report_type rtype,enum hid_class_request reqtype, +u64 source) +{ +return 0 ; +} + +static int __hid_bpf_hw_output_report (struct hid_bpf_ctx *ctx,u64 source) +{ +return 0 ; +} +static struct hid_bpf_ops __bpf_hid_bpf_ops = { .hid_device_event = __hid_bpf_device_event, .hid_rdesc_fixup = __hid_bpf_rdesc_fixup, + .hid_hw_request = __hid_bpf_hw_request, + .hid_hw_output_report = __hid_bpf_hw_output_report, };static struct bpf_struct_ops bpf_hid_bpf_ops = {
Signature · 1 line
2.46.2
Greg Kroah-Hartman
maintainerPATCH 489/558 cachefiles: fix dentry leak in cachefiles_open_file()
In reply to Greg Kroah-Hartman6.11-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
@@ -595,14 +595,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;
@@ -611,7 +609,6 @@ error_fput:fput (file); error:cachefiles_do_unmark_inode_in_use (object,d_inode (dentry)); -dput (dentry);return false; }
@@ -654,7 +651,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 490/558 pidfs: check for valid pid namespace
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
commit 8a46067783bdff222d1fb8f8c20e3b7b711e3ce5 upstream.
When we access a no-current task's pid namespace we need check that the task hasn't been reaped in the meantime and it's pid namespace isn't accessible anymore.
The user namespace is fine because it is only released when the last reference to struct task_struct is put and exit_creds() is called.
--- fs/pidfs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/pidfs.c +4 -1
@@ -120,6 +120,7 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct nsproxy *nsp __free(put_nsproxy) = NULL;struct pid *pid =pidfd_pid (file);struct ns_common *ns_common =NULL ; +struct pid_namespace *pid_ns;if (arg)return -EINVAL ;
@@ -202,7 +203,9 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)case PIDFD_GET_PID_NAMESPACE :if (IS_ENABLED (CONFIG_PID_NS )) {rcu_read_lock (); - ns_common =to_ns_common (get_pid_ns (task_active_pid_ns (task))); + pid_ns =task_active_pid_ns (task); +if (pid_ns) + ns_common =to_ns_common (get_pid_ns (pid_ns));rcu_read_unlock (); }break ;
Signature · 1 line
2.46.2
Greg Kroah-Hartman
maintainerPATCH 491/558 ACPI: video: Add backlight=native quirk for Dell OptiPlex 5480 AIO
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit ac78288fe062b64e45a479eaae74aaaafcc8ecdd upstream.
Dell All In One (AIO) models released after 2017 may use a backlight controller board connected to an UART.
In DSDT this uart port will be defined as:
Name (_HID, "DELL0501")
Name (_CID, EisaId ("PNP0501")
The Dell OptiPlex 5480 AIO has an ACPI device for one of its UARTs with the above _HID + _CID. Loading the dell-uart-backlight driver fails with the following errors:
[ 18.261353] dell_uart_backlight serial0-0: Timed out waiting for response. [ 18.261356] dell_uart_backlight serial0-0: error -ETIMEDOUT: getting firmware version [ 18.261359] dell_uart_backlight serial0-0: probe with driver dell_uart_backlight failed with error -110
Indicating that there is no backlight controller board attached to the UART, while the GPU's native backlight control method does work.
Add a quirk to use the GPU's native backlight control method on this model.
--- drivers/acpi/video_detect.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/acpi/video_detect.c +9 -0
@@ -845,6 +845,15 @@ static const struct dmi_system_id video_* which need native backlight control nevertheless. */ { +/* https://github.com/zabbly/linux/issues/26 */ + .callback = video_detect_force_native, + /* Dell OptiPlex 5480 AIO */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"Dell Inc." ), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 5480 AIO"), + }, + }, + {/* https://bugzilla.redhat.com/show_bug.cgi?id=2303936 */ .callback = video_detect_force_native,/* Dell OptiPlex 7760 AIO */
Greg Kroah-Hartman
maintainerPATCH 492/558 ACPI: resource: Remove duplicate Asus E1504GAB IRQ override
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit 65bdebf38e5fac7c56a9e05d3479a707e6dc783c upstream.
Commit d2aaf1996504 ("ACPI: resource: Add DMI quirks for ASUS Vivobook E1504GA and E1504GAB") does exactly what the subject says, adding DMI matches for both the E1504GA and E1504GAB.
But DMI_MATCH() does a substring match, so checking for E1504GA will also match E1504GAB.
Drop the unnecessary E1504GAB entry since that is covered already by the E1504GA entry.
--- drivers/acpi/resource.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
drivers/acpi/resource.c +1 -8
@@ -511,20 +511,13 @@ static const struct dmi_system_id irq1_l }, }, { -/* Asus Vivobook E1504GA */ +/* Asus Vivobook E1504GA* */ .matches = {DMI_MATCH (DMI_SYS_VENDOR ,"ASUSTeK COMPUTER INC." ), DMI_MATCH(DMI_BOARD_NAME, "E1504GA"), }, }, { -/* Asus Vivobook E1504GAB */ - .matches = { -DMI_MATCH (DMI_SYS_VENDOR ,"ASUSTeK COMPUTER INC." ), - DMI_MATCH(DMI_BOARD_NAME, "E1504GAB"), - }, - }, - {/* Asus Vivobook Pro N6506MV */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
Greg Kroah-Hartman
maintainerPATCH 493/558 ACPI: resource: Loosen the Asus E1404GAB DMI match to also cover the E1404GA
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit 63539defee17bf0cbd8e24078cf103efee9c6633 upstream.
Like other Asus Vivobooks, the Asus Vivobook Go E1404GA has a DSDT describing IRQ 1 as ActiveLow, while the kernel overrides to Edge_High.
$ sudo dmesg | grep DMI:.*BIOS
[ 0.000000] DMI: ASUSTeK COMPUTER INC. Vivobook Go E1404GA_E1404GA/E1404GA, BIOS E1404GA.302 08/23/2023
$ sudo cp /sys/firmware/acpi/tables/DSDT dsdt.dat
$ iasl -d dsdt.dat
$ grep -A 30 PS2K dsdt.dsl | grep IRQ -A 1
IRQ (Level, ActiveLow, Exclusive, )
{1}There already is an entry in the irq1_level_low_skip_override[] DMI match table for the "E1404GAB", change this to match on "E1404GA" to cover the E1404GA model as well (DMI_MATCH() does a substring match).
--- drivers/acpi/resource.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/acpi/resource.c +2 -2
@@ -504,10 +504,10 @@ static const struct dmi_system_id irq1_l }, }, { -/* Asus Vivobook Go E1404GAB */ +/* Asus Vivobook Go E1404GA* */ .matches = {DMI_MATCH (DMI_SYS_VENDOR ,"ASUSTeK COMPUTER INC." ), - DMI_MATCH(DMI_BOARD_NAME, "E1404GAB"), + DMI_MATCH(DMI_BOARD_NAME, "E1404GA"), }, }, {
Greg Kroah-Hartman
maintainerPATCH 494/558 ACPI: resource: Add Asus Vivobook X1704VAP to irq1_level_low_skip_override[]
In reply to Greg Kroah-Hartman6.11-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
@@ -441,6 +441,13 @@ static const struct dmi_system_id irq1_l }, }, { +/* Asus Vivobook X1704VAP */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"ASUSTeK COMPUTER INC." ), + DMI_MATCH(DMI_BOARD_NAME, "X1704VAP"), + }, + }, + {/* Asus ExpertBook B1402CBA */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
Greg Kroah-Hartman
maintainerPATCH 495/558 ACPI: resource: Add Asus ExpertBook B2502CVA to irq1_level_low_skip_override[]
In reply to Greg Kroah-Hartman6.11-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
@@ -511,6 +511,13 @@ static const struct dmi_system_id irq1_l }, }, { +/* Asus ExpertBook B2502CVA */ + .matches = { +DMI_MATCH (DMI_SYS_VENDOR ,"ASUSTeK COMPUTER INC." ), + DMI_MATCH(DMI_BOARD_NAME, "B2502CVA"), + }, + }, + {/* Asus Vivobook Go E1404GA* */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
Greg Kroah-Hartman
maintainerPATCH 496/558 btrfs: send: fix buffer overflow detection when copying path to cache entry
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 96c6ca71572a3556ed0c37237305657ff47174b7 upstream.
Starting with commit c0247d289e73 ("btrfs: send: annotate struct name_cache_entry with __counted_by()") we annotated the variable length array "name" from the name_cache_entry structure with __counted_by() to improve overflow detection. However that alone was not correct, because the length of that array does not match the "name_len" field - it matches that plus 1 to include the NUL string terminator, so that makes a fortified kernel think there's an overflow and report a splat like this:
strcpy: detected buffer overflow: 20 byte write of buffer size 19
WARNING: CPU: 3 PID: 3310 at __fortify_report+0x45/0x50 CPU: 3 UID: 0 PID: 3310 Comm: btrfs Not tainted 6.11.0-prnet #1 Hardware name: CompuLab Ltd. sbc-ihsw/Intense-PC2 (IPC2), BIOS IPC2_3.330.7 X64 03/15/2018 RIP: 0010:__fortify_report+0x45/0x50 Code: 48 8b 34 (...) RSP: 0018:ffff97ebc0d6f650 EFLAGS: 00010246 RAX: 7749924ef60fa600 RBX: ffff8bf5446a521a RCX: 0000000000000027 RDX: 00000000ffffdfff RSI: ffff97ebc0d6f548 RDI: ffff8bf84e7a1cc8 RBP: ffff8bf548574080 R08: ffffffffa8c40e10 R09: 0000000000005ffd R10: 0000000000000004 R11: ffffffffa8c70e10 R12: ffff8bf551eef400 R13: 0000000000000000 R14: 0000000000000013 R15: 00000000000003a8 FS: 00007fae144de8c0(0000) GS:ffff8bf84e780000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fae14691690 CR3: 00000001027a2003 CR4: 00000000001706f0 Call Trace: <TASK> ? __warn+0x12a/0x1d0 ? __fortify_report+0x45/0x50 ? report_bug+0x154/0x1c0 ? handle_bug+0x42/0x70 ? exc_invalid_op+0x1a/0x50 ? asm_exc_invalid_op+0x1a/0x20 ? __fortify_report+0x45/0x50 __fortify_panic+0x9/0x10 __get_cur_name_and_parent+0x3bc/0x3c0 get_cur_path+0x207/0x3b0 send_extent_data+0x709/0x10d0 ? find_parent_nodes+0x22df/0x25d0 ? mas_nomem+0x13/0x90 ? mtree_insert_range+0xa5/0x110 ? btrfs_lru_cache_store+0x5f/0x1e0 ? iterate_extent_inodes+0x52d/0x5a0 process_extent+0xa96/0x11a0 ? __pfx_lookup_backref_cache+0x10/0x10 ? __pfx_store_backref_cache+0x10/0x10 ? __pfx_iterate_backrefs+0x10/0x10 ? __pfx_check_extent_item+0x10/0x10 changed_cb+0x6fa/0x930 ? tree_advance+0x362/0x390 ? memcmp_extent_buffer+0xd7/0x160 send_subvol+0xf0a/0x1520 btrfs_ioctl_send+0x106b/0x11d0 ? __pfx___clone_root_cmp_sort+0x10/0x10 _btrfs_ioctl_send+0x1ac/0x240 btrfs_ioctl+0x75b/0x850 __se_sys_ioctl+0xca/0x150 do_syscall_64+0x85/0x160 ? __count_memcg_events+0x69/0x100 ? handle_mm_fault+0x1327/0x15c0 ? __se_sys_rt_sigprocmask+0xf1/0x180 ? syscall_exit_to_user_mode+0x75/0xa0 ? do_syscall_64+0x91/0x160 ? do_user_addr_fault+0x21d/0x630 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7fae145eeb4f Code: 00 48 89 (...) RSP: 002b:00007ffdf1cb09b0 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007fae145eeb4f RDX: 00007ffdf1cb0ad0 RSI: 0000000040489426 RDI: 0000000000000004 RBP: 00000000000078fe R08: 00007fae144006c0 R09: 00007ffdf1cb0927 R10: 0000000000000008 R11: 0000000000000246 R12: 00007ffdf1cb1ce8 R13: 0000000000000003 R14: 000055c499fab2e0 R15: 0000000000000004 </TASK>
Fix this by not storing the NUL string terminator since we don't actually need it for name cache entries, this way "name_len" corresponds to the actual size of the "name" array. This requires marking the "name" array field with __nonstring and using memcpy() instead of strcpy() as recommended by the guidelines at:
https://github.com/KSPP/linux/issues/90
--- fs/btrfs/send.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
fs/btrfs/send.c +5 -3
@@ -346,8 +346,10 @@ struct name_cache_entry {u64 parent_gen;int ret;int need_later_update; +/* Name length without NUL terminator. */ int name_len; - char name[] __counted_by(name_len); +/* Not NUL terminated. */ + char name[] __counted_by(name_len) __nonstring; };/* See the comment at lru_cache.h about struct btrfs_lru_cache_entry. */
@@ -2388,7 +2390,7 @@ out_cache:/* * Store the result of the lookup in the name cache. */ - nce =kmalloc (sizeof (*nce) +fs_path_len (dest) +1 ,GFP_KERNEL ); + nce =kmalloc (sizeof (*nce) +fs_path_len (dest),GFP_KERNEL );if (!nce) { ret = -ENOMEM ; goto out;
@@ -2400,7 +2402,7 @@ out_cache: nce->parent_gen = *parent_gen; nce->name_len =fs_path_len (dest); nce->ret = ret; -strcpy (nce->name, dest->start); +memcpy (nce->name, dest->start, nce->name_len);if (ino < sctx->send_progress) nce->need_later_update =0 ;
Signature · 1 line
2.46.2
Greg Kroah-Hartman
maintainerPATCH 497/558 btrfs: fix a NULL pointer dereference when failed to start a new trasacntion
In reply to Greg Kroah-Hartman6.11-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
@@ -923,7 +923,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 498/558 btrfs: drop the backref cache during relocation if we commit
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
commit db7e68b522c01eb666cfe1f31637775f18997811 upstream.
Since the inception of relocation we have maintained the backref cache across transaction commits, updating the backref cache with the new bytenr whenever we COWed blocks that were in the cache, and then updating their bytenr once we detected a transaction id change.
This works as long as we're only ever modifying blocks, not changing the structure of the tree.
However relocation does in fact change the structure of the tree. For example, if we are relocating a data extent, we will look up all the leaves that point to this data extent. We will then call do_relocation() on each of these leaves, which will COW down to the leaf and then update the file extent location.
But, a key feature of do_relocation() is the pending list. This is all the pending nodes that we modified when we updated the file extent item. We will then process all of these blocks via finish_pending_nodes, which calls do_relocation() on all of the nodes that led up to that leaf.
The purpose of this is to make sure we don't break sharing unless we absolutely have to. Consider the case that we have 3 snapshots that all point to this leaf through the same nodes, the initial COW would have created a whole new path. If we did this for all 3 snapshots we would end up with 3x the number of nodes we had originally. To avoid this we will cycle through each of the snapshots that point to each of these nodes and update their pointers to point at the new nodes.
Once we update the pointer to the new node we will drop the node we removed the link for and all of its children via btrfs_drop_subtree(). This is essentially just btrfs_drop_snapshot(), but for an arbitrary point in the snapshot.
The problem with this is that we will never reflect this in the backref cache. If we do this btrfs_drop_snapshot() for a node that is in the backref tree, we will leave the node in the backref tree. This becomes a problem when we change the transid, as now the backref cache has entire subtrees that no longer exist, but exist as if they still are pointed to by the same roots.
In the best case scenario you end up with "adding refs to an existing tree ref" errors from insert_inline_extent_backref(), where we attempt to link in nodes on roots that are no longer valid.
Worst case you will double free some random block and re-use it when there's still references to the block.
This is extremely subtle, and the consequences are quite bad. There isn't a way to make sure our backref cache is consistent between transid's.
In order to fix this we need to simply evict the entire backref cache anytime we cross transid's. This reduces performance in that we have to rebuild this backref cache every time we change transid's, but fixes the bug.
This has existed since relocation was added, and is a pretty critical bug. There's a lot more cleanup that can be done now that this functionality is going away, but this patch is as small as possible in order to fix the problem and make it easy for us to backport it to all the kernels it needs to be backported to.
Followup series will dismantle more of this code and simplify relocation drastically to remove this functionality.
We have a reproducer that reproduced the corruption within a few minutes of running. With this patch it survives several iterations/hours of running the reproducer.
--- fs/btrfs/backref.c | 12 +++++--- fs/btrfs/relocation.c | 75 ++------------------------------------------------ 2 files changed, 11 insertions(+), 76 deletions(-)
fs/btrfs/backref.c +8 -4
@@ -3179,10 +3179,14 @@ void btrfs_backref_release_cache(structbtrfs_backref_cleanup_node (cache, node); } - cache->last_trans =0 ; - -for (i =0 ; i <BTRFS_MAX_LEVEL ; i++) -ASSERT (list_empty (&cache->pending[i])); +for (i =0 ; i <BTRFS_MAX_LEVEL ; i++) { +while (!list_empty (&cache->pending[i])) { + node =list_first_entry (&cache->pending[i], + struct btrfs_backref_node, + list); +btrfs_backref_cleanup_node (cache, node); + } + }ASSERT (list_empty (&cache->pending_edge));ASSERT (list_empty (&cache->useless_node));ASSERT (list_empty (&cache->changed));
fs/btrfs/relocation.c +3 -72
93 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 499/558 btrfs: send: fix invalid clone operation for file that got its size decreased
In reply to Greg Kroah-Hartman6.11-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
@@ -6189,8 +6189,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 500/558 btrfs: wait for fixup workers before stopping cleaner kthread during umount
In reply to Greg Kroah-Hartman6.11-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
@@ -4266,6 +4266,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 501/558 cpufreq: Avoid a bad reference count on CPU node
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Sabaté Solà <[email protected]>
commit c0f02536fffbbec71aced36d52a765f8c4493dc2 upstream.
In the parse_perf_domain function, if the call to of_parse_phandle_with_args returns an error, then the reference to the CPU device node that was acquired at the start of the function would not be properly decremented.
Address this by declaring the variable with the __free(device_node) cleanup attribute.
--- include/linux/cpufreq.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
include/linux/cpufreq.h +1 -5
@@ -1113,10 +1113,9 @@ static inline int parse_perf_domain(intconst char *cell_name, struct of_phandle_args *args) { - struct device_node *cpu_np; int ret; - cpu_np =of_cpu_device_node_get (cpu); + struct device_node *cpu_np __free(device_node) = of_cpu_device_node_get(cpu);if (!cpu_np)return -ENODEV ;
@@ -1124,9 +1123,6 @@ static inline int parse_perf_domain(int args);if (ret <0 )return ret; - -of_node_put (cpu_np); -return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 502/558 cpufreq: intel_pstate: Make hwp_notify_lock a raw spinlock
In reply to Greg Kroah-Hartman6.11-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 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/cpufreq/intel_pstate.c +8 -8
@@ -1623,7 +1623,7 @@ static void intel_pstate_notify_work(strwrmsrl_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;#define HWP_GUARANTEED_PERF_CHANGE_STATUS BIT(0)
@@ -1646,7 +1646,7 @@ void notify_hwp_interrupt(void)if (!(value & status_mask))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;
@@ -1654,13 +1654,13 @@ void notify_hwp_interrupt(void)schedule_delayed_work (&all_cpu_data[this_cpu]->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)
@@ -1673,9 +1673,9 @@ static void intel_pstate_disable_hwp_int/* 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_irq (&hwp_notify_lock); +raw_spin_lock_irq (&hwp_notify_lock); cancel_work =cpumask_test_and_clear_cpu (cpudata->cpu, &hwp_intr_enable_mask); -spin_unlock_irq (&hwp_notify_lock); +raw_spin_unlock_irq (&hwp_notify_lock);if (cancel_work)cancel_delayed_work_sync (&cpudata->hwp_notify_work);
@@ -1690,10 +1690,10 @@ static void intel_pstate_enable_hwp_inteif (boot_cpu_has (X86_FEATURE_HWP_NOTIFY )) {u64 interrupt_mask =HWP_GUARANTEED_PERF_CHANGE_REQ ; -spin_lock_irq (&hwp_notify_lock); +raw_spin_lock_irq (&hwp_notify_lock);INIT_DELAYED_WORK (&cpudata->hwp_notify_work, intel_pstate_notify_work);cpumask_set_cpu (cpudata->cpu, &hwp_intr_enable_mask); -spin_unlock_irq (&hwp_notify_lock); +raw_spin_unlock_irq (&hwp_notify_lock);if (cpu_feature_enabled (X86_FEATURE_HWP_HIGHEST_PERF_CHANGE )) interrupt_mask |=HWP_HIGHEST_PERF_CHANGE_REQ ;
Greg Kroah-Hartman
maintainerPATCH 503/558 gpio: davinci: fix lazy disable
In reply to Greg Kroah-Hartman6.11-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
@@ -289,7 +289,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);
@@ -298,7 +298,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);
@@ -324,8 +324,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 504/558 net: pcs: xpcs: fix the wrong register that was written back
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiawen Wu <[email protected]>
commit 93ef6ee5c20e9330477930ec6347672c9e0cf5a6 upstream.
The value is read from the register TXGBE_RX_GEN_CTL3, and it should be written back to TXGBE_RX_GEN_CTL3 when it changes some fields.
--- drivers/net/pcs/pcs-xpcs-wx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/pcs/pcs-xpcs-wx.c +1 -1
@@ -109,7 +109,7 @@ static void txgbe_pma_config_1g(struct dtxgbe_write_pma (xpcs,TXGBE_DFE_TAP_CTL0 ,0 ); val =txgbe_read_pma (xpcs,TXGBE_RX_GEN_CTL3 ); val =u16_replace_bits (val,0x4 ,TXGBE_RX_GEN_CTL3_LOS_TRSHLD0 ); -txgbe_write_pma (xpcs,TXGBE_RX_EQ_ATTN_CTL , val); +txgbe_write_pma (xpcs,TXGBE_RX_GEN_CTL3 , val);txgbe_write_pma (xpcs,TXGBE_MPLLA_CTL0 ,0x20 );txgbe_write_pma (xpcs,TXGBE_MPLLA_CTL3 ,0x46 );
Greg Kroah-Hartman
maintainerPATCH 505/558 Bluetooth: hci_event: Align BR/EDR JUST_WORKS paring with LE
In reply to Greg Kroah-Hartman6.11-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
@@ -5324,19 +5324,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 506/558 mac802154: Fix potential RCU dereference issue in mac802154_scan_worker
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiawei Ye <[email protected]>
commit bff1709b3980bd7f80be6786f64cc9a9ee9e56da upstream.
In the mac802154_scan_worker function, the scan_req->type field was accessed after the RCU read-side critical section was unlocked. According to RCU usage rules, this is illegal and can lead to unpredictable behavior, such as accessing memory that has been updated or causing use-after-free issues.
This possible bug was identified using a static analysis tool developed by myself, specifically designed to detect RCU-related issues.
To address this, the scan_req->type value is now stored in a local variable scan_req_type while still within the RCU read-side critical section. The scan_req_type is then used after the RCU lock is released, ensuring that the type value is safely accessed without violating RCU rules.
--- net/mac802154/scan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/mac802154/scan.c +3 -1
@@ -176,6 +176,7 @@ void mac802154_scan_worker(struct work_sstruct ieee802154_local *local = container_of(work, struct ieee802154_local, scan_work.work);struct cfg802154_scan_request *scan_req; +enum nl802154_scan_types scan_req_type;struct ieee802154_sub_if_data *sdata;unsigned int scan_duration =0 ;struct wpan_phy *wpan_phy;
@@ -209,6 +210,7 @@ void mac802154_scan_worker(struct work_s } wpan_phy = scan_req->wpan_phy; + scan_req_type = scan_req->type; scan_req_duration = scan_req->duration;/* Look for the next valid chan */
@@ -246,7 +248,7 @@ void mac802154_scan_worker(struct work_s goto end_scan; } -if (scan_req->type ==NL802154_SCAN_ACTIVE ) { +if (scan_req_type ==NL802154_SCAN_ACTIVE ) { ret =mac802154_transmit_beacon_req (local, sdata);if (ret) dev_err(&sdata->dev->dev,
Greg Kroah-Hartman
maintainerPATCH 507/558 io_uring/net: harden multishot termination case for recv
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
commit c314094cb4cfa6fc5a17f4881ead2dfebfa717a7 upstream.
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
@@ -1126,6 +1126,7 @@ int io_recv(struct io_kiocb *req, unsignint 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 ))
@@ -1180,6 +1181,7 @@ out_free:req_set_fail (req); } + mshot_finished = ret <=0 ;if (ret >0 ) ret += sr->done_io;else if (sr->done_io)
@@ -1187,7 +1189,7 @@ out_free:else io_kbuf_recycle (req, issue_flags); -if (!io_recv_finish (req, &ret, kmsg, ret <=0 , issue_flags)) +if (!io_recv_finish (req, &ret, kmsg, mshot_finished, issue_flags)) goto retry_multishot;return ret;
Greg Kroah-Hartman
maintainerPATCH 508/558 ceph: fix cap ref leak via netfs init_request
In reply to Greg Kroah-Hartman6.11-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
@@ -473,8 +473,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 509/558 tracing/hwlat: Fix a race during cpuhp processing
In reply to Greg Kroah-Hartman6.11-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 510/558 tracing/timerlat: Drop interface_lock in stop_kthread()
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Li <[email protected]>
commit b484a02c9cedf8703eff8f0756f94618004bd165 upstream.
stop_kthread() is the offline callback for "trace/osnoise:online", since commit 5bfbcd1ee57b ("tracing/timerlat: Add interface_lock around clearing of kthread in stop_kthread()"), the following ABBA deadlock scenario is introduced:
T1 | T2 [BP] | T3 [AP]
osnoise_hotplug_workfn() | work_for_cpu_fn() | cpuhp_thread_fun()
| _cpu_down() | osnoise_cpu_die()
mutex_lock(&interface_lock) | | stop_kthread()
| cpus_write_lock() | mutex_lock(&interface_lock)
cpus_read_lock() | cpuhp_kick_ap() |As the interface_lock here in just for protecting the "kthread" field of the osn_var, use xchg() instead to fix this issue. Also use for_each_online_cpu() back in stop_per_cpu_kthreads() as it can take cpu_read_lock() again.
--- kernel/trace/trace_osnoise.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
kernel/trace/trace_osnoise.c +6 -7
@@ -1953,12 +1953,8 @@ static void stop_kthread(unsigned int cp {struct task_struct *kthread; -mutex_lock (&interface_lock); - kthread =per_cpu (per_cpu_osnoise_var, cpu).kthread; + kthread =xchg_relaxed (&(per_cpu (per_cpu_osnoise_var, cpu).kthread),NULL );if (kthread) { -per_cpu (per_cpu_osnoise_var, cpu).kthread =NULL ; -mutex_unlock (&interface_lock); -if (cpumask_test_and_clear_cpu (cpu, &kthread_cpumask) && !WARN_ON (!test_bit (OSN_WORKLOAD , &osnoise_options))) {kthread_stop (kthread);
@@ -1972,7 +1968,6 @@ static void stop_kthread(unsigned int cpput_task_struct (kthread); } }else { -mutex_unlock (&interface_lock);/* if no workload, just return */ if (!test_bit (OSN_WORKLOAD , &osnoise_options)) {/*
@@ -1994,8 +1989,12 @@ static void stop_per_cpu_kthreads(void) {int cpu; -for_each_possible_cpu (cpu) +cpus_read_lock (); + +for_each_online_cpu (cpu)stop_kthread (cpu); + +cpus_read_unlock (); }/*
Greg Kroah-Hartman
maintainerPATCH 511/558 tracing/timerlat: Fix a race during cpuhp processing
In reply to Greg Kroah-Hartman6.11-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
@@ -2094,6 +2094,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 512/558 tracing/timerlat: Fix duplicated kthread creation due to CPU online/offline
In reply to Greg Kroah-Hartman6.11-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Li <[email protected]>
commit 0bb0a5c12ecf36ad561542bbb95f96355e036a02 upstream.
osnoise_hotplug_workfn() is the asynchronous online callback for "trace/osnoise:online". It may be congested when a CPU goes online and offline repeatedly and is invoked for multiple times after a certain online.
This will lead to kthread leak and timer corruption. Add a check in start_kthread() to prevent this situation.
--- kernel/trace/trace_osnoise.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
kernel/trace/trace_osnoise.c +5 -2
@@ -2006,6 +2006,10 @@ static int start_kthread(unsigned int cpvoid *main = osnoise_main;char comm[24 ]; +/* Do not start a new thread if it is already running */ +if (per_cpu (per_cpu_osnoise_var, cpu).kthread) +return 0 ; +if (timerlat_enabled ()) {snprintf (comm,24 ,"timerlat/%d" , cpu); main = timerlat_main;
@@ -2060,11 +2064,10 @@ static int start_per_cpu_kthreads(void)if (cpumask_test_and_clear_cpu (cpu, &kthread_cpumask)) {struct task_struct *kthread; - kthread =per_cpu (per_cpu_osnoise_var, cpu).kthread; + kthread =xchg_relaxed (&(per_cpu (per_cpu_osnoise_var, cpu).kthread),NULL );if (!WARN_ON (!kthread))kthread_stop (kthread); } -per_cpu (per_cpu_osnoise_var, cpu).kthread =NULL ; }for_each_cpu (cpu, current_mask) {