4.19.105-stable review
Subsystems (2)
Greg Kroah-Hartman
maintainercover 4.19.105-stable review
This is the start of the stable review cycle for the 4.19.105 release. There are 38 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 20 Feb 2020 19:03:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.105-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.19.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.19.105-rc1
Sean Christopherson <[email protected]>
KVM: x86/mmu: Fix struct guest_walker arrays for 5-level paging
zhangyi (F) <[email protected]>
jbd2: do not clear the BH_Mapped flag when forgetting a metadata buffer
zhangyi (F) <[email protected]>
jbd2: move the clearing of b_modified flag to the journal_unmap_buffer()
Olga Kornievskaia <[email protected]>
NFSv4.1 make cachethis=no for writes
Mike Jones <[email protected]>
hwmon: (pmbus/ltc2978) Fix PMBus polling of MFR_COMMON definitions.
Kan Liang <[email protected]>
perf/x86/intel: Fix inaccurate period in context switch for auto-reload
Nathan Chancellor <[email protected]>
s390/time: Fix clk type in get_tod_clock
Leon Romanovsky <[email protected]>
RDMA/core: Fix protection fault in get_pkey_idx_qp_list
Zhu Yanjun <[email protected]>
RDMA/rxe: Fix soft lockup problem due to using tasklets in softirq
Kamal Heib <[email protected]>
RDMA/hfi1: Fix memory leak in _dev_comp_vect_mappings_create
Avihai Horon <[email protected]>
RDMA/core: Fix invalid memory access in spec_filter_size
Kaike Wan <[email protected]>
IB/rdmavt: Reset all QPs when the device is shut down
Mike Marciniszyn <[email protected]>
IB/hfi1: Close window for pq and request coliding
Kaike Wan <[email protected]>
IB/hfi1: Acquire lock to release TID entries when user file is closed
Yi Zhang <[email protected]>
nvme: fix the parameter order for nvme_get_log in nvme_get_fw_slot_info
Kim Phillips <[email protected]>
perf/x86/amd: Add missing L2 misses event spec to AMD Family 17h's event map
Sean Christopherson <[email protected]>
KVM: nVMX: Use correct root level for nested EPT shadow page tables
Will Deacon <[email protected]>
arm64: ssbs: Fix context-switch when SSBS is present on all CPUs
Krzysztof Kozlowski <[email protected]>
ARM: npcm: Bring back GPIOLIB support
David Sterba <[email protected]>
btrfs: log message when rw remount is attempted with unclean tree-log
David Sterba <[email protected]>
btrfs: print message when tree-log replay starts
Wenwen Wang <[email protected]>
btrfs: ref-verify: fix memory leaks
Filipe Manana <[email protected]>
Btrfs: fix race between using extent maps and merging them
Theodore Ts'o <[email protected]>
ext4: improve explanation of a mount failure caused by a misconfigured kernel
Shijie Luo <[email protected]>
ext4: add cond_resched() to ext4_protect_reserved_inode
Jan Kara <[email protected]>
ext4: fix checksum errors with indexed dirs
Theodore Ts'o <[email protected]>
ext4: fix support for inode sizes > 1024 bytes
Andreas Dilger <[email protected]>
ext4: don't assume that mmp_nodename/bdevname have NUL
Alexander Tsoy <[email protected]>
ALSA: usb-audio: Add clock validity quirk for Denon MC7000/MCX8000
Saurav Girepunje <[email protected]>
ALSA: usb-audio: sound: usb: usb true/false for bool return type
Suzuki K Poulose <[email protected]>
arm64: nofpsmid: Handle TIF_FOREIGN_FPSTATE flag cleanly
Suzuki K Poulose <[email protected]>
arm64: cpufeature: Set the FP/SIMD compat HWCAP bits properly
Arvind Sankar <[email protected]>
ALSA: usb-audio: Apply sample rate quirk for Audioengine D1
Takashi Iwai <[email protected]>
ALSA: hda/realtek - Fix silent output on MSI-GL73
Takashi Iwai <[email protected]>
ALSA: usb-audio: Fix UAC2/3 effect unit parsing
Benjamin Tissoires <[email protected]>
Input: synaptics - remove the LEN0049 dmi id from topbuttonpad list
Gaurav Agrawal <[email protected]>
Input: synaptics - enable SMBus on ThinkPad L470
Lyude Paul <[email protected]>
Input: synaptics - switch T470s to RMI4 by default
-------------
Diffstat:
Makefile | 4 +- arch/arm/mach-npcm/Kconfig | 2 +- arch/arm64/kernel/cpufeature.c | 52 +++++++++++++--- arch/arm64/kernel/fpsimd.c | 20 ++++++- arch/arm64/kernel/process.c | 7 +++ arch/arm64/kvm/hyp/switch.c | 10 +++- arch/s390/include/asm/timex.h | 2 +- arch/x86/events/amd/core.c | 1 + arch/x86/events/intel/ds.c | 2 + arch/x86/kvm/paging_tmpl.h | 2 +- arch/x86/kvm/vmx/vmx.c | 3 + drivers/hwmon/pmbus/ltc2978.c | 4 +- drivers/infiniband/core/security.c | 24 +++----- drivers/infiniband/core/uverbs_cmd.c | 15 +++-- drivers/infiniband/hw/hfi1/affinity.c | 2 + drivers/infiniband/hw/hfi1/file_ops.c | 52 +++++++++------- drivers/infiniband/hw/hfi1/hfi.h | 5 +- drivers/infiniband/hw/hfi1/user_exp_rcv.c | 5 +- drivers/infiniband/hw/hfi1/user_sdma.c | 17 ++++-- drivers/infiniband/sw/rdmavt/qp.c | 84 +++++++++++++++----------- drivers/infiniband/sw/rxe/rxe_comp.c | 8 +-- drivers/input/mouse/synaptics.c | 4 +- drivers/nvme/host/core.c | 2 +- fs/btrfs/disk-io.c | 1 + fs/btrfs/extent_map.c | 11 ++++ fs/btrfs/ref-verify.c | 5 ++ fs/btrfs/super.c | 2 + fs/ext4/block_validity.c | 1 + fs/ext4/dir.c | 14 +++-- fs/ext4/ext4.h | 5 +- fs/ext4/inode.c | 12 ++++ fs/ext4/mmp.c | 12 ++-- fs/ext4/namei.c | 7 +++ fs/ext4/super.c | 32 +++++----- fs/jbd2/commit.c | 46 +++++++------- fs/jbd2/transaction.c | 10 ++-- fs/nfs/nfs4proc.c | 2 +- sound/pci/hda/patch_realtek.c | 1 + sound/usb/clock.c | 99 +++++++++++++++++++++---------- sound/usb/clock.h | 4 +- sound/usb/format.c | 3 +- sound/usb/mixer.c | 12 +++- sound/usb/quirks.c | 1 + 43 files changed, 405 insertions(+), 202 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/38 Input: synaptics - switch T470s to RMI4 by default
From: Lyude Paul <[email protected]>
commit bf502391353b928e63096127e5fd8482080203f5 upstream.
This supports RMI4 and everything seems to work, including the touchpad buttons. So, let's enable this by default.
--- drivers/input/mouse/synaptics.c | 1 + 1 file changed, 1 insertion(+)
drivers/input/mouse/synaptics.c +1 -0
@@ -172,6 +172,7 @@ static const char * const smbus_pnp_ids["LEN004a" ,/* W541 */ "LEN005b" ,/* P50 */ "LEN005e" ,/* T560 */ +"LEN006c" ,/* T470s */ "LEN0071" ,/* T480 */ "LEN0072" ,/* X1 Carbon Gen 5 (2017) - Elan/ALPS trackpoint */ "LEN0073", /* X1 Carbon G5 (Elantech) */
Greg Kroah-Hartman
maintainerPATCH 2/38 Input: synaptics - enable SMBus on ThinkPad L470
In reply to Greg Kroah-HartmanFrom: Gaurav Agrawal <[email protected]>
commit b8a3d819f872e0a3a0a6db0dbbcd48071042fb98 upstream.
Add touchpad LEN2044 to the list, as it is capable of working with psmouse.synaptics_intertouch=1
--- drivers/input/mouse/synaptics.c | 1 + 1 file changed, 1 insertion(+)
drivers/input/mouse/synaptics.c +1 -0
@@ -183,6 +183,7 @@ static const char * const smbus_pnp_ids["LEN0097" ,/* X280 -> ALPS trackpoint */ "LEN009b" ,/* T580 */ "LEN200f" ,/* T450s */ +"LEN2044" ,/* L470 */ "LEN2054" ,/* E480 */ "LEN2055" ,/* E580 */ "SYN3052", /* HP EliteBook 840 G4 */
Greg Kroah-Hartman
maintainerPATCH 3/38 Input: synaptics - remove the LEN0049 dmi id from topbuttonpad list
In reply to Greg Kroah-HartmanFrom: Benjamin Tissoires <[email protected]>
commit 5179a9dfa9440c1781816e2c9a183d1d2512dc61 upstream.
The Yoga 11e is using LEN0049, but it doesn't have a trackstick.
Thus, there is no need to create a software top buttons row.
However, it seems that the device works under SMBus, so keep it as part of the smbus_pnp_ids.
--- drivers/input/mouse/synaptics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/mouse/synaptics.c +1 -1
@@ -149,7 +149,6 @@ static const char * const topbuttonpad_p"LEN0042" ,/* Yoga */ "LEN0045" ,"LEN0047" , -"LEN0049" ,"LEN2000" ,/* S540 */ "LEN2001" ,/* Edge E431 */ "LEN2002", /* Edge E531 */
@@ -169,6 +168,7 @@ static const char * const smbus_pnp_ids[/* all of the topbuttonpad_pnp_ids are valid, we just add some extras */ "LEN0048" ,/* X1 Carbon 3 */ "LEN0046" ,/* X250 */ +"LEN0049" ,/* Yoga 11e */ "LEN004a" ,/* W541 */ "LEN005b" ,/* P50 */ "LEN005e", /* T560 */
Greg Kroah-Hartman
maintainerPATCH 4/38 ALSA: usb-audio: Fix UAC2/3 effect unit parsing
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit d75a170fd848f037a1e28893ad10be7a4c51f8a6 upstream.
We've got a regression report about M-Audio Fast Track C400 device, and the git bisection resulted in the commit e0ccdef92653 ("ALSA:
usb-audio: Clean up check_input_term()"). This commit was about the rewrite of the input terminal parser, and it's not too obvious from the change what really broke. The answer is: it's the interpretation of UAC2/3 effect units.
In the original code, UAC2 effect unit is as if through UAC1 processing unit because both UAC1 PU and UAC2/3 EU share the same number (0x07). The old code went through a complex switch-case fallthrough, finally bailing out in the middle:
if (protocol == UAC_VERSION_2 &&
hdr[2] == UAC2_EFFECT_UNIT) {
/* UAC2/UAC1 unit IDs overlap here in an
* uncompatible way. Ignore this unit for now.
*/
return 0;}
... and this special handling was missing in the new code; the new code treats UAC2/3 effect unit as if it were equivalent with the processing unit.
Actually, the old code was too confusing. The effect unit has an incompatible unit description with the processing unit, so we shouldn't have dealt with EU in the same way.
This patch addresses the regression by changing the effect unit handling to the own parser function. The own parser function makes the clear distinct with PU, so it improves the readability, too.
The EU parser just sets the type and the id like the old kernels. Once when the proper effect unit support is added, we can revisit this parser function, but for now, let's keep this simple setup as is.
--- sound/usb/mixer.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
sound/usb/mixer.c +10 -2
@@ -912,6 +912,15 @@ static int parse_term_proc_unit(struct mreturn 0 ; } +static int parse_term_effect_unit (struct mixer_build *state, +struct usb_audio_term *term, +void *p1,int id) +{ + term->type =UAC3_EFFECT_UNIT <<16 ;/* virtual type */ + term->id = id; +return 0 ; +} +static int parse_term_uac2_clock_source (struct mixer_build *state,struct usb_audio_term *term,void *p1,int id)
@@ -996,8 +1005,7 @@ static int __check_input_term(struct mix UAC3_PROCESSING_UNIT);case PTYPE (UAC_VERSION_2 ,UAC2_EFFECT_UNIT ):case PTYPE (UAC_VERSION_3 ,UAC3_EFFECT_UNIT ): -return parse_term_proc_unit (state, term, p1, id, -UAC3_EFFECT_UNIT ); +return parse_term_effect_unit (state, term, p1, id);case PTYPE (UAC_VERSION_1 ,UAC1_EXTENSION_UNIT ):case PTYPE (UAC_VERSION_2 ,UAC2_EXTENSION_UNIT_V2 ):case PTYPE (UAC_VERSION_3 ,UAC3_EXTENSION_UNIT ):
Greg Kroah-Hartman
maintainerPATCH 5/38 ALSA: hda/realtek - Fix silent output on MSI-GL73
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 7dafba3762d6c0083ded00a48f8c1a158bc86717 upstream.
MSI-GL73 laptop with ALC1220 codec requires a similar workaround for Clevo laptops to enforce the DAC/mixer connection path. Set up a quirk entry for that.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -2442,6 +2442,7 @@ static const struct snd_pci_quirk alc882SND_PCI_QUIRK (0x1071 ,0x8258 ,"Evesham Voyaeger" ,ALC882_FIXUP_EAPD ),SND_PCI_QUIRK (0x1458 ,0xa002 ,"Gigabyte EP45-DS3/Z87X-UD3H" ,ALC889_FIXUP_FRONT_HP_NO_PRESENCE ),SND_PCI_QUIRK (0x1458 ,0xa0b8 ,"Gigabyte AZ370-Gaming" ,ALC1220_FIXUP_GB_DUAL_CODECS ), +SND_PCI_QUIRK (0x1462 ,0x1276 ,"MSI-GL73" ,ALC1220_FIXUP_CLEVO_P950 ),SND_PCI_QUIRK (0x1462 ,0x7350 ,"MSI-7350" ,ALC889_FIXUP_CD ),SND_PCI_QUIRK (0x1462 ,0xda57 ,"MSI Z270-Gaming" ,ALC1220_FIXUP_GB_DUAL_CODECS ), SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
Greg Kroah-Hartman
maintainerPATCH 6/38 ALSA: usb-audio: Apply sample rate quirk for Audioengine D1
In reply to Greg Kroah-HartmanFrom: Arvind Sankar <[email protected]>
commit 93f9d1a4ac5930654c17412e3911b46ece73755a upstream.
The Audioengine D1 (0x2912:0x30c8) does support reading the sample rate, but it returns the rate in byte-reversed order.
When setting sampling rate, the driver produces these warning messages:
[168840.944226] usb 3-2.2: current rate 4500480 is different from the runtime rate 44100 [168854.930414] usb 3-2.2: current rate 8436480 is different from the runtime rate 48000 [168905.185825] usb 3-2.1.2: current rate 30465 is different from the runtime rate 96000
As can be seen from the hexadecimal conversion, the current rate read back is byte-reversed from the rate that was set.
44100 == 0x00ac44, 4500480 == 0x44ac00
48000 == 0x00bb80, 8436480 == 0x80bb00
96000 == 0x017700, 30465 == 0x007701
Rather than implementing a new quirk to reverse the order, just skip checking the rate to avoid spamming the log.
--- sound/usb/quirks.c | 1 + 1 file changed, 1 insertion(+)
sound/usb/quirks.c +1 -0
@@ -1182,6 +1182,7 @@ bool snd_usb_get_sample_rate_quirk(struccase USB_ID (0x1395 ,0x740a ):/* Sennheiser DECT */ case USB_ID (0x1901 ,0x0191 ):/* GE B850V3 CP2114 audio interface */ case USB_ID (0x21B4 ,0x0081 ):/* AudioQuest DragonFly */ +case USB_ID (0x2912 ,0x30c8 ):/* Audioengine D1 */ return true; }
Greg Kroah-Hartman
maintainerPATCH 7/38 arm64: cpufeature: Set the FP/SIMD compat HWCAP bits properly
In reply to Greg Kroah-HartmanFrom: Suzuki K Poulose <[email protected]>
commit 7559950aef1ab8792c50797c6c5c7c5150a02460 upstream
We set the compat_elf_hwcap bits unconditionally on arm64 to include the VFP and NEON support. However, the FP/SIMD unit is optional on Arm v8 and thus could be missing. We already handle this properly in the kernel, but still advertise to the COMPAT applications that the VFP is available. Fix this to make sure we only advertise when we really have them.
--- arch/arm64/kernel/cpufeature.c | 52 +++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-)
arch/arm64/kernel/cpufeature.c +45 -7
@@ -42,9 +42,7 @@ EXPORT_SYMBOL_GPL(elf_hwcap);#define COMPAT_ELF_HWCAP_DEFAULT \ (COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\ COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\ - COMPAT_HWCAP_TLS|COMPAT_HWCAP_VFP|\ - COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\ - COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV|\ + COMPAT_HWCAP_TLS|COMPAT_HWCAP_IDIV|\ COMPAT_HWCAP_LPAE)unsigned int compat_elf_hwcap__read_mostly =COMPAT_ELF_HWCAP_DEFAULT ;unsigned int compat_elf_hwcap2__read_mostly ;
@@ -1341,17 +1339,30 @@ static const struct arm64_cpu_capabilities arm64_features[] = { {}, }; -#define HWCAP_CAP (reg, field, s, min_value, cap_type, cap) \ - { \ - .desc = #cap, \ - .type = ARM64_CPUCAP_SYSTEM_FEATURE, \ + +#define HWCAP_CPUID_MATCH (reg, field, s, min_value) \ .matches = has_cpuid_feature, \ .sys_reg = reg, \ .field_pos = field, \ .sign = s, \ .min_field_value = min_value, \ + +#define __HWCAP_CAP (name, cap_type, cap) \ + .desc = name, \ + .type = ARM64_CPUCAP_SYSTEM_FEATURE, \ .hwcap_type = cap_type, \ .hwcap = cap, \ + +#define HWCAP_CAP (reg, field, s, min_value, cap_type, cap) \ + { \ + __HWCAP_CAP(#cap, cap_type, cap) \ + HWCAP_CPUID_MATCH(reg, field, s, min_value) \ + } + +#define HWCAP_CAP_MATCH (match, cap_type, cap) \ + { \ + __HWCAP_CAP(#cap, cap_type, cap) \ + .matches = match, \ }static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
@@ -1387,8 +1398,35 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { {}, }; +#ifdef CONFIG_COMPAT +static bool compat_has_neon (const struct arm64_cpu_capabilities *cap,int scope) +{ +/* +* Check that all of MVFR1_EL1.{SIMDSP, SIMDInt, SIMDLS} are available, +* in line with that of arm32 as in vfp_init(). We make sure that the +* check is future proof, by making sure value is non-zero. +*/ +u32 mvfr1; + +WARN_ON (scope ==SCOPE_LOCAL_CPU &&preemptible ()); +if (scope ==SCOPE_SYSTEM ) + mvfr1 =read_sanitised_ftr_reg (SYS_MVFR1_EL1 ); +else + mvfr1 =read_sysreg_s (SYS_MVFR1_EL1 ); + +return cpuid_feature_extract_unsigned_field (mvfr1,MVFR1_SIMDSP_SHIFT ) && +cpuid_feature_extract_unsigned_field (mvfr1,MVFR1_SIMDINT_SHIFT ) && +cpuid_feature_extract_unsigned_field (mvfr1,MVFR1_SIMDLS_SHIFT ); +} +#endif +static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = { #ifdef CONFIG_COMPAT +HWCAP_CAP_MATCH (compat_has_neon,CAP_COMPAT_HWCAP ,COMPAT_HWCAP_NEON ), +HWCAP_CAP (SYS_MVFR1_EL1 ,MVFR1_SIMDFMAC_SHIFT ,FTR_UNSIGNED ,1 ,CAP_COMPAT_HWCAP , COMPAT_HWCAP_VFPv4), +/* Arm v8 mandates MVFR0.FPDP == {0, 2}. So, piggy back on this for the presence of VFP support */ +HWCAP_CAP (SYS_MVFR0_EL1 ,MVFR0_FPDP_SHIFT ,FTR_UNSIGNED ,2 ,CAP_COMPAT_HWCAP ,COMPAT_HWCAP_VFP ), +HWCAP_CAP (SYS_MVFR0_EL1 ,MVFR0_FPDP_SHIFT ,FTR_UNSIGNED ,2 ,CAP_COMPAT_HWCAP , COMPAT_HWCAP_VFPv3),HWCAP_CAP (SYS_ID_ISAR5_EL1 ,ID_ISAR5_AES_SHIFT ,FTR_UNSIGNED ,2 ,CAP_COMPAT_HWCAP2 ,COMPAT_HWCAP2_PMULL ),HWCAP_CAP (SYS_ID_ISAR5_EL1 ,ID_ISAR5_AES_SHIFT ,FTR_UNSIGNED ,1 ,CAP_COMPAT_HWCAP2 ,COMPAT_HWCAP2_AES ), HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 8/38 arm64: nofpsmid: Handle TIF_FOREIGN_FPSTATE flag cleanly
In reply to Greg Kroah-HartmanFrom: Suzuki K Poulose <[email protected]>
commit 52f73c383b2418f2d31b798e765ae7d596c35021 upstream
We detect the absence of FP/SIMD after an incapable CPU is brought up, and by then we have kernel threads running already with TIF_FOREIGN_FPSTATE set which could be set for early userspace applications (e.g, modprobe triggered from initramfs) and init. This could cause the applications to loop forever in do_nofity_resume() as we never clear the TIF flag, once we now know that we don't support FP.
Fix this by making sure that we clear the TIF_FOREIGN_FPSTATE flag for tasks which may have them set, as we would have done in the normal case, but avoiding touching the hardware state (since we don't support any).
Also to make sure we handle the cases seemlessly we categorise the helper functions to two :
1) Helpers for common core code, which calls into take appropriate actions without knowing the current FPSIMD state of the CPU/task.
e.g fpsimd_restore_current_state(), fpsimd_flush_task_state(),
fpsimd_save_and_flush_cpu_state().
We bail out early for these functions, taking any appropriate actions (e.g, clearing the TIF flag) where necessary to hide the handling from core code.
2) Helpers used when the presence of FP/SIMD is apparent. i.e, save/restore the FP/SIMD register state, modify the CPU/task FP/SIMD state.
e.g,
fpsimd_save(), task_fpsimd_load() - save/restore task FP/SIMD registers
fpsimd_bind_task_to_cpu() \
- Update the "state" metadata for CPU/task.
fpsimd_bind_state_to_cpu() /
fpsimd_update_current_state() - Update the fp/simd state for the current
task from memory.
These must not be called in the absence of FP/SIMD. Put in a WARNING to make sure they are not invoked in the absence of FP/SIMD.
KVM also uses the TIF_FOREIGN_FPSTATE flag to manage the FP/SIMD state on the CPU. However, without FP/SIMD support we trap all accesses and inject undefined instruction. Thus we should never "load" guest state. Add a sanity check to make sure this is valid.
--- arch/arm64/kernel/fpsimd.c | 20 ++++++++++++++++++-- arch/arm64/kvm/hyp/switch.c | 10 +++++++++- 2 files changed, 27 insertions(+), 3 deletions(-)
arch/arm64/kernel/fpsimd.c +18 -2
@@ -218,6 +218,7 @@ static void sve_free(struct task_struct *task)static void task_fpsimd_load (void ) {WARN_ON (!in_softirq () && !irqs_disabled ()); +WARN_ON (!system_supports_fpsimd ());if (system_supports_sve () &&test_thread_flag (TIF_SVE )) sve_load_state(sve_pffr(¤t->thread),
@@ -238,6 +239,7 @@ void fpsimd_save(void)struct user_fpsimd_state *st =__this_cpu_read (fpsimd_last_state.st);/* set by fpsimd_bind_task_to_cpu() or fpsimd_bind_state_to_cpu() */ +WARN_ON (!system_supports_fpsimd ());WARN_ON (!in_softirq () && !irqs_disabled ());if (!test_thread_flag (TIF_FOREIGN_FPSTATE )) {
@@ -977,6 +979,7 @@ void fpsimd_bind_task_to_cpu(void)struct fpsimd_last_state_struct *last =this_cpu_ptr (&fpsimd_last_state); +WARN_ON (!system_supports_fpsimd ()); last->st = ¤t->thread.uw.fpsimd_state; current->thread.fpsimd_cpu =smp_processor_id ();
@@ -996,6 +999,7 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st)struct fpsimd_last_state_struct *last =this_cpu_ptr (&fpsimd_last_state); +WARN_ON (!system_supports_fpsimd ());WARN_ON (!in_softirq () && !irqs_disabled ()); last->st = st;
@@ -1008,8 +1012,19 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st)*/ void fpsimd_restore_current_state (void ) { -if (!system_supports_fpsimd ()) +/* +* For the tasks that were created before we detected the absence of +* FP/SIMD, the TIF_FOREIGN_FPSTATE could be set via fpsimd_thread_switch(), +* e.g, init. This could be then inherited by the children processes. +* If we later detect that the system doesn't support FP/SIMD, +* we must clear the flag for all the tasks to indicate that the +* FPSTATE is clean (as we can't have one) to avoid looping for ever in +* do_notify_resume(). +*/ +if (!system_supports_fpsimd ()) { +clear_thread_flag (TIF_FOREIGN_FPSTATE );return ; + }local_bh_disable ();
@@ -1028,7 +1043,7 @@ void fpsimd_restore_current_state(void)*/ void fpsimd_update_current_state (struct user_fpsimd_state const *state) { -if (!system_supports_fpsimd ()) +if (WARN_ON (!system_supports_fpsimd ()))return ;local_bh_disable ();
@@ -1055,6 +1070,7 @@ void fpsimd_flush_task_state(struct task_struct *t)void fpsimd_flush_cpu_state (void ) { +WARN_ON (!system_supports_fpsimd ());__this_cpu_write (fpsimd_last_state.st,NULL );set_thread_flag (TIF_FOREIGN_FPSTATE ); }
arch/arm64/kvm/hyp/switch.c +9 -1
@@ -37,7 +37,15 @@/* Check whether the FP regs were dirtied while in the host-side run loop: */ static bool __hyp_text update_fp_enabled(struct kvm_vcpu *vcpu) { -if (vcpu->arch.host_thread_info->flags & _TIF_FOREIGN_FPSTATE) +/* +* When the system doesn't support FP/SIMD, we cannot rely on +* the _TIF_FOREIGN_FPSTATE flag. However, we always inject an +* abort on the very first access to FP and thus we should never +* see KVM_ARM64_FP_ENABLED. For added safety, make sure we always +* trap the accesses. +*/ +if (!system_supports_fpsimd () || + vcpu->arch.host_thread_info->flags & _TIF_FOREIGN_FPSTATE) vcpu->arch.flags &= ~(KVM_ARM64_FP_ENABLED |KVM_ARM64_FP_HOST );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 9/38 ALSA: usb-audio: sound: usb: usb true/false for bool return type
In reply to Greg Kroah-HartmanFrom: Saurav Girepunje <[email protected]>
commit 1d4961d9eb1aaa498dfb44779b7e4b95d79112d0 upstream.
Use true/false for bool type return in uac_clock_source_is_valid().
--- sound/usb/clock.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
sound/usb/clock.c +5 -5
@@ -179,21 +179,21 @@ static bool uac_clock_source_is_valid(stsnd_usb_find_clock_source_v3 (chip->ctrl_intf, source_id);if (!cs_desc) -return 0 ; +return false; bmControls =le32_to_cpu (cs_desc->bmControls); }else {/* UAC_VERSION_1/2 */ struct uac_clock_source_descriptor *cs_desc =snd_usb_find_clock_source (chip->ctrl_intf, source_id);if (!cs_desc) -return 0 ; +return false; bmControls = cs_desc->bmControls; }/* If a clock source can't tell us whether it's valid, we assume it is */ if (!uac_v2v3_control_is_readable (bmControls,UAC2_CS_CONTROL_CLOCK_VALID )) -return 1 ; +return true; err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
@@ -205,10 +205,10 @@ static bool uac_clock_source_is_valid(stdev_warn (&dev->dev,"%s(): cannot get clock validity for id %d\n" , __func__, source_id); -return 0 ; +return false; } -return !!data; +return data ? true : false; } static int __uac_clock_find_source(struct snd_usb_audio *chip, int entity_id,
Greg Kroah-Hartman
maintainerPATCH 10/38 ALSA: usb-audio: Add clock validity quirk for Denon MC7000/MCX8000
In reply to Greg Kroah-HartmanFrom: Alexander Tsoy <[email protected]>
commit 9f35a31283775e6f6af73fb2c95c686a4c0acac7 upstream.
It should be safe to ignore clock validity check result if the following conditions are met:
- only one single sample rate is supported;
- the terminal is directly connected to the clock source;
- the clock type is internal.
This is to deal with some Denon DJ controllers that always reports that clock is invalid.
--- sound/usb/clock.c | 91 ++++++++++++++++++++++++++++++++++++----------------- sound/usb/clock.h | 4 +- sound/usb/format.c | 3 - 3 files changed, 66 insertions(+), 32 deletions(-)
sound/usb/clock.c +63 -28
@@ -165,8 +165,34 @@ static int uac_clock_selector_set_val(streturn ret; } +/* +* Assume the clock is valid if clock source supports only one single sample +* rate, the terminal is connected directly to it (there is no clock selector) +* and clock type is internal. This is to deal with some Denon DJ controllers +* that always reports that clock is invalid. +*/ +static bool uac_clock_source_is_valid_quirk (struct snd_usb_audio *chip, +struct audioformat *fmt, +int source_id) +{ +if (fmt->protocol ==UAC_VERSION_2 ) { +struct uac_clock_source_descriptor *cs_desc = +snd_usb_find_clock_source (chip->ctrl_intf, source_id); + +if (!cs_desc) +return false; + +return (fmt->nr_rates ==1 && + (fmt->clock &0xff ) == cs_desc->bClockID && + (cs_desc->bmAttributes &0x3 ) != +UAC_CLOCK_SOURCE_TYPE_EXT ); + } + +return false; +} +static bool uac_clock_source_is_valid (struct snd_usb_audio *chip, -int protocol, +struct audioformat *fmt,int source_id) {int err;
@@ -174,7 +200,7 @@ static bool uac_clock_source_is_valid(ststruct usb_device *dev = chip->dev;u32 bmControls; -if (protocol ==UAC_VERSION_3 ) { +if (fmt->protocol ==UAC_VERSION_3 ) {struct uac3_clock_source_descriptor *cs_desc =snd_usb_find_clock_source_v3 (chip->ctrl_intf, source_id);
@@ -208,10 +234,14 @@ static bool uac_clock_source_is_valid(streturn false; } -return data ? true : false; +if (data) +return true; +else +return uac_clock_source_is_valid_quirk (chip, fmt, source_id); } -static int __uac_clock_find_source (struct snd_usb_audio *chip,int entity_id, +static int __uac_clock_find_source (struct snd_usb_audio *chip, +struct audioformat *fmt,int entity_id,unsigned long *visited,bool validate) {struct uac_clock_source_descriptor *source;
@@ -231,7 +261,7 @@ static int __uac_clock_find_source(struc source =snd_usb_find_clock_source (chip->ctrl_intf, entity_id);if (source) { entity_id = source->bClockID; -if (validate && !uac_clock_source_is_valid (chip,UAC_VERSION_2 , +if (validate && !uac_clock_source_is_valid (chip, fmt, entity_id)) { usb_audio_err(chip, "clock source %d is not valid, cannot use\n",
@@ -262,8 +292,9 @@ static int __uac_clock_find_source(struc } cur = ret; - ret =__uac_clock_find_source (chip, selector->baCSourceID[ret -1 ], - visited, validate); + ret =__uac_clock_find_source (chip, fmt, + selector->baCSourceID[ret -1 ], + visited, validate);if (!validate || ret >0 || !chip->autoclock)return ret;
@@ -274,8 +305,9 @@ static int __uac_clock_find_source(strucif (i == cur)continue ; - ret =__uac_clock_find_source (chip, selector->baCSourceID[i -1 ], - visited, true); + ret =__uac_clock_find_source (chip, fmt, + selector->baCSourceID[i -1 ], + visited, true);if (ret <0 )continue ;
@@ -295,14 +327,16 @@ static int __uac_clock_find_source(struc/* FIXME: multipliers only act as pass-thru element for now */ multiplier =snd_usb_find_clock_multiplier (chip->ctrl_intf, entity_id);if (multiplier) -return __uac_clock_find_source (chip, multiplier->bCSourceID, - visited, validate); +return __uac_clock_find_source (chip, fmt, + multiplier->bCSourceID, + visited, validate);return -EINVAL ; } -static int __uac3_clock_find_source (struct snd_usb_audio *chip,int entity_id, -unsigned long *visited,bool validate) +static int __uac3_clock_find_source (struct snd_usb_audio *chip, +struct audioformat *fmt,int entity_id, +unsigned long *visited,bool validate) {struct uac3_clock_source_descriptor *source;struct uac3_clock_selector_descriptor *selector;
@@ -321,7 +355,7 @@ static int __uac3_clock_find_source(stru source =snd_usb_find_clock_source_v3 (chip->ctrl_intf, entity_id);if (source) { entity_id = source->bClockID; -if (validate && !uac_clock_source_is_valid (chip,UAC_VERSION_3 , +if (validate && !uac_clock_source_is_valid (chip, fmt, entity_id)) { usb_audio_err(chip, "clock source %d is not valid, cannot use\n",
@@ -352,7 +386,8 @@ static int __uac3_clock_find_source(stru } cur = ret; - ret =__uac3_clock_find_source (chip, selector->baCSourceID[ret -1 ], + ret =__uac3_clock_find_source (chip, fmt, + selector->baCSourceID[ret -1 ], visited, validate);if (!validate || ret >0 || !chip->autoclock)return ret;
@@ -364,8 +399,9 @@ static int __uac3_clock_find_source(struif (i == cur)continue ; - ret =__uac3_clock_find_source (chip, selector->baCSourceID[i -1 ], - visited, true); + ret =__uac3_clock_find_source (chip, fmt, + selector->baCSourceID[i -1 ], + visited, true);if (ret <0 )continue ;
@@ -386,7 +422,8 @@ static int __uac3_clock_find_source(stru multiplier =snd_usb_find_clock_multiplier_v3 (chip->ctrl_intf, entity_id);if (multiplier) -return __uac3_clock_find_source (chip, multiplier->bCSourceID, +return __uac3_clock_find_source (chip, fmt, + multiplier->bCSourceID, visited, validate);return -EINVAL ;
@@ -403,18 +440,18 @@ static int __uac3_clock_find_source(stru* * Returns the clock source UnitID (>=0) on success, or an error. */ -int snd_usb_clock_find_source (struct snd_usb_audio *chip,int protocol, -int entity_id,bool validate) +int snd_usb_clock_find_source (struct snd_usb_audio *chip, +struct audioformat *fmt,bool validate) {DECLARE_BITMAP (visited,256 );memset (visited,0 ,sizeof (visited)); -switch (protocol) { +switch (fmt->protocol) {case UAC_VERSION_2 : -return __uac_clock_find_source (chip, entity_id, visited, +return __uac_clock_find_source (chip, fmt, fmt->clock, visited, validate);case UAC_VERSION_3 : -return __uac3_clock_find_source (chip, entity_id, visited, +return __uac3_clock_find_source (chip, fmt, fmt->clock, visited, validate);default :return -EINVAL ;
@@ -515,8 +552,7 @@ static int set_sample_rate_v2v3(struct s* automatic clock selection if the current clock is not * valid. */ - clock =snd_usb_clock_find_source (chip, fmt->protocol, - fmt->clock, true); + clock =snd_usb_clock_find_source (chip, fmt, true);if (clock <0 ) {/* We did not find a valid clock, but that might be * because the current sample rate does not match an
@@ -524,8 +560,7 @@ static int set_sample_rate_v2v3(struct s* and we will do another validation after setting the * rate. */ - clock =snd_usb_clock_find_source (chip, fmt->protocol, - fmt->clock, false); + clock =snd_usb_clock_find_source (chip, fmt, false);if (clock <0 )return clock; }
@@ -591,7 +626,7 @@ static int set_sample_rate_v2v3(struct s validation:/* validate clock after rate change */ -if (!uac_clock_source_is_valid (chip, fmt->protocol, clock)) +if (!uac_clock_source_is_valid (chip, fmt, clock))return -ENXIO ;return 0 ; }
sound/usb/clock.h +2 -2
@@ -6,7 +6,7 @@ int snd_usb_init_sample_rate(struct snd_struct usb_host_interface *alts, struct audioformat *fmt, int rate); -int snd_usb_clock_find_source (struct snd_usb_audio *chip,int protocol, -int entity_id,bool validate); +int snd_usb_clock_find_source (struct snd_usb_audio *chip, +struct audioformat *fmt,bool validate);#endif /* __USBAUDIO_CLOCK_H */
sound/usb/format.c +1 -2
@@ -306,8 +306,7 @@ static int parse_audio_format_rates_v2v3struct usb_device *dev = chip->dev;unsigned char tmp[2 ], *data;int nr_triplets, data_size, ret =0 ; -int clock =snd_usb_clock_find_source (chip, fp->protocol, - fp->clock, false); +int clock =snd_usb_clock_find_source (chip, fp, false);if (clock <0 ) { dev_err(&dev->dev,
Greg Kroah-Hartman
maintainerPATCH 11/38 ext4: dont assume that mmp_nodename/bdevname have NUL
In reply to Greg Kroah-HartmanFrom: Andreas Dilger <[email protected]>
commit 14c9ca0583eee8df285d68a0e6ec71053efd2228 upstream.
Don't assume that the mmp_nodename and mmp_bdevname strings are NUL terminated, since they are filled in by snprintf(), which is not guaranteed to do so.
--- fs/ext4/mmp.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
fs/ext4/mmp.c +7 -5
@@ -120,10 +120,10 @@ void __dump_mmp_msg(struct super_block * {__ext4_warning (sb, function, line,"%s" , msg);__ext4_warning (sb, function, line, -"MMP failure info: last update time: %llu, last update " -"node: %s, last update device: %s" , - (long long unsigned int )le64_to_cpu (mmp->mmp_time), - mmp->mmp_nodename, mmp->mmp_bdevname); +"MMP failure info: last update time: %llu, last update node: %.*s, last update device: %.*s" , + (unsigned long long )le64_to_cpu (mmp->mmp_time), + (int )sizeof (mmp->mmp_nodename), mmp->mmp_nodename, + (int )sizeof (mmp->mmp_bdevname), mmp->mmp_bdevname); }/*
@@ -154,6 +154,7 @@ static int kmmpd(void *data) mmp_check_interval =max (EXT4_MMP_CHECK_MULT * mmp_update_interval,EXT4_MMP_MIN_CHECK_INTERVAL ); mmp->mmp_check_interval =cpu_to_le16 (mmp_check_interval); +BUILD_BUG_ON (sizeof (mmp->mmp_bdevname) <BDEVNAME_SIZE );bdevname (bh->b_bdev, mmp->mmp_bdevname); memcpy(mmp->mmp_nodename, init_utsname()->nodename,
@@ -375,7 +376,8 @@ skip:/* * Start a kernel thread to update the MMP block periodically. */ -EXT4_SB (sb)->s_mmp_tsk =kthread_run (kmmpd, mmpd_data,"kmmpd-%s" , +EXT4_SB (sb)->s_mmp_tsk =kthread_run (kmmpd, mmpd_data,"kmmpd-%.*s" , + (int )sizeof (mmp->mmp_bdevname),bdevname (bh->b_bdev, mmp->mmp_bdevname));if (IS_ERR (EXT4_SB (sb)->s_mmp_tsk)) {
Greg Kroah-Hartman
maintainerPATCH 12/38 ext4: fix support for inode sizes > 1024 bytes
In reply to Greg Kroah-HartmanFrom: Theodore Ts'o <[email protected]>
commit 4f97a68192bd33b9963b400759cef0ca5963af00 upstream.
A recent commit, 9803387c55f7 ("ext4: validate the debug_want_extra_isize mount option at parse time"), moved mount-time checks around. One of those changes moved the inode size check before the blocksize variable was set to the blocksize of the file system. After 9803387c55f7 was set to the minimum allowable blocksize, which in practice on most systems would be 1024 bytes. This cuased file systems with inode sizes larger than 1024 bytes to be rejected with a message:
EXT4-fs (sdXX): unsupported inode size: 4096
--- fs/ext4/super.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
fs/ext4/super.c +10 -8
@@ -3727,6 +3727,15 @@ static int ext4_fill_super(struct super_*/ sbi->s_li_wait_mult =EXT4_DEF_LI_WAIT_MULT ; + blocksize =BLOCK_SIZE <<le32_to_cpu (es->s_log_block_size); +if (blocksize <EXT4_MIN_BLOCK_SIZE || + blocksize >EXT4_MAX_BLOCK_SIZE ) { +ext4_msg (sb,KERN_ERR , +"Unsupported filesystem blocksize %d (%d log_block_size)" , + blocksize,le32_to_cpu (es->s_log_block_size)); + goto failed_mount; + } +if (le32_to_cpu (es->s_rev_level) ==EXT4_GOOD_OLD_REV ) { sbi->s_inode_size =EXT4_GOOD_OLD_INODE_SIZE ; sbi->s_first_ino =EXT4_GOOD_OLD_FIRST_INO ;
@@ -3744,6 +3753,7 @@ static int ext4_fill_super(struct super_ext4_msg (sb,KERN_ERR ,"unsupported inode size: %d" , sbi->s_inode_size); +ext4_msg (sb,KERN_ERR ,"blocksize: %d" , blocksize); goto failed_mount; }/*
@@ -3907,14 +3917,6 @@ static int ext4_fill_super(struct super_if (!ext4_feature_set_ok (sb, (sb_rdonly (sb)))) goto failed_mount; - blocksize =BLOCK_SIZE <<le32_to_cpu (es->s_log_block_size); -if (blocksize <EXT4_MIN_BLOCK_SIZE || - blocksize >EXT4_MAX_BLOCK_SIZE ) { -ext4_msg (sb,KERN_ERR , -"Unsupported filesystem blocksize %d (%d log_block_size)" , - blocksize,le32_to_cpu (es->s_log_block_size)); - goto failed_mount; - }if (le32_to_cpu (es->s_log_block_size) > (EXT4_MAX_BLOCK_LOG_SIZE -EXT4_MIN_BLOCK_LOG_SIZE )) { ext4_msg(sb, KERN_ERR,
Greg Kroah-Hartman
maintainerPATCH 13/38 ext4: fix checksum errors with indexed dirs
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
commit 48a34311953d921235f4d7bbd2111690d2e469cf upstream.
DIR_INDEX has been introduced as a compat ext4 feature. That means that even kernels / tools that don't understand the feature may modify the filesystem. This works because for kernels not understanding indexed dir format, internal htree nodes appear just as empty directory entries. Index dir aware kernels then check the htree structure is still consistent before using the data. This all worked reasonably well until metadata checksums were introduced. The problem is that these effectively made DIR_INDEX only ro-compatible because internal htree nodes store checksums in a different place than normal directory blocks. Thus any modification ignorant to DIR_INDEX (or just clearing EXT4_INDEX_FL from the inode) will effectively cause checksum mismatch and trigger kernel errors. So we have to be more careful when dealing with indexed directories on filesystems with checksumming enabled.
1) We just disallow loading any directory inodes with EXT4_INDEX_FL when DIR_INDEX is not enabled. This is harsh but it should be very rare (it means someone disabled DIR_INDEX on existing filesystem and didn't run e2fsck), e2fsck can fix the problem, and we don't want to answer the difficult question: "Should we rather corrupt the directory more or should we ignore that DIR_INDEX feature is not set?"
2) When we find out htree structure is corrupted (but the filesystem and the directory should in support htrees), we continue just ignoring htree information for reading but we refuse to add new entries to the directory to avoid corrupting it more.
--- fs/ext4/dir.c | 14 ++++++++------ fs/ext4/ext4.h | 5 ++++- fs/ext4/inode.c | 12 ++++++++++++ fs/ext4/namei.c | 7 +++++++ 4 files changed, 31 insertions(+), 7 deletions(-)
fs/ext4/dir.c +8 -6
@@ -126,12 +126,14 @@ static int ext4_readdir(struct file *filif (err !=ERR_BAD_DX_DIR ) {return err; } -/* -* We don't set the inode dirty flag since it's not -* critical that it get flushed back to the disk. -*/ -ext4_clear_inode_flag (file_inode (file), -EXT4_INODE_INDEX ); +/* Can we just clear INDEX flag to ignore htree information? */ +if (!ext4_has_metadata_csum (sb)) { +/* +* We don't set the inode dirty flag since it's not +* critical that it gets flushed back to the disk. +*/ +ext4_clear_inode_flag (inode,EXT4_INODE_INDEX ); + } }if (ext4_has_inline_data (inode)) {
fs/ext4/ext4.h +4 -1
@@ -2375,8 +2375,11 @@ void ext4_insert_dentry(struct inode *in struct ext4_filename *fname);static inline void ext4_update_dx_flag (struct inode *inode) { -if (!ext4_has_feature_dir_index (inode->i_sb)) +if (!ext4_has_feature_dir_index (inode->i_sb)) { +/* ext4_iget() should have caught this... */ +WARN_ON_ONCE (ext4_has_feature_metadata_csum (inode->i_sb));ext4_clear_inode_flag (inode,EXT4_INODE_INDEX ); + } }static const unsigned char ext4_filetype_table[] = {DT_UNKNOWN ,DT_REG ,DT_DIR ,DT_CHR ,DT_BLK ,DT_FIFO ,DT_SOCK ,DT_LNK
fs/ext4/inode.c +12 -0
@@ -4975,6 +4975,18 @@ struct inode *__ext4_iget(struct super_b ret = -EFSCORRUPTED ; goto bad_inode; } +/* +* If dir_index is not enabled but there's dir with INDEX flag set, +* we'd normally treat htree data as empty space. But with metadata +* checksumming that corrupts checksums so forbid that. +*/ +if (!ext4_has_feature_dir_index (sb) &&ext4_has_metadata_csum (sb) && +ext4_test_inode_flag (inode,EXT4_INODE_INDEX )) { +ext4_error_inode (inode, function, line,0 , +"iget: Dir with htree data on filesystem without dir_index feature." ); + ret = -EFSCORRUPTED ; + goto bad_inode; + } ei->i_disksize = inode->i_size;#ifdef CONFIG_QUOTA ei->i_reserved_quota =0 ;
fs/ext4/namei.c +7 -0
@@ -2085,6 +2085,13 @@ static int ext4_add_entry(handle_t *hand retval =ext4_dx_add_entry (handle, &fname, dir, inode);if (!retval || (retval !=ERR_BAD_DX_DIR )) goto out; +/* Can we just ignore htree data? */ +if (ext4_has_metadata_csum (sb)) { +EXT4_ERROR_INODE (dir, +"Directory has corrupted htree index." ); + retval = -EFSCORRUPTED ; + goto out; + }ext4_clear_inode_flag (dir,EXT4_INODE_INDEX ); dx_fallback++;ext4_mark_inode_dirty (handle, dir);
Greg Kroah-Hartman
maintainerPATCH 14/38 ext4: add cond_resched() to ext4_protect_reserved_inode
In reply to Greg Kroah-HartmanFrom: Shijie Luo <[email protected]>
commit af133ade9a40794a37104ecbcc2827c0ea373a3c upstream.
When journal size is set too big by "mkfs.ext4 -J size=", or when we mount a crafted image to make journal inode->i_size too big, the loop, "while (i < num)", holds cpu too long. This could cause soft lockup.
[ 529.357541] Call trace: [ 529.357551] dump_backtrace+0x0/0x198 [ 529.357555] show_stack+0x24/0x30 [ 529.357562] dump_stack+0xa4/0xcc [ 529.357568] watchdog_timer_fn+0x300/0x3e8 [ 529.357574] __hrtimer_run_queues+0x114/0x358 [ 529.357576] hrtimer_interrupt+0x104/0x2d8 [ 529.357580] arch_timer_handler_virt+0x38/0x58 [ 529.357584] handle_percpu_devid_irq+0x90/0x248 [ 529.357588] generic_handle_irq+0x34/0x50 [ 529.357590] __handle_domain_irq+0x68/0xc0 [ 529.357593] gic_handle_irq+0x6c/0x150 [ 529.357595] el1_irq+0xb8/0x140 [ 529.357599] __ll_sc_atomic_add_return_acquire+0x14/0x20 [ 529.357668] ext4_map_blocks+0x64/0x5c0 [ext4] [ 529.357693] ext4_setup_system_zone+0x330/0x458 [ext4] [ 529.357717] ext4_fill_super+0x2170/0x2ba8 [ext4] [ 529.357722] mount_bdev+0x1a8/0x1e8 [ 529.357746] ext4_mount+0x44/0x58 [ext4] [ 529.357748] mount_fs+0x50/0x170 [ 529.357752] vfs_kern_mount.part.9+0x54/0x188 [ 529.357755] do_mount+0x5ac/0xd78 [ 529.357758] ksys_mount+0x9c/0x118 [ 529.357760] __arm64_sys_mount+0x28/0x38 [ 529.357764] el0_svc_common+0x78/0x130 [ 529.357766] el0_svc_handler+0x38/0x78 [ 529.357769] el0_svc+0x8/0xc [ 541.356516] watchdog: BUG: soft lockup - CPU#0 stuck for 23s! [mount:18674]
--- fs/ext4/block_validity.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/block_validity.c +1 -0
@@ -203,6 +203,7 @@ static int ext4_protect_reserved_inode(sreturn PTR_ERR (inode); num = (inode->i_size + sb->s_blocksize -1 ) >> sb->s_blocksize_bits;while (i < num) { +cond_resched (); map.m_lblk = i; map.m_len = num - i; n =ext4_map_blocks (NULL , inode, &map,0 );
Greg Kroah-Hartman
maintainerPATCH 15/38 ext4: improve explanation of a mount failure caused by a misconfigured kernel
In reply to Greg Kroah-HartmanFrom: Theodore Ts'o <[email protected]>
commit d65d87a07476aa17df2dcb3ad18c22c154315bec upstream.
If CONFIG_QFMT_V2 is not enabled, but CONFIG_QUOTA is enabled, when a user tries to mount a file system with the quota or project quota enabled, the kernel will emit a very confusing messsage:
EXT4-fs warning (device vdc): ext4_enable_quotas:5914: Failed to enable quota tracking (type=0, err=-3). Please run e2fsck to fix. EXT4-fs (vdc): mount failed
We will now report an explanatory message indicating which kernel configuration options have to be enabled, to avoid customer/sysadmin confusion.
Google-Bug-Id: 149093531
--- fs/ext4/super.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
fs/ext4/super.c +4 -10
@@ -2923,17 +2923,11 @@ static int ext4_feature_set_ok(struct sureturn 0 ; } -#ifndef CONFIG_QUOTA -if (ext4_has_feature_quota (sb) && !readonly) { +#if !defined(CONFIG_QUOTA ) || !defined(CONFIG_QFMT_V2 ) +if (!readonly && (ext4_has_feature_quota (sb) || +ext4_has_feature_project (sb))) {ext4_msg (sb,KERN_ERR , -"Filesystem with quota feature cannot be mounted RDWR " -"without CONFIG_QUOTA" ); -return 0 ; - } -if (ext4_has_feature_project (sb) && !readonly) { -ext4_msg (sb,KERN_ERR , -"Filesystem with project quota feature cannot be mounted RDWR " -"without CONFIG_QUOTA" ); +"The kernel was not built with CONFIG_QUOTA and CONFIG_QFMT_V2" );return 0 ; }#endif /* CONFIG_QUOTA */
Greg Kroah-Hartman
maintainerPATCH 16/38 Btrfs: fix race between using extent maps and merging them
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit ac05ca913e9f3871126d61da275bfe8516ff01ca upstream.
We have a few cases where we allow an extent map that is in an extent map tree to be merged with other extents in the tree. Such cases include the unpinning of an extent after the respective ordered extent completed or after logging an extent during a fast fsync. This can lead to subtle and dangerous problems because when doing the merge some other task might be using the same extent map and as consequence see an inconsistent state of the extent map - for example sees the new length but has seen the old start offset.
With luck this triggers a BUG_ON(), and not some silent bug, such as the following one in __do_readpage():
$ cat -n fs/btrfs/extent_io.c
3061 static int __do_readpage(struct extent_io_tree *tree,
3062 struct page *page,
(...)
3127 em = __get_extent_map(inode, page, pg_offset, cur,
3128 end - cur + 1, get_extent, em_cached);
3129 if (IS_ERR_OR_NULL(em)) {
3130 SetPageError(page);
3131 unlock_extent(tree, cur, end);
3132 break;
3133 }
3134 extent_offset = cur - em->start;
3135 BUG_ON(extent_map_end(em) <= cur);
(...)Consider the following example scenario, where we end up hitting the BUG_ON() in __do_readpage().
We have an inode with a size of 8KiB and 2 extent maps:
extent A: file offset 0, length 4KiB, disk_bytenr = X, persisted on disk by
a previous transaction
extent B: file offset 4KiB, length 4KiB, disk_bytenr = X + 4KiB, not yet
persisted but writeback started for it already. The extent map is pinned since there's writeback and an ordered extent in progress, so it can not be merged with extent map A yet
The following sequence of steps leads to the BUG_ON():
1) The ordered extent for extent B completes, the respective page gets its writeback bit cleared and the extent map is unpinned, at that point it is not yet merged with extent map A because it's in the list of modified extents;
2) Due to memory pressure, or some other reason, the MM subsystem releases the page corresponding to extent B - btrfs_releasepage() is called and returns 1, meaning the page can be released as it's not dirty, not under writeback anymore and the extent range is not locked in the inode's iotree. However the extent map is not released, either because we are not in a context that allows memory allocations to block or because the inode's size is smaller than 16MiB - in this case our inode has a size of 8KiB;
3) Task B needs to read extent B and ends up __do_readpage() through the btrfs_readpage() callback. At __do_readpage() it gets a reference to extent map B;
4) Task A, doing a fast fsync, calls clear_em_loggin() against extent map B while holding the write lock on the inode's extent map tree - this results in try_merge_map() being called and since it's possible to merge extent map B with extent map A now (the extent map B was removed from the list of modified extents), the merging begins - it sets extent map B's start offset to 0 (was 4KiB), but before it increments the map's length to 8KiB (4kb + 4KiB), task A is at:
BUG_ON(extent_map_end(em) <= cur);
The call to extent_map_end() sees the extent map has a start of 0 and a length still at 4KiB, so it returns 4KiB and 'cur' is 4KiB, so the BUG_ON() is triggered.
So it's dangerous to modify an extent map that is in the tree, because some other task might have got a reference to it before and still using it, and needs to see a consistent map while using it. Generally this is very rare since most paths that lookup and use extent maps also have the file range locked in the inode's iotree. The fsync path is pretty much the only exception where we don't do it to avoid serialization with concurrent reads.
Fix this by not allowing an extent map do be merged if if it's being used by tasks other then the one attempting to merge the extent map (when the reference count of the extent map is greater than 2).
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=206211
--- fs/btrfs/extent_map.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
fs/btrfs/extent_map.c +11 -0
@@ -228,6 +228,17 @@ static void try_merge_map(struct extent_struct extent_map *merge =NULL ;struct rb_node *rb; +/* +* We can't modify an extent map that is in the tree and that is being +* used by another task, as it can cause that other task to see it in +* inconsistent state during the merging. We always have 1 reference for +* the tree and 1 for this task (which is unpinning the extent map or +* clearing the logging flag), so anything > 2 means it's being used by +* other tasks too. +*/ +if (refcount_read (&em->refs) >2 ) +return ; +if (em->start !=0 ) { rb =rb_prev (&em->rb_node);if (rb)
Greg Kroah-Hartman
maintainerPATCH 17/38 btrfs: ref-verify: fix memory leaks
In reply to Greg Kroah-HartmanFrom: Wenwen Wang <[email protected]>
commit f311ade3a7adf31658ed882aaab9f9879fdccef7 upstream.
In btrfs_ref_tree_mod(), 'ref' and 'ra' are allocated through kzalloc() and kmalloc(), respectively. In the following code, if an error occurs, the execution will be redirected to 'out' or 'out_unlock' and the function will be exited. However, on some of the paths, 'ref' and 'ra' are not deallocated, leading to memory leaks. For example, if 'action' is BTRFS_ADD_DELAYED_EXTENT, add_block_entry() will be invoked. If the return value indicates an error, the execution will be redirected to 'out'. But, 'ref' is not deallocated on this path, causing a memory leak.
To fix the above issues, deallocate both 'ref' and 'ra' before exiting from the function when an error is encountered.
--- fs/btrfs/ref-verify.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/btrfs/ref-verify.c +5 -0
@@ -747,6 +747,7 @@ int btrfs_ref_tree_mod(struct btrfs_root*/ be =add_block_entry (root->fs_info, bytenr, num_bytes, ref_root);if (IS_ERR (be)) { +kfree (ref);kfree (ra); ret =PTR_ERR (be); goto out;
@@ -760,6 +761,8 @@ int btrfs_ref_tree_mod(struct btrfs_root "re-allocated a block that still has references to it!");dump_block_entry (fs_info, be);dump_ref_action (fs_info, ra); +kfree (ref); +kfree (ra); goto out_unlock; }
@@ -822,6 +825,7 @@ int btrfs_ref_tree_mod(struct btrfs_root "dropping a ref for a existing root that doesn't have a ref on the block");dump_block_entry (fs_info, be);dump_ref_action (fs_info, ra); +kfree (ref);kfree (ra); goto out_unlock; }
@@ -837,6 +841,7 @@ int btrfs_ref_tree_mod(struct btrfs_root "attempting to add another ref for an existing ref on a tree block");dump_block_entry (fs_info, be);dump_ref_action (fs_info, ra); +kfree (ref);kfree (ra); goto out_unlock; }
Greg Kroah-Hartman
maintainerPATCH 18/38 btrfs: print message when tree-log replay starts
In reply to Greg Kroah-HartmanFrom: David Sterba <[email protected]>
commit e8294f2f6aa6208ed0923aa6d70cea3be178309a upstream.
There's no logged information about tree-log replay although this is something that points to previous unclean unmount. Other filesystems report that as well.
--- fs/btrfs/disk-io.c | 1 + 1 file changed, 1 insertion(+)
fs/btrfs/disk-io.c +1 -0
@@ -3117,6 +3117,7 @@ retry_root_backup:/* do not make disk changes in broken FS or nologreplay is given */ if (btrfs_super_log_root (disk_super) !=0 && !btrfs_test_opt (fs_info,NOLOGREPLAY )) { +btrfs_info (fs_info,"start tree-log replay" ); ret =btrfs_replay_log (fs_info, fs_devices);if (ret) { err = ret;
Greg Kroah-Hartman
maintainerPATCH 19/38 btrfs: log message when rw remount is attempted with unclean tree-log
In reply to Greg Kroah-HartmanFrom: David Sterba <[email protected]>
commit 10a3a3edc5b89a8cd095bc63495fb1e0f42047d9 upstream.
A remount to a read-write filesystem is not safe when there's tree-log to be replayed. Files that could be opened until now might be affected by the changes in the tree-log.
A regular mount is needed to replay the log so the filesystem presents the consistent view with the pending changes included.
--- fs/btrfs/super.c | 2 ++ 1 file changed, 2 insertions(+)
fs/btrfs/super.c +2 -0
@@ -1857,6 +1857,8 @@ static int btrfs_remount(struct super_bl }if (btrfs_super_log_root (fs_info->super_copy) !=0 ) { +btrfs_warn (fs_info, +"mount required to replay tree-log, cannot remount read-write" ); ret = -EINVAL ; goto restore; }
Greg Kroah-Hartman
maintainerPATCH 20/38 ARM: npcm: Bring back GPIOLIB support
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
commit e383e871ab54f073c2a798a9e0bde7f1d0528de8 upstream.
The CONFIG_ARCH_REQUIRE_GPIOLIB is gone since commit 65053e1a7743 ("gpio: delete ARCH_[WANTS_OPTIONAL|REQUIRE]_GPIOLIB") and all platforms should explicitly select GPIOLIB to have it.
--- arch/arm/mach-npcm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-npcm/Kconfig +1 -1
@@ -10,7 +10,7 @@ config ARCH_NPCM7XX depends on ARCH_MULTI_V7 select PINCTRL_NPCM7XX select NPCM7XX_TIMER - select ARCH_REQUIRE_GPIOLIB + select GPIOLIB select CACHE_L2X0 select ARM_GIC select HAVE_ARM_TWD if SMP
Greg Kroah-Hartman
maintainerPATCH 21/38 arm64: ssbs: Fix context-switch when SSBS is present on all CPUs
In reply to Greg Kroah-HartmanFrom: Will Deacon <[email protected]>
commit fca3d33d8ad61eb53eca3ee4cac476d1e31b9008 upstream.
When all CPUs in the system implement the SSBS extension, the SSBS field in PSTATE is the definitive indication of the mitigation state. Further, when the CPUs implement the SSBS manipulation instructions (advertised to userspace via an HWCAP), EL0 can toggle the SSBS field directly and so we cannot rely on any shadow state such as TIF_SSBD at all.
Avoid forcing the SSBS field in context-switch on such a system, and simply rely on the PSTATE register instead.
--- arch/arm64/kernel/process.c | 7 +++++++ 1 file changed, 7 insertions(+)
arch/arm64/kernel/process.c +7 -0
@@ -414,6 +414,13 @@ static void ssbs_thread_switch(struct taif (unlikely (next->flags &PF_KTHREAD ))return ; +/* +* If all CPUs implement the SSBS extension, then we just need to +* context-switch the PSTATE field. +*/ +if (cpu_have_feature (cpu_feature (SSBS ))) +return ; +/* If the mitigation is enabled, then we leave SSBS clear. */ if ((arm64_get_ssbd_state () ==ARM64_SSBD_FORCE_ENABLE ) ||test_tsk_thread_flag (next,TIF_SSBD ))
Greg Kroah-Hartman
maintainerPATCH 22/38 KVM: nVMX: Use correct root level for nested EPT shadow page tables
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit 148d735eb55d32848c3379e460ce365f2c1cbe4b upstream.
Hardcode the EPT page-walk level for L2 to be 4 levels, as KVM's MMU currently also hardcodes the page walk level for nested EPT to be 4 levels. The L2 guest is all but guaranteed to soft hang on its first instruction when L1 is using EPT, as KVM will construct 4-level page tables and then tell hardware to use 5-level page tables.
--- arch/x86/kvm/vmx/vmx.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/kvm/vmx/vmx.c +3 -0
@@ -2968,6 +2968,9 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu,static int get_ept_level (struct kvm_vcpu *vcpu) { +/* Nested EPT currently only supports 4-level walks. */ +if (is_guest_mode (vcpu) &&nested_cpu_has_ept (get_vmcs12 (vcpu))) +return 4 ;if (cpu_has_vmx_ept_5levels () && (cpuid_maxphyaddr (vcpu) >48 ))return 5 ;return 4 ;
Greg Kroah-Hartman
maintainerPATCH 23/38 perf/x86/amd: Add missing L2 misses event spec to AMD Family 17hs event map
In reply to Greg Kroah-HartmanFrom: Kim Phillips <[email protected]>
commit 25d387287cf0330abf2aad761ce6eee67326a355 upstream.
Commit 3fe3331bb285 ("perf/x86/amd: Add event map for AMD Family 17h"), claimed L2 misses were unsupported, due to them not being found in its referenced documentation, whose link has now moved [1].
That old documentation listed PMCx064 unit mask bit 3 as:
"LsRdBlkC: LS Read Block C S L X Change to X Miss."
and bit 0 as:
"IcFillMiss: IC Fill Miss"
We now have new public documentation [2] with improved descriptions, that clearly indicate what events those unit mask bits represent:
Bit 3 now clearly states:
"LsRdBlkC: Data Cache Req Miss in L2 (all types)"
and bit 0 is:
"IcFillMiss: Instruction Cache Req Miss in L2."
So we can now add support for L2 misses in perf's genericised events as PMCx064 with both the above unit masks.
[1] The commit's original documentation reference, "Processor Programming Reference (PPR) for AMD Family 17h Model 01h, Revision B1 Processors", originally available here:
https://www.amd.com/system/files/TechDocs/54945_PPR_Family_17h_Models_00h-0Fh.pdf
is now available here:
https://developer.amd.com/wordpress/media/2017/11/54945_PPR_Family_17h_Models_00h-0Fh.pdf
[2] "Processor Programming Reference (PPR) for Family 17h Model 31h, Revision B0 Processors", available here:
https://developer.amd.com/wp-content/resources/55803_0.54-PUB.pdf
--- arch/x86/events/amd/core.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/events/amd/core.c +1 -0
@@ -245,6 +245,7 @@ static const u64 amd_f17h_perfmon_event_ [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, [PERF_COUNT_HW_CACHE_REFERENCES] = 0xff60, + [PERF_COUNT_HW_CACHE_MISSES] = 0x0964, [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2, [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3, [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x0287,
Greg Kroah-Hartman
maintainerPATCH 24/38 nvme: fix the parameter order for nvme_get_log in nvme_get_fw_slot_info
In reply to Greg Kroah-HartmanFrom: Yi Zhang <[email protected]>
commit f25372ffc3f6c2684b57fb718219137e6ee2b64c upstream.
nvme fw-activate operation will get bellow warning log, fix it by update the parameter order
[ 113.231513] nvme nvme0: Get FW SLOT INFO log error
--- drivers/nvme/host/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/host/core.c +1 -1
@@ -3449,7 +3449,7 @@ static void nvme_get_fw_slot_info(structif (!log)return ; -if (nvme_get_log (ctrl,NVME_NSID_ALL ,0 ,NVME_LOG_FW_SLOT , log, +if (nvme_get_log (ctrl,NVME_NSID_ALL ,NVME_LOG_FW_SLOT ,0 , log,sizeof (*log),0 ))dev_warn (ctrl->device,"Get FW SLOT INFO log error\n" );kfree (log);
Greg Kroah-Hartman
maintainerPATCH 25/38 IB/hfi1: Acquire lock to release TID entries when user file is closed
In reply to Greg Kroah-HartmanFrom: Kaike Wan <[email protected]>
commit a70ed0f2e6262e723ae8d70accb984ba309eacc2 upstream.
Each user context is allocated a certain number of RcvArray (TID) entries and these entries are managed through TID groups. These groups are put into one of three lists in each user context: tid_group_list, tid_used_list, and tid_full_list, depending on the number of used TID entries within each group. When TID packets are expected, one or more TID groups will be allocated. After the packets are received, the TID groups will be freed. Since multiple user threads may access the TID groups simultaneously, a mutex exp_mutex is used to synchronize the access. However, when the user file is closed, it tries to release all TID groups without acquiring the mutex first, which risks a race condition with another thread that may be releasing its TID groups, leading to data corruption.
This patch addresses the issue by acquiring the mutex first before releasing the TID groups when the file is closed.
--- drivers/infiniband/hw/hfi1/user_exp_rcv.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/infiniband/hw/hfi1/user_exp_rcv.c +2 -0
@@ -165,10 +165,12 @@ void hfi1_user_exp_rcv_free(struct hfi1_if (fd->handler) {hfi1_mmu_rb_unregister (fd->handler); }else { +mutex_lock (&uctxt->exp_mutex);if (!EXP_TID_SET_EMPTY (uctxt->tid_full_list))unlock_exp_tids (uctxt, &uctxt->tid_full_list, fd);if (!EXP_TID_SET_EMPTY (uctxt->tid_used_list))unlock_exp_tids (uctxt, &uctxt->tid_used_list, fd); +mutex_unlock (&uctxt->exp_mutex); }kfree (fd->invalid_tids);
Greg Kroah-Hartman
maintainerPATCH 26/38 IB/hfi1: Close window for pq and request coliding
In reply to Greg Kroah-HartmanFrom: Mike Marciniszyn <[email protected]>
commit be8638344c70bf492963ace206a9896606b6922d upstream.
Cleaning up a pq can result in the following warning and panic:
WARNING: CPU: 52 PID: 77418 at lib/list_debug.c:53 __list_del_entry+0x63/0xd0 list_del corruption, ffff88cb2c6ac068->next is LIST_POISON1 (dead000000000100) Modules linked in: mmfs26(OE) mmfslinux(OE) tracedev(OE) 8021q garp mrp ib_isert iscsi_target_mod target_core_mod crc_t10dif crct10dif_generic opa_vnic rpcrdma ib_iser libiscsi scsi_transport_iscsi ib_ipoib(OE) bridge stp llc iTCO_wdt iTCO_vendor_support intel_powerclamp coretemp intel_rapl iosf_mbi kvm_intel kvm irqbypass crct10dif_pclmul crct10dif_common crc32_pclmul ghash_clmulni_intel ast aesni_intel ttm lrw gf128mul glue_helper ablk_helper drm_kms_helper cryptd syscopyarea sysfillrect sysimgblt fb_sys_fops drm pcspkr joydev lpc_ich mei_me drm_panel_orientation_quirks i2c_i801 mei wmi ipmi_si ipmi_devintf ipmi_msghandler nfit libnvdimm acpi_power_meter acpi_pad hfi1(OE) rdmavt(OE) rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm ib_core binfmt_misc numatools(OE) xpmem(OE) ip_tables nfsv3 nfs_acl nfs lockd grace sunrpc fscache igb ahci i2c_algo_bit libahci dca ptp libata pps_core crc32c_intel [last unloaded: i2c_algo_bit] CPU: 52 PID: 77418 Comm: pvbatch Kdump: loaded Tainted: G OE ------------ 3.10.0-957.38.3.el7.x86_64 #1 Hardware name: HPE.COM HPE SGI 8600-XA730i Gen10/X11DPT-SB-SG007, BIOS SBED1229 01/22/2019 Call Trace: [<ffffffff90365ac0>] dump_stack+0x19/0x1b [<ffffffff8fc98b78>] __warn+0xd8/0x100 [<ffffffff8fc98bff>] warn_slowpath_fmt+0x5f/0x80 [<ffffffff8ff970c3>] __list_del_entry+0x63/0xd0 [<ffffffff8ff9713d>] list_del+0xd/0x30 [<ffffffff8fddda70>] kmem_cache_destroy+0x50/0x110 [<ffffffffc0328130>] hfi1_user_sdma_free_queues+0xf0/0x200 [hfi1] [<ffffffffc02e2350>] hfi1_file_close+0x70/0x1e0 [hfi1] [<ffffffff8fe4519c>] __fput+0xec/0x260 [<ffffffff8fe453fe>] ____fput+0xe/0x10 [<ffffffff8fcbfd1b>] task_work_run+0xbb/0xe0 [<ffffffff8fc2bc65>] do_notify_resume+0xa5/0xc0 [<ffffffff90379134>] int_signal+0x12/0x17 BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 IP: [<ffffffff8fe1f93e>] kmem_cache_close+0x7e/0x300 PGD 2cdab19067 PUD 2f7bfdb067 PMD 0 Oops: 0000 [#1] SMP Modules linked in: mmfs26(OE) mmfslinux(OE) tracedev(OE) 8021q garp mrp ib_isert iscsi_target_mod target_core_mod crc_t10dif crct10dif_generic opa_vnic rpcrdma ib_iser libiscsi scsi_transport_iscsi ib_ipoib(OE) bridge stp llc iTCO_wdt iTCO_vendor_support intel_powerclamp coretemp intel_rapl iosf_mbi kvm_intel kvm irqbypass crct10dif_pclmul crct10dif_common crc32_pclmul ghash_clmulni_intel ast aesni_intel ttm lrw gf128mul glue_helper ablk_helper drm_kms_helper cryptd syscopyarea sysfillrect sysimgblt fb_sys_fops drm pcspkr joydev lpc_ich mei_me drm_panel_orientation_quirks i2c_i801 mei wmi ipmi_si ipmi_devintf ipmi_msghandler nfit libnvdimm acpi_power_meter acpi_pad hfi1(OE) rdmavt(OE) rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm ib_core binfmt_misc numatools(OE) xpmem(OE) ip_tables nfsv3 nfs_acl nfs lockd grace sunrpc fscache igb ahci i2c_algo_bit libahci dca ptp libata pps_core crc32c_intel [last unloaded: i2c_algo_bit] CPU: 52 PID: 77418 Comm: pvbatch Kdump: loaded Tainted: G W OE ------------ 3.10.0-957.38.3.el7.x86_64 #1 Hardware name: HPE.COM HPE SGI 8600-XA730i Gen10/X11DPT-SB-SG007, BIOS SBED1229 01/22/2019 task: ffff88cc26db9040 ti: ffff88b5393a8000 task.ti: ffff88b5393a8000 RIP: 0010:[<ffffffff8fe1f93e>] [<ffffffff8fe1f93e>] kmem_cache_close+0x7e/0x300 RSP: 0018:ffff88b5393abd60 EFLAGS: 00010287 RAX: 0000000000000000 RBX: ffff88cb2c6ac000 RCX: 0000000000000003 RDX: 0000000000000400 RSI: 0000000000000400 RDI: ffffffff9095b800 RBP: ffff88b5393abdb0 R08: ffffffff9095b808 R09: ffffffff8ff77c19 R10: ffff88b73ce1f160 R11: ffffddecddde9800 R12: ffff88cb2c6ac000 R13: 000000000000000c R14: ffff88cf3fdca780 R15: 0000000000000000 FS: 00002aaaaab52500(0000) GS:ffff88b73ce00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000010 CR3: 0000002d27664000 CR4: 00000000007607e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: [<ffffffff8fe20d44>] __kmem_cache_shutdown+0x14/0x80 [<ffffffff8fddda78>] kmem_cache_destroy+0x58/0x110 [<ffffffffc0328130>] hfi1_user_sdma_free_queues+0xf0/0x200 [hfi1] [<ffffffffc02e2350>] hfi1_file_close+0x70/0x1e0 [hfi1] [<ffffffff8fe4519c>] __fput+0xec/0x260 [<ffffffff8fe453fe>] ____fput+0xe/0x10 [<ffffffff8fcbfd1b>] task_work_run+0xbb/0xe0 [<ffffffff8fc2bc65>] do_notify_resume+0xa5/0xc0 [<ffffffff90379134>] int_signal+0x12/0x17 Code: 00 00 ba 00 04 00 00 0f 4f c2 3d 00 04 00 00 89 45 bc 0f 84 e7 01 00 00 48 63 45 bc 49 8d 04 c4 48 89 45 b0 48 8b 80 c8 00 00 00 <48> 8b 78 10 48 89 45 c0 48 83 c0 10 48 89 45 d0 48 8b 17 48 39 RIP [<ffffffff8fe1f93e>] kmem_cache_close+0x7e/0x300 RSP <ffff88b5393abd60> CR2: 0000000000000010
The panic is the result of slab entries being freed during the destruction of the pq slab.
The code attempts to quiesce the pq, but looking for n_req == 0 doesn't account for new requests.
Fix the issue by using SRCU to get a pq pointer and adjust the pq free logic to NULL the fd pq pointer prior to the quiesce.
--- drivers/infiniband/hw/hfi1/file_ops.c | 52 ++++++++++++++++++------------ drivers/infiniband/hw/hfi1/hfi.h | 5 ++ drivers/infiniband/hw/hfi1/user_exp_rcv.c | 3 - drivers/infiniband/hw/hfi1/user_sdma.c | 17 ++++++--- 4 files changed, 48 insertions(+), 29 deletions(-)
drivers/infiniband/hw/hfi1/file_ops.c +32 -20
@@ -200,23 +200,24 @@ static int hfi1_file_open(struct inode * fd =kzalloc (sizeof (*fd),GFP_KERNEL ); -if (fd) { - fd->rec_cpu_num =-1 ;/* no cpu affinity by default */ - fd->mm = current->mm; -mmgrab (fd->mm); - fd->dd = dd; -kobject_get (&fd->dd->kobj); - fp->private_data = fd; - }else { - fp->private_data =NULL ; - -if (atomic_dec_and_test (&dd->user_refcount)) -complete (&dd->user_comp); - -return -ENOMEM ; - } - +if (!fd ||init_srcu_struct (&fd->pq_srcu)) + goto nomem; +spin_lock_init (&fd->pq_rcu_lock); +spin_lock_init (&fd->tid_lock); +spin_lock_init (&fd->invalid_lock); + fd->rec_cpu_num =-1 ;/* no cpu affinity by default */ + fd->mm = current->mm; +mmgrab (fd->mm); + fd->dd = dd; +kobject_get (&fd->dd->kobj); + fp->private_data = fd;return 0 ; +nomem: +kfree (fd); + fp->private_data =NULL ; +if (atomic_dec_and_test (&dd->user_refcount)) +complete (&dd->user_comp); +return -ENOMEM ; } static long hfi1_file_ioctl(struct file *fp, unsigned int cmd,
@@ -301,21 +302,30 @@ static long hfi1_file_ioctl(struct filestatic ssize_t hfi1_write_iter (struct kiocb *kiocb,struct iov_iter *from) {struct hfi1_filedata *fd = kiocb->ki_filp->private_data; -struct hfi1_user_sdma_pkt_q *pq = fd->pq; +struct hfi1_user_sdma_pkt_q *pq;struct hfi1_user_sdma_comp_q *cq = fd->cq;int done =0 , reqs =0 ;unsigned long dim = from->nr_segs; +int idx; -if (!cq || !pq) + idx =srcu_read_lock (&fd->pq_srcu); + pq =srcu_dereference (fd->pq, &fd->pq_srcu); +if (!cq || !pq) { +srcu_read_unlock (&fd->pq_srcu, idx);return -EIO ; + } -if (!iter_is_iovec (from) || !dim) +if (!iter_is_iovec (from) || !dim) { +srcu_read_unlock (&fd->pq_srcu, idx);return -EINVAL ; + }trace_hfi1_sdma_request (fd->dd, fd->uctxt->ctxt, fd->subctxt, dim); -if (atomic_read (&pq->n_reqs) == pq->n_max_reqs) +if (atomic_read (&pq->n_reqs) == pq->n_max_reqs) { +srcu_read_unlock (&fd->pq_srcu, idx);return -ENOSPC ; + }while (dim) {int ret;
@@ -333,6 +343,7 @@ static ssize_t hfi1_write_iter(struct ki reqs++; } +srcu_read_unlock (&fd->pq_srcu, idx);return reqs; }
@@ -706,6 +717,7 @@ done:if (atomic_dec_and_test (&dd->user_refcount))complete (&dd->user_comp); +cleanup_srcu_struct (&fdata->pq_srcu);kfree (fdata);return 0 ; }
drivers/infiniband/hw/hfi1/hfi.h +4 -1
@@ -1376,10 +1376,13 @@ struct mmu_rb_handler;/* Private data for file operations */ struct hfi1_filedata { +struct srcu_struct pq_srcu;struct hfi1_devdata *dd;struct hfi1_ctxtdata *uctxt;struct hfi1_user_sdma_comp_q *cq; -struct hfi1_user_sdma_pkt_q *pq; +/* update side lock for SRCU */ +spinlock_t pq_rcu_lock; +struct hfi1_user_sdma_pkt_q __rcu *pq;u16 subctxt;/* for cpu affinity; -1 if none */ int rec_cpu_num;
drivers/infiniband/hw/hfi1/user_exp_rcv.c +0 -3
@@ -90,9 +90,6 @@ int hfi1_user_exp_rcv_init(struct hfi1_fstruct hfi1_devdata *dd = uctxt->dd;int ret =0 ; -spin_lock_init (&fd->tid_lock); -spin_lock_init (&fd->invalid_lock); - fd->entry_to_rb =kcalloc (uctxt->expected_count,sizeof (struct rb_node *),GFP_KERNEL );
drivers/infiniband/hw/hfi1/user_sdma.c +12 -5
@@ -179,7 +179,6 @@ int hfi1_user_sdma_alloc_queues(struct h pq =kzalloc (sizeof (*pq),GFP_KERNEL );if (!pq)return -ENOMEM ; - pq->dd = dd; pq->ctxt = uctxt->ctxt; pq->subctxt = fd->subctxt;
@@ -236,7 +235,7 @@ int hfi1_user_sdma_alloc_queues(struct h goto pq_mmu_fail; } - fd->pq = pq; +rcu_assign_pointer (fd->pq, pq); fd->cq = cq;return 0 ;
@@ -264,8 +263,14 @@ int hfi1_user_sdma_free_queues(struct hftrace_hfi1_sdma_user_free_queues (uctxt->dd, uctxt->ctxt, fd->subctxt); - pq = fd->pq; +spin_lock (&fd->pq_rcu_lock); + pq =srcu_dereference_check (fd->pq, &fd->pq_srcu, +lockdep_is_held (&fd->pq_rcu_lock));if (pq) { +rcu_assign_pointer (fd->pq,NULL ); +spin_unlock (&fd->pq_rcu_lock); +synchronize_srcu (&fd->pq_srcu); +/* at this point there can be no more new requests */ if (pq->handler)hfi1_mmu_rb_unregister (pq->handler);iowait_sdma_drain (&pq->busy);
@@ -277,7 +282,8 @@ int hfi1_user_sdma_free_queues(struct hfkfree (pq->req_in_use);kmem_cache_destroy (pq->txreq_cache);kfree (pq); - fd->pq =NULL ; + }else { +spin_unlock (&fd->pq_rcu_lock); }if (fd->cq) {vfree (fd->cq->comps);
@@ -321,7 +327,8 @@ int hfi1_user_sdma_process_request(struc {int ret =0 , i;struct hfi1_ctxtdata *uctxt = fd->uctxt; -struct hfi1_user_sdma_pkt_q *pq = fd->pq; +struct hfi1_user_sdma_pkt_q *pq = +srcu_dereference (fd->pq, &fd->pq_srcu);struct hfi1_user_sdma_comp_q *cq = fd->cq;struct hfi1_devdata *dd = pq->dd;unsigned long idx =0 ;
Greg Kroah-Hartman
maintainerPATCH 27/38 IB/rdmavt: Reset all QPs when the device is shut down
In reply to Greg Kroah-HartmanFrom: Kaike Wan <[email protected]>
commit f92e48718889b3d49cee41853402aa88cac84a6b upstream.
When the hfi1 device is shut down during a system reboot, it is possible that some QPs might have not not freed by ULPs. More requests could be post sent and a lingering timer could be triggered to schedule more packet sends, leading to a crash:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000102 IP: [ffffffff810a65f2] __queue_work+0x32/0x3c0 PGD 0 Oops: 0000 1 SMP Modules linked in: nvmet_rdma(OE) nvmet(OE) nvme(OE) dm_round_robin nvme_rdma(OE) nvme_fabrics(OE) nvme_core(OE) pal_raw(POE) pal_pmt(POE) pal_cache(POE) pal_pile(POE) pal(POE) pal_compatible(OE) rpcrdma sunrpc ib_isert iscsi_target_mod target_core_mod ib_iser libiscsi scsi_transport_iscsi ib_ipoib rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm mlx4_ib sb_edac edac_core intel_powerclamp coretemp intel_rapl iosf_mbi kvm irqbypass crc32_pclmul ghash_clmulni_intel aesni_intel lrw gf128mul glue_helper ablk_helper cryptd iTCO_wdt iTCO_vendor_support mxm_wmi ipmi_ssif pcspkr ses enclosure joydev scsi_transport_sas i2c_i801 sg mei_me lpc_ich mei ioatdma shpchp ipmi_si ipmi_devintf ipmi_msghandler wmi acpi_power_meter acpi_pad dm_multipath hangcheck_timer ip_tables ext4 mbcache jbd2 mlx4_en sd_mod crc_t10dif crct10dif_generic mgag200 drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm mlx4_core crct10dif_pclmul crct10dif_common hfi1(OE) igb crc32c_intel rdmavt(OE) ahci ib_core libahci libata ptp megaraid_sas pps_core dca i2c_algo_bit i2c_core devlink dm_mirror dm_region_hash dm_log dm_mod CPU: 23 PID: 0 Comm: swapper/23 Tainted: P OE ------------ 3.10.0-693.el7.x86_64 #1 Hardware name: Intel Corporation S2600CWR/S2600CWR, BIOS SE5C610.86B.01.01.0028.121720182203 12/17/2018 task: ffff8808f4ec4f10 ti: ffff8808f4ed8000 task.ti: ffff8808f4ed8000 RIP: 0010:[ffffffff810a65f2] [ffffffff810a65f2] __queue_work+0x32/0x3c0 RSP: 0018:ffff88105df43d48 EFLAGS: 00010046 RAX: 0000000000000086 RBX: 0000000000000086 RCX: 0000000000000000 RDX: ffff880f74e758b0 RSI: 0000000000000000 RDI: 000000000000001f RBP: ffff88105df43d80 R08: ffff8808f3c583c8 R09: ffff8808f3c58000 R10: 0000000000000002 R11: ffff88105df43da8 R12: ffff880f74e758b0 R13: 000000000000001f R14: 0000000000000000 R15: ffff88105a300000 FS: 0000000000000000(0000) GS:ffff88105df40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000102 CR3: 00000000019f2000 CR4: 00000000001407e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Stack: ffff88105b6dd708 0000001f00000286 0000000000000086 ffff88105a300000 ffff880f74e75800 0000000000000000 ffff88105a300000 ffff88105df43d98 ffffffff810a6b85 ffff88105a301e80 ffff88105df43dc8 ffffffffc0224cde Call Trace: IRQ
[ffffffff810a6b85] queue_work_on+0x45/0x50 [ffffffffc0224cde] _hfi1_schedule_send+0x6e/0xc0 [hfi1] [ffffffffc0170570] ? get_map_page+0x60/0x60 [rdmavt] [ffffffffc0224d62] hfi1_schedule_send+0x32/0x70 [hfi1] [ffffffffc0170644] rvt_rc_timeout+0xd4/0x120 [rdmavt] [ffffffffc0170570] ? get_map_page+0x60/0x60 [rdmavt] [ffffffff81097316] call_timer_fn+0x36/0x110 [ffffffffc0170570] ? get_map_page+0x60/0x60 [rdmavt] [ffffffff8109982d] run_timer_softirq+0x22d/0x310 [ffffffff81090b3f] __do_softirq+0xef/0x280 [ffffffff816b6a5c] call_softirq+0x1c/0x30 [ffffffff8102d3c5] do_softirq+0x65/0xa0 [ffffffff81090ec5] irq_exit+0x105/0x110 [ffffffff816b76c2] smp_apic_timer_interrupt+0x42/0x50 [ffffffff816b5c1d] apic_timer_interrupt+0x6d/0x80 EOI
[ffffffff81527a02] ? cpuidle_enter_state+0x52/0xc0 [ffffffff81527b48] cpuidle_idle_call+0xd8/0x210 [ffffffff81034fee] arch_cpu_idle+0xe/0x30 [ffffffff810e7bca] cpu_startup_entry+0x14a/0x1c0 [ffffffff81051af6] start_secondary+0x1b6/0x230
Code: 89 e5 41 57 41 56 49 89 f6 41 55 41 89 fd 41 54 49 89 d4 53 48 83 ec 10 89 7d d4 9c 58 0f 1f 44 00 00 f6 c4 02 0f 85 be 02 00 00 41 f6 86 02 01 00 00 01 0f 85 58 02 00 00 49 c7 c7 28 19 01 00 RIP [ffffffff810a65f2] __queue_work+0x32/0x3c0 RSP ffff88105df43d48 CR2: 0000000000000102
The solution is to reset the QPs before the device resources are freed. This reset will change the QP state to prevent post sends and delete timers to prevent callbacks.
--- drivers/infiniband/sw/rdmavt/qp.c | 84 +++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 33 deletions(-)
drivers/infiniband/sw/rdmavt/qp.c +51 -33
@@ -58,6 +58,8 @@#include "trace.h" static void rvt_rc_timeout (struct timer_list *t); +static void rvt_reset_qp (struct rvt_dev_info *rdi,struct rvt_qp *qp, +enum ib_qp_type type);/* * Convert the AETH RNR timeout code into the number of microseconds.
@@ -268,40 +270,41 @@ no_qp_table: }/** -* free_all_qps - check for QPs still in use +* rvt_free_qp_cb - callback function to reset a qp +* @qp: the qp to reset +* @v: a 64-bit value +* +* This function resets the qp and removes it from the +* qp hash table. +*/ +static void rvt_free_qp_cb (struct rvt_qp *qp,u64 v) +{ +unsigned int *qp_inuse = (unsigned int *)v; +struct rvt_dev_info *rdi =ib_to_rvt (qp->ibqp.device); + +/* Reset the qp and remove it from the qp hash list */ +rvt_reset_qp (rdi, qp, qp->ibqp.qp_type); + +/* Increment the qp_inuse count */ + (*qp_inuse)++; +} + +/** +* rvt_free_all_qps - check for QPs still in use * @rdi: rvt device info structure * * There should not be any QPs still in use. * Free memory for table. +* Return the number of QPs still in use. */ static unsigned rvt_free_all_qps (struct rvt_dev_info *rdi) { -unsigned long flags; -struct rvt_qp *qp; -unsigned n, qp_inuse =0 ; -spinlock_t *ql;/* work around too long line below */ - -if (rdi->driver_f.free_all_qps) - qp_inuse = rdi->driver_f.free_all_qps (rdi); +unsigned int qp_inuse =0 ; qp_inuse +=rvt_mcast_tree_empty (rdi); -if (!rdi->qp_dev) -return qp_inuse; +rvt_qp_iter (rdi, (u64)&qp_inuse, rvt_free_qp_cb); - ql = &rdi->qp_dev->qpt_lock; -spin_lock_irqsave (ql, flags); -for (n =0 ; n < rdi->qp_dev->qp_table_size; n++) { - qp =rcu_dereference_protected (rdi->qp_dev->qp_table[n], -lockdep_is_held (ql)); -RCU_INIT_POINTER (rdi->qp_dev->qp_table[n],NULL ); - -for (; qp; qp =rcu_dereference_protected (qp->next, -lockdep_is_held (ql))) - qp_inuse++; - } -spin_unlock_irqrestore (ql, flags); -synchronize_rcu ();return qp_inuse; }
@@ -684,14 +687,14 @@ static void rvt_init_qp(struct rvt_dev_i }/** -* rvt_reset_qp - initialize the QP state to the reset state +* _rvt_reset_qp - initialize the QP state to the reset state * @qp: the QP to reset * @type: the QP type * * r_lock, s_hlock, and s_lock are required to be held by the caller */ -static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp, - enum ib_qp_type type) +static void _rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp, + enum ib_qp_type type) __must_hold(&qp->s_lock) __must_hold(&qp->s_hlock) __must_hold(&qp->r_lock)
@@ -737,6 +740,27 @@ static void rvt_reset_qp(struct rvt_dev_lockdep_assert_held (&qp->s_lock); } +/** +* rvt_reset_qp - initialize the QP state to the reset state +* @rdi: the device info +* @qp: the QP to reset +* @type: the QP type +* +* This is the wrapper function to acquire the r_lock, s_hlock, and s_lock +* before calling _rvt_reset_qp(). +*/ +static void rvt_reset_qp (struct rvt_dev_info *rdi,struct rvt_qp *qp, +enum ib_qp_type type) +{ +spin_lock_irq (&qp->r_lock); +spin_lock (&qp->s_hlock); +spin_lock (&qp->s_lock); +_rvt_reset_qp (rdi, qp, type); +spin_unlock (&qp->s_lock); +spin_unlock (&qp->s_hlock); +spin_unlock_irq (&qp->r_lock); +} +/** rvt_free_qpn - Free a qpn from the bit map * @qpt: QP table * @qpn: queue pair number to free
@@ -1285,7 +1309,7 @@ int rvt_modify_qp(struct ib_qp *ibqp, stswitch (new_state) {case IB_QPS_RESET :if (qp->state !=IB_QPS_RESET ) -rvt_reset_qp (rdi, qp, ibqp->qp_type); +_rvt_reset_qp (rdi, qp, ibqp->qp_type);break ;case IB_QPS_RTR :
@@ -1434,13 +1458,7 @@ int rvt_destroy_qp(struct ib_qp *ibqp)struct rvt_qp *qp =ibqp_to_rvtqp (ibqp);struct rvt_dev_info *rdi =ib_to_rvt (ibqp->device); -spin_lock_irq (&qp->r_lock); -spin_lock (&qp->s_hlock); -spin_lock (&qp->s_lock);rvt_reset_qp (rdi, qp, ibqp->qp_type); -spin_unlock (&qp->s_lock); -spin_unlock (&qp->s_hlock); -spin_unlock_irq (&qp->r_lock);wait_event (qp->wait, !atomic_read (&qp->refcount));/* qpn is now available for use again */
Greg Kroah-Hartman
maintainerPATCH 28/38 RDMA/core: Fix invalid memory access in spec_filter_size
In reply to Greg Kroah-HartmanFrom: Avihai Horon <[email protected]>
commit a72f4ac1d778f7bde93dfee69bfc23377ec3d74f upstream.
Add a check that the size specified in the flow spec header doesn't cause an overflow when calculating the filter size, and thus prevent access to invalid memory. The following crash from syzkaller revealed it.
kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] SMP KASAN PTI
CPU: 1 PID: 17834 Comm: syz-executor.3 Not tainted 5.5.0-rc5 #2
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
RIP: 0010:memchr_inv+0xd3/0x330
Code: 89 f9 89 f5 83 e1 07 0f 85 f9 00 00 00 49 89 d5 49 c1 ed 03 45 85
ed 74 6f 48 89 d9 48 b8 00 00 00 00 00 fc ff df 48 c1 e9 03 <80> 3c 01
00 0f 85 0d 02 00 00 44 0f b6 e5 48 b8 01 01 01 01 01 01
RSP: 0018:ffffc9000a13fa50 EFLAGS: 00010202
RAX: dffffc0000000000 RBX: 7fff88810de9d820 RCX: 0ffff11021bd3b04
RDX: 000000000000fff8 RSI: 0000000000000000 RDI: 7fff88810de9d820
RBP: 0000000000000000 R08: ffff888110d69018 R09: 0000000000000009
R10: 0000000000000001 R11: ffffed10236267cc R12: 0000000000000004
R13: 0000000000001fff R14: ffff88810de9d820 R15: 0000000000000040
FS: 00007f9ee0e51700(0000) GS:ffff88811b100000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000115ea0006 CR4: 0000000000360ee0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
spec_filter_size.part.16+0x34/0x50
ib_uverbs_kern_spec_to_ib_spec_filter+0x691/0x770
ib_uverbs_ex_create_flow+0x9ea/0x1b40
ib_uverbs_write+0xaa5/0xdf0
__vfs_write+0x7c/0x100
vfs_write+0x168/0x4a0
ksys_write+0xc8/0x200
do_syscall_64+0x9c/0x390
entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x465b49
Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 48 89
f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01
f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f9ee0e50c58 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 000000000073bf00 RCX: 0000000000465b49
RDX: 00000000000003a0 RSI: 00000000200007c0 RDI: 0000000000000004
RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007f9ee0e516bc
R13: 00000000004ca2da R14: 000000000070deb8 R15: 00000000ffffffff
Modules linked in:
Dumping ftrace buffer:
(ftrace buffer empty)--- drivers/infiniband/core/uverbs_cmd.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
drivers/infiniband/core/uverbs_cmd.c +7 -8
@@ -2914,12 +2914,6 @@ static int kern_spec_to_ib_spec_action(sreturn 0 ; } -static size_t kern_spec_filter_sz (const struct ib_uverbs_flow_spec_hdr *spec) -{ -/* Returns user space filter size, includes padding */ -return (spec->size -sizeof (struct ib_uverbs_flow_spec_hdr )) /2 ; -} -static ssize_t spec_filter_size (const void *kern_spec_filter,u16 kern_filter_size,u16 ib_real_filter_sz) {
@@ -3063,11 +3057,16 @@ int ib_uverbs_kern_spec_to_ib_spec_filtestatic int kern_spec_to_ib_spec_filter (struct ib_uverbs_flow_spec *kern_spec,union ib_flow_spec *ib_spec) { -ssize_t kern_filter_sz; +size_t kern_filter_sz;void *kern_spec_mask;void *kern_spec_val; - kern_filter_sz =kern_spec_filter_sz (&kern_spec->hdr); +if (check_sub_overflow ((size_t )kern_spec->hdr.size, +sizeof (struct ib_uverbs_flow_spec_hdr ), + &kern_filter_sz)) +return -EINVAL ; + + kern_filter_sz /=2 ; kern_spec_val = (void *)kern_spec +sizeof (struct ib_uverbs_flow_spec_hdr );
Greg Kroah-Hartman
maintainerPATCH 29/38 RDMA/hfi1: Fix memory leak in _dev_comp_vect_mappings_create
In reply to Greg Kroah-HartmanFrom: Kamal Heib <[email protected]>
commit 8a4f300b978edbbaa73ef9eca660e45eb9f13873 upstream.
Make sure to free the allocated cpumask_var_t's to avoid the following reported memory leak by kmemleak:
$ cat /sys/kernel/debug/kmemleak
unreferenced object 0xffff8897f812d6a8 (size 8):
comm "kworker/1:1", pid 347, jiffies 4294751400 (age 101.703s)
hex dump (first 8 bytes):
00 00 00 00 00 00 00 00 ........
backtrace:
[<00000000bff49664>] alloc_cpumask_var_node+0x4c/0xb0
[<0000000075d3ca81>] hfi1_comp_vectors_set_up+0x20f/0x800 [hfi1]
[<0000000098d420df>] hfi1_init_dd+0x3311/0x4960 [hfi1]
[<0000000071be7e52>] init_one+0x25e/0xf10 [hfi1]
[<000000005483d4c2>] local_pci_probe+0xd4/0x180
[<000000007c3cbc6e>] work_for_cpu_fn+0x51/0xa0
[<000000001d626905>] process_one_work+0x8f0/0x17b0
[<000000007e569e7e>] worker_thread+0x536/0xb50
[<00000000fd39a4a5>] kthread+0x30c/0x3d0
[<0000000056f2edb3>] ret_from_fork+0x3a/0x50--- drivers/infiniband/hw/hfi1/affinity.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/infiniband/hw/hfi1/affinity.c +2 -0
@@ -478,6 +478,8 @@ static int _dev_comp_vect_mappings_creat rvt_get_ibdev_name(&(dd)->verbs_dev.rdi), i, cpu); } +free_cpumask_var (available_cpus); +free_cpumask_var (non_intr_cpus);return 0 ; fail:
Greg Kroah-Hartman
maintainerPATCH 30/38 RDMA/rxe: Fix soft lockup problem due to using tasklets in softirq
In reply to Greg Kroah-HartmanFrom: Zhu Yanjun <[email protected]>
commit 8ac0e6641c7ca14833a2a8c6f13d8e0a435e535c upstream.
When run stress tests with RXE, the following Call Traces often occur
watchdog: BUG: soft lockup - CPU#2 stuck for 22s! [swapper/2:0] ... Call Trace: <IRQ> create_object+0x3f/0x3b0 kmem_cache_alloc_node_trace+0x129/0x2d0 __kmalloc_reserve.isra.52+0x2e/0x80 __alloc_skb+0x83/0x270 rxe_init_packet+0x99/0x150 [rdma_rxe] rxe_requester+0x34e/0x11a0 [rdma_rxe] rxe_do_task+0x85/0xf0 [rdma_rxe] tasklet_action_common.isra.21+0xeb/0x100 __do_softirq+0xd0/0x298 irq_exit+0xc5/0xd0 smp_apic_timer_interrupt+0x68/0x120 apic_timer_interrupt+0xf/0x20 </IRQ> ...
The root cause is that tasklet is actually a softirq. In a tasklet handler, another softirq handler is triggered. Usually these softirq handlers run on the same cpu core. So this will cause "soft lockup Bug".
--- drivers/infiniband/sw/rxe/rxe_comp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/infiniband/sw/rxe/rxe_comp.c +4 -4
@@ -329,7 +329,7 @@ static inline enum comp_state check_ack( qp->comp.psn = pkt->psn;if (qp->req.wait_psn) { qp->req.wait_psn =0 ; -rxe_run_task (&qp->req.task,1 ); +rxe_run_task (&qp->req.task,0 ); } }return COMPST_ERROR_RETRY ;
@@ -457,7 +457,7 @@ static void do_complete(struct rxe_qp *q*/ if (qp->req.wait_fence) { qp->req.wait_fence =0 ; -rxe_run_task (&qp->req.task,1 ); +rxe_run_task (&qp->req.task,0 ); } }
@@ -473,7 +473,7 @@ static inline enum comp_state complete_aif (qp->req.need_rd_atomic) { qp->comp.timeout_retry =0 ; qp->req.need_rd_atomic =0 ; -rxe_run_task (&qp->req.task,1 ); +rxe_run_task (&qp->req.task,0 ); } }
@@ -719,7 +719,7 @@ int rxe_completer(void *arg) RXE_CNT_COMP_RETRY); qp->req.need_retry =1 ; qp->comp.started_retry =1 ; -rxe_run_task (&qp->req.task,1 ); +rxe_run_task (&qp->req.task,0 ); }if (pkt) {
Greg Kroah-Hartman
maintainerPATCH 31/38 RDMA/core: Fix protection fault in get_pkey_idx_qp_list
In reply to Greg Kroah-HartmanFrom: Leon Romanovsky <[email protected]>
commit 1dd017882e01d2fcd9c5dbbf1eb376211111c393 upstream.
We don't need to set pkey as valid in case that user set only one of pkey index or port number, otherwise it will be resulted in NULL pointer dereference while accessing to uninitialized pkey list. The following crash from Syzkaller revealed it.
kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] SMP KASAN PTI CPU: 1 PID: 14753 Comm: syz-executor.2 Not tainted 5.5.0-rc5 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 RIP: 0010:get_pkey_idx_qp_list+0x161/0x2d0 Code: 01 00 00 49 8b 5e 20 4c 39 e3 0f 84 b9 00 00 00 e8 e4 42 6e fe 48 8d 7b 10 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <0f> b6 04 02 84 c0 74 08 3c 01 0f 8e d0 00 00 00 48 8d 7d 04 48 b8 RSP: 0018:ffffc9000bc6f950 EFLAGS: 00010202 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff82c8bdec RDX: 0000000000000002 RSI: ffffc900030a8000 RDI: 0000000000000010 RBP: ffff888112c8ce80 R08: 0000000000000004 R09: fffff5200178df1f R10: 0000000000000001 R11: fffff5200178df1f R12: ffff888115dc4430 R13: ffff888115da8498 R14: ffff888115dc4410 R15: ffff888115da8000 FS: 00007f20777de700(0000) GS:ffff88811b100000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b2f721000 CR3: 00000001173ca002 CR4: 0000000000360ee0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: port_pkey_list_insert+0xd7/0x7c0 ib_security_modify_qp+0x6fa/0xfc0 _ib_modify_qp+0x8c4/0xbf0 modify_qp+0x10da/0x16d0 ib_uverbs_modify_qp+0x9a/0x100 ib_uverbs_write+0xaa5/0xdf0 __vfs_write+0x7c/0x100 vfs_write+0x168/0x4a0 ksys_write+0xc8/0x200 do_syscall_64+0x9c/0x390 entry_SYSCALL_64_after_hwframe+0x44/0xa9
Message-Id: <20200212080651.GB679970@unreal>
--- drivers/infiniband/core/security.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-)
drivers/infiniband/core/security.c +9 -15
@@ -336,22 +336,16 @@ static struct ib_ports_pkeys *get_new_ppif (!new_pps)return NULL ; -if (qp_attr_mask & (IB_QP_PKEY_INDEX |IB_QP_PORT )) { -if (!qp_pps) { - new_pps->main.port_num = qp_attr->port_num; - new_pps->main.pkey_index = qp_attr->pkey_index; - }else { - new_pps->main.port_num = (qp_attr_mask &IB_QP_PORT ) ? - qp_attr->port_num : - qp_pps->main.port_num; - - new_pps->main.pkey_index = - (qp_attr_mask &IB_QP_PKEY_INDEX ) ? - qp_attr->pkey_index : - qp_pps->main.pkey_index; - } +if (qp_attr_mask &IB_QP_PORT ) + new_pps->main.port_num = + (qp_pps) ? qp_pps->main.port_num : qp_attr->port_num; +if (qp_attr_mask &IB_QP_PKEY_INDEX ) + new_pps->main.pkey_index = (qp_pps) ? qp_pps->main.pkey_index : + qp_attr->pkey_index; +if ((qp_attr_mask &IB_QP_PKEY_INDEX ) && (qp_attr_mask &IB_QP_PORT )) new_pps->main.state =IB_PORT_PKEY_VALID ; - }else if (qp_pps) { + +if (!(qp_attr_mask & (IB_QP_PKEY_INDEX ||IB_QP_PORT )) && qp_pps) { new_pps->main.port_num = qp_pps->main.port_num; new_pps->main.pkey_index = qp_pps->main.pkey_index;if (qp_pps->main.state !=IB_PORT_PKEY_NOT_VALID )
Greg Kroah-Hartman
maintainerPATCH 32/38 s390/time: Fix clk type in get_tod_clock
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
commit 0f8a206df7c920150d2aa45574fba0ab7ff6be4f upstream.
Clang warns:
In file included from ../arch/s390/boot/startup.c:3:
In file included from ../include/linux/elf.h:5:
In file included from ../arch/s390/include/asm/elf.h:132:
In file included from ../include/linux/compat.h:10:
In file included from ../include/linux/time.h:74:
In file included from ../include/linux/time32.h:13:
In file included from ../include/linux/timex.h:65:../arch/s390/include/asm/timex.h:160:20: warning: passing 'unsigned char [16]' to parameter of type 'char *' converts between pointers to integer types with different sign [-Wpointer-sign]
get_tod_clock_ext(clk);
^~~
../arch/s390/include/asm/timex.h:149:44: note: passing argument to
parameter 'clk' here
static inline void get_tod_clock_ext(char *clk)
^Change clk's type to just be char so that it matches what happens in get_tod_clock_ext.
--- arch/s390/include/asm/timex.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/include/asm/timex.h +1 -1
@@ -155,7 +155,7 @@ static inline void get_tod_clock_ext(chastatic inline unsigned long long get_tod_clock (void ) { -unsigned char clk[STORE_CLOCK_EXT_SIZE ]; +char clk[STORE_CLOCK_EXT_SIZE ];get_tod_clock_ext (clk);return *((unsigned long long *)&clk[1 ]);
Greg Kroah-Hartman
maintainerPATCH 33/38 perf/x86/intel: Fix inaccurate period in context switch for auto-reload
In reply to Greg Kroah-HartmanFrom: Kan Liang <[email protected]>
commit f861854e1b435b27197417f6f90d87188003cb24 upstream.
Perf doesn't take the left period into account when auto-reload is enabled with fixed period sampling mode in context switch.
Here is the MSR trace of the perf command as below. (The MSR trace is simplified from a ftrace log.)
#perf record -e cycles:p -c 2000000 -- ./triad_loop
//The MSR trace of task schedule out
//perf disable all counters, disable PEBS, disable GP counter 0,
//read GP counter 0, and re-enable all counters.
//The counter 0 stops at 0xfffffff82840
write_msr: MSR_CORE_PERF_GLOBAL_CTRL(38f), value 0
write_msr: MSR_IA32_PEBS_ENABLE(3f1), value 0
write_msr: MSR_P6_EVNTSEL0(186), value 40003003c
rdpmc: 0, value fffffff82840
write_msr: MSR_CORE_PERF_GLOBAL_CTRL(38f), value f000000ff
//The MSR trace of the same task schedule in again
//perf disable all counters, enable and set GP counter 0,
//enable PEBS, and re-enable all counters.
//0xffffffe17b80 (-2000000) is written to GP counter 0.
write_msr: MSR_CORE_PERF_GLOBAL_CTRL(38f), value 0
write_msr: MSR_IA32_PMC0(4c1), value ffffffe17b80
write_msr: MSR_P6_EVNTSEL0(186), value 40043003c
write_msr: MSR_IA32_PEBS_ENABLE(3f1), value 1
write_msr: MSR_CORE_PERF_GLOBAL_CTRL(38f), value f000000ffWhen the same task schedule in again, the counter should starts from previous left. However, it starts from the fixed period -2000000 again.
A special variant of intel_pmu_save_and_restart() is used for auto-reload, which doesn't update the hwc->period_left. When the monitored task schedules in again, perf doesn't know the left period. The fixed period is used, which is inaccurate.
With auto-reload, the counter always has a negative counter value. So the left period is -value. Update the period_left in intel_pmu_save_and_restart_reload().
With the patch:
//The MSR trace of task schedule out
write_msr: MSR_CORE_PERF_GLOBAL_CTRL(38f), value 0
write_msr: MSR_IA32_PEBS_ENABLE(3f1), value 0
write_msr: MSR_P6_EVNTSEL0(186), value 40003003c
rdpmc: 0, value ffffffe25cbc
write_msr: MSR_CORE_PERF_GLOBAL_CTRL(38f), value f000000ff
//The MSR trace of the same task schedule in again
write_msr: MSR_CORE_PERF_GLOBAL_CTRL(38f), value 0
write_msr: MSR_IA32_PMC0(4c1), value ffffffe25cbc
write_msr: MSR_P6_EVNTSEL0(186), value 40043003c
write_msr: MSR_IA32_PEBS_ENABLE(3f1), value 1
write_msr: MSR_CORE_PERF_GLOBAL_CTRL(38f), value f000000ff--- arch/x86/events/intel/ds.c | 2 ++ 1 file changed, 2 insertions(+)
arch/x86/events/intel/ds.c +2 -0
@@ -1402,6 +1402,8 @@ intel_pmu_save_and_restart_reload(struct old = ((s64)(prev_raw_count << shift) >> shift);local64_add (new - old + count * period, &event->count); +local64_set (&hwc->period_left, -new); +perf_event_update_userpage (event);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 34/38 hwmon: (pmbus/ltc2978) Fix PMBus polling of MFR_COMMON definitions.
In reply to Greg Kroah-HartmanFrom: Mike Jones <[email protected]>
commit cf2b012c90e74e85d8aea7d67e48868069cfee0c upstream.
Change 21537dc driver PMBus polling of MFR_COMMON from bits 5/4 to bits 6/5. This fixs a LTC297X family bug where polling always returns not busy even when the part is busy. This fixes a LTC388X and LTM467X bug where polling used PEND and NOT_IN_TRANS, and BUSY was not polled, which can lead to NACKing of commands. LTC388X and LTM467X modules now poll BUSY and PEND, increasing reliability by eliminating NACKing of commands.
--- drivers/hwmon/pmbus/ltc2978.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hwmon/pmbus/ltc2978.c +2 -2
@@ -89,8 +89,8 @@ enum chips { ltc2974, ltc2975, ltc2977,#define LTC_POLL_TIMEOUT 100/* in milli-seconds */ -#define LTC_NOT_BUSY BIT(5) -#define LTC_NOT_PENDING BIT(4) +#define LTC_NOT_BUSY BIT(6) +#define LTC_NOT_PENDING BIT(5)/* * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which
Greg Kroah-Hartman
maintainerPATCH 35/38 NFSv4.1 make cachethis=no for writes
In reply to Greg Kroah-HartmanFrom: Olga Kornievskaia <[email protected]>
commit cd1b659d8ce7697ee9799b64f887528315b9097b upstream.
Turning caching off for writes on the server should improve performance.
--- fs/nfs/nfs4proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/nfs4proc.c +1 -1
@@ -5117,7 +5117,7 @@ static void nfs4_proc_write_setup(struct hdr->timestamp = jiffies; msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE ]; -nfs4_init_sequence (&hdr->args.seq_args, &hdr->res.seq_res,1 ,0 ); +nfs4_init_sequence (&hdr->args.seq_args, &hdr->res.seq_res,0 ,0 );nfs4_state_protect_write (server->nfs_client, clnt, msg, hdr); }
Greg Kroah-Hartman
maintainerPATCH 36/38 jbd2: move the clearing of b_modified flag to the journal_unmap_buffer()
In reply to Greg Kroah-HartmanFrom: zhangyi (F) <[email protected]>
[ Upstream commit 6a66a7ded12baa6ebbb2e3e82f8cb91382814839 ]
There is no need to delay the clearing of b_modified flag to the transaction committing time when unmapping the journalled buffer, so just move it to the journal_unmap_buffer().
--- fs/jbd2/commit.c | 43 +++++++++++++++---------------------------- fs/jbd2/transaction.c | 10 ++++++---- 2 files changed, 21 insertions(+), 32 deletions(-)
fs/jbd2/commit.c +15 -28
@@ -971,34 +971,21 @@ void jbd2_journal_commit_transaction(journal_t *journal)* it. */ /* -* A buffer which has been freed while still being journaled by -* a previous transaction. -*/ -if (buffer_freed (bh)) { -/* -* If the running transaction is the one containing -* "add to orphan" operation (b_next_transaction != -* NULL), we have to wait for that transaction to -* commit before we can really get rid of the buffer. -* So just clear b_modified to not confuse transaction -* credit accounting and refile the buffer to -* BJ_Forget of the running transaction. If the just -* committed transaction contains "add to orphan" -* operation, we can completely invalidate the buffer -* now. We are rather through in that since the -* buffer may be still accessible when blocksize < -* pagesize and it is attached to the last partial -* page. -*/ - jh->b_modified =0 ; -if (!jh->b_next_transaction) { -clear_buffer_freed (bh); -clear_buffer_jbddirty (bh); -clear_buffer_mapped (bh); -clear_buffer_new (bh); -clear_buffer_req (bh); - bh->b_bdev =NULL ; - } +* A buffer which has been freed while still being journaled +* by a previous transaction, refile the buffer to BJ_Forget of +* the running transaction. If the just committed transaction +* contains "add to orphan" operation, we can completely +* invalidate the buffer now. We are rather through in that +* since the buffer may be still accessible when blocksize < +* pagesize and it is attached to the last partial page. +*/ +if (buffer_freed (bh) && !jh->b_next_transaction) { +clear_buffer_freed (bh); +clear_buffer_jbddirty (bh); +clear_buffer_mapped (bh); +clear_buffer_new (bh); +clear_buffer_req (bh); + bh->b_bdev =NULL ; }if (buffer_jbddirty (bh)) {
fs/jbd2/transaction.c +6 -4
@@ -2228,14 +2228,16 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh,return -EBUSY ; }/* -* OK, buffer won't be reachable after truncate. We just set -* j_next_transaction to the running transaction (if there is -* one) and mark buffer as freed so that commit code knows it -* should clear dirty bits when it is done with the buffer. +* OK, buffer won't be reachable after truncate. We just clear +* b_modified to not confuse transaction credit accounting, and +* set j_next_transaction to the running transaction (if there +* is one) and mark buffer as freed so that commit code knows +* it should clear dirty bits when it is done with the buffer. */ set_buffer_freed (bh);if (journal->j_running_transaction &&buffer_jbddirty (bh)) jh->b_next_transaction = journal->j_running_transaction; + jh->b_modified =0 ;jbd2_journal_put_journal_head (jh);spin_unlock (&journal->j_list_lock);jbd_unlock_bh_state (bh);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 37/38 jbd2: do not clear the BH_Mapped flag when forgetting a metadata buffer
In reply to Greg Kroah-HartmanFrom: zhangyi (F) <[email protected]>
[ Upstream commit c96dceeabf765d0b1b1f29c3bf50a5c01315b820 ]
Commit 904cdbd41d74 ("jbd2: clear dirty flag when revoking a buffer from an older transaction") set the BH_Freed flag when forgetting a metadata buffer which belongs to the committing transaction, it indicate the committing process clear dirty bits when it is done with the buffer. But it also clear the BH_Mapped flag at the same time, which may trigger below NULL pointer oops when block_size < PAGE_SIZE.
rmdir 1 kjournald2 mkdir 2
jbd2_journal_commit_transaction commit transaction Njbd2_journal_forgetset_buffer_freed(bh1)
jbd2_journal_commit_transaction
commit transaction N+1
...
clear_buffer_mapped(bh1)
ext4_getblk(bh2 ummapped)
...
grow_dev_page
init_page_buffers
bh1->b_private=NULL
bh2->b_private=NULL
jbd2_journal_put_journal_head(jh1)
__journal_remove_journal_head(hb1)
jh1 is NULL and trigger oops*) Dir entry block bh1 and bh2 belongs to one page, and the bh2 has
already been unmapped.
For the metadata buffer we forgetting, we should always keep the mapped flag and clear the dirty flags is enough, so this patch pick out the these buffers and keep their BH_Mapped flag.
--- fs/jbd2/commit.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-)
fs/jbd2/commit.c +21 -4
@@ -980,12 +980,29 @@ void jbd2_journal_commit_transaction(journal_t *journal)* pagesize and it is attached to the last partial page. */ if (buffer_freed (bh) && !jh->b_next_transaction) { +struct address_space *mapping; +clear_buffer_freed (bh);clear_buffer_jbddirty (bh); -clear_buffer_mapped (bh); -clear_buffer_new (bh); -clear_buffer_req (bh); - bh->b_bdev =NULL ; + +/* +* Block device buffers need to stay mapped all the +* time, so it is enough to clear buffer_jbddirty and +* buffer_freed bits. For the file mapping buffers (i.e. +* journalled data) we need to unmap buffer and clear +* more bits. We also need to be careful about the check +* because the data page mapping can get cleared under +* out hands, which alse need not to clear more bits +* because the page and buffers will be freed and can +* never be reused once we are done with them. +*/ + mapping =READ_ONCE (bh->b_page->mapping); +if (mapping && !sb_is_blkdev_sb (mapping->host->i_sb)) { +clear_buffer_mapped (bh); +clear_buffer_new (bh); +clear_buffer_req (bh); + bh->b_bdev =NULL ; + } }if (buffer_jbddirty (bh)) {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 38/38 KVM: x86/mmu: Fix struct guest_walker arrays for 5-level paging
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit f6ab0107a4942dbf9a5cf0cca3f37e184870a360 ]
Define PT_MAX_FULL_LEVELS as PT64_ROOT_MAX_LEVEL, i.e. 5, to fix shadow paging for 5-level guest page tables. PT_MAX_FULL_LEVELS is used to size the arrays that track guest pages table information, i.e. using a "max levels" of 4 causes KVM to access garbage beyond the end of an array when querying state for level 5 entries. E.g. FNAME(gpte_changed) will read garbage and most likely return %true for a level 5 entry, soft-hanging the guest because FNAME(fetch) will restart the guest instead of creating SPTEs because it thinks the guest PTE has changed.
Note, KVM doesn't yet support 5-level nested EPT, so PT_MAX_FULL_LEVELS gets to stay "4" for the PTTYPE_EPT case.
--- arch/x86/kvm/paging_tmpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/paging_tmpl.h +1 -1
@@ -36,7 +36,7 @@#define PT_GUEST_ACCESSED_SHIFT PT_ACCESSED_SHIFT#define PT_HAVE_ACCESSED_DIRTY (mmu) true#ifdef CONFIG_X86_64 -#define PT_MAX_FULL_LEVELS 4 +#define PT_MAX_FULL_LEVELS PT64_ROOT_MAX_LEVEL#define CMPXCHG cmpxchg#else #define CMPXCHG cmpxchg64
Signature · 1 line
2.20.1
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.19.105 release. There are 38 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 20 Feb 2020 19:03:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.105-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.19.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.19.105 release. There are 38 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 20 Feb 2020 19:03:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.105-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.19.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
Summary
------------------------------------------------------------------------
kernel: 4.19.105-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.19.y
git commit: 85265e81d664e50b5da918dbdf02b5bbb926b2ea
git describe: v4.19.104-39-g85265e81d664
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.19-oe/build/v4.19.104-39-g85265e81d664
No regressions (compared to build v4.19.104)
No fixes (compared to build v4.19.104)
Ran 23734 total tests in the following environments and test suites.
Environments
--------------
- dragonboard-410c - arm64
- hi6220-hikey - arm64
- i386
- juno-r2 - arm64
- nxp-ls2088
- qemu_arm
- qemu_arm64
- qemu_i386
- qemu_x86_64
- x15 - arm
- x86_64
Test Suites
-----------
* build
* install-android-platform-tools-r2600
* kselftest
* libhugetlbfs
* linux-log-parser
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-cpuhotplug-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* spectre-meltdown-checker-test
* v4l2-compliance
* ltp-fs-tests
* ltp-syscalls-tests
* network-basic-tests
* perf
* ltp-open-posix-tests
* kvm-unit-tests
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Jon Hunter
maintainerQuoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.19.105 release. There are 38 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 20 Feb 2020 19:03:19 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.105-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.19.y
and the diffstat can be found below.thanks,
greg k-h
All tests are passing for Tegra ...
Test results for stable-v4.19:
11 builds: 11 pass, 0 fail
22 boots: 22 pass, 0 fail
32 tests: 32 pass, 0 failLinux version: 4.19.105-rc1-g85265e81d664
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra20-ventana,
tegra210-p2371-2180, tegra30-cardhu-a04Cheers
Jon
Signature · 1 line
nvpublic
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.19.105 release. There are 38 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 20 Feb 2020 19:03:19 +0000. Anything received after that time might be too late.
Build results:
total: 156 pass: 156 fail: 0 Qemu test results: total: 403 pass: 403 fail: 0
Guenter