6.0.18-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainercover 6.0.18-rc1 review
This is the start of the stable review cycle for the 6.0.18 release. There are 177 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 Fri, 06 Jan 2023 16:04:29 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.0.18-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-6.0.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.0.18-rc1
Evan Quan <[email protected]>
drm/amd/pm: correct the fan speed retrieving in PWM for some SMU13 asics
Evan Quan <[email protected]>
drm/amd/pm: bump SMU13.0.0 driver_if header to version 0x34
Evan Quan <[email protected]>
drm/amd/pm: add missing SMU13.0.7 mm_dpm feature mapping
Evan Quan <[email protected]>
drm/amd/pm: add missing SMU13.0.0 mm_dpm feature mapping
Chris Wilson <[email protected]>
drm/i915/migrate: Account for the reserved_space
Matthew Auld <[email protected]>
drm/i915: improve the catch-all evict to handle lock contention
Alex Deucher <[email protected]>
drm/amdgpu: make display pinning more flexible (v2)
Alex Deucher <[email protected]>
drm/amdgpu: handle polaris10/11 overlap asics (v2)
Yifan Zhang <[email protected]>
drm/amd/display: Add DCN314 display SG Support
Matthew Auld <[email protected]>
drm/i915/ttm: consider CCS for backup objects
Ye Bin <[email protected]>
ext4: allocate extended attribute value in vmalloc area
Jan Kara <[email protected]>
ext4: avoid unaccounted block allocation when expanding inode
Jan Kara <[email protected]>
ext4: initialize quota before expanding inode in setproject ioctl
Ye Bin <[email protected]>
ext4: fix inode leak in ext4_xattr_inode_create() on an error path
Ye Bin <[email protected]>
ext4: fix kernel BUG in 'ext4_write_inline_data_end()'
Jan Kara <[email protected]>
ext4: fix deadlock due to mbcache entry corruption
Jan Kara <[email protected]>
ext4: avoid BUG_ON when creating xattrs
Baokun Li <[email protected]>
ext4: fix corrupt backup group descriptors after online resize
Darrick J. Wong <[email protected]>
ext4: dont return EINVAL from GETFSUUID when reporting UUID length
Baokun Li <[email protected]>
ext4: fix bad checksum after online resize
Luís Henriques <[email protected]>
ext4: fix error code return to user-space in ext4_get_branch()
Baokun Li <[email protected]>
ext4: fix corruption when online resizing a 1K bigalloc fs
Eric Whitney <[email protected]>
ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline
Darrick J. Wong <[email protected]>
ext4: don't fail GETFSUUID when the caller provides a long buffer
Ye Bin <[email protected]>
ext4: init quota for 'old.inode' in 'ext4_rename'
Ye Bin <[email protected]>
ext4: fix uninititialized value in 'ext4_evict_inode'
Eric Biggers <[email protected]>
ext4: fix off-by-one errors in fast-commit block filling
Eric Biggers <[email protected]>
ext4: fix unaligned memory access in ext4_fc_reserve_space()
Eric Biggers <[email protected]>
ext4: add missing validation of fast-commit record lengths
Eric Biggers <[email protected]>
ext4: don't set up encryption key during jbd2 transaction
Eric Biggers <[email protected]>
ext4: fix leaking uninitialized memory in fast-commit journal
Eric Biggers <[email protected]>
ext4: disable fast-commit of encrypted dir operations
Eric Biggers <[email protected]>
ext4: don't allow journal inode to have encrypt flag
Baokun Li <[email protected]>
ext4: fix bug_on in __es_tree_search caused by bad boot loader inode
Zhang Yi <[email protected]>
ext4: check and assert if marking an no_delete evicting inode dirty
Lukas Czerner <[email protected]>
ext4: journal_path mount options should follow links
Ye Bin <[email protected]>
ext4: fix reserved cluster accounting in __es_remove_extent()
Baokun Li <[email protected]>
ext4: fix bug_on in __es_tree_search caused by bad quota inode
Baokun Li <[email protected]>
ext4: add helper to check quota inums
Baokun Li <[email protected]>
ext4: add EXT4_IGET_BAD flag to prevent unexpected bad inode
Gaosheng Cui <[email protected]>
ext4: fix undefined behavior in bit shift for ext4_check_flag_values
Baokun Li <[email protected]>
ext4: fix use-after-free in ext4_orphan_cleanup
Alexander Potapenko <[email protected]>
fs: ext4: initialize fsdata in pagecache_write()
Luís Henriques <[email protected]>
ext4: remove trailing newline from ext4_msg() message
Baokun Li <[email protected]>
ext4: add inode table check in __ext4_get_inode_loc to aovid possible infinite loop
Zhang Yi <[email protected]>
ext4: silence the warning when evicting inode with dioread_nolock
Ard Biesheuvel <[email protected]>
arm64: efi: Execute runtime services from a dedicated stack
Lucas Stach <[email protected]>
drm/etnaviv: reap idle mapping if it doesn't match the softpin address
Yuan Can <[email protected]>
drm/ingenic: Fix missing platform_driver_unregister() call in ingenic_drm_init()
Mikko Kovanen <[email protected]>
drm/i915/dsi: fix VBT send packet port selection for dual link DSI
Lucas Stach <[email protected]>
drm/etnaviv: move idle mapping reaping into separate function
Zack Rusin <[email protected]>
drm/vmwgfx: Validate the box size for the snooped cursor
Simon Ser <[email protected]>
drm/connector: send hotplug uevent on connector cleanup
Wang Weiyang <[email protected]>
device_cgroup: Roll back to original exceptions after copy failure
Helge Deller <[email protected]>
parisc: Drop PMD_SHIFT from calculation in pgtable.h
Helge Deller <[email protected]>
parisc: Add missing FORCE prerequisites in Makefile
Helge Deller <[email protected]>
parisc: Fix locking in pdc_iodc_print() firmware call
Shang XiaoJing <[email protected]>
parisc: led: Fix potential null-ptr-deref in start_task()
Peng Fan <[email protected]>
remoteproc: imx_rproc: Correct i.MX93 DRAM mapping
Maria Yu <[email protected]>
remoteproc: core: Do pm_relax when in RPROC_OFFLINE state
Shengjiu Wang <[email protected]>
remoteproc: imx_dsp_rproc: Add mutex protection for workqueue
Li Hua <[email protected]>
test_kprobes: Fix implicit declaration error of test_kprobes
Kim Phillips <[email protected]>
iommu/amd: Fix ill-formed ivrs_ioapic, ivrs_hpet and ivrs_acpihid options
Kim Phillips <[email protected]>
iommu/amd: Fix ivrs_acpihid cmdline parsing code
Johan Hovold <[email protected]>
phy: qcom-qmp-combo: fix sc8180x reset
Qiang Yu <[email protected]>
bus: mhi: host: Fix race between channel preparation and M0 event
Isaac J. Manjarres <[email protected]>
driver core: Fix bus_type.match() error handling in __driver_attach()
Mario Limonciello <[email protected]>
crypto: ccp - Add support for TEE for PCI ID 0x14CA
Corentin Labbe <[email protected]>
crypto: n2 - add missing hash statesize
Sergey Matyukevich <[email protected]>
riscv: mm: notify remote harts about mmu cache updates
Guo Ren <[email protected]>
riscv: stacktrace: Fixup ftrace_graph_ret_addr retp argument
Li Huafei <[email protected]>
RISC-V: kexec: Fix memory leak of elf header buffer
Guo Ren <[email protected]>
riscv: Fixup compile error with !MMU
Li Huafei <[email protected]>
RISC-V: kexec: Fix memory leak of fdt buffer
Sascha Hauer <[email protected]>
PCI/sysfs: Fix double free in error path
Michael S. Tsirkin <[email protected]>
PCI: Fix pci_device_is_present() for VFs by checking PF
Tianjia Zhang <[email protected]>
crypto: ccree,hisilicon - Fix dependencies to correct algorithm
Roberto Sassu <[email protected]>
ima: Fix memory leak in __ima_inode_hash()
Yaliang Wang <[email protected]>
mtd: spi-nor: gigadevice: gd25q256: replace gd25q256_default_init with gd25q256_post_bfpt
Dan Carpenter <[email protected]>
ipmi: fix use after free in _ipmi_destroy_user()
Huaxin Lu <[email protected]>
ima: Fix a potential NULL pointer access in ima_restore_measurement_list
Alexander Sverdlin <[email protected]>
mtd: spi-nor: Check for zero erase size in spi_nor_find_best_erase_type()
Zhang Yuchen <[email protected]>
ipmi: fix long wait in unload when IPMI disconnect
Maximilian Luz <[email protected]>
ipu3-imgu: Fix NULL pointer dereference in imgu_subdev_set_selection()
Aidan MacDonald <[email protected]>
ASoC: jz4740-i2s: Handle independent FIFO flush bits
Michael Walle <[email protected]>
wifi: wilc1000: sdio: fix module autoloading
Aditya Garg <[email protected]>
efi: Add iMac Pro 2017 to uefi skip cert quirk
Florian-Ewald Mueller <[email protected]>
md/bitmap: Fix bitmap chunk size overflow issues
Damien Le Moal <[email protected]>
block: mq-deadline: Do not break sequential write streams to zoned HDDs
Damien Le Moal <[email protected]>
block: mq-deadline: Fix dd_finish_request() for zoned devices
Yang Wang <[email protected]>
drm/amdgpu: fix mmhub register base coding error
Ian Abbott <[email protected]>
rtc: ds1347: fix value written to century register
Biju Das <[email protected]>
ravb: Fix "failed to switch device to config mode" message during unbind
Paulo Alcantara <[email protected]>
cifs: set correct status of tcon ipc when reconnecting
Paulo Alcantara <[email protected]>
cifs: set correct ipc status after initial tree connect
Paulo Alcantara <[email protected]>
cifs: set correct tcon status after initial tree connect
Steve French <[email protected]>
cifs: fix missing display of three mount options
Paulo Alcantara <[email protected]>
cifs: fix confusing debug message
Takashi Iwai <[email protected]>
media: dvb-core: Fix UAF due to refcount races at releasing
Keita Suzuki <[email protected]>
media: dvb-core: Fix double free in dvb_register_device()
Nick Desaulniers <[email protected]>
ARM: 9256/1: NWFPE: avoid compiler-generated __aeabi_uldivmod
Macpaul Lin <[email protected]>
arm64: dts: mediatek: mt8195-demo: fix the memory size of node secmon
Luca Ceresoli <[email protected]>
staging: media: tegra-video: fix device_node use after free
Luca Ceresoli <[email protected]>
staging: media: tegra-video: fix chan->mipi value on error
Yang Jihong <[email protected]>
tracing: Fix infinite loop in tracing_read_pipe on overflowed print_trace_line
Zheng Yejian <[email protected]>
tracing: Fix issue of missing one synthetic field
Steven Rostedt (Google) <[email protected]>
tracing/probes: Handle system names with hyphens
Zheng Yejian <[email protected]>
tracing/hist: Fix wrong return value in parse_action_params()
Masami Hiramatsu (Google) <[email protected]>
tracing: Fix complicated dependency of CONFIG_TRACER_MAX_TRACE
Michael Jeanson <[email protected]>
powerpc/ftrace: fix syscall tracing on PPC64_ELF_ABI_V1
Steven Rostedt (Google) <[email protected]>
tracing: Fix race where eprobes can be called before the event
Masami Hiramatsu (Google) <[email protected]>
x86/kprobes: Fix optprobe optimization check with CONFIG_RETHUNK
Masami Hiramatsu (Google) <[email protected]>
x86/kprobes: Fix kprobes instruction boudary check with CONFIG_RETHUNK
Steven Rostedt (Google) <[email protected]>
ftrace/x86: Add back ftrace_expected for ftrace bug reports
Ashok Raj <[email protected]>
x86/microcode/intel: Do not retry microcode reloading on the APs
Sean Christopherson <[email protected]>
KVM: nVMX: Properly expose ENABLE_USR_WAIT_PAUSE control to L1
Yuan ZhaoXiong <[email protected]>
KVM: x86: fix APICv/x2AVIC disabled when vm reboot by itself
Sean Christopherson <[email protected]>
KVM: nVMX: Inject #GP, not #UD, if "generic" VMXON CR0/CR4 check fails
Sean Christopherson <[email protected]>
KVM: VMX: Resume guest immediately when injecting #GP on ECREATE
Tianjia Zhang <[email protected]>
ima: Fix hash dependency to correct algorithm
Rob Herring <[email protected]>
of/kexec: Fix reading 32-bit "linux,initrd-{start,end}" values
Max Filippov <[email protected]>
xtensa: add __umulsidi3 helper
Namhyung Kim <[email protected]>
perf/core: Call LSM hook after copying perf_event_attr
Zheng Yejian <[email protected]>
tracing/hist: Fix out-of-bound write on 'action_data.var_ref_idx'
Li Ming <[email protected]>
PCI/DOE: Fix maximum data object length miscalculation
Mike Snitzer <[email protected]>
dm cache: set needs_check flag after aborting metadata
Luo Meng <[email protected]>
dm cache: Fix UAF in destroy()
Luo Meng <[email protected]>
dm clone: Fix UAF in clone_dtr()
Luo Meng <[email protected]>
dm integrity: Fix UAF in dm_integrity_dtr()
Luo Meng <[email protected]>
dm thin: Fix UAF in run_timer_softirq()
Luo Meng <[email protected]>
dm thin: resume even if in FAIL mode
Zhihao Cheng <[email protected]>
dm thin: Use last transaction's pmd->root when commit failed
Zhihao Cheng <[email protected]>
dm thin: Fix ABBA deadlock between shrink_slab and dm_pool_abort_metadata
Mike Snitzer <[email protected]>
dm cache: Fix ABBA deadlock between shrink_slab and dm_cache_metadata_abort
Matthieu Baerts <[email protected]>
mptcp: use proper req destructor for IPv6
Matthieu Baerts <[email protected]>
mptcp: dedicated request sock for subflow in v6
Matthieu Baerts <[email protected]>
mptcp: remove MPTCP 'ifdef' in TCP SYN cookies
Wei Yongjun <[email protected]>
mptcp: netlink: fix some error return code
Alexander Aring <[email protected]>
fs: dlm: retry accept() until -EAGAIN or error returns
Alexander Aring <[email protected]>
fs: dlm: fix sock release if listen fails
Chris Chiu <[email protected]>
ALSA: hda/realtek: Apply dual codec fixup for Dell Latitude laptops
Philipp Jungkamp <[email protected]>
ALSA: patch_realtek: Fix Dell Inspiron Plus 16
Toke Høiland-Jørgensen <[email protected]>
bpf: Resolve fext program type when checking map compatibility
Smitha T Murthy <[email protected]>
media: s5p-mfc: Fix in register read and write for H264
Smitha T Murthy <[email protected]>
media: s5p-mfc: Clear workbit to handle error condition
Smitha T Murthy <[email protected]>
media: s5p-mfc: Fix to handle reference queue during finishing
Al Viro <[email protected]>
ext2: unbugger ext2_empty_dir()
Yongqiang Liu <[email protected]>
cpufreq: Init completion before kobject_init_and_add()
Kant Fan <[email protected]>
PM/devfreq: governor: Add a private governor_data for governor
Yazen Ghannam <[email protected]>
x86/MCE/AMD: Clear DFR errors found in THR handler
Mickaël Salaün <[email protected]>
selftests: Use optional USERCFLAGS and USERLDFLAGS
Yazen Ghannam <[email protected]>
EDAC/mc_sysfs: Increase legacy channel support to 12
Dan Williams <[email protected]>
cxl/region: Fix missing probe failure
Krzysztof Kozlowski <[email protected]>
arm64: dts: qcom: sdm850-lenovo-yoga-c630: correct I2C12 pins drive strength
Andrew Cooper <[email protected]>
x86/fpu/xstate: Fix XSTATE_WARN_ON() to emit relevant diagnostics
Krzysztof Kozlowski <[email protected]>
arm64: dts: qcom: sdm850-samsung-w737: correct I2C12 pins drive strength
Jason A. Donenfeld <[email protected]>
ARM: ux500: do not directly dereference __iomem
Boris Burkov <[email protected]>
btrfs: fix resolving backrefs for inline extent followed by prealloc
void0red <[email protected]>
btrfs: fix extent map use-after-free when handling missing device in read_one_chunk
Evan Quan <[email protected]>
drm/amd/pm: correct SMU13.0.0 pstate profiling clock settings
Evan Quan <[email protected]>
drm/amd/pm: update SMU13.0.0 reported maximum shader clock
Johan Hovold <[email protected]>
phy: qcom-qmp-combo: fix out-of-bounds clock access
Wenchao Chen <[email protected]>
mmc: sdhci-sprd: Disable CLK_AUTO when the clock is less than 400K
Johan Hovold <[email protected]>
arm64: dts: qcom: sc8280xp: fix UFS reference clocks
Krzysztof Kozlowski <[email protected]>
arm64: dts: qcom: sdm845-db845c: correct SPI2 pins drive strength
Alexander Antonov <[email protected]>
perf/x86/intel/uncore: Clear attr_update properly
Alexander Antonov <[email protected]>
perf/x86/intel/uncore: Disable I/O stacks to PMU mapping on ICX-D
Bixuan Cui <[email protected]>
jbd2: use the correct print format
Steven Rostedt <[email protected]>
ktest.pl minconfig: Unset configs instead of just removing them
Steven Rostedt <[email protected]>
kest.pl: Fix grub2 menu handling for rebooting
Manivannan Sadhasivam <[email protected]>
soc: qcom: Select REMAP_MMIO for ICC_BWMON driver
Manivannan Sadhasivam <[email protected]>
soc: qcom: Select REMAP_MMIO for LLCC driver
Masami Hiramatsu (Google) <[email protected]>
arm64: Prohibit instrumentation on arch_stack_walk()
Johan Hovold <[email protected]>
arm64: dts: qcom: sc8280xp: fix UFS DMA coherency
Fan Ni <[email protected]>
cxl/region: Fix memdev reuse check
Jason A. Donenfeld <[email protected]>
media: stv0288: use explicitly signed char
Alex Deucher <[email protected]>
drm/amdgpu: skip MES for S0ix as well since it's part of GFX
-------------
Diffstat:
Documentation/admin-guide/kernel-parameters.txt | 27 ++- Documentation/filesystems/mount_api.rst | 1 + Makefile | 4 +- arch/arm/nwfpe/Makefile | 6 + arch/arm64/boot/dts/mediatek/mt8195-demo.dts | 4 +- arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 10 +- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 5 +- .../boot/dts/qcom/sdm850-lenovo-yoga-c630.dts | 6 +- arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts | 6 +- arch/arm64/include/asm/efi.h | 3 + arch/arm64/kernel/efi-rt-wrapper.S | 13 +- arch/arm64/kernel/efi.c | 27 +++ arch/arm64/kernel/stacktrace.c | 10 +- arch/parisc/include/asm/pgtable.h | 4 +- arch/parisc/kernel/firmware.c | 24 ++- arch/parisc/kernel/vdso32/Makefile | 4 +- arch/parisc/kernel/vdso64/Makefile | 4 +- arch/powerpc/include/asm/ftrace.h | 12 -- arch/riscv/Kconfig | 2 +- arch/riscv/include/asm/kexec.h | 5 + arch/riscv/include/asm/mmu.h | 2 + arch/riscv/include/asm/pgtable.h | 2 +- arch/riscv/include/asm/tlbflush.h | 18 ++ arch/riscv/kernel/elf_kexec.c | 14 ++ arch/riscv/kernel/stacktrace.c | 2 +- arch/riscv/mm/context.c | 10 + arch/riscv/mm/tlbflush.c | 28 +-- arch/x86/events/intel/uncore.h | 1 + arch/x86/events/intel/uncore_snbep.c | 22 +- arch/x86/kernel/cpu/mce/amd.c | 33 +-- arch/x86/kernel/cpu/microcode/intel.c | 8 +- arch/x86/kernel/fpu/xstate.c | 12 +- arch/x86/kernel/ftrace.c | 2 + arch/x86/kernel/kprobes/core.c | 10 +- arch/x86/kernel/kprobes/opt.c | 28 +-- arch/x86/kvm/lapic.c | 5 +- arch/x86/kvm/vmx/nested.c | 47 +++-- arch/x86/kvm/vmx/sgx.c | 4 +- arch/xtensa/kernel/xtensa_ksyms.c | 2 + arch/xtensa/lib/Makefile | 2 +- arch/xtensa/lib/umulsidi3.S | 230 +++++++++++++++++++++ block/mq-deadline.c | 83 +++++++- drivers/base/dd.c | 6 +- drivers/bus/mhi/host/pm.c | 3 +- drivers/char/ipmi/ipmi_msghandler.c | 4 +- drivers/char/ipmi/ipmi_si_intf.c | 27 ++- drivers/cpufreq/cpufreq.c | 2 +- drivers/crypto/Kconfig | 4 +- drivers/crypto/ccp/sp-pci.c | 11 +- drivers/crypto/hisilicon/Kconfig | 2 +- drivers/crypto/n2_core.c | 6 + drivers/cxl/core/region.c | 5 +- drivers/devfreq/devfreq.c | 6 +- drivers/devfreq/governor_userspace.c | 12 +- drivers/edac/edac_mc_sysfs.c | 24 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 13 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 3 +- drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c | 2 +- drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c | 2 +- drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c | 2 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + .../pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h | 2 +- drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h | 1 + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 2 + .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 111 +++++++++- .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 19 +- drivers/gpu/drm/drm_connector.c | 3 + drivers/gpu/drm/etnaviv/etnaviv_gem.c | 7 +- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 23 ++- drivers/gpu/drm/etnaviv/etnaviv_mmu.h | 1 + drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 4 +- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 59 +++++- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_object.c | 3 + drivers/gpu/drm/i915/gem/i915_gem_object_types.h | 10 +- drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c | 18 +- drivers/gpu/drm/i915/gt/intel_migrate.c | 16 +- drivers/gpu/drm/i915/i915_gem_evict.c | 37 +++- drivers/gpu/drm/i915/i915_gem_evict.h | 4 +- drivers/gpu/drm/i915/i915_vma.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_evict.c | 4 +- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 6 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 3 +- drivers/iommu/amd/init.c | 86 +++++--- drivers/md/dm-cache-metadata.c | 54 ++++- drivers/md/dm-cache-target.c | 11 +- drivers/md/dm-clone-target.c | 1 + drivers/md/dm-integrity.c | 2 + drivers/md/dm-thin-metadata.c | 60 +++++- drivers/md/dm-thin.c | 18 +- drivers/md/md-bitmap.c | 20 +- drivers/media/dvb-core/dmxdev.c | 8 + drivers/media/dvb-core/dvbdev.c | 1 + drivers/media/dvb-frontends/stv0288.c | 5 +- .../media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c | 4 +- .../media/platform/samsung/s5p-mfc/s5p_mfc_enc.c | 12 +- .../platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 14 +- drivers/mmc/host/sdhci-sprd.c | 16 +- drivers/mtd/spi-nor/core.c | 2 + drivers/mtd/spi-nor/gigadevice.c | 24 ++- drivers/net/ethernet/renesas/ravb_main.c | 2 +- drivers/net/wireless/microchip/wilc1000/sdio.c | 1 + drivers/of/kexec.c | 10 +- drivers/parisc/led.c | 3 + drivers/pci/doe.c | 20 +- drivers/pci/pci-sysfs.c | 13 +- drivers/pci/pci.c | 2 + drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 8 +- drivers/remoteproc/imx_dsp_rproc.c | 12 +- drivers/remoteproc/imx_rproc.c | 4 +- drivers/remoteproc/remoteproc_core.c | 9 +- drivers/rtc/rtc-ds1347.c | 2 +- drivers/soc/qcom/Kconfig | 2 + drivers/soc/ux500/ux500-soc-id.c | 10 +- drivers/staging/media/ipu3/ipu3-v4l2.c | 57 ++--- drivers/staging/media/tegra-video/csi.c | 4 +- drivers/staging/media/tegra-video/csi.h | 2 +- fs/btrfs/backref.c | 4 + fs/btrfs/volumes.c | 3 +- fs/cifs/cifsfs.c | 8 +- fs/cifs/connect.c | 16 +- fs/dlm/lowcomms.c | 9 +- fs/ext2/dir.c | 2 +- fs/ext4/ext4.h | 9 +- fs/ext4/extents.c | 8 + fs/ext4/extents_status.c | 3 +- fs/ext4/fast_commit.c | 171 ++++++++------- fs/ext4/fast_commit.h | 3 +- fs/ext4/indirect.c | 9 +- fs/ext4/inode.c | 48 ++++- fs/ext4/ioctl.c | 24 ++- fs/ext4/namei.c | 47 +++-- fs/ext4/orphan.c | 2 +- fs/ext4/resize.c | 32 +-- fs/ext4/super.c | 33 ++- fs/ext4/verity.c | 2 +- fs/ext4/xattr.c | 19 +- fs/fs_parser.c | 3 +- fs/mbcache.c | 14 +- fs/quota/dquot.c | 2 + include/linux/bpf_verifier.h | 2 +- include/linux/devfreq.h | 7 +- include/linux/fs_parser.h | 1 + include/linux/mbcache.h | 9 +- include/net/mptcp.h | 12 +- include/trace/events/ext4.h | 7 +- include/trace/events/jbd2.h | 44 ++-- kernel/bpf/core.c | 5 +- kernel/events/core.c | 6 +- kernel/trace/Kconfig | 2 + kernel/trace/trace.c | 38 +++- kernel/trace/trace.h | 27 ++- kernel/trace/trace_eprobe.c | 3 + kernel/trace/trace_events_hist.c | 11 +- kernel/trace/trace_events_synth.c | 2 +- kernel/trace/trace_probe.c | 2 +- lib/Kconfig.debug | 1 + net/ipv4/syncookies.c | 7 +- net/mptcp/pm_userspace.c | 4 + net/mptcp/subflow.c | 61 +++++- security/device_cgroup.c | 33 ++- security/integrity/ima/Kconfig | 2 +- security/integrity/ima/ima_main.c | 7 +- security/integrity/ima/ima_template.c | 5 +- security/integrity/platform_certs/load_uefi.c | 1 + sound/pci/hda/patch_realtek.c | 50 +++++ sound/soc/jz4740/jz4740-i2s.c | 39 +++- tools/testing/ktest/ktest.pl | 23 ++- tools/testing/selftests/lib.mk | 5 + 172 files changed, 1961 insertions(+), 648 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/177 drm/amdgpu: skip MES for S0ix as well since its part of GFX
From: Alex Deucher <[email protected]>
commit afa6646b1c5d3affd541f76bd7476e4b835a9174 upstream.
It's also part of gfxoff.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +3 -2
@@ -2998,14 +2998,15 @@ static int amdgpu_device_ip_suspend_phascontinue ; } -/* skip suspend of gfx and psp for S0ix +/* skip suspend of gfx/mes and psp for S0ix * gfx is in gfxoff state, so on resume it will exit gfxoff just * like at runtime. PSP is also part of the always on hardware * so no need to suspend it. */ if (adev->in_s0ix && (adev->ip_blocks[i].version->type ==AMD_IP_BLOCK_TYPE_PSP || - adev->ip_blocks[i].version->type ==AMD_IP_BLOCK_TYPE_GFX )) + adev->ip_blocks[i].version->type ==AMD_IP_BLOCK_TYPE_GFX || + adev->ip_blocks[i].version->type ==AMD_IP_BLOCK_TYPE_MES ))continue ;/* XXX handle errors */
Greg Kroah-Hartman
maintainerPATCH 2/177 media: stv0288: use explicitly signed char
In reply to Greg Kroah-HartmanFrom: Jason A. Donenfeld <[email protected]>
commit 7392134428c92a4cb541bd5c8f4f5c8d2e88364d upstream.
With char becoming unsigned by default, and with char alone being ambiguous and based on architecture, signed chars need to be marked explicitly as such. Use s8 and u8 types here, since that's what surrounding code does. This fixes:
drivers/media/dvb-frontends/stv0288.c:471 stv0288_set_frontend() warn: assigning (-9) to unsigned variable 'tm' drivers/media/dvb-frontends/stv0288.c:471 stv0288_set_frontend() warn: we never enter this loop
--- drivers/media/dvb-frontends/stv0288.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/media/dvb-frontends/stv0288.c +2 -3
@@ -440,9 +440,8 @@ static int stv0288_set_frontend(struct dstruct stv0288_state *state = fe->demodulator_priv;struct dtv_frontend_properties *c = &fe->dtv_property_cache; -char tm; -unsigned char tda[3 ]; -u8 reg, time_out =0 ; +u8 tda[3 ], reg, time_out =0 ; +s8 tm;dprintk ("%s : FE_SET_FRONTEND\n" , __func__);
Greg Kroah-Hartman
maintainerPATCH 3/177 cxl/region: Fix memdev reuse check
In reply to Greg Kroah-HartmanFrom: Fan Ni <[email protected]>
commit f04facfb993de47e2133b2b842d72b97b1c50162 upstream.
Due to a typo, the check of whether or not a memdev has already been used as a target for the region (above code piece) will always be skipped. Given a memdev with more than one HDM decoder, an interleaved region can be created that maps multiple HPAs to the same DPA. According to CXL spec 3.0 8.1.3.8.4, "Aliasing (mapping more than one Host Physical Address (HPA) to a single Device Physical Address) is forbidden."
Fix this by using existing iterator for memdev reuse check.
--- drivers/cxl/core/region.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cxl/core/region.c +1 -1
@@ -1225,7 +1225,7 @@ static int cxl_region_attach(struct cxl_struct cxl_endpoint_decoder *cxled_target;struct cxl_memdev *cxlmd_target; - cxled_target = p->targets[pos]; + cxled_target = p->targets[i];if (!cxled_target)continue ;
Greg Kroah-Hartman
maintainerPATCH 4/177 arm64: dts: qcom: sc8280xp: fix UFS DMA coherency
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 0953777640354dc459a22369eea488603d225dd9 upstream.
The SC8280XP UFS controllers are cache coherent and must be marked as such in the devicetree to avoid potential data corruption.
--- arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/qcom/sc8280xp.dtsi +2 -0
@@ -855,6 +855,7 @@ required-opps = <&rpmhpd_opp_nom>; iommus = <&apps_smmu 0xe0 0x0>; + dma-coherent; clocks = <&gcc GCC_UFS_PHY_AXI_CLK>, <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
@@ -923,6 +924,7 @@ power-domains = <&gcc UFS_CARD_GDSC>; iommus = <&apps_smmu 0x4a0 0x0>; + dma-coherent; clocks = <&gcc GCC_UFS_CARD_AXI_CLK>, <&gcc GCC_AGGRE_UFS_CARD_AXI_CLK>,
Greg Kroah-Hartman
maintainerPATCH 5/177 arm64: Prohibit instrumentation on arch_stack_walk()
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu (Google) <[email protected]>
commit 0fbcd8abf3375052cc7627cc53aba6f2eb189fbb upstream.
Mark arch_stack_walk() as noinstr instead of notrace and inline functions called from arch_stack_walk() as __always_inline so that user does not put any instrumentations on it, because this function can be used from return_address() which is used by lockdep.
Without this, if the kernel built with CONFIG_LOCKDEP=y, just probing arch_stack_walk() via <tracefs>/kprobe_events will crash the kernel on arm64.
# echo p arch_stack_walk >> ${TRACEFS}/kprobe_events
# echo 1 > ${TRACEFS}/events/kprobes/enable
kprobes: Failed to recover from reentered kprobes.
kprobes: Dump kprobe:
.symbol_name = arch_stack_walk, .offset = 0, .addr = arch_stack_walk+0x0/0x1c0
------------[ cut here ]------------
kernel BUG at arch/arm64/kernel/probes/kprobes.c:241!
kprobes: Failed to recover from reentered kprobes.
kprobes: Dump kprobe:
.symbol_name = arch_stack_walk, .offset = 0, .addr = arch_stack_walk+0x0/0x1c0
------------[ cut here ]------------
kernel BUG at arch/arm64/kernel/probes/kprobes.c:241!
PREEMPT SMP
Modules linked in:
CPU: 0 PID: 17 Comm: migration/0 Tainted: G N 6.1.0-rc5+ #6
Hardware name: linux,dummy-virt (DT)
Stopper: 0x0 <- 0x0
pstate: 600003c5 (nZCv DAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : kprobe_breakpoint_handler+0x178/0x17c
lr : kprobe_breakpoint_handler+0x178/0x17c
sp : ffff8000080d3090
x29: ffff8000080d3090 x28: ffff0df5845798c0 x27: ffffc4f59057a774
x26: ffff0df5ffbba770 x25: ffff0df58f420f18 x24: ffff49006f641000
x23: ffffc4f590579768 x22: ffff0df58f420f18 x21: ffff8000080d31c0
x20: ffffc4f590579768 x19: ffffc4f590579770 x18: 0000000000000006
x17: 5f6b636174735f68 x16: 637261203d207264 x15: 64612e202c30203d
x14: 2074657366666f2e x13: 30633178302f3078 x12: 302b6b6c61775f6b
x11: 636174735f686372 x10: ffffc4f590dc5bd8 x9 : ffffc4f58eb31958
x8 : 00000000ffffefff x7 : ffffc4f590dc5bd8 x6 : 80000000fffff000
x5 : 000000000000bff4 x4 : 0000000000000000 x3 : 0000000000000000
x2 : 0000000000000000 x1 : ffff0df5845798c0 x0 : 0000000000000064
Call trace:
kprobes: Failed to recover from reentered kprobes.
kprobes: Dump kprobe:
.symbol_name = arch_stack_walk, .offset = 0, .addr = arch_stack_walk+0x0/0x1c0
------------[ cut here ]------------
kernel BUG at arch/arm64/kernel/probes/kprobes.c:241!--- arch/arm64/kernel/stacktrace.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
arch/arm64/kernel/stacktrace.c +5 -5
@@ -23,8 +23,8 @@* * The regs must be on a stack currently owned by the calling task. */ -static inline void unwind_init_from_regs (struct unwind_state *state, -struct pt_regs *regs) +static __always_inline void unwind_init_from_regs(struct unwind_state *state, +struct pt_regs *regs) {unwind_init_common (state, current);
@@ -58,8 +58,8 @@ static __always_inline void unwind_init_* duration of the unwind, or the unwind will be bogus. It is never valid to * call this for the current task. */ -static inline void unwind_init_from_task (struct unwind_state *state, -struct task_struct *task) +static __always_inline void unwind_init_from_task(struct unwind_state *state, +struct task_struct *task) {unwind_init_common (state, task);
@@ -190,7 +190,7 @@ void show_stack(struct task_struct *tsk,barrier (); } -noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry, +noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,void *cookie,struct task_struct *task,struct pt_regs *regs) {
Greg Kroah-Hartman
maintainerPATCH 6/177 soc: qcom: Select REMAP_MMIO for LLCC driver
In reply to Greg Kroah-HartmanFrom: Manivannan Sadhasivam <[email protected]>
commit 5d2fe2d7b616b8baa18348ead857b504fc2de336 upstream.
LLCC driver uses REGMAP_MMIO for accessing the hardware registers. So select the dependency in Kconfig. Without this, there will be errors while building the driver with COMPILE_TEST only:
ERROR: modpost: "__devm_regmap_init_mmio_clk" [drivers/soc/qcom/llcc-qcom.ko] undefined! make[1]: *** [scripts/Makefile.modpost:126: Module.symvers] Error 1
make: *** [Makefile:1944: modpost] Error 2
--- drivers/soc/qcom/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/soc/qcom/Kconfig +1 -0
@@ -63,6 +63,7 @@ config QCOM_GSBI config QCOM_LLCC tristate "Qualcomm Technologies, Inc. LLCC driver" depends on ARCH_QCOM || COMPILE_TEST + select REGMAP_MMIO help Qualcomm Technologies, Inc. platform specific Last Level Cache Controller(LLCC) driver for platforms such as,
Greg Kroah-Hartman
maintainerPATCH 7/177 soc: qcom: Select REMAP_MMIO for ICC_BWMON driver
In reply to Greg Kroah-HartmanFrom: Manivannan Sadhasivam <[email protected]>
commit a84160fbf4f2c8c5ffa588e19ea8f92eabd7ad17 upstream.
ICC_BWMON driver uses REGMAP_MMIO for accessing the hardware registers. So select the dependency in Kconfig. Without this, there will be errors while building the driver with COMPILE_TEST only:
ERROR: modpost: "__devm_regmap_init_mmio_clk" [drivers/soc/qcom/icc-bwmon.ko] undefined! make[1]: *** [scripts/Makefile.modpost:126: Module.symvers] Error 1
make: *** [Makefile:1944: modpost] Error 2
--- drivers/soc/qcom/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/soc/qcom/Kconfig +1 -0
@@ -237,6 +237,7 @@ config QCOM_ICC_BWMON tristate "QCOM Interconnect Bandwidth Monitor driver" depends on ARCH_QCOM || COMPILE_TEST select PM_OPP + select REGMAP_MMIO help Sets up driver monitoring bandwidth on various interconnects and based on that voting for interconnect bandwidth, adjusting their
Signature · 1 line
2.39.0
Greg Kroah-Hartman
maintainerPATCH 8/177 kest.pl: Fix grub2 menu handling for rebooting
In reply to Greg Kroah-HartmanFrom: Steven Rostedt <[email protected]>
commit 26df05a8c1420ad3de314fdd407e7fc2058cc7aa upstream.
grub2 has submenus where to use grub-reboot, it requires:
grub-reboot X>Y
where X is the main index and Y is the submenu. Thus if you have:
menuentry 'Debian GNU/Linux' --class debian --class gnu-linux ...
[...]
}
submenu 'Advanced options for Debian GNU/Linux' $menuentry_id_option ...
menuentry 'Debian GNU/Linux, with Linux 6.0.0-4-amd64' --class debian --class gnu-linux ...
[...]
}
menuentry 'Debian GNU/Linux, with Linux 6.0.0-4-amd64 (recovery mode)' --class debian --class gnu-linux ...
[...]
}
menuentry 'Debian GNU/Linux, with Linux test' --class debian --class gnu-linux ...
[...]
}And wanted to boot to the "Linux test" kernel, you need to run:
# grub-reboot 1>2
As 1 is the second top menu (the submenu) and 2 is the third of the sub menu entries.
Have the grub.cfg parsing for grub2 handle such cases.
--- tools/testing/ktest/ktest.pl | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
tools/testing/ktest/ktest.pl +15 -5
@@ -1963,7 +1963,7 @@ sub run_scp_mod { sub _get_grub_index { - my ($command, $target, $skip) = @_; + my ($command, $target, $skip, $submenu) = @_; return if (defined($grub_number) && defined($last_grub_menu) && $last_grub_menu eq $grub_menu && defined($last_machine) &&
@@ -1980,11 +1980,16 @@ sub _get_grub_index { my $found = 0; + my $submenu_number = 0; + while (<IN>) { if (/$target/) { $grub_number++; $found = 1; last; + } elsif (defined($submenu) && /$submenu/) { + $submenu_number++; + $grub_number = -1; } elsif (/$skip/) { $grub_number++; }
@@ -1993,6 +1998,9 @@ sub _get_grub_index { dodie "Could not find '$grub_menu' through $command on $machine" if (!$found); + if ($submenu_number > 0) { + $grub_number = "$submenu_number>$grub_number"; + } doprint "$grub_number\n"; $last_grub_menu = $grub_menu; $last_machine = $machine;
@@ -2003,6 +2011,7 @@ sub get_grub_index { my $command; my $target; my $skip; + my $submenu; my $grub_menu_qt; if ($reboot_type !~ /^grub/) {
@@ -2017,8 +2026,9 @@ sub get_grub_index { $skip = '^\s*title\s'; } elsif ($reboot_type eq "grub2") { $command = "cat $grub_file"; - $target = '^menuentry.*' . $grub_menu_qt; - $skip = '^menuentry\s|^submenu\s'; + $target = '^\s*menuentry.*' . $grub_menu_qt; + $skip = '^\s*menuentry'; + $submenu = '^\s*submenu\s'; } elsif ($reboot_type eq "grub2bls") { $command = $grub_bls_get; $target = '^title=.*' . $grub_menu_qt;
@@ -2027,7 +2037,7 @@ sub get_grub_index { return; } - _get_grub_index($command, $target, $skip); + _get_grub_index($command, $target, $skip, $submenu); } sub wait_for_input {
@@ -2090,7 +2100,7 @@ sub reboot_to { if ($reboot_type eq "grub") { run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'"; } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) { - run_ssh "$grub_reboot $grub_number"; + run_ssh "$grub_reboot \"'$grub_number'\""; } elsif ($reboot_type eq "syslinux") { run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path"; } elsif (defined $reboot_script) {
Greg Kroah-Hartman
maintainerPATCH 9/177 ktest.pl minconfig: Unset configs instead of just removing them
In reply to Greg Kroah-HartmanFrom: Steven Rostedt <[email protected]>
commit ef784eebb56425eed6e9b16e7d47e5c00dcf9c38 upstream.
After a full run of a make_min_config test, I noticed there were a lot of CONFIGs still enabled that really should not be. Looking at them, I noticed they were all defined as "default y". The issue is that the test simple removes the config and re-runs make oldconfig, which enables it again because it is set to default 'y'. Instead, explicitly disable the config with writing "# CONFIG_FOO is not set" to the file to keep it from being set again.
With this change, one of my box's minconfigs went from 768 configs set, down to 521 configs set.
--- tools/testing/ktest/ktest.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/ktest/ktest.pl +2 -1
@@ -3778,9 +3778,10 @@ sub test_this_config { # .config to make sure it is missing the config that # we had before my %configs = %min_configs; - delete $configs{$config}; + $configs{$config} = "# $config is not set"; make_new_config ((values %configs), (values %keep_configs)); make_oldconfig; + delete $configs{$config}; undef %configs; assign_configs \%configs, $output_config;
Greg Kroah-Hartman
maintainerPATCH 10/177 jbd2: use the correct print format
In reply to Greg Kroah-HartmanFrom: Bixuan Cui <[email protected]>
commit d87a7b4c77a997d5388566dd511ca8e6b8e8a0a8 upstream.
The print format error was found when using ftrace event:
<...>-1406 [000] .... 23599442.895823: jbd2_end_commit: dev 252,8 transaction -1866216965 sync 0 head -1866217368
<...>-1406 [000] .... 23599442.896299: jbd2_start_commit: dev 252,8 transaction -1866216964 sync 0Use the correct print format for transaction, head and tid.
--- include/trace/events/jbd2.h | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-)
include/trace/events/jbd2.h +22 -22
@@ -40,7 +40,7 @@ DECLARE_EVENT_CLASS(jbd2_commit,TP_STRUCT__entry (__field (dev_t ,dev )__field ( char, sync_commit ) -__field ( int, transaction ) +__field ( tid_t, transaction ) ), TP_fast_assign(
@@ -49,7 +49,7 @@ DECLARE_EVENT_CLASS(jbd2_commit, __entry->transaction = commit_transaction->t_tid; ), -TP_printk ("dev %d,%d transaction %d sync %d" , +TP_printk ("dev %d,%d transaction %u sync %d" ,MAJOR (__entry->dev),MINOR (__entry->dev), __entry->transaction, __entry->sync_commit) );
@@ -97,8 +97,8 @@ TRACE_EVENT(jbd2_end_commit,TP_STRUCT__entry (__field (dev_t ,dev )__field ( char, sync_commit ) -__field ( int, transaction ) -__field ( int, head ) +__field ( tid_t, transaction ) +__field ( tid_t, head ) ), TP_fast_assign(
@@ -108,7 +108,7 @@ TRACE_EVENT(jbd2_end_commit, __entry->head = journal->j_tail_sequence; ), -TP_printk ("dev %d,%d transaction %d sync %d head %d" , +TP_printk ("dev %d,%d transaction %u sync %d head %u" ,MAJOR (__entry->dev),MINOR (__entry->dev), __entry->transaction, __entry->sync_commit, __entry->head) );
@@ -134,14 +134,14 @@ TRACE_EVENT(jbd2_submit_inode_data, ); DECLARE_EVENT_CLASS(jbd2_handle_start_class, - TP_PROTO(dev_t dev, unsigned long tid, unsigned int type, + TP_PROTO(dev_t dev, tid_t tid, unsigned int type, unsigned int line_no, int requested_blocks), TP_ARGS(dev, tid, type, line_no, requested_blocks), TP_STRUCT__entry( __field( dev_t, dev ) - __field( unsigned long, tid ) + __field( tid_t, tid ) __field( unsigned int, type ) __field( unsigned int, line_no ) __field( int, requested_blocks)
@@ -155,28 +155,28 @@ DECLARE_EVENT_CLASS(jbd2_handle_start_cl __entry->requested_blocks = requested_blocks; ), -TP_printk ("dev %d,%d tid %lu type %u line_no %u " +TP_printk ("dev %d,%d tid %u type %u line_no %u " "requested_blocks %d" ,MAJOR (__entry->dev),MINOR (__entry->dev), __entry->tid, __entry->type, __entry->line_no, __entry->requested_blocks) );DEFINE_EVENT (jbd2_handle_start_class, jbd2_handle_start, - TP_PROTO(dev_t dev, unsigned long tid, unsigned int type, + TP_PROTO(dev_t dev, tid_t tid, unsigned int type, unsigned int line_no, int requested_blocks),TP_ARGS (dev, tid, type, line_no, requested_blocks) );DEFINE_EVENT (jbd2_handle_start_class, jbd2_handle_restart, - TP_PROTO(dev_t dev, unsigned long tid, unsigned int type, + TP_PROTO(dev_t dev, tid_t tid, unsigned int type, unsigned int line_no, int requested_blocks),TP_ARGS (dev, tid, type, line_no, requested_blocks) ); TRACE_EVENT(jbd2_handle_extend, - TP_PROTO(dev_t dev, unsigned long tid, unsigned int type, + TP_PROTO(dev_t dev, tid_t tid, unsigned int type, unsigned int line_no, int buffer_credits, int requested_blocks),
@@ -184,7 +184,7 @@ TRACE_EVENT(jbd2_handle_extend,TP_STRUCT__entry (__field (dev_t ,dev ) - __field( unsigned long, tid ) +__field ( tid_t, tid ) __field( unsigned int, type ) __field( unsigned int, line_no ) __field( int, buffer_credits )
@@ -200,7 +200,7 @@ TRACE_EVENT(jbd2_handle_extend, __entry->requested_blocks = requested_blocks; ), - TP_printk("dev %d,%d tid %lu type %u line_no %u " + TP_printk("dev %d,%d tid %u type %u line_no %u " "buffer_credits %d requested_blocks %d", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, __entry->type, __entry->line_no, __entry->buffer_credits,
@@ -208,7 +208,7 @@ TRACE_EVENT(jbd2_handle_extend, ); TRACE_EVENT(jbd2_handle_stats, - TP_PROTO(dev_t dev, unsigned long tid, unsigned int type, + TP_PROTO(dev_t dev, tid_t tid, unsigned int type, unsigned int line_no, int interval, int sync, int requested_blocks, int dirtied_blocks),
@@ -217,7 +217,7 @@ TRACE_EVENT(jbd2_handle_stats,TP_STRUCT__entry (__field (dev_t ,dev ) - __field( unsigned long, tid ) +__field ( tid_t, tid ) __field( unsigned int, type ) __field( unsigned int, line_no ) __field( int, interval )
@@ -237,7 +237,7 @@ TRACE_EVENT(jbd2_handle_stats, __entry->dirtied_blocks = dirtied_blocks; ), - TP_printk("dev %d,%d tid %lu type %u line_no %u interval %d " + TP_printk("dev %d,%d tid %u type %u line_no %u interval %d " "sync %d requested_blocks %d dirtied_blocks %d", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, __entry->type, __entry->line_no, __entry->interval,
@@ -246,14 +246,14 @@ TRACE_EVENT(jbd2_handle_stats, ); TRACE_EVENT(jbd2_run_stats, - TP_PROTO(dev_t dev, unsigned long tid, + TP_PROTO(dev_t dev, tid_t tid, struct transaction_run_stats_s *stats), TP_ARGS(dev, tid, stats), TP_STRUCT__entry( __field( dev_t, dev ) - __field( unsigned long, tid ) + __field( tid_t, tid ) __field( unsigned long, wait ) __field( unsigned long, request_delay ) __field( unsigned long, running )
@@ -279,7 +279,7 @@ TRACE_EVENT(jbd2_run_stats, __entry->blocks_logged = stats->rs_blocks_logged; ), - TP_printk("dev %d,%d tid %lu wait %u request_delay %u running %u " + TP_printk("dev %d,%d tid %u wait %u request_delay %u running %u " "locked %u flushing %u logging %u handle_count %u " "blocks %u blocks_logged %u", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
@@ -294,14 +294,14 @@ TRACE_EVENT(jbd2_run_stats, ); TRACE_EVENT(jbd2_checkpoint_stats, - TP_PROTO(dev_t dev, unsigned long tid, + TP_PROTO(dev_t dev, tid_t tid, struct transaction_chp_stats_s *stats), TP_ARGS(dev, tid, stats), TP_STRUCT__entry( __field( dev_t, dev ) - __field( unsigned long, tid ) + __field( tid_t, tid ) __field( unsigned long, chp_time ) __field( __u32, forced_to_close ) __field( __u32, written )
@@ -317,7 +317,7 @@ TRACE_EVENT(jbd2_checkpoint_stats, __entry->dropped = stats->cs_dropped; ), - TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u " + TP_printk("dev %d,%d tid %u chp_time %u forced_to_close %u " "written %u dropped %u", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, jiffies_to_msecs(__entry->chp_time),
Greg Kroah-Hartman
maintainerPATCH 11/177 perf/x86/intel/uncore: Disable I/O stacks to PMU mapping on ICX-D
In reply to Greg Kroah-HartmanFrom: Alexander Antonov <[email protected]>
commit efe062705d149b20a15498cb999a9edbb8241e6f upstream.
Current implementation of I/O stacks to PMU mapping doesn't support ICX-D. Detect ICX-D system to disable mapping.
--- arch/x86/events/intel/uncore.h | 1 + arch/x86/events/intel/uncore_snbep.c | 5 +++++ 2 files changed, 6 insertions(+)
arch/x86/events/intel/uncore.h +1 -0
@@ -2,6 +2,7 @@#include <linux/slab.h> #include <linux/pci.h> #include <asm/apicdef.h> +#include <asm/intel-family.h> #include <linux/io-64-nonatomic-lo-hi.h> #include <linux/perf_event.h>
arch/x86/events/intel/uncore_snbep.c +5 -0
@@ -5144,6 +5144,11 @@ static int icx_iio_get_topology(struct istatic int icx_iio_set_mapping (struct intel_uncore_type *type) { +/* Detect ICX-D system. This case is not supported */ +if (boot_cpu_data.x86_model ==INTEL_FAM6_ICELAKE_D ) { +pmu_clear_mapping_attr (type->attr_update, &icx_iio_mapping_group); +return -EPERM ; + }return pmu_iio_set_mapping (type, &icx_iio_mapping_group); }
Greg Kroah-Hartman
maintainerPATCH 12/177 perf/x86/intel/uncore: Clear attr_update properly
In reply to Greg Kroah-HartmanFrom: Alexander Antonov <[email protected]>
commit 6532783310e2b2f50dc13f46c49aa6546cb6e7a3 upstream.
Current clear_attr_update procedure in pmu_set_mapping() sets attr_update field in NULL that is not correct because intel_uncore_type pmu types can contain several groups in attr_update field. For example, SPR platform already has uncore_alias_group to update and then UPI topology group will be added in next patches.
Fix current behavior and clear attr_update group related to mapping only.
--- arch/x86/events/intel/uncore_snbep.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
arch/x86/events/intel/uncore_snbep.c +16 -1
@@ -3804,6 +3804,21 @@ static const struct attribute_group *skx NULL, }; +static void pmu_clear_mapping_attr (const struct attribute_group **groups, +struct attribute_group *ag) +{ +int i; + +for (i =0 ; groups[i]; i++) { +if (groups[i] == ag) { +for (i++; groups[i]; i++) + groups[i -1 ] = groups[i]; + groups[i -1 ] =NULL ; +break ; + } + } +} +static int pmu_iio_set_mapping (struct intel_uncore_type *type,struct attribute_group *ag) {
@@ -3852,7 +3867,7 @@ clear_attrs: clear_topology:kfree (type->topology); clear_attr_update: - type->attr_update =NULL ; +pmu_clear_mapping_attr (type->attr_update, ag);return ret; }
Greg Kroah-Hartman
maintainerPATCH 13/177 arm64: dts: qcom: sdm845-db845c: correct SPI2 pins drive strength
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
commit 9905370560d9c29adc15f4937c5a0c0dac05f0b4 upstream.
The pin configuration (done with generic pin controller helpers and as expressed by bindings) requires children nodes with either:
1. "pins" property and the actual configuration,
2. another set of nodes with above point.
The qup_spi2_default pin configuration uses alreaady the second method with a "pinmux" child, so configure drive-strength similarly in "pinconf". Otherwise the PIN drive strength would not be applied.
--- arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sdm845-db845c.dts +4 -1
@@ -1123,7 +1123,10 @@ /* PINCTRL - additions to nodes defined in sdm845.dtsi */ &qup_spi2_default { - drive-strength = <16>; + pinconf { + pins = "gpio27", "gpio28", "gpio29", "gpio30"; + drive-strength = <16>; + }; }; &qup_uart3_default{
Greg Kroah-Hartman
maintainerPATCH 14/177 arm64: dts: qcom: sc8280xp: fix UFS reference clocks
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit f446022b932aff1d6a308ca5d537ec2b512debdc upstream.
There are three UFS reference clocks on SC8280XP which are used as follows:
- The GCC_UFS_REF_CLKREF_CLK clock is fed to any UFS device connected to either controller.
- The GCC_UFS_1_CARD_CLKREF_CLK and GCC_UFS_CARD_CLKREF_CLK clocks provide reference clocks to the two PHYs.
Note that this depends on first updating the clock driver to reflect that all three clocks are sourced from CXO. Specifically, the UFS controller driver expects the device reference clock to have a valid frequency:
ufshcd-qcom 1d84000.ufs: invalid ref_clk setting = 0
--- arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm64/boot/dts/qcom/sc8280xp.dtsi +4 -4
@@ -861,7 +861,7 @@ <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>, <&gcc GCC_UFS_PHY_AHB_CLK>, <&gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>, - <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_UFS_REF_CLKREF_CLK>, <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>, <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>, <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>;
@@ -892,7 +892,7 @@ ranges; clock-names = "ref", "ref_aux"; - clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>, + clocks = <&gcc GCC_UFS_CARD_CLKREF_CLK>, <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; resets = <&ufs_mem_hc 0>;
@@ -930,7 +930,7 @@ <&gcc GCC_AGGRE_UFS_CARD_AXI_CLK>, <&gcc GCC_UFS_CARD_AHB_CLK>, <&gcc GCC_UFS_CARD_UNIPRO_CORE_CLK>, - <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_UFS_REF_CLKREF_CLK>, <&gcc GCC_UFS_CARD_TX_SYMBOL_0_CLK>, <&gcc GCC_UFS_CARD_RX_SYMBOL_0_CLK>, <&gcc GCC_UFS_CARD_RX_SYMBOL_1_CLK>;
@@ -961,7 +961,7 @@ ranges; clock-names = "ref", "ref_aux"; - clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>, + clocks = <&gcc GCC_UFS_1_CARD_CLKREF_CLK>, <&gcc GCC_UFS_CARD_PHY_AUX_CLK>; resets = <&ufs_card_hc 0>;
Greg Kroah-Hartman
maintainerPATCH 15/177 mmc: sdhci-sprd: Disable CLK_AUTO when the clock is less than 400K
In reply to Greg Kroah-HartmanFrom: Wenchao Chen <[email protected]>
commit ff874dbc4f868af128b412a9bd92637103cf11d7 upstream.
When the clock is less than 400K, some SD cards fail to initialize because CLK_AUTO is enabled.
--- drivers/mmc/host/sdhci-sprd.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/mmc/host/sdhci-sprd.c +9 -7
@@ -228,13 +228,15 @@ static inline void _sdhci_sprd_set_clock div = ((div &0x300 ) >>2 ) | ((div &0xFF ) <<8 );sdhci_enable_clk (host, div); -/* enable auto gate sdhc_enable_auto_gate */ - val =sdhci_readl (host,SDHCI_SPRD_REG_32_BUSY_POSI ); - mask =SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN | -SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN ; -if (mask != (val & mask)) { - val |= mask; -sdhci_writel (host, val,SDHCI_SPRD_REG_32_BUSY_POSI ); +/* Enable CLK_AUTO when the clock is greater than 400K. */ +if (clk >400000 ) { + val =sdhci_readl (host,SDHCI_SPRD_REG_32_BUSY_POSI ); + mask =SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN | +SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN ; +if (mask != (val & mask)) { + val |= mask; +sdhci_writel (host, val,SDHCI_SPRD_REG_32_BUSY_POSI ); + } } }
Greg Kroah-Hartman
maintainerPATCH 16/177 phy: qcom-qmp-combo: fix out-of-bounds clock access
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit d8a5b59c5fc75c99ba17e3eb1a8f580d8d172b28 upstream.
The SM8250 only uses three clocks but the DP configuration erroneously described four clocks.
In case the DP part of the PHY is initialised before the USB part, this would lead to uninitialised memory beyond the bulk-clocks array to be treated as a clock pointer as the clocks are requested based on the USB configuration.
--- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/phy/qualcomm/phy-qcom-qmp-combo.c +2 -2
@@ -1032,8 +1032,8 @@ static const struct qmp_phy_cfg sm8250_d .serdes_tbl_hbr3 = qmp_v4_dp_serdes_tbl_hbr3, .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3), - .clk_list = qmp_v4_phy_clk_l, - .num_clks = ARRAY_SIZE(qmp_v4_phy_clk_l), + .clk_list = qmp_v4_sm8250_usbphy_clk_l, + .num_clks = ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l), .reset_list = msm8996_usb3phy_reset_l, .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l,
Greg Kroah-Hartman
maintainerPATCH 17/177 drm/amd/pm: update SMU13.0.0 reported maximum shader clock
In reply to Greg Kroah-HartmanFrom: Evan Quan <[email protected]>
commit 7a18e089eff02f17eaee49fc18641f5d16a8284b upstream.
Update the reported maximum shader clock to the value which can be guarded to be achieved on all cards. This is to align with Window setting.
--- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 70 ++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +69 -1
@@ -517,6 +517,23 @@ static int smu_v13_0_0_set_default_dpm_t dpm_table);if (ret)return ret; + +/* +* Update the reported maximum shader clock to the value +* which can be guarded to be achieved on all cards. This +* is aligned with Window setting. And considering that value +* might be not the peak frequency the card can achieve, it +* is normal some real-time clock frequency can overtake this +* labelled maximum clock frequency(for example in pp_dpm_sclk +* sysfs output). +*/ +if (skutable->DriverReportedClocks.GameClockAc && + (dpm_table->dpm_levels[dpm_table->count -1 ].value > + skutable->DriverReportedClocks.GameClockAc)) { + dpm_table->dpm_levels[dpm_table->count -1 ].value = + skutable->DriverReportedClocks.GameClockAc; + dpm_table->max = skutable->DriverReportedClocks.GameClockAc; + } }else { dpm_table->count =1 ; dpm_table->dpm_levels[0 ].value = smu->smu_table.boot_values.gfxclk /100 ;
@@ -779,6 +796,57 @@ static int smu_v13_0_0_get_smu_metrics_dreturn ret; } +static int smu_v13_0_0_get_dpm_ultimate_freq (struct smu_context *smu, +enum smu_clk_type clk_type, +uint32_t *min, +uint32_t *max) +{ +struct smu_13_0_dpm_context *dpm_context = + smu->smu_dpm.dpm_context; +struct smu_13_0_dpm_table *dpm_table; + +switch (clk_type) { +case SMU_MCLK : +case SMU_UCLK : +/* uclk dpm table */ + dpm_table = &dpm_context->dpm_tables.uclk_table; +break ; +case SMU_GFXCLK : +case SMU_SCLK : +/* gfxclk dpm table */ + dpm_table = &dpm_context->dpm_tables.gfx_table; +break ; +case SMU_SOCCLK : +/* socclk dpm table */ + dpm_table = &dpm_context->dpm_tables.soc_table; +break ; +case SMU_FCLK : +/* fclk dpm table */ + dpm_table = &dpm_context->dpm_tables.fclk_table; +break ; +case SMU_VCLK : +case SMU_VCLK1 : +/* vclk dpm table */ + dpm_table = &dpm_context->dpm_tables.vclk_table; +break ; +case SMU_DCLK : +case SMU_DCLK1 : +/* dclk dpm table */ + dpm_table = &dpm_context->dpm_tables.dclk_table; +break ; +default : +dev_err (smu->adev->dev,"Unsupported clock type!\n" ); +return -EINVAL ; + } + +if (min) + *min = dpm_table->min; +if (max) + *max = dpm_table->max; + +return 0 ; +} + static int smu_v13_0_0_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor, void *data,
@@ -1813,7 +1881,7 @@ static const struct pptable_funcs smu_v1 .get_enabled_mask = smu_cmn_get_enabled_mask, .dpm_set_vcn_enable = smu_v13_0_set_vcn_enable, .dpm_set_jpeg_enable = smu_v13_0_set_jpeg_enable, - .get_dpm_ultimate_freq = smu_v13_0_get_dpm_ultimate_freq, + .get_dpm_ultimate_freq = smu_v13_0_0_get_dpm_ultimate_freq, .get_vbios_bootup_values = smu_v13_0_get_vbios_bootup_values, .read_sensor = smu_v13_0_0_read_sensor, .feature_is_enabled = smu_cmn_feature_is_enabled,
Greg Kroah-Hartman
maintainerPATCH 18/177 drm/amd/pm: correct SMU13.0.0 pstate profiling clock settings
In reply to Greg Kroah-HartmanFrom: Evan Quan <[email protected]>
commit 32a7819ff8e25375c7515aaae5cfcb8c44a461b7 upstream.
Correct the pstate standard/peak profiling mode clock settings for SMU13.0.0.
--- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 22 ++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +15 -7
@@ -1349,9 +1349,17 @@ static int smu_v13_0_0_populate_umd_stat &dpm_context->dpm_tables.fclk_table;struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; +struct smu_table_context *table_context = &smu->smu_table; +PPTable_t *pptable = table_context->driver_pptable; +DriverReportedClocks_t driver_clocks = + pptable->SkuTable.DriverReportedClocks; pstate_table->gfxclk_pstate.min = gfx_table->min; - pstate_table->gfxclk_pstate.peak = gfx_table->max; +if (driver_clocks.GameClockAc && + (driver_clocks.GameClockAc < gfx_table->max)) + pstate_table->gfxclk_pstate.peak = driver_clocks.GameClockAc; +else + pstate_table->gfxclk_pstate.peak = gfx_table->max; pstate_table->uclk_pstate.min = mem_table->min; pstate_table->uclk_pstate.peak = mem_table->max;
@@ -1368,12 +1376,12 @@ static int smu_v13_0_0_populate_umd_stat pstate_table->fclk_pstate.min = fclk_table->min; pstate_table->fclk_pstate.peak = fclk_table->max; -/* -* For now, just use the mininum clock frequency. -* TODO: update them when the real pstate settings available -*/ - pstate_table->gfxclk_pstate.standard = gfx_table->min; - pstate_table->uclk_pstate.standard = mem_table->min; +if (driver_clocks.BaseClockAc && + driver_clocks.BaseClockAc < gfx_table->max) + pstate_table->gfxclk_pstate.standard = driver_clocks.BaseClockAc; +else + pstate_table->gfxclk_pstate.standard = gfx_table->max; + pstate_table->uclk_pstate.standard = mem_table->max; pstate_table->socclk_pstate.standard = soc_table->min; pstate_table->vclk_pstate.standard = vclk_table->min; pstate_table->dclk_pstate.standard = dclk_table->min;
Greg Kroah-Hartman
maintainerPATCH 19/177 btrfs: fix extent map use-after-free when handling missing device in read_one_chunk
In reply to Greg Kroah-HartmanFrom: void0red <[email protected]>
commit 1742e1c90c3da344f3bb9b1f1309b3f47482756a upstream.
Store the error code before freeing the extent_map. Though it's reference counted structure, in that function it's the first and last allocation so this would lead to a potential use-after-free.
The error can happen eg. when chunk is stored on a missing device and the degraded mount option is missing.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216721
--- fs/btrfs/volumes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/btrfs/volumes.c +2 -1
@@ -7128,8 +7128,9 @@ static int read_one_chunk(struct btrfs_k map->stripes[i].dev =handle_missing_device (fs_info, devid, uuid);if (IS_ERR (map->stripes[i].dev)) { + ret =PTR_ERR (map->stripes[i].dev);free_extent_map (em); -return PTR_ERR (map->stripes[i].dev); +return ret; } }
Greg Kroah-Hartman
maintainerPATCH 20/177 btrfs: fix resolving backrefs for inline extent followed by prealloc
In reply to Greg Kroah-HartmanFrom: Boris Burkov <[email protected]>
commit 560840afc3e63bbe5d9c5ef6b2ecf8f3589adff6 upstream.
If a file consists of an inline extent followed by a regular or prealloc extent, then a legitimate attempt to resolve a logical address in the non-inline region will result in add_all_parents reading the invalid offset field of the inline extent. If the inline extent item is placed in the leaf eb s.t. it is the first item, attempting to access the offset field will not only be meaningless, it will go past the end of the eb and cause this panic:
[17.626048] BTRFS warning (device dm-2): bad eb member end: ptr 0x3fd4 start 30834688 member offset 16377 size 8 [17.631693] general protection fault, probably for non-canonical address 0x5088000000000: 0000 [#1] SMP PTI [17.635041] CPU: 2 PID: 1267 Comm: btrfs Not tainted 5.12.0-07246-g75175d5adc74-dirty #199 [17.637969] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 [17.641995] RIP: 0010:btrfs_get_64+0xe7/0x110 [17.649890] RSP: 0018:ffffc90001f73a08 EFLAGS: 00010202 [17.651652] RAX: 0000000000000001 RBX: ffff88810c42d000 RCX: 0000000000000000 [17.653921] RDX: 0005088000000000 RSI: ffffc90001f73a0f RDI: 0000000000000001 [17.656174] RBP: 0000000000000ff9 R08: 0000000000000007 R09: c0000000fffeffff [17.658441] R10: ffffc90001f73790 R11: ffffc90001f73788 R12: ffff888106afe918 [17.661070] R13: 0000000000003fd4 R14: 0000000000003f6f R15: cdcdcdcdcdcdcdcd [17.663617] FS: 00007f64e7627d80(0000) GS:ffff888237c80000(0000) knlGS:0000000000000000 [17.666525] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [17.668664] CR2: 000055d4a39152e8 CR3: 000000010c596002 CR4: 0000000000770ee0 [17.671253] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [17.673634] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [17.676034] PKRU: 55555554 [17.677004] Call Trace: [17.677877] add_all_parents+0x276/0x480 [17.679325] find_parent_nodes+0xfae/0x1590 [17.680771] btrfs_find_all_leafs+0x5e/0xa0 [17.682217] iterate_extent_inodes+0xce/0x260 [17.683809] ? btrfs_inode_flags_to_xflags+0x50/0x50 [17.685597] ? iterate_inodes_from_logical+0xa1/0xd0 [17.687404] iterate_inodes_from_logical+0xa1/0xd0 [17.689121] ? btrfs_inode_flags_to_xflags+0x50/0x50 [17.691010] btrfs_ioctl_logical_to_ino+0x131/0x190 [17.692946] btrfs_ioctl+0x104a/0x2f60 [17.694384] ? selinux_file_ioctl+0x182/0x220 [17.695995] ? __x64_sys_ioctl+0x84/0xc0 [17.697394] __x64_sys_ioctl+0x84/0xc0 [17.698697] do_syscall_64+0x33/0x40 [17.700017] entry_SYSCALL_64_after_hwframe+0x44/0xae [17.701753] RIP: 0033:0x7f64e72761b7 [17.709355] RSP: 002b:00007ffefb067f58 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [17.712088] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007f64e72761b7 [17.714667] RDX: 00007ffefb067fb0 RSI: 00000000c0389424 RDI: 0000000000000003 [17.717386] RBP: 00007ffefb06d188 R08: 000055d4a390d2b0 R09: 00007f64e7340a60 [17.719938] R10: 0000000000000231 R11: 0000000000000246 R12: 0000000000000001 [17.722383] R13: 0000000000000000 R14: 00000000c0389424 R15: 000055d4a38fd2a0 [17.724839] Modules linked in:
Fix the bug by detecting the inline extent item in add_all_parents and skipping to the next extent item.
--- fs/btrfs/backref.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/btrfs/backref.c +4 -0
@@ -433,6 +433,7 @@ static int add_all_parents(struct btrfs_u64 wanted_disk_byte = ref->wanted_disk_byte;u64 count =0 ;u64 data_offset; +u8 type;if (level !=0 ) { eb = path->nodes[level];
@@ -487,6 +488,9 @@ static int add_all_parents(struct btrfs_continue ; } fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); + type =btrfs_file_extent_type (eb, fi); +if (type ==BTRFS_FILE_EXTENT_INLINE ) + goto next; disk_byte =btrfs_file_extent_disk_bytenr (eb, fi); data_offset =btrfs_file_extent_offset (eb, fi);
Greg Kroah-Hartman
maintainerPATCH 21/177 ARM: ux500: do not directly dereference __iomem
In reply to Greg Kroah-HartmanFrom: Jason A. Donenfeld <[email protected]>
commit 65b0e307a1a9193571db12910f382f84195a3d29 upstream.
Sparse reports that calling add_device_randomness() on uid is a violation of address spaces. And indeed the next usage uses readl() properly, but that was left out when passing it toadd_device_ randomness(). So instead copy the whole thing to the stack first.
--- drivers/soc/ux500/ux500-soc-id.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/soc/ux500/ux500-soc-id.c +4 -6
@@ -167,20 +167,18 @@ ATTRIBUTE_GROUPS(ux500_soc);static const char *db8500_read_soc_id (struct device_node *backupram) {void __iomem *base; -void __iomem *uid;const char *retstr; +u32 uid[5 ]; base =of_iomap (backupram,0 );if (!base)return NULL ; - uid = base +0x1fc0 ; +memcpy_fromio (uid, base +0x1fc0 ,sizeof (uid));/* Throw these device-specific numbers into the entropy pool */ -add_device_randomness (uid,0x14 ); +add_device_randomness (uid,sizeof (uid)); retstr =kasprintf (GFP_KERNEL ,"%08x%08x%08x%08x%08x" , -readl ((u32 *)uid+0 ), -readl ((u32 *)uid+1 ),readl ((u32 *)uid+2 ), -readl ((u32 *)uid+3 ),readl ((u32 *)uid+4 )); + uid[0 ], uid[1 ], uid[2 ], uid[3 ], uid[4 ]);iounmap (base);return retstr; }
Greg Kroah-Hartman
maintainerPATCH 22/177 arm64: dts: qcom: sdm850-samsung-w737: correct I2C12 pins drive strength
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
commit 3638ea010c37e1e6d93474c4b3368f403600413f upstream.
The pin configuration (done with generic pin controller helpers and as expressed by bindings) requires children nodes with either:
1. "pins" property and the actual configuration,
2. another set of nodes with above point.
The qup_i2c12_default pin configuration used second method - with a "pinmux" child.
--- arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts +4 -2
@@ -415,8 +415,10 @@ pinconf { }; &qup_i2c12_default { - drive-strength = <2>; - bias-disable; + pinmux { + drive-strength = <2>; + bias-disable; + }; }; &qup_uart6_default {
Signature · 1 line
2.39.0
Greg Kroah-Hartman
maintainerPATCH 23/177 x86/fpu/xstate: Fix XSTATE_WARN_ON() to emit relevant diagnostics
In reply to Greg Kroah-HartmanFrom: Andrew Cooper <[email protected]>
commit 48280042f2c6e3ac2cfb1d8b752ab4a7e0baea24 upstream.
"XSAVE consistency problem" has been reported under Xen, but that's the extent of my divination skills.
Modify XSTATE_WARN_ON() to force the caller to provide relevant diagnostic information, and modify each caller suitably.
For check_xstate_against_struct(), this removes a double WARN() where one will do perfectly fine.
CC stable as this has been wonky debugging for 7 years and it is good to have there too.
--- arch/x86/kernel/fpu/xstate.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
arch/x86/kernel/fpu/xstate.c +6 -6
@@ -440,8 +440,8 @@ static void __init __xstate_dump_leaves( } } -#define XSTATE_WARN_ON (x) do { \ - if (WARN_ONCE(x, "XSAVE consistency problem, dumping leaves")) { \ +#define XSTATE_WARN_ON (x, fmt, ...) do { \ + if (WARN_ONCE(x, "XSAVE consistency problem: " fmt, ##__VA_ARGS__)) { \ __xstate_dump_leaves(); \ } \ } while (0)
@@ -554,8 +554,7 @@ static bool __init check_xstate_against_ (nr >= XFEATURE_MAX) || (nr == XFEATURE_PT_UNIMPLEMENTED_SO_FAR) || ((nr >= XFEATURE_RSRVD_COMP_11) && (nr <= XFEATURE_RSRVD_COMP_16))) { -WARN_ONCE (1 ,"no structure for xstate: %d\n" , nr); -XSTATE_WARN_ON (1 ); +XSTATE_WARN_ON (1 ,"No structure for xstate: %d\n" , nr);return false; }return true;
@@ -598,12 +597,13 @@ static bool __init paranoid_xstate_size_* XSAVES. */ if (!xsaves &&xfeature_is_supervisor (i)) { -XSTATE_WARN_ON (1 ); +XSTATE_WARN_ON (1 ,"Got supervisor feature %d, but XSAVES not advertised\n" , i);return false; } } size =xstate_calculate_size (fpu_kernel_cfg.max_features, compacted); -XSTATE_WARN_ON (size != kernel_size); +XSTATE_WARN_ON (size != kernel_size, +"size %u != kernel_size %u\n" , size, kernel_size);return size == kernel_size; }
Greg Kroah-Hartman
maintainerPATCH 24/177 arm64: dts: qcom: sdm850-lenovo-yoga-c630: correct I2C12 pins drive strength
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
commit fd49776d8f458bba5499384131eddc0b8bcaf50c upstream.
The pin configuration (done with generic pin controller helpers and as expressed by bindings) requires children nodes with either:
1. "pins" property and the actual configuration,
2. another set of nodes with above point.
The qup_i2c12_default pin configuration used second method - with a "pinmux" child.
--- arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +4 -2
@@ -487,8 +487,10 @@ }; &qup_i2c12_default { - drive-strength = <2>; - bias-disable; + pinmux { + drive-strength = <2>; + bias-disable; + }; }; &qup_uart6_default {
Greg Kroah-Hartman
maintainerPATCH 25/177 cxl/region: Fix missing probe failure
In reply to Greg Kroah-HartmanFrom: Dan Williams <[email protected]>
commit bf3e5da8cb43a671b32fc125fa81b8f6a3677192 upstream.
cxl_region_probe() allows for regions not in the 'commit' state to be enabled. Fail probe when the region is not committed otherwise the kernel may indicate that an address range is active when none of the decoders are active.
--- drivers/cxl/core/region.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/cxl/core/region.c +3 -0
@@ -1922,6 +1922,9 @@ static int cxl_region_probe(struct devic*/ up_read (&cxl_region_rwsem); +if (rc) +return rc; +switch (cxlr->mode) {case CXL_DECODER_PMEM :return devm_cxl_add_pmem_region (cxlr);
Greg Kroah-Hartman
maintainerPATCH 26/177 EDAC/mc_sysfs: Increase legacy channel support to 12
In reply to Greg Kroah-HartmanFrom: Yazen Ghannam <[email protected]>
commit 25836ce1df827cb4830291cb2325067efb46753a upstream.
Newer AMD systems, such as Genoa, can support up to 12 channels per EDAC "mc" device. These are detected by the device's EDAC module, and the current EDAC interface is properly enumerated. However, the legacy EDAC sysfs interface provides device attributes only for channels 0 to 7. Therefore, channels 8 to 11 will not be visible in the legacy interface. This was overlooked in the initial support for AMD Genoa.
Add additional device attributes so that up to 12 channels are visible in the legacy EDAC sysfs interface.
--- drivers/edac/edac_mc_sysfs.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
drivers/edac/edac_mc_sysfs.c +24 -0
@@ -298,6 +298,14 @@ DEVICE_CHANNEL(ch6_dimm_label, S_IRUGO | channel_dimm_label_show, channel_dimm_label_store, 6);DEVICE_CHANNEL (ch7_dimm_label,S_IRUGO |S_IWUSR , channel_dimm_label_show, channel_dimm_label_store,7 ); +DEVICE_CHANNEL (ch8_dimm_label,S_IRUGO |S_IWUSR , + channel_dimm_label_show, channel_dimm_label_store,8 ); +DEVICE_CHANNEL (ch9_dimm_label,S_IRUGO |S_IWUSR , + channel_dimm_label_show, channel_dimm_label_store,9 ); +DEVICE_CHANNEL (ch10_dimm_label,S_IRUGO |S_IWUSR , + channel_dimm_label_show, channel_dimm_label_store,10 ); +DEVICE_CHANNEL (ch11_dimm_label,S_IRUGO |S_IWUSR , + channel_dimm_label_show, channel_dimm_label_store,11 );/* Total possible dynamic DIMM Label attribute file table */ static struct attribute *dynamic_csrow_dimm_attr[] = {
@@ -309,6 +317,10 @@ static struct attribute *dynamic_csrow_d &dev_attr_legacy_ch5_dimm_label.attr.attr, &dev_attr_legacy_ch6_dimm_label.attr.attr, &dev_attr_legacy_ch7_dimm_label.attr.attr, + &dev_attr_legacy_ch8_dimm_label.attr.attr, + &dev_attr_legacy_ch9_dimm_label.attr.attr, + &dev_attr_legacy_ch10_dimm_label.attr.attr, + &dev_attr_legacy_ch11_dimm_label.attr.attr, NULL };
@@ -329,6 +341,14 @@ DEVICE_CHANNEL(ch6_ce_count, S_IRUGO, channel_ce_count_show, NULL, 6);DEVICE_CHANNEL (ch7_ce_count,S_IRUGO , channel_ce_count_show,NULL ,7 ); +DEVICE_CHANNEL (ch8_ce_count,S_IRUGO , + channel_ce_count_show,NULL ,8 ); +DEVICE_CHANNEL (ch9_ce_count,S_IRUGO , + channel_ce_count_show,NULL ,9 ); +DEVICE_CHANNEL (ch10_ce_count,S_IRUGO , + channel_ce_count_show,NULL ,10 ); +DEVICE_CHANNEL (ch11_ce_count,S_IRUGO , + channel_ce_count_show,NULL ,11 );/* Total possible dynamic ce_count attribute file table */ static struct attribute *dynamic_csrow_ce_count_attr[] = {
@@ -340,6 +360,10 @@ static struct attribute *dynamic_csrow_c &dev_attr_legacy_ch5_ce_count.attr.attr, &dev_attr_legacy_ch6_ce_count.attr.attr, &dev_attr_legacy_ch7_ce_count.attr.attr, + &dev_attr_legacy_ch8_ce_count.attr.attr, + &dev_attr_legacy_ch9_ce_count.attr.attr, + &dev_attr_legacy_ch10_ce_count.attr.attr, + &dev_attr_legacy_ch11_ce_count.attr.attr, NULL };
Greg Kroah-Hartman
maintainerPATCH 27/177 selftests: Use optional USERCFLAGS and USERLDFLAGS
In reply to Greg Kroah-HartmanFrom: Mickaël Salaün <[email protected]>
commit de3ee3f63400a23954e7c1ad1cb8c20f29ab6fe3 upstream.
This change enables to extend CFLAGS and LDFLAGS from command line, e.g. to extend compiler checks: make USERCFLAGS=-Werror USERLDFLAGS=-static
USERCFLAGS and USERLDFLAGS are documented in Documentation/kbuild/makefiles.rst and Documentation/kbuild/kbuild.rst
This should be backported (down to 5.10) to improve previous kernel versions testing as well.
--- tools/testing/selftests/lib.mk | 5 +++++ 1 file changed, 5 insertions(+)
tools/testing/selftests/lib.mk +5 -0
@@ -123,6 +123,11 @@ endef clean: $(CLEAN) +# Enables to extend CFLAGS and LDFLAGS from command line, e.g. +# make USERCFLAGS=-Werror USERLDFLAGS=-static +CFLAGS += $(USERCFLAGS) +LDFLAGS += $(USERLDFLAGS) + # When make O= with kselftest target from main level # the following aren't defined. #
Greg Kroah-Hartman
maintainerPATCH 28/177 x86/MCE/AMD: Clear DFR errors found in THR handler
In reply to Greg Kroah-HartmanFrom: Yazen Ghannam <[email protected]>
commit bc1b705b0eee4c645ad8b3bbff3c8a66e9688362 upstream.
AMD's MCA Thresholding feature counts errors of all severity levels, not just correctable errors. If a deferred error causes the threshold limit to be reached (it was the error that caused the overflow), then both a deferred error interrupt and a thresholding interrupt will be triggered.
The order of the interrupts is not guaranteed. If the threshold interrupt handler is executed first, then it will clear MCA_STATUS for the error. It will not check or clear MCA_DESTAT which also holds a copy of the deferred error. When the deferred error interrupt handler runs it will not find an error in MCA_STATUS, but it will find the error in MCA_DESTAT. This will cause two errors to be logged.
Check for deferred errors when handling a threshold interrupt. If a bank contains a deferred error, then clear the bank's MCA_DESTAT register.
Define a new helper function to do the deferred error check and clearing of MCA_DESTAT.
[ bp: Simplify, convert comment to passive voice. ]
--- arch/x86/kernel/cpu/mce/amd.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-)
arch/x86/kernel/cpu/mce/amd.c +20 -13
@@ -788,6 +788,24 @@ _log_error_bank(unsigned int bank, u32 mreturn status &MCI_STATUS_DEFERRED ; } +static bool _log_error_deferred (unsigned int bank,u32 misc) +{ +if (!_log_error_bank (bank,mca_msr_reg (bank,MCA_STATUS ), +mca_msr_reg (bank,MCA_ADDR ), misc)) +return false; + +/* +* Non-SMCA systems don't have MCA_DESTAT/MCA_DEADDR registers. +* Return true here to avoid accessing these registers. +*/ +if (!mce_flags.smca) +return true; + +/* Clear MCA_DESTAT if the deferred error was logged from MCA_STATUS. */ +wrmsrl (MSR_AMD64_SMCA_MCx_DESTAT (bank),0 ); +return true; +} +/* * We have three scenarios for checking for Deferred errors: *
@@ -799,19 +817,8 @@ _log_error_bank(unsigned int bank, u32 m*/ static void log_error_deferred (unsigned int bank) { -bool defrd; - - defrd =_log_error_bank (bank,mca_msr_reg (bank,MCA_STATUS ), -mca_msr_reg (bank,MCA_ADDR ),0 ); - -if (!mce_flags.smca) -return ; - -/* Clear MCA_DESTAT if we logged the deferred error from MCA_STATUS. */ -if (defrd) { -wrmsrl (MSR_AMD64_SMCA_MCx_DESTAT (bank),0 ); +if (_log_error_deferred (bank,0 ))return ; - }/* * Only deferred errors are logged in MCA_DE{STAT,ADDR} so just check
@@ -832,7 +839,7 @@ static void amd_deferred_error_interruptstatic void log_error_thresholding (unsigned int bank,u64 misc) { -_log_error_bank (bank,mca_msr_reg (bank,MCA_STATUS ),mca_msr_reg (bank,MCA_ADDR ), misc); +_log_error_deferred (bank, misc); }static void log_and_reset_block (struct threshold_block *block)
Greg Kroah-Hartman
maintainerPATCH 29/177 PM/devfreq: governor: Add a private governor_data for governor
In reply to Greg Kroah-HartmanFrom: Kant Fan <[email protected]>
commit 5fdded8448924e3631d466eea499b11606c43640 upstream.
The member void *data in the structure devfreq can be overwrite by governor_userspace. For example:
1. The device driver assigned the devfreq governor to simple_ondemand by the function devfreq_add_device() and init the devfreq member void *data to a pointer of a static structure devfreq_simple_ondemand_data by the function devfreq_add_device().
2. The user changed the devfreq governor to userspace by the command "echo userspace > /sys/class/devfreq/.../governor".
3. The governor userspace alloced a dynamic memory for the struct userspace_data and assigend the member void *data of devfreq to this memory by the function userspace_init().
4. The user changed the devfreq governor back to simple_ondemand by the command "echo simple_ondemand > /sys/class/devfreq/.../governor".
5. The governor userspace exited and assigned the member void *data in the structure devfreq to NULL by the function userspace_exit().
6. The governor simple_ondemand fetched the static information of devfreq_simple_ondemand_data in the function devfreq_simple_ondemand_func() but the member void *data of devfreq was assigned to NULL by the function userspace_exit().
7. The information of upthreshold and downdifferential is lost and the governor simple_ondemand can't work correctly.
The member void *data in the structure devfreq is designed for a static pointer used in a governor and inited by the function devfreq_add_device(). This patch add an element named governor_data in the devfreq structure which can be used by a governor(E.g userspace) who want to assign a private data to do some private things.
--- drivers/devfreq/devfreq.c | 6 ++---- drivers/devfreq/governor_userspace.c | 12 ++++++------ include/linux/devfreq.h | 7 ++++--- 3 files changed, 12 insertions(+), 13 deletions(-)
drivers/devfreq/devfreq.c +2 -4
@@ -776,8 +776,7 @@ static void remove_sysfs_files(struct de* @dev: the device to add devfreq feature. * @profile: device-specific profile to run devfreq. * @governor_name: name of the policy to choose frequency. -* @data: private data for the governor. The devfreq framework does not -* touch this value. +* @data: devfreq driver pass to governors, governor should not change it. */ struct devfreq *devfreq_add_device(struct device *dev, struct devfreq_dev_profile *profile,
@@ -1011,8 +1010,7 @@ static void devm_devfreq_dev_release(str* @dev: the device to add devfreq feature. * @profile: device-specific profile to run devfreq. * @governor_name: name of the policy to choose frequency. -* @data: private data for the governor. The devfreq framework does not -* touch this value. +* @data: devfreq driver pass to governors, governor should not change it. * * This function manages automatically the memory of devfreq device using device * resource management and simplify the free operation for memory of devfreq
drivers/devfreq/governor_userspace.c +6 -6
@@ -21,7 +21,7 @@ struct userspace_data {static int devfreq_userspace_func (struct devfreq *df,unsigned long *freq) { -struct userspace_data *data = df->data; +struct userspace_data *data = df->governor_data;if (data->valid) *freq = data->user_frequency;
@@ -40,7 +40,7 @@ static ssize_t set_freq_store(struct devint err =0 ;mutex_lock (&devfreq->lock); - data = devfreq->data; + data = devfreq->governor_data;sscanf (buf,"%lu" , &wanted); data->user_frequency = wanted;
@@ -60,7 +60,7 @@ static ssize_t set_freq_show(struct deviint err =0 ;mutex_lock (&devfreq->lock); - data = devfreq->data; + data = devfreq->governor_data;if (data->valid) err =sprintf (buf,"%lu\n" , data->user_frequency);
@@ -91,7 +91,7 @@ static int userspace_init(struct devfreq goto out; } data->valid = false; - devfreq->data = data; + devfreq->governor_data = data; err =sysfs_create_group (&devfreq->dev.kobj, &dev_attr_group); out:
@@ -107,8 +107,8 @@ static void userspace_exit(struct devfreif (devfreq->dev.kobj.sd)sysfs_remove_group (&devfreq->dev.kobj, &dev_attr_group); -kfree (devfreq->data); - devfreq->data =NULL ; +kfree (devfreq->governor_data); + devfreq->governor_data =NULL ; } static int devfreq_userspace_handler(struct devfreq *devfreq,
include/linux/devfreq.h +4 -3
@@ -152,8 +152,8 @@ struct devfreq_stats {* @max_state: count of entry present in the frequency table. * @previous_freq: previously configured frequency value. * @last_status: devfreq user device info, performance statistics -* @data: Private data of the governor. The devfreq framework does not -* touch this. +* @data: devfreq driver pass to governors, governor should not change it. +* @governor_data: private data for governors, devfreq core doesn't touch it. * @user_min_freq_req: PM QoS minimum frequency request from user (via sysfs) * @user_max_freq_req: PM QoS maximum frequency request from user (via sysfs) * @scaling_min_freq: Limit minimum frequency requested by OPP interface
@@ -193,7 +193,8 @@ struct devfreq {unsigned long previous_freq;struct devfreq_dev_status last_status; -void *data;/* private data for governors */ +void *data; +void *governor_data;struct dev_pm_qos_request user_min_freq_req;struct dev_pm_qos_request user_max_freq_req;
Greg Kroah-Hartman
maintainerPATCH 30/177 cpufreq: Init completion before kobject_init_and_add()
In reply to Greg Kroah-HartmanFrom: Yongqiang Liu <[email protected]>
commit 5c51054896bcce1d33d39fead2af73fec24f40b6 upstream.
In cpufreq_policy_alloc(), it will call uninitialed completion in cpufreq_sysfs_release() when kobject_init_and_add() fails. And that will cause a crash such as the following page fault in complete:
BUG: unable to handle page fault for address: fffffffffffffff8 [..] RIP: 0010:complete+0x98/0x1f0 [..] Call Trace: kobject_put+0x1be/0x4c0 cpufreq_online.cold+0xee/0x1fd cpufreq_add_dev+0x183/0x1e0 subsys_interface_register+0x3f5/0x4e0 cpufreq_register_driver+0x3b7/0x670 acpi_cpufreq_init+0x56c/0x1000 [acpi_cpufreq] do_one_initcall+0x13d/0x780 do_init_module+0x1c3/0x630 load_module+0x6e67/0x73b0 __do_sys_finit_module+0x181/0x240 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
--- drivers/cpufreq/cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/cpufreq.c +1 -1
@@ -1207,6 +1207,7 @@ static struct cpufreq_policy *cpufreq_poif (!zalloc_cpumask_var (&policy->real_cpus,GFP_KERNEL )) goto err_free_rcpumask; +init_completion (&policy->kobj_unregister); ret =kobject_init_and_add (&policy->kobj, &ktype_cpufreq, cpufreq_global_kobject,"policy%u" , cpu);if (ret) {
@@ -1245,7 +1246,6 @@ static struct cpufreq_policy *cpufreq_poinit_rwsem (&policy->rwsem);spin_lock_init (&policy->transition_lock);init_waitqueue_head (&policy->transition_wait); -init_completion (&policy->kobj_unregister);INIT_WORK (&policy->update, handle_update); policy->cpu = cpu;
Greg Kroah-Hartman
maintainerPATCH 31/177 ext2: unbugger ext2_empty_dir()
In reply to Greg Kroah-HartmanFrom: Al Viro <[email protected]>
commit 27e714c007e4ad01837bf0fac5c11913a38d7695 upstream.
In 27cfa258951a "ext2: fix fs corruption when trying to remove a non-empty directory with IO error" a funny thing has happened:
- page = ext2_get_page(inode, i, dir_has_error, &page_addr);
+ page = ext2_get_page(inode, i, 0, &page_addr);
- if (IS_ERR(page)) {
- dir_has_error = 1;
- continue;
- }
+ if (IS_ERR(page))
+ goto not_empty;
And at not_empty: we hit ext2_put_page(page, page_addr), which does put_page(page). Which, unless I'm very mistaken, should oops immediately when given ERR_PTR(-E...) as page.
OK, shit happens, insufficiently tested patches included. But when commit in question describes the fault-injection test that exercised that particular failure exit...
Ow.
--- fs/ext2/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext2/dir.c +1 -1
@@ -679,7 +679,7 @@ int ext2_empty_dir (struct inode * inode page =ext2_get_page (inode, i,0 , &page_addr);if (IS_ERR (page)) - goto not_empty; +return 0 ; kaddr = page_addr; de = (ext2_dirent *)kaddr;
Greg Kroah-Hartman
maintainerPATCH 32/177 media: s5p-mfc: Fix to handle reference queue during finishing
In reply to Greg Kroah-HartmanFrom: Smitha T Murthy <[email protected]>
commit d8a46bc4e1e0446459daa77c4ce14218d32dacf9 upstream.
On receiving last buffer driver puts MFC to MFCINST_FINISHING state which in turn skips transferring of frame from SRC to REF queue. This causes driver to stop MFC encoding and last frame is lost.
This patch guarantees safe handling of frames during MFCINST_FINISHING and correct clearing of workbit to avoid early stopping of encoding.
--- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c +10 -2
@@ -1218,6 +1218,7 @@ static int enc_post_frame_start(struct sunsigned long mb_y_addr, mb_c_addr;int slice_type;unsigned int strm_size; +bool src_ready; slice_type =s5p_mfc_hw_call (dev->mfc_ops, get_enc_slice_type, dev); strm_size =s5p_mfc_hw_call (dev->mfc_ops, get_enc_strm_size, dev);
@@ -1257,7 +1258,8 @@ static int enc_post_frame_start(struct s } } } -if ((ctx->src_queue_cnt >0 ) && (ctx->state ==MFCINST_RUNNING )) { +if (ctx->src_queue_cnt >0 && (ctx->state ==MFCINST_RUNNING || + ctx->state ==MFCINST_FINISHING )) { mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);if (mb_entry->flags &MFC_BUF_FLAG_USED ) {
@@ -1288,7 +1290,13 @@ static int enc_post_frame_start(struct svb2_set_plane_payload (&mb_entry->b->vb2_buf,0 , strm_size);vb2_buffer_done (&mb_entry->b->vb2_buf,VB2_BUF_STATE_DONE ); } -if ((ctx->src_queue_cnt ==0 ) || (ctx->dst_queue_cnt ==0 )) + + src_ready = true; +if (ctx->state ==MFCINST_RUNNING && ctx->src_queue_cnt ==0 ) + src_ready = false; +if (ctx->state ==MFCINST_FINISHING && ctx->ref_queue_cnt ==0 ) + src_ready = false; +if (!src_ready || ctx->dst_queue_cnt ==0 )clear_work_bit (ctx);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 33/177 media: s5p-mfc: Clear workbit to handle error condition
In reply to Greg Kroah-HartmanFrom: Smitha T Murthy <[email protected]>
commit d3f3c2fe54e30b0636496d842ffbb5ad3a547f9b upstream.
During error on CLOSE_INSTANCE command, ctx_work_bits was not getting cleared. During consequent mfc execution NULL pointer dereferencing of this context led to kernel panic. This patch fixes this issue by making sure to clear ctx_work_bits always.
--- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c +3 -1
@@ -468,8 +468,10 @@ void s5p_mfc_close_mfc_inst(struct s5p_ms5p_mfc_hw_call (dev->mfc_ops, try_run, dev);/* Wait until instance is returned or timeout occurred */ if (s5p_mfc_wait_for_done_ctx (ctx, -S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET ,0 )) +S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET ,0 )){ +clear_work_bit_irqsave (ctx);mfc_err ("Err returning instance\n" ); + }/* Free resources */ s5p_mfc_hw_call (dev->mfc_ops, release_codec_buffers, ctx);
Greg Kroah-Hartman
maintainerPATCH 34/177 media: s5p-mfc: Fix in register read and write for H264
In reply to Greg Kroah-HartmanFrom: Smitha T Murthy <[email protected]>
commit 06710cd5d2436135046898d7e4b9408c8bb99446 upstream.
Few of the H264 encoder registers written were not getting reflected since the read values were not stored and getting overwritten.
--- drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c +7 -7
@@ -1060,7 +1060,7 @@ static int s5p_mfc_set_enc_params_h264(s }/* aspect ratio VUI */ -readl (mfc_regs->e_h264_options); + reg =readl (mfc_regs->e_h264_options); reg &= ~(0x1 <<5 ); reg |= ((p_h264->vui_sar &0x1 ) <<5 );writel (reg, mfc_regs->e_h264_options);
@@ -1083,7 +1083,7 @@ static int s5p_mfc_set_enc_params_h264(s/* intra picture period for H.264 open GOP */ /* control */ -readl (mfc_regs->e_h264_options); + reg =readl (mfc_regs->e_h264_options); reg &= ~(0x1 <<4 ); reg |= ((p_h264->open_gop &0x1 ) <<4 );writel (reg, mfc_regs->e_h264_options);
@@ -1097,23 +1097,23 @@ static int s5p_mfc_set_enc_params_h264(s }/* 'WEIGHTED_BI_PREDICTION' for B is disable */ -readl (mfc_regs->e_h264_options); + reg =readl (mfc_regs->e_h264_options); reg &= ~(0x3 <<9 );writel (reg, mfc_regs->e_h264_options);/* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */ -readl (mfc_regs->e_h264_options); + reg =readl (mfc_regs->e_h264_options); reg &= ~(0x1 <<14 );writel (reg, mfc_regs->e_h264_options);/* ASO */ -readl (mfc_regs->e_h264_options); + reg =readl (mfc_regs->e_h264_options); reg &= ~(0x1 <<6 ); reg |= ((p_h264->aso &0x1 ) <<6 );writel (reg, mfc_regs->e_h264_options);/* hier qp enable */ -readl (mfc_regs->e_h264_options); + reg =readl (mfc_regs->e_h264_options); reg &= ~(0x1 <<8 ); reg |= ((p_h264->open_gop &0x1 ) <<8 );writel (reg, mfc_regs->e_h264_options);
@@ -1134,7 +1134,7 @@ static int s5p_mfc_set_enc_params_h264(swritel (reg, mfc_regs->e_h264_num_t_layer);/* frame packing SEI generation */ -readl (mfc_regs->e_h264_options); + reg =readl (mfc_regs->e_h264_options); reg &= ~(0x1 <<25 ); reg |= ((p_h264->sei_frame_packing &0x1 ) <<25 );writel (reg, mfc_regs->e_h264_options);
Greg Kroah-Hartman
maintainerPATCH 35/177 bpf: Resolve fext program type when checking map compatibility
In reply to Greg Kroah-HartmanFrom: Toke Høiland-Jørgensen <[email protected]>
[ Upstream commit 1c123c567fb138ebd187480b7fc0610fcb0851f5 ]
The bpf_prog_map_compatible() check makes sure that BPF program types are not mixed inside BPF map types that can contain programs (tail call maps, cpumaps and devmaps). It does this by setting the fields of the map->owner struct to the values of the first program being checked against, and rejecting any subsequent programs if the values don't match.
One of the values being set in the map owner struct is the program type, and since the code did not resolve the prog type for fext programs, the map owner type would be set to PROG_TYPE_EXT and subsequent loading of programs of the target type into the map would fail.
This bug is seen in particular for XDP programs that are loaded as PROG_TYPE_EXT using libxdp; these cannot insert programs into devmaps and cpumaps because the check fails as described above.
Fix the bug by resolving the fext program type to its target program type as elsewhere in the verifier.
v3:
- Add Yonghong's ACK
--- include/linux/bpf_verifier.h | 2 +- kernel/bpf/core.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-)
include/linux/bpf_verifier.h +1 -1
@@ -634,7 +634,7 @@ static inline u32 type_flag(u32 type) }/* only use after check_attach_btf_id() */ -static inline enum bpf_prog_type resolve_prog_type (struct bpf_prog *prog) +static inline enum bpf_prog_type resolve_prog_type (const struct bpf_prog *prog) {return prog->type ==BPF_PROG_TYPE_EXT ? prog->aux->dst_prog->type : prog->type;
kernel/bpf/core.c +3 -2
@@ -2088,6 +2088,7 @@ static unsigned int __bpf_prog_ret0_warn(const void *ctx,bool bpf_prog_map_compatible (struct bpf_map *map,const struct bpf_prog *fp) { +enum bpf_prog_type prog_type =resolve_prog_type (fp);bool ret;if (fp->kprobe_override)
@@ -2098,12 +2099,12 @@ bool bpf_prog_map_compatible(struct bpf_map *map,/* There's no owner yet where we could check for * compatibility. */ - map->owner.type = fp->type; + map->owner.type = prog_type; map->owner.jited = fp->jited; map->owner.xdp_has_frags = fp->aux->xdp_has_frags; ret = true; }else { - ret = map->owner.type == fp->type && + ret = map->owner.type == prog_type && map->owner.jited == fp->jited && map->owner.xdp_has_frags == fp->aux->xdp_has_frags; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 36/177 ALSA: patch_realtek: Fix Dell Inspiron Plus 16
In reply to Greg Kroah-HartmanFrom: Philipp Jungkamp <[email protected]>
[ Upstream commit 2912cdda734d9136615ed05636d9fcbca2a7a3c5 ]
The Dell Inspiron Plus 16, in both laptop and 2in1 form factor, has top speakers connected on NID 0x17, which the codec reports as unconnected. These speakers should be connected to the DAC on NID 0x03.
Stable-dep-of: a4517c4f3423 ("ALSA: hda/realtek: Apply dual codec fixup for Dell Latitude laptops")
--- sound/pci/hda/patch_realtek.c | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
sound/pci/hda/patch_realtek.c +37 -0
@@ -6925,6 +6925,34 @@ static void alc287_fixup_yoga9_14iap7_bass_spk_pin(struct hda_codec *codec, } } +static void alc295_fixup_dell_inspiron_top_speakers (struct hda_codec *codec, +const struct hda_fixup *fix,int action) +{ +static const struct hda_pintbl pincfgs[] = { + {0x14 ,0x90170151 }, + {0x17 ,0x90170150 }, + { } + }; +static const hda_nid_t conn[] = {0x02 ,0x03 }; +static const hda_nid_t preferred_pairs[] = { +0x14 ,0x02 , +0x17 ,0x03 , +0x21 ,0x02 , +0 + }; +struct alc_spec *spec = codec->spec; + +alc_fixup_no_shutup (codec, fix, action); + +switch (action) { +case HDA_FIXUP_ACT_PRE_PROBE : +snd_hda_apply_pincfgs (codec, pincfgs); +snd_hda_override_conn_list (codec,0x17 ,ARRAY_SIZE (conn), conn); + spec->gen.preferred_dacs = preferred_pairs; +break ; + } +} +enum {ALC269_FIXUP_GPIO2 ,ALC269_FIXUP_SONY_VAIO ,
@@ -7168,6 +7196,7 @@ enum {ALC287_FIXUP_LEGION_16ITHG6 ,ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK ,ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN , + ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS, };/* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -9117,6 +9146,12 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK, }, + [ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc295_fixup_dell_inspiron_top_speakers, + .chained = true, + .chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -9217,6 +9252,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x1028 ,0x0a9e ,"Dell Latitude 5430" ,ALC269_FIXUP_DELL4_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1028 ,0x0b19 ,"Dell XPS 15 9520" ,ALC289_FIXUP_DUAL_SPK ),SND_PCI_QUIRK (0x1028 ,0x0b1a ,"Dell Precision 5570" ,ALC289_FIXUP_DUAL_SPK ), +SND_PCI_QUIRK (0x1028 ,0x0b37 ,"Dell Inspiron 16 Plus 7620 2-in-1" ,ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS ), +SND_PCI_QUIRK (0x1028 ,0x0b71 ,"Dell Inspiron 16 Plus 7620" ,ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS ),SND_PCI_QUIRK (0x1028 ,0x164a ,"Dell" ,ALC293_FIXUP_DELL1_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1028 ,0x164b ,"Dell" ,ALC293_FIXUP_DELL1_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 37/177 ALSA: hda/realtek: Apply dual codec fixup for Dell Latitude laptops
In reply to Greg Kroah-HartmanFrom: Chris Chiu <[email protected]>
[ Upstream commit a4517c4f3423c7c448f2c359218f97c1173523a1 ]
The Dell Latiture 3340/3440/3540 laptops with Realtek ALC3204 have dual codecs and need the ALC1220_FIXUP_GB_DUAL_CODECS to fix the conflicts of Master controls. The existing headset mic fixup for Dell is also required to enable the jack sense and the headset mic.
Introduce a new fixup to fix the dual codec and headset mic issues for particular Dell laptops since other old Dell laptops with the same codec configuration are already well handled by the fixup in alc269_fallback_pin_fixup_tbl[].
--- sound/pci/hda/patch_realtek.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
sound/pci/hda/patch_realtek.c +13 -0
@@ -7197,6 +7197,7 @@ enum {ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK ,ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN ,ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS , + ALC236_FIXUP_DELL_DUAL_CODECS, };/* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -9152,6 +9153,12 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, }, + [ALC236_FIXUP_DELL_DUAL_CODECS] = { + .type = HDA_FIXUP_PINS, + .v.func = alc1220_fixup_gb_dual_codecs, + .chained = true, + .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -9254,6 +9261,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {SND_PCI_QUIRK (0x1028 ,0x0b1a ,"Dell Precision 5570" ,ALC289_FIXUP_DUAL_SPK ),SND_PCI_QUIRK (0x1028 ,0x0b37 ,"Dell Inspiron 16 Plus 7620 2-in-1" ,ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS ),SND_PCI_QUIRK (0x1028 ,0x0b71 ,"Dell Inspiron 16 Plus 7620" ,ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS ), +SND_PCI_QUIRK (0x1028 ,0x0c19 ,"Dell Precision 3340" ,ALC236_FIXUP_DELL_DUAL_CODECS ), +SND_PCI_QUIRK (0x1028 ,0x0c1a ,"Dell Precision 3340" ,ALC236_FIXUP_DELL_DUAL_CODECS ), +SND_PCI_QUIRK (0x1028 ,0x0c1b ,"Dell Precision 3440" ,ALC236_FIXUP_DELL_DUAL_CODECS ), +SND_PCI_QUIRK (0x1028 ,0x0c1c ,"Dell Precision 3540" ,ALC236_FIXUP_DELL_DUAL_CODECS ), +SND_PCI_QUIRK (0x1028 ,0x0c1d ,"Dell Precision 3440" ,ALC236_FIXUP_DELL_DUAL_CODECS ), +SND_PCI_QUIRK (0x1028 ,0x0c1e ,"Dell Precision 3540" ,ALC236_FIXUP_DELL_DUAL_CODECS ),SND_PCI_QUIRK (0x1028 ,0x164a ,"Dell" ,ALC293_FIXUP_DELL1_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1028 ,0x164b ,"Dell" ,ALC293_FIXUP_DELL1_MIC_NO_PRESENCE ), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 38/177 fs: dlm: fix sock release if listen fails
In reply to Greg Kroah-HartmanFrom: Alexander Aring <[email protected]>
commit 08ae0547e75ec3d062b6b6b9cf4830c730df68df upstream.
This patch fixes a double sock_release() call when the listen() is called for the dlm lowcomms listen socket. The caller of dlm_listen_for_all should never care about releasing the socket if dlm_listen_for_all() fails, it's done now only once if listen() fails.
--- fs/dlm/lowcomms.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/dlm/lowcomms.c +1 -2
@@ -1820,7 +1820,7 @@ static int dlm_listen_for_all(void) result = sock->ops->listen (sock,5 );if (result <0 ) {dlm_close_sock (&listen_con.sock); - goto out; +return result; }return 0 ;
@@ -2023,7 +2023,6 @@ fail_listen: dlm_proto_ops =NULL ; fail_proto_ops: dlm_allow_conn =0 ; -dlm_close_sock (&listen_con.sock);work_stop (); fail_local:deinit_local ();
Greg Kroah-Hartman
maintainerPATCH 39/177 fs: dlm: retry accept() until -EAGAIN or error returns
In reply to Greg Kroah-HartmanFrom: Alexander Aring <[email protected]>
commit f0f4bb431bd543ed7bebbaea3ce326cfcd5388bc upstream.
This patch fixes a race if we get two times an socket data ready event while the listen connection worker is queued. Currently it will be served only once but we need to do it (in this case twice) until we hit -EAGAIN which tells us there is no pending accept going on.
This patch wraps an do while loop until we receive a return value which is different than 0 as it was done before commit d11ccd451b65 ("fs: dlm:
listen socket out of connection hash").
--- fs/dlm/lowcomms.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/dlm/lowcomms.c +5 -1
@@ -1543,7 +1543,11 @@ static void process_recv_sockets(structstatic void process_listen_recv_socket (struct work_struct *work) { -accept_from_sock (&listen_con); +int ret; + +do { + ret =accept_from_sock (&listen_con); + }while (!ret); }static void dlm_connect (struct connection *con)
Greg Kroah-Hartman
maintainerPATCH 40/177 mptcp: netlink: fix some error return code
In reply to Greg Kroah-HartmanFrom: Wei Yongjun <[email protected]>
commit e0fe1123ab2b07d2cd5475660bd0b4e6993ffaa7 upstream.
Fix to return negative error code -EINVAL from some error handling case instead of 0, as done elsewhere in those functions.
--- net/mptcp/pm_userspace.c | 4 ++++ 1 file changed, 4 insertions(+)
net/mptcp/pm_userspace.c +4 -0
@@ -156,6 +156,7 @@ int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info)if (addr_val.addr.id ==0 || !(addr_val.flags &MPTCP_PM_ADDR_FLAG_SIGNAL )) {GENL_SET_ERR_MSG (info,"invalid addr id or flags" ); + err = -EINVAL ; goto announce_err; }
@@ -282,6 +283,7 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info)if (addr_l.id ==0 ) {NL_SET_ERR_MSG_ATTR (info->extack, laddr,"missing local addr id" ); + err = -EINVAL ; goto create_err; }
@@ -395,11 +397,13 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info)if (addr_l.family != addr_r.family) {GENL_SET_ERR_MSG (info,"address families do not match" ); + err = -EINVAL ; goto destroy_err; }if (!addr_l.port || !addr_r.port) {GENL_SET_ERR_MSG (info,"missing local or remote port" ); + err = -EINVAL ; goto destroy_err; }
Signature · 1 line
2.39.0
Greg Kroah-Hartman
maintainerPATCH 41/177 mptcp: remove MPTCP ifdef in TCP SYN cookies
In reply to Greg Kroah-HartmanFrom: Matthieu Baerts <[email protected]>
commit 3fff88186f047627bb128d65155f42517f8e448f upstream.
To ease the maintenance, it is often recommended to avoid having #ifdef preprocessor conditions.
Here the section related to CONFIG_MPTCP was quite short but the next commit needs to add more code around. It is then cleaner to move specific MPTCP code to functions located in net/mptcp directory.
Now that mptcp_subflow_request_sock_ops structure can be static, it can also be marked as "read only after init".
--- include/net/mptcp.h | 12 ++++++++++-- net/ipv4/syncookies.c | 7 +++---- net/mptcp/subflow.c | 12 +++++++++++- 3 files changed, 24 insertions(+), 7 deletions(-)
include/net/mptcp.h +10 -2
@@ -97,8 +97,6 @@ struct mptcp_out_options { };#ifdef CONFIG_MPTCP -extern struct request_sock_ops mptcp_subflow_request_sock_ops; -void mptcp_init (void );static inline bool sk_is_mptcp (const struct sock *sk)
@@ -188,6 +186,9 @@ void mptcp_seq_show(struct seq_file *seqint mptcp_subflow_init_cookie_req (struct request_sock *req,const struct sock *sk_listener,struct sk_buff *skb); +struct request_sock *mptcp_subflow_reqsk_alloc (const struct request_sock_ops *ops, +struct sock *sk_listener, +bool attach_listener);__be32 mptcp_get_reset_option (const struct sk_buff *skb);
@@ -274,6 +275,13 @@ static inline int mptcp_subflow_init_coo return 0; /* TCP fallback */ } +static inline struct request_sock *mptcp_subflow_reqsk_alloc (const struct request_sock_ops *ops, +struct sock *sk_listener, +bool attach_listener) +{ +return NULL ; +} +static inline __be32 mptcp_reset_option (const struct sk_buff *skb) {return htonl (0u ); }#endif /* CONFIG_MPTCP */
net/ipv4/syncookies.c +3 -4
@@ -288,12 +288,11 @@ struct request_sock *cookie_tcp_reqsk_alstruct tcp_request_sock *treq;struct request_sock *req; -#ifdef CONFIG_MPTCP if (sk_is_mptcp (sk)) - ops = &mptcp_subflow_request_sock_ops; -#endif + req =mptcp_subflow_reqsk_alloc (ops, sk, false); +else + req =inet_reqsk_alloc (ops, sk, false); - req =inet_reqsk_alloc (ops, sk, false);if (!req)return NULL ;
net/mptcp/subflow.c +11 -1
@@ -529,7 +529,7 @@ static int subflow_v6_rebuild_header(str }#endif -struct request_sock_ops mptcp_subflow_request_sock_ops; +static struct request_sock_ops mptcp_subflow_request_sock_ops__ro_after_init ;static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops__ro_after_init ;static int subflow_v4_conn_request (struct sock *sk,struct sk_buff *skb)
@@ -582,6 +582,16 @@ drop: }#endif +struct request_sock *mptcp_subflow_reqsk_alloc (const struct request_sock_ops *ops, +struct sock *sk_listener, +bool attach_listener) +{ + ops = &mptcp_subflow_request_sock_ops; + +return inet_reqsk_alloc (ops, sk_listener, attach_listener); +} +EXPORT_SYMBOL (mptcp_subflow_reqsk_alloc); +/* validate hmac received in third ACK */ static bool subflow_hmac_valid (const struct request_sock *req,const struct mptcp_options_received *mp_opt)
Greg Kroah-Hartman
maintainerPATCH 42/177 mptcp: dedicated request sock for subflow in v6
In reply to Greg Kroah-HartmanFrom: Matthieu Baerts <[email protected]>
commit 34b21d1ddc8ace77a8fa35c1b1e06377209e0dae upstream.
tcp_request_sock_ops structure is specific to IPv4. It should then not be used with MPTCP subflows on top of IPv6.
For example, it contains the 'family' field, initialised to AF_INET. This 'family' field is used by TCP FastOpen code to generate the cookie but also by TCP Metrics, SELinux and SYN Cookies. Using the wrong family will not lead to crashes but displaying/using/checking wrong things.
Note that 'send_reset' callback from request_sock_ops structure is used in some error paths. It is then also important to use the correct one for IPv4 or IPv6.
The slab name can also be different in IPv4 and IPv6, it will be used when printing some log messages. The slab pointer will anyway be the same because the object size is the same for both v4 and v6. A BUILD_BUG_ON() has also been added to make sure this size is the same.
--- net/mptcp/subflow.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-)
net/mptcp/subflow.c +26 -8
@@ -529,7 +529,7 @@ static int subflow_v6_rebuild_header(str }#endif -static struct request_sock_ops mptcp_subflow_request_sock_ops__ro_after_init ; +static struct request_sock_ops mptcp_subflow_v4_request_sock_ops__ro_after_init ;static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops__ro_after_init ;static int subflow_v4_conn_request (struct sock *sk,struct sk_buff *skb)
@@ -542,7 +542,7 @@ static int subflow_v4_conn_request(strucif (skb_rtable (skb)->rt_flags & (RTCF_BROADCAST |RTCF_MULTICAST )) goto drop; -return tcp_conn_request (&mptcp_subflow_request_sock_ops, +return tcp_conn_request (&mptcp_subflow_v4_request_sock_ops, &subflow_request_sock_ipv4_ops, sk, skb); drop:
@@ -551,6 +551,7 @@ drop: }#if IS_ENABLED (CONFIG_MPTCP_IPV6 ) +static struct request_sock_ops mptcp_subflow_v6_request_sock_ops__ro_after_init ;static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops__ro_after_init ;static struct inet_connection_sock_af_ops subflow_v6_specific__ro_after_init ;static struct inet_connection_sock_af_ops subflow_v6m_specific__ro_after_init ;
@@ -573,7 +574,7 @@ static int subflow_v6_conn_request(strucreturn 0 ; } -return tcp_conn_request (&mptcp_subflow_request_sock_ops, +return tcp_conn_request (&mptcp_subflow_v6_request_sock_ops, &subflow_request_sock_ipv6_ops, sk, skb); drop:
@@ -586,7 +587,12 @@ struct request_sock *mptcp_subflow_reqsk struct sock *sk_listener, bool attach_listener) { - ops = &mptcp_subflow_request_sock_ops; +if (ops->family ==AF_INET ) + ops = &mptcp_subflow_v4_request_sock_ops; +#if IS_ENABLED (CONFIG_MPTCP_IPV6 ) + else if (ops->family == AF_INET6) + ops = &mptcp_subflow_v6_request_sock_ops; +#endif return inet_reqsk_alloc (ops, sk_listener, attach_listener); }
@@ -1914,7 +1920,6 @@ static struct tcp_ulp_ops subflow_ulp_opstatic int subflow_ops_init (struct request_sock_ops *subflow_ops) { subflow_ops->obj_size =sizeof (struct mptcp_subflow_request_sock ); - subflow_ops->slab_name ="request_sock_subflow" ; subflow_ops->slab = kmem_cache_create(subflow_ops->slab_name, subflow_ops->obj_size, 0,
@@ -1931,9 +1936,10 @@ static int subflow_ops_init(struct requevoid __init mptcp_subflow_init (void ) { - mptcp_subflow_request_sock_ops = tcp_request_sock_ops; -if (subflow_ops_init (&mptcp_subflow_request_sock_ops) !=0 ) -panic ("MPTCP: failed to init subflow request sock ops\n" ); + mptcp_subflow_v4_request_sock_ops = tcp_request_sock_ops; + mptcp_subflow_v4_request_sock_ops.slab_name ="request_sock_subflow_v4" ; +if (subflow_ops_init (&mptcp_subflow_v4_request_sock_ops) !=0 ) +panic ("MPTCP: failed to init subflow v4 request sock ops\n" ); subflow_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops; subflow_request_sock_ipv4_ops.route_req = subflow_v4_route_req;
@@ -1948,6 +1954,18 @@ void __init mptcp_subflow_init(void) tcp_prot_override.release_cb = tcp_release_cb_override;#if IS_ENABLED (CONFIG_MPTCP_IPV6 ) +/* In struct mptcp_subflow_request_sock, we assume the TCP request sock +* structures for v4 and v6 have the same size. It should not changed in +* the future but better to make sure to be warned if it is no longer +* the case. +*/ +BUILD_BUG_ON (sizeof (struct tcp_request_sock ) !=sizeof (struct tcp6_request_sock )); + + mptcp_subflow_v6_request_sock_ops = tcp6_request_sock_ops; + mptcp_subflow_v6_request_sock_ops.slab_name ="request_sock_subflow_v6" ; +if (subflow_ops_init (&mptcp_subflow_v6_request_sock_ops) !=0 ) +panic ("MPTCP: failed to init subflow v6 request sock ops\n" ); + subflow_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops; subflow_request_sock_ipv6_ops.route_req = subflow_v6_route_req;
Greg Kroah-Hartman
maintainerPATCH 43/177 mptcp: use proper req destructor for IPv6
In reply to Greg Kroah-HartmanFrom: Matthieu Baerts <[email protected]>
commit d3295fee3c756ece33ac0d935e172e68c0a4161b upstream.
Before, only the destructor from TCP request sock in IPv4 was called even if the subflow was IPv6.
It is important to use the right destructor to avoid memory leaks with some advanced IPv6 features, e.g. when the request socks contain specific IPv6 options.
--- net/mptcp/subflow.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
net/mptcp/subflow.c +16 -3
@@ -45,7 +45,6 @@ static void subflow_req_destructor(strucsock_put ((struct sock *)subflow_req->msk);mptcp_token_destroy_request (req); - tcp_request_sock_ops.destructor (req); } static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
@@ -550,6 +549,12 @@ drop:return 0 ; } +static void subflow_v4_req_destructor (struct request_sock *req) +{ +subflow_req_destructor (req); + tcp_request_sock_ops.destructor (req); +} +#if IS_ENABLED (CONFIG_MPTCP_IPV6 )static struct request_sock_ops mptcp_subflow_v6_request_sock_ops__ro_after_init ;static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops__ro_after_init ;
@@ -581,6 +586,12 @@ drop:tcp_listendrop (sk);return 0 ;/* don't send reset */ } + +static void subflow_v6_req_destructor (struct request_sock *req) +{ +subflow_req_destructor (req); + tcp6_request_sock_ops.destructor (req); +}#endif struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
@@ -1929,8 +1940,6 @@ static int subflow_ops_init(struct requeif (!subflow_ops->slab)return -ENOMEM ; - subflow_ops->destructor = subflow_req_destructor; -return 0 ; }
@@ -1938,6 +1947,8 @@ void __init mptcp_subflow_init(void) { mptcp_subflow_v4_request_sock_ops = tcp_request_sock_ops; mptcp_subflow_v4_request_sock_ops.slab_name ="request_sock_subflow_v4" ; + mptcp_subflow_v4_request_sock_ops.destructor = subflow_v4_req_destructor; +if (subflow_ops_init (&mptcp_subflow_v4_request_sock_ops) !=0 )panic ("MPTCP: failed to init subflow v4 request sock ops\n" );
@@ -1963,6 +1974,8 @@ void __init mptcp_subflow_init(void) mptcp_subflow_v6_request_sock_ops = tcp6_request_sock_ops; mptcp_subflow_v6_request_sock_ops.slab_name ="request_sock_subflow_v6" ; + mptcp_subflow_v6_request_sock_ops.destructor = subflow_v6_req_destructor; +if (subflow_ops_init (&mptcp_subflow_v6_request_sock_ops) !=0 )panic ("MPTCP: failed to init subflow v6 request sock ops\n" );
Greg Kroah-Hartman
maintainerPATCH 44/177 dm cache: Fix ABBA deadlock between shrink_slab and dm_cache_metadata_abort
In reply to Greg Kroah-HartmanFrom: Mike Snitzer <[email protected]>
commit 352b837a5541690d4f843819028cf2b8be83d424 upstream.
Same ABBA deadlock pattern fixed in commit 4b60f452ec51 ("dm thin: Fix ABBA deadlock between shrink_slab and dm_pool_abort_metadata") to DM-cache's metadata.
--- drivers/md/dm-cache-metadata.c | 54 +++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-)
drivers/md/dm-cache-metadata.c +47 -7
@@ -551,11 +551,13 @@ static int __create_persistent_data_objereturn r; } -static void __destroy_persistent_data_objects (struct dm_cache_metadata *cmd) +static void __destroy_persistent_data_objects (struct dm_cache_metadata *cmd, +bool destroy_bm) {dm_sm_destroy (cmd->metadata_sm);dm_tm_destroy (cmd->tm); -dm_block_manager_destroy (cmd->bm); +if (destroy_bm) +dm_block_manager_destroy (cmd->bm); }typedef unsigned long (*flags_mutator )(unsigned long );
@@ -826,7 +828,7 @@ static struct dm_cache_metadata *lookup_ cmd2 =lookup (bdev);if (cmd2) {mutex_unlock (&table_lock); -__destroy_persistent_data_objects (cmd); +__destroy_persistent_data_objects (cmd, true);kfree (cmd);return cmd2; }
@@ -874,7 +876,7 @@ void dm_cache_metadata_close(struct dm_cmutex_unlock (&table_lock);if (!cmd->fail_io) -__destroy_persistent_data_objects (cmd); +__destroy_persistent_data_objects (cmd, true);kfree (cmd); } }
@@ -1807,14 +1809,52 @@ int dm_cache_metadata_needs_check(structint dm_cache_metadata_abort (struct dm_cache_metadata *cmd) { -int r; +int r = -EINVAL ; +struct dm_block_manager *old_bm =NULL , *new_bm =NULL ; + +/* fail_io is double-checked with cmd->root_lock held below */ +if (unlikely (cmd->fail_io)) +return r; + +/* +* Replacement block manager (new_bm) is created and old_bm destroyed outside of +* cmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of +* shrinker associated with the block manager's bufio client vs cmd root_lock). +* - must take shrinker_rwsem without holding cmd->root_lock +*/ + new_bm =dm_block_manager_create (cmd->bdev,DM_CACHE_METADATA_BLOCK_SIZE <<SECTOR_SHIFT , +CACHE_MAX_CONCURRENT_LOCKS );WRITE_LOCK (cmd); -__destroy_persistent_data_objects (cmd); - r =__create_persistent_data_objects (cmd, false); +if (cmd->fail_io) { +WRITE_UNLOCK (cmd); + goto out; + } + +__destroy_persistent_data_objects (cmd, false); + old_bm = cmd->bm; +if (IS_ERR (new_bm)) { +DMERR ("could not create block manager during abort" ); + cmd->bm =NULL ; + r =PTR_ERR (new_bm); + goto out_unlock; + } + + cmd->bm = new_bm; + r =__open_or_format_metadata (cmd, false); +if (r) { + cmd->bm =NULL ; + goto out_unlock; + } + new_bm =NULL ; +out_unlock:if (r) cmd->fail_io = true;WRITE_UNLOCK (cmd); +dm_block_manager_destroy (old_bm); +out: +if (new_bm && !IS_ERR (new_bm)) +dm_block_manager_destroy (new_bm);return r; }
Greg Kroah-Hartman
maintainerPATCH 45/177 dm thin: Fix ABBA deadlock between shrink_slab and dm_pool_abort_metadata
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
commit 8111964f1b8524c4bb56b02cd9c7a37725ea21fd upstream.
Following concurrent processes:
P1(drop cache) P2(kworker)drop_caches_sysctl_handler
drop_slab
shrink_slab
down_read(&shrinker_rwsem) - LOCK A
do_shrink_slab
super_cache_scan
prune_icache_sb
dispose_list
evict
ext4_evict_inode
ext4_clear_inode
ext4_discard_preallocations
ext4_mb_load_buddy_gfp
ext4_mb_init_cache
ext4_read_block_bitmap_nowait
ext4_read_bh_nowait
submit_bh
dm_submit_bio
do_worker
process_deferred_bios
commit
metadata_operation_failed
dm_pool_abort_metadata
down_write(&pmd->root_lock) - LOCK B
__destroy_persistent_data_objects
dm_block_manager_destroy
dm_bufio_client_destroy
unregister_shrinker
down_write(&shrinker_rwsem)
thin_map |
dm_thin_find_block ↓
down_read(&pmd->root_lock) --> ABBA deadlock, which triggers hung task:
[ 76.974820] INFO: task kworker/u4:3:63 blocked for more than 15 seconds. [ 76.976019] Not tainted 6.1.0-rc4-00011-g8f17dd350364-dirty #910 [ 76.978521] task:kworker/u4:3 state:D stack:0 pid:63 ppid:2 [ 76.978534] Workqueue: dm-thin do_worker [ 76.978552] Call Trace: [ 76.978564] __schedule+0x6ba/0x10f0 [ 76.978582] schedule+0x9d/0x1e0 [ 76.978588] rwsem_down_write_slowpath+0x587/0xdf0 [ 76.978600] down_write+0xec/0x110 [ 76.978607] unregister_shrinker+0x2c/0xf0 [ 76.978616] dm_bufio_client_destroy+0x116/0x3d0 [ 76.978625] dm_block_manager_destroy+0x19/0x40 [ 76.978629] __destroy_persistent_data_objects+0x5e/0x70 [ 76.978636] dm_pool_abort_metadata+0x8e/0x100 [ 76.978643] metadata_operation_failed+0x86/0x110 [ 76.978649] commit+0x6a/0x230 [ 76.978655] do_worker+0xc6e/0xd90 [ 76.978702] process_one_work+0x269/0x630 [ 76.978714] worker_thread+0x266/0x630 [ 76.978730] kthread+0x151/0x1b0 [ 76.978772] INFO: task test.sh:2646 blocked for more than 15 seconds. [ 76.979756] Not tainted 6.1.0-rc4-00011-g8f17dd350364-dirty #910 [ 76.982111] task:test.sh state:D stack:0 pid:2646 ppid:2459 [ 76.982128] Call Trace: [ 76.982139] __schedule+0x6ba/0x10f0 [ 76.982155] schedule+0x9d/0x1e0 [ 76.982159] rwsem_down_read_slowpath+0x4f4/0x910 [ 76.982173] down_read+0x84/0x170 [ 76.982177] dm_thin_find_block+0x4c/0xd0 [ 76.982183] thin_map+0x201/0x3d0 [ 76.982188] __map_bio+0x5b/0x350 [ 76.982195] dm_submit_bio+0x2b6/0x930 [ 76.982202] __submit_bio+0x123/0x2d0 [ 76.982209] submit_bio_noacct_nocheck+0x101/0x3e0 [ 76.982222] submit_bio_noacct+0x389/0x770 [ 76.982227] submit_bio+0x50/0xc0 [ 76.982232] submit_bh_wbc+0x15e/0x230 [ 76.982238] submit_bh+0x14/0x20 [ 76.982241] ext4_read_bh_nowait+0xc5/0x130 [ 76.982247] ext4_read_block_bitmap_nowait+0x340/0xc60 [ 76.982254] ext4_mb_init_cache+0x1ce/0xdc0 [ 76.982259] ext4_mb_load_buddy_gfp+0x987/0xfa0 [ 76.982263] ext4_discard_preallocations+0x45d/0x830 [ 76.982274] ext4_clear_inode+0x48/0xf0 [ 76.982280] ext4_evict_inode+0xcf/0xc70 [ 76.982285] evict+0x119/0x2b0 [ 76.982290] dispose_list+0x43/0xa0 [ 76.982294] prune_icache_sb+0x64/0x90 [ 76.982298] super_cache_scan+0x155/0x210 [ 76.982303] do_shrink_slab+0x19e/0x4e0 [ 76.982310] shrink_slab+0x2bd/0x450 [ 76.982317] drop_slab+0xcc/0x1a0 [ 76.982323] drop_caches_sysctl_handler+0xb7/0xe0 [ 76.982327] proc_sys_call_handler+0x1bc/0x300 [ 76.982331] proc_sys_write+0x17/0x20 [ 76.982334] vfs_write+0x3d3/0x570 [ 76.982342] ksys_write+0x73/0x160 [ 76.982347] __x64_sys_write+0x1e/0x30 [ 76.982352] do_syscall_64+0x35/0x80 [ 76.982357] entry_SYSCALL_64_after_hwframe+0x63/0xcd
Function metadata_operation_failed() is called when operations failed on dm pool metadata, dm pool will destroy and recreate metadata. So, shrinker will be unregistered and registered, which could down write shrinker_rwsem under pmd_write_lock.
Fix it by allocating dm_block_manager before locking pmd->root_lock and destroying old dm_block_manager after unlocking pmd->root_lock, then old dm_block_manager is replaced with new dm_block_manager under pmd->root_lock. So, shrinker register/unregister could be done without holding pmd->root_lock.
Fetch a reproducer in [Link].
--- drivers/md/dm-thin-metadata.c | 51 +++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 8 deletions(-)
drivers/md/dm-thin-metadata.c +43 -8
@@ -776,13 +776,15 @@ static int __create_persistent_data_objereturn r; } -static void __destroy_persistent_data_objects (struct dm_pool_metadata *pmd) +static void __destroy_persistent_data_objects (struct dm_pool_metadata *pmd, +bool destroy_bm) {dm_sm_destroy (pmd->data_sm);dm_sm_destroy (pmd->metadata_sm);dm_tm_destroy (pmd->nb_tm);dm_tm_destroy (pmd->tm); -dm_block_manager_destroy (pmd->bm); +if (destroy_bm) +dm_block_manager_destroy (pmd->bm); }static int __begin_transaction (struct dm_pool_metadata *pmd)
@@ -989,7 +991,7 @@ int dm_pool_metadata_close(struct dm_poo }pmd_write_unlock (pmd);if (!pmd->fail_io) -__destroy_persistent_data_objects (pmd); +__destroy_persistent_data_objects (pmd, true);kfree (pmd);return 0 ;
@@ -1860,19 +1862,52 @@ static void __set_abort_with_changes_flaint dm_pool_abort_metadata (struct dm_pool_metadata *pmd) {int r = -EINVAL ; +struct dm_block_manager *old_bm =NULL , *new_bm =NULL ; + +/* fail_io is double-checked with pmd->root_lock held below */ +if (unlikely (pmd->fail_io)) +return r; + +/* +* Replacement block manager (new_bm) is created and old_bm destroyed outside of +* pmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of +* shrinker associated with the block manager's bufio client vs pmd root_lock). +* - must take shrinker_rwsem without holding pmd->root_lock +*/ + new_bm =dm_block_manager_create (pmd->bdev,THIN_METADATA_BLOCK_SIZE <<SECTOR_SHIFT , +THIN_MAX_CONCURRENT_LOCKS );pmd_write_lock (pmd); -if (pmd->fail_io) +if (pmd->fail_io) { +pmd_write_unlock (pmd); goto out; + }__set_abort_with_changes_flags (pmd); -__destroy_persistent_data_objects (pmd); - r =__create_persistent_data_objects (pmd, false); +__destroy_persistent_data_objects (pmd, false); + old_bm = pmd->bm; +if (IS_ERR (new_bm)) { +DMERR ("could not create block manager during abort" ); + pmd->bm =NULL ; + r =PTR_ERR (new_bm); + goto out_unlock; + } + + pmd->bm = new_bm; + r =__open_or_format_metadata (pmd, false); +if (r) { + pmd->bm =NULL ; + goto out_unlock; + } + new_bm =NULL ; +out_unlock:if (r) pmd->fail_io = true; - -out:pmd_write_unlock (pmd); +dm_block_manager_destroy (old_bm); +out: +if (new_bm && !IS_ERR (new_bm)) +dm_block_manager_destroy (new_bm);return r; }
Greg Kroah-Hartman
maintainerPATCH 46/177 dm thin: Use last transactions pmd->root when commit failed
In reply to Greg Kroah-HartmanFrom: Zhihao Cheng <[email protected]>
commit 7991dbff6849f67e823b7cc0c15e5a90b0549b9f upstream.
Recently we found a softlock up problem in dm thin pool btree lookup code due to corrupted metadata:
Kernel panic - not syncing: softlockup: hung tasks CPU: 7 PID: 2669225 Comm: kworker/u16:3 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) Workqueue: dm-thin do_worker [dm_thin_pool] Call Trace: <IRQ> dump_stack+0x9c/0xd3 panic+0x35d/0x6b9 watchdog_timer_fn.cold+0x16/0x25 __run_hrtimer+0xa2/0x2d0 </IRQ> RIP: 0010:__relink_lru+0x102/0x220 [dm_bufio] __bufio_new+0x11f/0x4f0 [dm_bufio] new_read+0xa3/0x1e0 [dm_bufio] dm_bm_read_lock+0x33/0xd0 [dm_persistent_data] ro_step+0x63/0x100 [dm_persistent_data] btree_lookup_raw.constprop.0+0x44/0x220 [dm_persistent_data] dm_btree_lookup+0x16f/0x210 [dm_persistent_data] dm_thin_find_block+0x12c/0x210 [dm_thin_pool] __process_bio_read_only+0xc5/0x400 [dm_thin_pool] process_thin_deferred_bios+0x1a4/0x4a0 [dm_thin_pool] process_one_work+0x3c5/0x730
Following process may generate a broken btree mixed with fresh and stale btree nodes, which could get dm thin trapped in an infinite loop while looking up data block:
Transaction 1: pmd->root = A, A->B->C // One path in btree
pmd->root = X, X->Y->Z // Copy-up
Transaction 2: X,Z is updated on disk, Y write failed.
// Commit failed, dm thin becomes read-only.
process_bio_read_only
dm_thin_find_block
__find_block
dm_btree_lookup(pmd->root)The pmd->root points to a broken btree, Y may contain stale node pointing to any block, for example X, which gets dm thin trapped into a dead loop while looking up Z.
Fix this by setting pmd->root in __open_metadata(), so that dm thin will use the last transaction's pmd->root if commit failed.
Fetch a reproducer in [Link].
Linke: https://bugzilla.kernel.org/show_bug.cgi?id=216790
--- drivers/md/dm-thin-metadata.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/md/dm-thin-metadata.c +9 -0
@@ -724,6 +724,15 @@ static int __open_metadata(struct dm_poo goto bad_cleanup_data_sm; } +/* +* For pool metadata opening process, root setting is redundant +* because it will be set again in __begin_transaction(). But dm +* pool aborting process really needs to get last transaction's +* root to avoid accessing broken btree. +*/ + pmd->root =le64_to_cpu (disk_super->data_mapping_root); + pmd->details_root =le64_to_cpu (disk_super->device_details_root); +__setup_btree_details (pmd);dm_bm_unlock (sblock);
Greg Kroah-Hartman
maintainerPATCH 47/177 dm thin: resume even if in FAIL mode
In reply to Greg Kroah-HartmanFrom: Luo Meng <[email protected]>
commit 19eb1650afeb1aa86151f61900e9e5f1de5d8d02 upstream.
If a thinpool set fail_io while suspending, resume will fail with:
device-mapper: resume ioctl on vg-thinpool failed: Invalid argument
The thin-pool also can't be removed if an in-flight bio is in the deferred list.
This can be easily reproduced using:
echo "offline" > /sys/block/sda/device/state dd if=/dev/zero of=/dev/mapper/thin bs=4K count=1 dmsetup suspend /dev/mapper/pool mkfs.ext4 /dev/mapper/thin
dmsetup resume /dev/mapper/pool
The root cause is maybe_resize_data_dev() will check fail_io and return error before called dm_resume.
Fix this by adding FAIL mode check at the end of pool_preresume().
--- drivers/md/dm-thin.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/md/dm-thin.c +12 -4
@@ -3540,20 +3540,28 @@ static int pool_preresume(struct dm_targ*/ r =bind_control_target (pool, ti);if (r) -return r; + goto out; r =maybe_resize_data_dev (ti, &need_commit1);if (r) -return r; + goto out; r =maybe_resize_metadata_dev (ti, &need_commit2);if (r) -return r; + goto out;if (need_commit1 || need_commit2) (void )commit (pool); +out: +/* +* When a thin-pool is PM_FAIL, it cannot be rebuilt if +* bio is in deferred list. Therefore need to return 0 +* to allow pool_resume() to flush IO. +*/ +if (r &&get_pool_mode (pool) ==PM_FAIL ) + r =0 ; -return 0 ; +return r; }static void pool_suspend_active_thins (struct pool *pool)
Greg Kroah-Hartman
maintainerPATCH 48/177 dm thin: Fix UAF in run_timer_softirq()
In reply to Greg Kroah-HartmanFrom: Luo Meng <[email protected]>
commit 88430ebcbc0ec637b710b947738839848c20feff upstream.
When dm_resume() and dm_destroy() are concurrent, it will lead to UAF, as follows:
BUG: KASAN: use-after-free in __run_timers+0x173/0x710 Write of size 8 at addr ffff88816d9490f0 by task swapper/0/0 <snip> Call Trace: <IRQ> dump_stack_lvl+0x73/0x9f print_report.cold+0x132/0xaa2 _raw_spin_lock_irqsave+0xcd/0x160 __run_timers+0x173/0x710 kasan_report+0xad/0x110 __run_timers+0x173/0x710 __asan_store8+0x9c/0x140 __run_timers+0x173/0x710 call_timer_fn+0x310/0x310 pvclock_clocksource_read+0xfa/0x250 kvm_clock_read+0x2c/0x70 kvm_clock_get_cycles+0xd/0x20 ktime_get+0x5c/0x110 lapic_next_event+0x38/0x50 clockevents_program_event+0xf1/0x1e0 run_timer_softirq+0x49/0x90 __do_softirq+0x16e/0x62c __irq_exit_rcu+0x1fa/0x270 irq_exit_rcu+0x12/0x20 sysvec_apic_timer_interrupt+0x8e/0xc0
One of the concurrency UAF can be shown as below:
use free
do_resume |
__find_device_hash_cell |
dm_get |
atomic_inc(&md->holders) |
| dm_destroy
| __dm_destroy
| if (!dm_suspended_md(md))
| atomic_read(&md->holders)
| msleep(1)
dm_resume |
__dm_resume |
dm_table_resume_targets |
pool_resume |
do_waker #add delay work |
dm_put |
atomic_dec(&md->holders) |
| dm_table_destroy
| pool_dtr
| __pool_dec
| __pool_destroy
| destroy_workqueue
| kfree(pool) # free pool time out__do_softirq
run_timer_softirq # pool has already been freed
This can be easily reproduced using:
1. create thin-pool
2. dmsetup suspend pool
3. dmsetup resume pool
4. dmsetup remove_all # Concurrent with 3
The root cause of this UAF bug is that dm_resume() adds timer after dm_destroy() skips cancelling the timer because of suspend status. After timeout, it will call run_timer_softirq(), however pool has already been freed. The concurrency UAF bug will happen.
Therefore, cancelling timer again in __pool_destroy().
--- drivers/md/dm-thin.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/md/dm-thin.c +2 -0
@@ -2889,6 +2889,8 @@ static void __pool_destroy(struct pool *dm_bio_prison_destroy (pool->prison);dm_kcopyd_client_destroy (pool->copier); +cancel_delayed_work_sync (&pool->waker); +cancel_delayed_work_sync (&pool->no_space_timeout);if (pool->wq)destroy_workqueue (pool->wq);
Greg Kroah-Hartman
maintainerPATCH 49/177 dm integrity: Fix UAF in dm_integrity_dtr()
In reply to Greg Kroah-HartmanFrom: Luo Meng <[email protected]>
commit f50cb2cbabd6c4a60add93d72451728f86e4791c upstream.
Dm_integrity also has the same UAF problem when dm_resume() and dm_destroy() are concurrent.
Therefore, cancelling timer again in dm_integrity_dtr().
--- drivers/md/dm-integrity.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/md/dm-integrity.c +2 -0
@@ -4558,6 +4558,8 @@ static void dm_integrity_dtr(struct dm_tBUG_ON (!RB_EMPTY_ROOT (&ic->in_progress));BUG_ON (!list_empty (&ic->wait_list)); +if (ic->mode =='B' ) +cancel_delayed_work_sync (&ic->bitmap_flush_work);if (ic->metadata_wq)destroy_workqueue (ic->metadata_wq);if (ic->wait_wq)
Greg Kroah-Hartman
maintainerPATCH 50/177 dm clone: Fix UAF in clone_dtr()
In reply to Greg Kroah-HartmanFrom: Luo Meng <[email protected]>
commit e4b5957c6f749a501c464f92792f1c8e26b61a94 upstream.
Dm_clone also has the same UAF problem when dm_resume() and dm_destroy() are concurrent.
Therefore, cancelling timer again in clone_dtr().
--- drivers/md/dm-clone-target.c | 1 + 1 file changed, 1 insertion(+)
drivers/md/dm-clone-target.c +1 -0
@@ -1958,6 +1958,7 @@ static void clone_dtr(struct dm_target *mempool_exit (&clone->hydration_pool);dm_kcopyd_client_destroy (clone->kcopyd_client); +cancel_delayed_work_sync (&clone->waker);destroy_workqueue (clone->wq);hash_table_exit (clone);dm_clone_metadata_close (clone->cmd);
Greg Kroah-Hartman
maintainerPATCH 51/177 dm cache: Fix UAF in destroy()
In reply to Greg Kroah-HartmanFrom: Luo Meng <[email protected]>
commit 6a459d8edbdbe7b24db42a5a9f21e6aa9e00c2aa upstream.
Dm_cache also has the same UAF problem when dm_resume() and dm_destroy() are concurrent.
Therefore, cancelling timer again in destroy().
--- drivers/md/dm-cache-target.c | 1 + 1 file changed, 1 insertion(+)
drivers/md/dm-cache-target.c +1 -0
@@ -1887,6 +1887,7 @@ static void destroy(struct cache *cache)if (cache->prison)dm_bio_prison_destroy_v2 (cache->prison); +cancel_delayed_work_sync (&cache->waker);if (cache->wq)destroy_workqueue (cache->wq);
Greg Kroah-Hartman
maintainerPATCH 52/177 dm cache: set needs_check flag after aborting metadata
In reply to Greg Kroah-HartmanFrom: Mike Snitzer <[email protected]>
commit 6b9973861cb2e96dcd0bb0f1baddc5c034207c5c upstream.
Otherwise the commit that will be aborted will be associated with the metadata objects that will be torn down. Must write needs_check flag to metadata with a reset block manager.
Found through code-inspection (and compared against dm-thin.c).
--- drivers/md/dm-cache-target.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/md/dm-cache-target.c +5 -5
@@ -907,16 +907,16 @@ static void abort_transaction(struct cacif (get_cache_mode (cache) >=CM_READ_ONLY )return ; -if (dm_cache_metadata_set_needs_check (cache->cmd)) { -DMERR ("%s: failed to set 'needs_check' flag in metadata" , dev_name); -set_cache_mode (cache,CM_FAIL ); - } -DMERR_LIMIT ("%s: aborting current metadata transaction" , dev_name);if (dm_cache_metadata_abort (cache->cmd)) {DMERR ("%s: failed to abort metadata transaction" , dev_name);set_cache_mode (cache,CM_FAIL ); } + +if (dm_cache_metadata_set_needs_check (cache->cmd)) { +DMERR ("%s: failed to set 'needs_check' flag in metadata" , dev_name); +set_cache_mode (cache,CM_FAIL ); + } }static void metadata_operation_failed (struct cache *cache,const char *op,int r)
Greg Kroah-Hartman
maintainerPATCH 53/177 PCI/DOE: Fix maximum data object length miscalculation
In reply to Greg Kroah-HartmanFrom: Li Ming <[email protected]>
commit a4ff8e7a71601321f7bf7b58ede664dc0d774274 upstream.
Per PCIe r6.0, sec 6.30.1, a data object Length of 0x0 indicates 2^18 DWORDs (256K DW or 1MB) being transferred. Adjust the value of data object length for this case on both sending side and receiving side.
Don't bother checking whether Length is greater than SZ_1M because all values of the 18-bit Length field are valid, and it is impossible to represent anything larger than SZ_1M:
0x00000 256K DW (1M bytes)
0x00001 1 DW (4 bytes)
...
0x3ffff 256K-1 DW (1M - 4 bytes)
--- drivers/pci/doe.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
drivers/pci/doe.c +16 -4
@@ -29,6 +29,9 @@#define PCI_DOE_FLAG_CANCEL 0#define PCI_DOE_FLAG_DEAD 1 +/* Max data object length is 2^18 dwords */ +#define PCI_DOE_MAX_LENGTH (1 << 18) +/** * struct pci_doe_mb - State for a single DOE mailbox *
@@ -107,6 +110,7 @@ static int pci_doe_send_req(struct pci_d {struct pci_dev *pdev = doe_mb->pdev;int offset = doe_mb->cap_offset; +size_t length;u32 val;int i;
@@ -123,15 +127,20 @@ static int pci_doe_send_req(struct pci_dif (FIELD_GET (PCI_DOE_STATUS_ERROR , val))return -EIO ; +/* Length is 2 DW of header + length of payload in DW */ + length =2 + task->request_pl_sz /sizeof (u32); +if (length >PCI_DOE_MAX_LENGTH ) +return -EIO ; +if (length ==PCI_DOE_MAX_LENGTH ) + length =0 ; +/* Write DOE Header */ val =FIELD_PREP (PCI_DOE_DATA_OBJECT_HEADER_1_VID , task->prot.vid) |FIELD_PREP (PCI_DOE_DATA_OBJECT_HEADER_1_TYPE , task->prot.type);pci_write_config_dword (pdev, offset +PCI_DOE_WRITE , val); -/* Length is 2 DW of header + length of payload in DW */ pci_write_config_dword (pdev, offset +PCI_DOE_WRITE ,FIELD_PREP (PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH , -2 + task->request_pl_sz / -sizeof (u32))); + length));for (i =0 ; i < task->request_pl_sz /sizeof (u32); i++)pci_write_config_dword (pdev, offset +PCI_DOE_WRITE , task->request_pl[i]);
@@ -178,7 +187,10 @@ static int pci_doe_recv_resp(struct pci_pci_write_config_dword (pdev, offset +PCI_DOE_READ ,0 ); length =FIELD_GET (PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH , val); -if (length >SZ_1M || length <2 ) +/* A value of 0x0 indicates max data object length */ +if (!length) + length =PCI_DOE_MAX_LENGTH ; +if (length <2 )return -EIO ;/* First 2 dwords have already been read */
Greg Kroah-Hartman
maintainerPATCH 54/177 tracing/hist: Fix out-of-bound write on action_data.var_ref_idx
In reply to Greg Kroah-HartmanFrom: Zheng Yejian <[email protected]>
commit 82470f7d9044842618c847a7166de2b7458157a7 upstream.
When generate a synthetic event with many params and then create a trace action for it [1], kernel panic happened [2].
It is because that in trace_action_create() 'data->n_params' is up to SYNTH_FIELDS_MAX (current value is 64), and array 'data->var_ref_idx' keeps indices into array 'hist_data->var_refs' for each synthetic event param, but the length of 'data->var_ref_idx' is TRACING_MAP_VARS_MAX (current value is 16), so out-of-bound write happened when 'data->n_params' more than 16. In this case, 'data->match_data.event' is overwritten and eventually cause the panic.
To solve the issue, adjust the length of 'data->var_ref_idx' to be SYNTH_FIELDS_MAX and add sanity checks to avoid out-of-bound write.
[1]
# cd /sys/kernel/tracing/ # echo "my_synth_event int v1; int v2; int v3; int v4; int v5; int v6;\ int v7; int v8; int v9; int v10; int v11; int v12; int v13; int v14;\ int v15; int v16; int v17; int v18; int v19; int v20; int v21; int v22;\ int v23; int v24; int v25; int v26; int v27; int v28; int v29; int v30;\ int v31; int v32; int v33; int v34; int v35; int v36; int v37; int v38;\ int v39; int v40; int v41; int v42; int v43; int v44; int v45; int v46;\ int v47; int v48; int v49; int v50; int v51; int v52; int v53; int v54;\ int v55; int v56; int v57; int v58; int v59; int v60; int v61; int v62;\ int v63" >> synthetic_events # echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="bash"' >> \ events/sched/sched_waking/trigger # echo "hist:keys=next_pid:onmatch(sched.sched_waking).my_synth_event(\ pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,\ pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,\ pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,\ pid,pid,pid,pid,pid,pid,pid,pid,pid)" >> events/sched/sched_switch/trigger
[2]
BUG: unable to handle page fault for address: ffff91c900000000 PGD 61001067 P4D 61001067 PUD 0 Oops: 0000 [#1] PREEMPT SMP NOPTI CPU: 2 PID: 322 Comm: bash Tainted: G W 6.1.0-rc8+ #229 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 RIP: 0010:strcmp+0xc/0x30 Code: 75 f7 31 d2 44 0f b6 04 16 44 88 04 11 48 83 c2 01 45 84 c0 75 ee c3 cc cc cc cc 0f 1f 00 31 c0 eb 08 48 83 c0 01 84 d2 74 13 <0f> b6 14 07 3a 14 06 74 ef 19 c0 83 c8 01 c3 cc cc cc cc 31 c3 RSP: 0018:ffff9b3b00f53c48 EFLAGS: 00000246 RAX: 0000000000000000 RBX: ffffffffba958a68 RCX: 0000000000000000 RDX: 0000000000000010 RSI: ffff91c943d33a90 RDI: ffff91c900000000 RBP: ffff91c900000000 R08: 00000018d604b529 R09: 0000000000000000 R10: ffff91c9483eddb1 R11: ffff91ca483eddab R12: ffff91c946171580 R13: ffff91c9479f0538 R14: ffff91c9457c2848 R15: ffff91c9479f0538 FS: 00007f1d1cfbe740(0000) GS:ffff91c9bdc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffff91c900000000 CR3: 0000000006316000 CR4: 00000000000006e0 Call Trace: <TASK> __find_event_file+0x55/0x90 action_create+0x76c/0x1060 event_hist_trigger_parse+0x146d/0x2060 ? event_trigger_write+0x31/0xd0 trigger_process_regex+0xbb/0x110 event_trigger_write+0x6b/0xd0 vfs_write+0xc8/0x3e0 ? alloc_fd+0xc0/0x160 ? preempt_count_add+0x4d/0xa0 ? preempt_count_add+0x70/0xa0 ksys_write+0x5f/0xe0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f1d1d0cf077 Code: 64 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 00 00 00 00 f3 0f 1e
fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 48 89 54 24 18 48 89 74
RSP: 002b:00007ffcebb0e568 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000000000000143 RCX: 00007f1d1d0cf077
RDX: 0000000000000143 RSI: 00005639265aa7e0 RDI: 0000000000000001
RBP: 00005639265aa7e0 R08: 000000000000000a R09: 0000000000000142
R10: 000056392639c017 R11: 0000000000000246 R12: 0000000000000143
R13: 00007f1d1d1ae6a0 R14: 00007f1d1d1aa4a0 R15: 00007f1d1d1a98a0
</TASK> Modules linked in: CR2: ffff91c900000000 ---[ end trace 0000000000000000 ]--- RIP: 0010:strcmp+0xc/0x30 Code: 75 f7 31 d2 44 0f b6 04 16 44 88 04 11 48 83 c2 01 45 84 c0 75 ee c3 cc cc cc cc 0f 1f 00 31 c0 eb 08 48 83 c0 01 84 d2 74 13 <0f> b6 14 07 3a 14 06 74 ef 19 c0 83 c8 01 c3 cc cc cc cc 31 c3 RSP: 0018:ffff9b3b00f53c48 EFLAGS: 00000246 RAX: 0000000000000000 RBX: ffffffffba958a68 RCX: 0000000000000000 RDX: 0000000000000010 RSI: ffff91c943d33a90 RDI: ffff91c900000000 RBP: ffff91c900000000 R08: 00000018d604b529 R09: 0000000000000000 R10: ffff91c9483eddb1 R11: ffff91ca483eddab R12: ffff91c946171580 R13: ffff91c9479f0538 R14: ffff91c9457c2848 R15: ffff91c9479f0538 FS: 00007f1d1cfbe740(0000) GS:ffff91c9bdc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffff91c900000000 CR3: 0000000006316000 CR4: 00000000000006e0
--- kernel/trace/trace_events_hist.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
kernel/trace/trace_events_hist.c +8 -2
@@ -588,7 +588,7 @@ struct action_data {* event param, and is passed to the synthetic event * invocation. */ -unsigned int var_ref_idx[TRACING_MAP_VARS_MAX ]; +unsigned int var_ref_idx[SYNTH_FIELDS_MAX ];struct synth_event *synth_event;bool use_trace_keyword;char *synth_event_name;
@@ -2150,7 +2150,9 @@ static struct hist_field *create_var_refreturn ref_field; } } - +/* Sanity check to avoid out-of-bound write on 'hist_data->var_refs' */ +if (hist_data->n_var_refs >=TRACING_MAP_VARS_MAX ) +return NULL ; ref_field =create_hist_field (var_field->hist_data,NULL , flags,NULL );if (ref_field) {if (init_var_ref (ref_field, var_field, system, event_name)) {
@@ -3898,6 +3900,10 @@ static int trace_action_create(struct hilockdep_assert_held (&event_mutex); +/* Sanity check to avoid out-of-bound write on 'data->var_ref_idx' */ +if (data->n_params >SYNTH_FIELDS_MAX ) +return -EINVAL ; +if (data->use_trace_keyword) synth_event_name = data->synth_event_name;else
Greg Kroah-Hartman
maintainerPATCH 55/177 perf/core: Call LSM hook after copying perf_event_attr
In reply to Greg Kroah-HartmanFrom: Namhyung Kim <[email protected]>
commit 0a041ebca4956292cadfb14a63ace3a9c1dcb0a3 upstream.
It passes the attr struct to the security_perf_event_open() but it's not initialized yet.
--- kernel/events/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/events/core.c +3 -3
@@ -12176,12 +12176,12 @@ SYSCALL_DEFINE5(perf_event_open,if (flags & ~PERF_FLAG_ALL )return -EINVAL ; -/* Do we allow access to perf_event_open(2) ? */ - err =security_perf_event_open (&attr,PERF_SECURITY_OPEN ); + err =perf_copy_attr (attr_uptr, &attr);if (err)return err; - err =perf_copy_attr (attr_uptr, &attr); +/* Do we allow access to perf_event_open(2) ? */ + err =security_perf_event_open (&attr,PERF_SECURITY_OPEN );if (err)return err;
Greg Kroah-Hartman
maintainerPATCH 56/177 xtensa: add __umulsidi3 helper
In reply to Greg Kroah-HartmanFrom: Max Filippov <[email protected]>
commit 8939c58d68f97ce530f02d46c9f2b56c3ec88399 upstream.
xtensa gcc-13 has changed multiplication handling and may now use __umulsidi3 helper where it used to use __muldi3. As a result building the kernel with the new gcc may fail with the following error:
linux/init/main.c:1287: undefined reference to `__umulsidi3'
Fix the build by providing __umulsidi3 implementation for xtensa.
--- arch/xtensa/kernel/xtensa_ksyms.c | 2 + arch/xtensa/lib/Makefile | 2 +- arch/xtensa/lib/umulsidi3.S | 230 ++++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 arch/xtensa/lib/umulsidi3.S
arch/xtensa/kernel/xtensa_ksyms.c +2 -0
@@ -62,6 +62,7 @@ extern int __modsi3(int, int);extern int __mulsi3 (int ,int );extern unsigned int __udivsi3 (unsigned int ,unsigned int );extern unsigned int __umodsi3 (unsigned int ,unsigned int ); +extern unsigned long long __umulsidi3 (unsigned int ,unsigned int );EXPORT_SYMBOL (__ashldi3);EXPORT_SYMBOL (__ashrdi3);
@@ -71,6 +72,7 @@ EXPORT_SYMBOL(__modsi3);EXPORT_SYMBOL (__mulsi3);EXPORT_SYMBOL (__udivsi3);EXPORT_SYMBOL (__umodsi3); +EXPORT_SYMBOL (__umulsidi3);unsigned int __sync_fetch_and_and_4 (volatile void *p,unsigned int v) {
arch/xtensa/lib/Makefile +1 -1
@@ -5,7 +5,7 @@ lib-y += memcopy.o memset.o checksum.o \ ashldi3.o ashrdi3.o lshrdi3.o \ - divsi3.o udivsi3.o modsi3.o umodsi3.o mulsi3.o \ + divsi3.o udivsi3.o modsi3.o umodsi3.o mulsi3.o umulsidi3.o \ usercopy.o strncpy_user.o strnlen_user.o lib-$(CONFIG_PCI) += pci-auto.o lib-$(CONFIG_KCSAN) += kcsan-stubs.o
arch/xtensa/lib/umulsidi3.S new file +230 -0
230 lines not on this page · raw message
Signature · 1 line
2.39.0
Greg Kroah-Hartman
maintainerPATCH 57/177 of/kexec: Fix reading 32-bit "linux,initrd-{start,end}" values
In reply to Greg Kroah-HartmanFrom: Rob Herring <[email protected]>
commit e553ad8d7957697385e81034bf76db3b2cb2cf27 upstream.
"linux,initrd-start" and "linux,initrd-end" can be 32-bit values even on a 64-bit platform. Ideally, the size should be based on '#address-cells', but that has never been enforced in the kernel's FDT boot parsing code (early_init_dt_check_for_initrd()). Bootloader behavior is known to vary. For example, kexec always writes these as 64-bit. The result of incorrectly reading 32-bit values is most likely the reserved memory for the original initrd will still be reserved for the new kernel. The original arm64 equivalent of this code failed to release the initrd reserved memory in *all* cases.
Use of_read_number() to mirror the early_init_dt_check_for_initrd() code.
--- drivers/of/kexec.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/of/kexec.c +5 -5
@@ -281,7 +281,7 @@ void *of_kexec_alloc_and_setup_fdt(const const char *cmdline, size_t extra_fdt_size) { void *fdt; -int ret, chosen_node; +int ret, chosen_node, len;const void *prop;size_t fdt_size;
@@ -324,19 +324,19 @@ void *of_kexec_alloc_and_setup_fdt(const goto out;/* Did we boot using an initrd? */ - prop =fdt_getprop (fdt, chosen_node,"linux,initrd-start" ,NULL ); + prop =fdt_getprop (fdt, chosen_node,"linux,initrd-start" , &len);if (prop) {u64 tmp_start, tmp_end, tmp_size; - tmp_start =fdt64_to_cpu (*((const fdt64_t *) prop)); + tmp_start =of_read_number (prop, len /4 ); - prop =fdt_getprop (fdt, chosen_node,"linux,initrd-end" ,NULL ); + prop =fdt_getprop (fdt, chosen_node,"linux,initrd-end" , &len);if (!prop) { ret = -EINVAL ; goto out; } - tmp_end =fdt64_to_cpu (*((const fdt64_t *) prop)); + tmp_end =of_read_number (prop, len /4 );/* * kexec reserves exact initrd size, while firmware may
Greg Kroah-Hartman
maintainerPATCH 58/177 ima: Fix hash dependency to correct algorithm
In reply to Greg Kroah-HartmanFrom: Tianjia Zhang <[email protected]>
commit b6018af440a07bd0d74b58c4e18045f4a8dbfe6b upstream.
Commit d2825fa9365d ("crypto: sm3,sm4 - move into crypto directory") moves the SM3 and SM4 stand-alone library and the algorithm implementation for the Crypto API into the same directory, and the corresponding relationship of Kconfig is modified, CONFIG_CRYPTO_SM3/4 corresponds to the stand-alone library of SM3/4, and CONFIG_CRYPTO_SM3/4_GENERIC corresponds to the algorithm implementation for the Crypto API. Therefore, it is necessary for this module to depend on the correct algorithm.
--- security/integrity/ima/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/integrity/ima/Kconfig +1 -1
@@ -112,7 +112,7 @@ choice config IMA_DEFAULT_HASH_SM3 bool "SM3" - depends on CRYPTO_SM3=y + depends on CRYPTO_SM3_GENERIC=y endchoice config IMA_DEFAULT_HASH
Greg Kroah-Hartman
maintainerPATCH 59/177 KVM: VMX: Resume guest immediately when injecting #GP on ECREATE
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit eb3992e833d3a17f9b0a3e0371d0b1d3d566f740 upstream.
Resume the guest immediately when injecting a #GP on ECREATE due to an invalid enclave size, i.e. don't attempt ECREATE in the host. The #GP is a terminal fault, e.g. skipping the instruction if ECREATE is successful would result in KVM injecting #GP on the instruction following ECREATE.
--- arch/x86/kvm/vmx/sgx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/kvm/vmx/sgx.c +3 -1
@@ -182,8 +182,10 @@ static int __handle_encls_ecreate(struct/* Enforce CPUID restriction on max enclave size. */ max_size_log2 = (attributes &SGX_ATTR_MODE64BIT ) ? sgx_12_0->edx >>8 : sgx_12_0->edx; -if (size >=BIT_ULL (max_size_log2)) +if (size >=BIT_ULL (max_size_log2)) {kvm_inject_gp (vcpu,0 ); +return 1 ; + }/* * sgx_virt_ecreate() returns:
Greg Kroah-Hartman
maintainerPATCH 60/177 KVM: nVMX: Inject #GP, not #UD, if "generic" VMXON CR0/CR4 check fails
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit 9cc409325ddd776f6fd6293d5ce93ce1248af6e4 upstream.
Inject #GP for if VMXON is attempting with a CR0/CR4 that fails the generic "is CRx valid" check, but passes the CR4.VMXE check, and do the generic checks _after_ handling the post-VMXON VM-Fail.
The CR4.VMXE check, and all other #UD cases, are special pre-conditions that are enforced prior to pivoting on the current VMX mode, i.e. occur before interception if VMXON is attempted in VMX non-root mode.
All other CR0/CR4 checks generate #GP and effectively have lower priority than the post-VMXON check.
Per the SDM:
IF (register operand) or (CR0.PE = 0) or (CR4.VMXE = 0) or ...
THEN #UD;
ELSIF not in VMX operation
THEN
IF (CPL > 0) or (in A20M mode) or
(the values of CR0 and CR4 are not supported in VMX operation)
THEN #GP(0);
ELSIF in VMX non-root operation
THEN VMexit;
ELSIF CPL > 0
THEN #GP(0);
ELSE VMfail("VMXON executed in VMX root operation");
FI;which, if re-written without ELSIF, yields:
IF (register operand) or (CR0.PE = 0) or (CR4.VMXE = 0) or ...
THEN #UD
IF in VMX non-root operation
THEN VMexit;
IF CPL > 0
THEN #GP(0)
IF in VMX operation
THEN VMfail("VMXON executed in VMX root operation");
IF (in A20M mode) or
(the values of CR0 and CR4 are not supported in VMX operation)
THEN #GP(0);
Note, KVM unconditionally forwards VMXON VM-Exits that occur in L2 to L1, i.e. there is no need to check the vCPU is not in VMX non-root mode. Add a comment to explain why unconditionally forwarding such exits is functionally correct.
--- arch/x86/kvm/vmx/nested.c | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-)
arch/x86/kvm/vmx/nested.c +33 -11
@@ -4953,24 +4953,35 @@ static int handle_vmxon(struct kvm_vcpu | FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;/* -* Note, KVM cannot rely on hardware to perform the CR0/CR4 #UD checks -* that have higher priority than VM-Exit (see Intel SDM's pseudocode -* for VMXON), as KVM must load valid CR0/CR4 values into hardware while -* running the guest, i.e. KVM needs to check the _guest_ values. +* Manually check CR4.VMXE checks, KVM must force CR4.VMXE=1 to enter +* the guest and so cannot rely on hardware to perform the check, +* which has higher priority than VM-Exit (see Intel SDM's pseudocode +* for VMXON). * -* Rely on hardware for the other two pre-VM-Exit checks, !VM86 and -* !COMPATIBILITY modes. KVM may run the guest in VM86 to emulate Real -* Mode, but KVM will never take the guest out of those modes. +* Rely on hardware for the other pre-VM-Exit checks, CR0.PE=1, !VM86 +* and !COMPATIBILITY modes. For an unrestricted guest, KVM doesn't +* force any of the relevant guest state. For a restricted guest, KVM +* does force CR0.PE=1, but only to also force VM86 in order to emulate +* Real Mode, and so there's no need to check CR0.PE manually. */ -if (!nested_host_cr0_valid (vcpu,kvm_read_cr0 (vcpu)) || - !nested_host_cr4_valid (vcpu,kvm_read_cr4 (vcpu))) { +if (!kvm_read_cr4_bits (vcpu,X86_CR4_VMXE )) {kvm_queue_exception (vcpu,UD_VECTOR );return 1 ; }/* -* CPL=0 and all other checks that are lower priority than VM-Exit must -* be checked manually. +* The CPL is checked for "not in VMX operation" and for "in VMX root", +* and has higher priority than the VM-Fail due to being post-VMXON, +* i.e. VMXON #GPs outside of VMX non-root if CPL!=0. In VMX non-root, +* VMXON causes VM-Exit and KVM unconditionally forwards VMXON VM-Exits +* from L2 to L1, i.e. there's no need to check for the vCPU being in +* VMX non-root. +* +* Forwarding the VM-Exit unconditionally, i.e. without performing the +* #UD checks (see above), is functionally ok because KVM doesn't allow +* L1 to run L2 without CR4.VMXE=0, and because KVM never modifies L2's +* CR0 or CR4, i.e. it's L2's responsibility to emulate #UDs that are +* missed by hardware due to shadowing CR0 and/or CR4. */ if (vmx_get_cpl (vcpu)) {kvm_inject_gp (vcpu,0 );
@@ -4980,6 +4991,17 @@ static int handle_vmxon(struct kvm_vcpuif (vmx->nested.vmxon)return nested_vmx_fail (vcpu,VMXERR_VMXON_IN_VMX_ROOT_OPERATION ); +/* +* Invalid CR0/CR4 generates #GP. These checks are performed if and +* only if the vCPU isn't already in VMX operation, i.e. effectively +* have lower priority than the VM-Fail above. +*/ +if (!nested_host_cr0_valid (vcpu,kvm_read_cr0 (vcpu)) || + !nested_host_cr4_valid (vcpu,kvm_read_cr4 (vcpu))) { +kvm_inject_gp (vcpu,0 ); +return 1 ; + } +if ((vmx->msr_ia32_feature_control &VMXON_NEEDED_FEATURES ) !=VMXON_NEEDED_FEATURES ) {kvm_inject_gp (vcpu,0 );
Greg Kroah-Hartman
maintainerPATCH 61/177 KVM: x86: fix APICv/x2AVIC disabled when vm reboot by itself
In reply to Greg Kroah-HartmanFrom: Yuan ZhaoXiong <[email protected]>
commit ef40757743b47cc95de9b4ed41525c94f8dc73d9 upstream.
When a VM reboots itself, the reset process will result in an ioctl(KVM_SET_LAPIC, ...) to disable x2APIC mode and set the xAPIC id of the vCPU to its default value, which is the vCPU id.
That will be handled in KVM as follows:
kvm_vcpu_ioctl_set_lapic
kvm_apic_set_state
kvm_lapic_set_base => disable X2APIC mode
kvm_apic_state_fixup
kvm_lapic_xapic_id_updated
kvm_xapic_id(apic) != apic->vcpu->vcpu_id
kvm_set_apicv_inhibit(APICV_INHIBIT_REASON_APIC_ID_MODIFIED)
memcpy(vcpu->arch.apic->regs, s->regs, sizeof(*s)) => update APIC_IDWhen kvm_apic_set_state invokes kvm_lapic_set_base to disable x2APIC mode, the old 32-bit x2APIC id is still present rather than the 8-bit xAPIC id. kvm_lapic_xapic_id_updated will set the APICV_INHIBIT_REASON_APIC_ID_MODIFIED bit and disable APICv/x2AVIC.
Instead, kvm_lapic_xapic_id_updated must be called after APIC_ID is changed.
In fact, this fixes another small issue in the code in that potential changes to a vCPU's xAPIC ID need not be tracked for KVM_GET_LAPIC.
Message-Id: <[email protected]>
--- arch/x86/kvm/lapic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/x86/kvm/lapic.c +3 -2
@@ -2722,8 +2722,6 @@ static int kvm_apic_state_fixup(struct k icr =__kvm_lapic_get_reg64 (s->regs,APIC_ICR );__kvm_lapic_set_reg (s->regs,APIC_ICR2 , icr >>32 ); } - }else { -kvm_lapic_xapic_id_updated (vcpu->arch.apic); }return 0 ;
@@ -2759,6 +2757,9 @@ int kvm_apic_set_state(struct kvm_vcpu * }memcpy (vcpu->arch.apic->regs, s->regs,sizeof (*s)); +if (!apic_x2apic_mode (apic)) +kvm_lapic_xapic_id_updated (apic); +atomic_set_release (&apic->vcpu->kvm->arch.apic_map_dirty,DIRTY );kvm_recalculate_apic_map (vcpu->kvm);kvm_apic_set_version (vcpu);
Greg Kroah-Hartman
maintainerPATCH 62/177 KVM: nVMX: Properly expose ENABLE_USR_WAIT_PAUSE control to L1
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit 31de69f4eea77b28a9724b3fa55aae104fc91fc7 upstream.
Set ENABLE_USR_WAIT_PAUSE in KVM's supported VMX MSR configuration if the feature is supported in hardware and enabled in KVM's base, non-nested configuration, i.e. expose ENABLE_USR_WAIT_PAUSE to L1 if it's supported. This fixes a bug where saving/restoring, i.e. migrating, a vCPU will fail if WAITPKG (the associated CPUID feature) is enabled for the vCPU, and obviously allows L1 to enable the feature for L2.
KVM already effectively exposes ENABLE_USR_WAIT_PAUSE to L1 by stuffing the allowed-1 control ina vCPU's virtual MSR_IA32_VMX_PROCBASED_CTLS2 when updating secondary controls in response to KVM_SET_CPUID(2), but (a) that depends on flawed code (KVM shouldn't touch VMX MSRs in response to CPUID updates) and (b) runs afoul of vmx_restore_control_msr()'s restriction that the guest value must be a strict subset of the supported host value.
Although no past commit explicitly enabled nested support for WAITPKG, doing so is safe and functionally correct from an architectural perspective as no additional KVM support is needed to virtualize TPAUSE, UMONITOR, and UMWAIT for L2 relative to L1, and KVM already forwards VM-Exits to L1 as necessary (commit bf653b78f960, "KVM: vmx: Introduce handle_unexpected_vmexit and handle WAITPKG vmexit").
Note, KVM always keeps the hosts MSR_IA32_UMWAIT_CONTROL resident in hardware, i.e. always runs both L1 and L2 with the host's power management settings for TPAUSE and UMWAIT. See commit bf09fb6cba4f ("KVM: VMX: Stop context switching MSR_IA32_UMWAIT_CONTROL") for more details.
Message-Id: <[email protected]>
--- arch/x86/kvm/vmx/nested.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/kvm/vmx/nested.c +2 -1
@@ -6685,7 +6685,8 @@ void nested_vmx_setup_ctls_msrs(struct nSECONDARY_EXEC_ENABLE_INVPCID |SECONDARY_EXEC_RDSEED_EXITING |SECONDARY_EXEC_XSAVES | -SECONDARY_EXEC_TSC_SCALING ; +SECONDARY_EXEC_TSC_SCALING | +SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE ;/* * We can emulate "VMCS shadowing," even if the hardware
Greg Kroah-Hartman
maintainerPATCH 63/177 x86/microcode/intel: Do not retry microcode reloading on the APs
In reply to Greg Kroah-HartmanFrom: Ashok Raj <[email protected]>
commit be1b670f61443aa5d0d01782e9b8ea0ee825d018 upstream.
The retries in load_ucode_intel_ap() were in place to support systems with mixed steppings. Mixed steppings are no longer supported and there is only one microcode image at a time. Any retries will simply reattempt to apply the same image over and over without making progress.
[ bp: Zap the circumstantial reasoning from the commit message. ]
--- arch/x86/kernel/cpu/microcode/intel.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
arch/x86/kernel/cpu/microcode/intel.c +1 -7
@@ -621,7 +621,6 @@ void load_ucode_intel_ap(void)else iup = &intel_ucode_patch; -reget:if (!*iup) { patch =__load_ucode_intel (&uci);if (!patch)
@@ -632,12 +631,7 @@ reget: uci.mc = *iup; -if (apply_microcode_early (&uci, true)) { -/* Mixed-silicon system? Try to refetch the proper patch: */ - *iup =NULL ; - - goto reget; - } +apply_microcode_early (&uci, true); }static struct microcode_intel *find_patch (struct ucode_cpu_info *uci)
Greg Kroah-Hartman
maintainerPATCH 64/177 ftrace/x86: Add back ftrace_expected for ftrace bug reports
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (Google) <[email protected]>
commit fd3dc56253acbe9c641a66d312d8393cd55eb04c upstream.
After someone reported a bug report with a failed modification due to the expected value not matching what was found, it came to my attention that the ftrace_expected is no longer set when that happens. This makes for debugging the issue a bit more difficult.
Set ftrace_expected to the expected code before calling ftrace_bug, so that it shows what was expected and why it failed.
--- arch/x86/kernel/ftrace.c | 2 ++ 1 file changed, 2 insertions(+)
arch/x86/kernel/ftrace.c +2 -0
@@ -217,7 +217,9 @@ void ftrace_replace_code(int enable) ret =ftrace_verify_code (rec->ip, old);if (ret) { + ftrace_expected = old;ftrace_bug (ret, rec); + ftrace_expected =NULL ;return ; } }
Greg Kroah-Hartman
maintainerPATCH 65/177 x86/kprobes: Fix kprobes instruction boudary check with CONFIG_RETHUNK
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu (Google) <[email protected]>
commit 1993bf97992df2d560287f3c4120eda57426843d upstream.
Since the CONFIG_RETHUNK and CONFIG_SLS will use INT3 for stopping speculative execution after RET instruction, kprobes always failes to check the probed instruction boundary by decoding the function body if the probed address is after such sequence. (Note that some conditional code blocks will be placed after function return, if compiler decides it is not on the hot path.)
This is because kprobes expects kgdb puts the INT3 as a software breakpoint and it will replace the original instruction. But these INT3 are not such purpose, it doesn't need to recover the original instruction.
To avoid this issue, kprobes checks whether the INT3 is owned by kgdb or not, and if so, stop decoding and make it fail. The other INT3 will come from CONFIG_RETHUNK/CONFIG_SLS and those can be treated as a one-byte instruction.
--- arch/x86/kernel/kprobes/core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
arch/x86/kernel/kprobes/core.c +7 -3
@@ -37,6 +37,7 @@#include <linux/extable.h> #include <linux/kdebug.h> #include <linux/kallsyms.h> +#include <linux/kgdb.h> #include <linux/ftrace.h> #include <linux/kasan.h> #include <linux/moduleloader.h>
@@ -283,12 +284,15 @@ static int can_probe(unsigned long paddrif (ret <0 )return 0 ; +#ifdef CONFIG_KGDB /* -* Another debugging subsystem might insert this breakpoint. -* In that case, we can't recover it. +* If there is a dynamically installed kgdb sw breakpoint, +* this function should not be probed. */ -if (insn.opcode.bytes[0 ] ==INT3_INSN_OPCODE ) +if (insn.opcode.bytes[0 ] ==INT3_INSN_OPCODE && +kgdb_has_hit_break (addr))return 0 ; +#endif addr += insn.length; }
Greg Kroah-Hartman
maintainerPATCH 66/177 x86/kprobes: Fix optprobe optimization check with CONFIG_RETHUNK
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu (Google) <[email protected]>
commit 63dc6325ff41ee9e570bde705ac34a39c5dbeb44 upstream.
Since the CONFIG_RETHUNK and CONFIG_SLS will use INT3 for stopping speculative execution after function return, kprobe jump optimization always fails on the functions with such INT3 inside the function body. (It already checks the INT3 padding between functions, but not inside
the function)
To avoid this issue, as same as kprobes, check whether the INT3 comes from kgdb or not, and if so, stop decoding and make it fail. The other INT3 will come from CONFIG_RETHUNK/CONFIG_SLS and those can be treated as a one-byte instruction.
--- arch/x86/kernel/kprobes/opt.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-)
arch/x86/kernel/kprobes/opt.c +8 -20
@@ -15,6 +15,7 @@#include <linux/extable.h> #include <linux/kdebug.h> #include <linux/kallsyms.h> +#include <linux/kgdb.h> #include <linux/ftrace.h> #include <linux/objtool.h> #include <linux/pgtable.h>
@@ -279,19 +280,6 @@ static int insn_is_indirect_jump(structreturn ret; } -static bool is_padding_int3 (unsigned long addr,unsigned long eaddr) -{ -unsigned char ops; - -for (; addr < eaddr; addr++) { -if (get_kernel_nofault (ops, (void *)addr) <0 || - ops !=INT3_INSN_OPCODE ) -return false; - } - -return true; -} -/* Decode whole function to ensure any instructions don't jump into target */ static int can_optimize (unsigned long paddr) {
@@ -334,15 +322,15 @@ static int can_optimize(unsigned long pa ret =insn_decode_kernel (&insn, (void *)recovered_insn);if (ret <0 )return 0 ; - +#ifdef CONFIG_KGDB /* -* In the case of detecting unknown breakpoint, this could be -* a padding INT3 between functions. Let's check that all the -* rest of the bytes are also INT3. +* If there is a dynamically installed kgdb sw breakpoint, +* this function should not be probed. */ -if (insn.opcode.bytes[0 ] ==INT3_INSN_OPCODE ) -return is_padding_int3 (addr, paddr - offset + size) ?1 :0 ; - +if (insn.opcode.bytes[0 ] ==INT3_INSN_OPCODE && +kgdb_has_hit_break (addr)) +return 0 ; +#endif /* Recover address */ insn.kaddr = (void *)addr; insn.next_byte = (void *)(addr + insn.length);
Greg Kroah-Hartman
maintainerPATCH 67/177 tracing: Fix race where eprobes can be called before the event
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (Google) <[email protected]>
commit d5f30a7da8ea8e6450250275cec5670cee3c4264 upstream.
The flag that tells the event to call its triggers after reading the event is set for eprobes after the eprobe is enabled. This leads to a race where the eprobe may be triggered at the beginning of the event where the record information is NULL. The eprobe then dereferences the NULL record causing a NULL kernel pointer bug.
Test for a NULL record to keep this from happening.
--- kernel/trace/trace_eprobe.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/trace/trace_eprobe.c +3 -0
@@ -563,6 +563,9 @@ static void eprobe_trigger_func(struct eif (unlikely (!rec))return ; +if (unlikely (!rec)) +return ; +__eprobe_trace_func (edata, rec); }
Greg Kroah-Hartman
maintainerPATCH 68/177 powerpc/ftrace: fix syscall tracing on PPC64_ELF_ABI_V1
In reply to Greg Kroah-HartmanFrom: Michael Jeanson <[email protected]>
commit ad050d2390fccb22aa3e6f65e11757ce7a5a7ca5 upstream.
In v5.7 the powerpc syscall entry/exit logic was rewritten in C, on PPC64_ELF_ABI_V1 this resulted in the symbols in the syscall table changing from their dot prefixed variant to the non-prefixed ones.
Since ftrace prefixes a dot to the syscall names when matching them to build its syscall event list, this resulted in no syscall events being available.
Remove the PPC64_ELF_ABI_V1 specific version of arch_syscall_match_sym_name to have the same behavior across all powerpc variants.
--- arch/powerpc/include/asm/ftrace.h | 12 ------------ 1 file changed, 12 deletions(-)
arch/powerpc/include/asm/ftrace.h +0 -12
@@ -64,17 +64,6 @@ void ftrace_graph_func(unsigned long ip,* those. */ #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME -#ifdef CONFIG_PPC64_ELF_ABI_V1 -static inline bool arch_syscall_match_sym_name (const char *sym,const char *name) -{ -/* We need to skip past the initial dot, and the __se_sys alias */ -return !strcmp (sym +1 , name) || - (!strncmp (sym,".__se_sys" ,9 ) && !strcmp (sym +6 , name)) || - (!strncmp (sym,".ppc_" ,5 ) && !strcmp (sym +5 , name +4 )) || - (!strncmp (sym,".ppc32_" ,7 ) && !strcmp (sym +7 , name +4 )) || - (!strncmp (sym,".ppc64_" ,7 ) && !strcmp (sym +7 , name +4 )); -} -#else static inline bool arch_syscall_match_sym_name (const char *sym,const char *name) { return !strcmp(sym, name) ||
@@ -83,7 +72,6 @@ static inline bool arch_syscall_match_sy (!strncmp (sym,"ppc32_" ,6 ) && !strcmp (sym +6 , name +4 )) || (!strncmp(sym, "ppc64_", 6) && !strcmp(sym + 6, name + 4)); } -#endif /* CONFIG_PPC64_ELF_ABI_V1 */ #endif /* CONFIG_FTRACE_SYSCALLS */ #if defined(CONFIG_PPC64 ) && defined(CONFIG_FUNCTION_TRACER )
m_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = qmp_v3_usb3phy_regs_layout,
+
+ .dp_aux_init = qcom_qmp_v3_phy_dp_aux_init,
+ .configure_dp_tx = qcom_qmp_v3_phy_configure_dp_tx,
+ .configure_dp_phy = qcom_qmp_v3_phy_configure_dp_phy,
+ .calibrate_dp_phy = qcom_qmp_v3_dp_phy_calibrate,
+};
+
static const struct qmp_phy_combo_cfg sdm845_usb3dpphy_cfg = {
.usb_cfg = &sdm845_usb3phy_cfg, - .dp_cfg = &sc7180_dpphy_cfg, + .dp_cfg = &sdm845_dpphy_cfg,
};
static const struct qmp_phy_cfg sm8150_usb3phy_cfg = {
Greg Kroah-Hartman
maintainerPATCH 69/177 tracing: Fix complicated dependency of CONFIG_TRACER_MAX_TRACE
In reply to Greg Kroah-HartmanFrom: Masami Hiramatsu (Google) <[email protected]>
commit e25e43a4e5d8cb2323553d8b6a7ba08d2ebab21f upstream.
Both CONFIG_OSNOISE_TRACER and CONFIG_HWLAT_TRACER partially enables the CONFIG_TRACER_MAX_TRACE code, but that is complicated and has introduced a bug; It declares tracing_max_lat_fops data structure outside of #ifdefs, but since it is defined only when CONFIG_TRACER_MAX_TRACE=y or CONFIG_HWLAT_TRACER=y, if only CONFIG_OSNOISE_TRACER=y, that declaration comes to a definition(!).
To fix this issue, and do not repeat the similar problem, makes CONFIG_OSNOISE_TRACER and CONFIG_HWLAT_TRACER enables the CONFIG_TRACER_MAX_TRACE always. It has there benefits;
- Fix the tracing_max_lat_fops bug
- Simplify the #ifdefs
- CONFIG_TRACER_MAX_TRACE code is fully enabled, or not.
--- kernel/trace/Kconfig | 2 ++ kernel/trace/trace.c | 23 +++++++++++++---------- kernel/trace/trace.h | 8 +++----- 3 files changed, 18 insertions(+), 15 deletions(-)
kernel/trace/Kconfig +2 -0
@@ -369,6 +369,7 @@ config SCHED_TRACER config HWLAT_TRACER bool "Tracer to detect hardware latencies (like SMIs)" select GENERIC_TRACER + select TRACER_MAX_TRACE help This tracer, when enabled will create one or more kernel threads, depending on what the cpumask file is set to, which each thread
@@ -404,6 +405,7 @@ config HWLAT_TRACER config OSNOISE_TRACER bool "OS Noise tracer" select GENERIC_TRACER + select TRACER_MAX_TRACE help In the context of high-performance computing (HPC), the Operating System Noise (osnoise) refers to the interference experienced by an
kernel/trace/trace.c +13 -10
@@ -1421,6 +1421,7 @@ int tracing_snapshot_cond_disable(struct return false; }EXPORT_SYMBOL_GPL (tracing_snapshot_cond_disable); +#define free_snapshot (tr) do { } while (0)#endif /* CONFIG_TRACER_SNAPSHOT */ void tracer_tracing_off (struct trace_array *tr)
@@ -1692,6 +1693,8 @@ static ssize_t trace_seq_to_buffer(struc }unsigned long __read_mostly tracing_thresh; + +#ifdef CONFIG_TRACER_MAX_TRACE static const struct file_operations tracing_max_lat_fops;#ifdef LATENCY_FS_NOTIFY
@@ -1748,18 +1751,14 @@ void latency_fsnotify(struct trace_array irq_work_queue(&tr->fsnotify_irqwork); } -#elif defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \ - || defined(CONFIG_OSNOISE_TRACER) +#else /* !LATENCY_FS_NOTIFY */ #define trace_create_maxlat_file (tr, d_tracer) \ trace_create_file("tracing_max_latency", TRACE_MODE_WRITE, \ d_tracer, &tr->max_latency, &tracing_max_lat_fops) -#else -#define trace_create_maxlat_file (tr, d_tracer) do { } while (0)#endif -#ifdef CONFIG_TRACER_MAX_TRACE /* * Copy the new maximum trace into the separate maximum-trace * structure. (this way the maximum trace is permanently saved,
@@ -1834,14 +1833,15 @@ update_max_tr(struct trace_array *tr, string_buffer_record_off (tr->max_buffer.buffer);#ifdef CONFIG_TRACER_SNAPSHOT -if (tr->cond_snapshot && !tr->cond_snapshot->update (tr, cond_data)) - goto out_unlock; +if (tr->cond_snapshot && !tr->cond_snapshot->update (tr, cond_data)) { +arch_spin_unlock (&tr->max_lock); +return ; + }#endif swap (tr->array_buffer.buffer, tr->max_buffer.buffer);__update_max_tr (tr, tsk, cpu); - out_unlock:arch_spin_unlock (&tr->max_lock); }
@@ -1888,6 +1888,7 @@ update_max_tr_single(struct trace_array__update_max_tr (tr, tsk, cpu); arch_spin_unlock(&tr->max_lock); } +#endif /* CONFIG_TRACER_MAX_TRACE */ static int wait_on_pipe (struct trace_iterator *iter,int full)
@@ -6563,7 +6564,7 @@ out:return ret; } -#if defined(CONFIG_TRACER_MAX_TRACE ) || defined(CONFIG_HWLAT_TRACER ) +#ifdef CONFIG_TRACER_MAX_TRACE static ssize_t tracing_max_lat_read(struct file *filp, char __user *ubuf,
@@ -7578,7 +7579,7 @@ static const struct file_operations trac .llseek = generic_file_llseek, }; -#if defined(CONFIG_TRACER_MAX_TRACE ) || defined(CONFIG_HWLAT_TRACER ) +#ifdef CONFIG_TRACER_MAX_TRACE static const struct file_operations tracing_max_lat_fops = { .open = tracing_open_generic, .read = tracing_max_lat_read,
@@ -9592,7 +9593,9 @@ init_tracer_tracefs(struct trace_array *create_trace_options_dir (tr); +#ifdef CONFIG_TRACER_MAX_TRACE trace_create_maxlat_file (tr, d_tracer); +#endif if (ftrace_create_function_files (tr, d_tracer))MEM_FAIL (1 ,"Could not allocate function filter files" );
kernel/trace/trace.h +3 -5
@@ -308,8 +308,7 @@ struct trace_array {struct array_buffer max_buffer;bool allocated_snapshot;#endif -#if defined(CONFIG_TRACER_MAX_TRACE ) || defined(CONFIG_HWLAT_TRACER ) \ - || defined(CONFIG_OSNOISE_TRACER ) +#ifdef CONFIG_TRACER_MAX_TRACE unsigned long max_latency;#ifdef CONFIG_FSNOTIFY struct dentry *d_max_latency;
@@ -687,12 +686,11 @@ void update_max_tr(struct trace_array *t void *cond_data);void update_max_tr_single (struct trace_array *tr,struct task_struct *tsk,int cpu); -#endif /* CONFIG_TRACER_MAX_TRACE */ -#if (defined(CONFIG_TRACER_MAX_TRACE ) || defined(CONFIG_HWLAT_TRACER ) \ - || defined(CONFIG_OSNOISE_TRACER )) && defined(CONFIG_FSNOTIFY ) +#ifdef CONFIG_FSNOTIFY #define LATENCY_FS_NOTIFY #endif +#endif /* CONFIG_TRACER_MAX_TRACE */ #ifdef LATENCY_FS_NOTIFY void latency_fsnotify (struct trace_array *tr);
Greg Kroah-Hartman
maintainerPATCH 70/177 tracing/hist: Fix wrong return value in parse_action_params()
In reply to Greg Kroah-HartmanFrom: Zheng Yejian <[email protected]>
commit 2cc6a528882d0e0ccbc1bca5f95b8c963cedac54 upstream.
When number of synth fields is more than SYNTH_FIELDS_MAX, parse_action_params() should return -EINVAL.
--- kernel/trace/trace_events_hist.c | 1 + 1 file changed, 1 insertion(+)
kernel/trace/trace_events_hist.c +1 -0
@@ -3564,6 +3564,7 @@ static int parse_action_params(struct trwhile (params) {if (data->n_params >=SYNTH_FIELDS_MAX ) {hist_err (tr,HIST_ERR_TOO_MANY_PARAMS ,0 ); + ret = -EINVAL ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 71/177 tracing/probes: Handle system names with hyphens
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (Google) <[email protected]>
commit 575b76cb885532aae13a9d979fd476bb2b156cb9 upstream.
When creating probe names, a check is done to make sure it matches basic C standard variable naming standards. Basically, starts with alphabetic or underline, and then the rest of the characters have alpha-numeric or underline in them.
But system names do not have any true naming conventions, as they are created by the TRACE_SYSTEM macro and nothing tests to see what they are. The "xhci-hcd" trace events has a '-' in the system name. When trying to attach a eprobe to one of these trace points, it fails because the system name does not follow the variable naming convention because of the hyphen, and the eprobe checks fail on this.
Allow hyphens in the system name so that eprobes can attach to the "xhci-hcd" trace events.
--- kernel/trace/trace.h | 19 ++++++++++++++++--- kernel/trace/trace_probe.c | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-)
kernel/trace/trace.h +16 -3
@@ -1966,17 +1966,30 @@ static __always_inline void trace_iterat }/* Check the name is good for event/group/fields */ -static inline bool is_good_name (const char *name) +static inline bool __is_good_name (const char *name,bool hash_ok) { -if (!isalpha (*name) && *name !='_' ) +if (!isalpha (*name) && *name !='_' && (!hash_ok || *name !='-' ))return false;while (*++name !='\0' ) { -if (!isalpha (*name) && !isdigit (*name) && *name !='_' ) +if (!isalpha (*name) && !isdigit (*name) && *name !='_' && + (!hash_ok || *name !='-' ))return false; }return true; } +/* Check the name is good for event/group/fields */ +static inline bool is_good_name (const char *name) +{ +return __is_good_name (name, false); +} + +/* Check the name is good for system */ +static inline bool is_good_system_name (const char *name) +{ +return __is_good_name (name, true); +} +/* Convert certain expected symbols into '_' when generating event names */ static inline void sanitize_event_name (char *name) {
kernel/trace/trace_probe.c +1 -1
@@ -246,7 +246,7 @@ int traceprobe_parse_event_name(const chreturn -EINVAL ; }strlcpy (buf, event, slash - event +1 ); -if (!is_good_name (buf)) { +if (!is_good_system_name (buf)) {trace_probe_log_err (offset,BAD_GROUP_NAME );return -EINVAL ; }
Greg Kroah-Hartman
maintainerPATCH 72/177 tracing: Fix issue of missing one synthetic field
In reply to Greg Kroah-HartmanFrom: Zheng Yejian <[email protected]>
commit ff4837f7fe59ff018eca4705a70eca5e0b486b97 upstream.
The maximum number of synthetic fields supported is defined as SYNTH_FIELDS_MAX which value currently is 64, but it actually fails when try to generate a synthetic event with 64 fields by executing like:
# echo "my_synth_event int v1; int v2; int v3; int v4; int v5; int v6;\ int v7; int v8; int v9; int v10; int v11; int v12; int v13; int v14;\ int v15; int v16; int v17; int v18; int v19; int v20; int v21; int v22;\ int v23; int v24; int v25; int v26; int v27; int v28; int v29; int v30;\ int v31; int v32; int v33; int v34; int v35; int v36; int v37; int v38;\ int v39; int v40; int v41; int v42; int v43; int v44; int v45; int v46;\ int v47; int v48; int v49; int v50; int v51; int v52; int v53; int v54;\ int v55; int v56; int v57; int v58; int v59; int v60; int v61; int v62;\ int v63; int v64" >> /sys/kernel/tracing/synthetic_events
Correct the field counting to fix it.
--- kernel/trace/trace_events_synth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/trace_events_synth.c +1 -1
@@ -1282,12 +1282,12 @@ static int __create_synth_event(const ch goto err_free_arg; } - fields[n_fields++] = field;if (n_fields ==SYNTH_FIELDS_MAX ) {synth_err (SYNTH_ERR_TOO_MANY_FIELDS ,0 ); ret = -EINVAL ; goto err_free_arg; } + fields[n_fields++] = field; n_fields_this_loop++; }
Greg Kroah-Hartman
maintainerPATCH 73/177 tracing: Fix infinite loop in tracing_read_pipe on overflowed print_trace_line
In reply to Greg Kroah-HartmanFrom: Yang Jihong <[email protected]>
commit c1ac03af6ed45d05786c219d102f37eb44880f28 upstream.
print_trace_line may overflow seq_file buffer. If the event is not consumed, the while loop keeps peeking this event, causing a infinite loop.
--- kernel/trace/trace.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
kernel/trace/trace.c +14 -1
@@ -6788,7 +6788,20 @@ waitagain: ret =print_trace_line (iter);if (ret ==TRACE_TYPE_PARTIAL_LINE ) { -/* don't print partial lines */ +/* +* If one print_trace_line() fills entire trace_seq in one shot, +* trace_seq_to_user() will returns -EBUSY because save_len == 0, +* In this case, we need to consume it, otherwise, loop will peek +* this event next time, resulting in an infinite loop. +*/ +if (save_len ==0 ) { + iter->seq.full =0 ; +trace_seq_puts (&iter->seq,"[LINE TOO BIG]\n" ); +trace_consume (iter); +break ; + } + +/* In other cases, don't print partial lines */ iter->seq.seq.len = save_len;break ; }
Greg Kroah-Hartman
maintainerPATCH 74/177 staging: media: tegra-video: fix chan->mipi value on error
In reply to Greg Kroah-HartmanFrom: Luca Ceresoli <[email protected]>
commit 10b5ce6743c839fa75336042c64e2479caec9430 upstream.
chan->mipi takes the return value of tegra_mipi_request() which can be a valid pointer or an error. However chan->mipi is checked in several places, including error-cleanup code in tegra_csi_channels_cleanup(), as 'if (chan->mipi)', which suggests the initial intent was that chan->mipi should be either NULL or a valid pointer, never an error. As a consequence, cleanup code in case of tegra_mipi_request() errors would dereference an invalid pointer.
Fix by ensuring chan->mipi always contains either NULL or a void pointer.
Also add that to the documentation.
--- drivers/staging/media/tegra-video/csi.c | 1 + drivers/staging/media/tegra-video/csi.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/staging/media/tegra-video/csi.c +1 -0
@@ -448,6 +448,7 @@ static int tegra_csi_channel_alloc(struc chan->mipi =tegra_mipi_request (csi->dev, node);if (IS_ERR (chan->mipi)) { ret =PTR_ERR (chan->mipi); + chan->mipi =NULL ;dev_err (csi->dev,"failed to get mipi device: %d\n" , ret); }
drivers/staging/media/tegra-video/csi.h +1 -1
@@ -56,7 +56,7 @@ struct tegra_csi;* @framerate: active framerate for TPG * @h_blank: horizontal blanking for TPG active format * @v_blank: vertical blanking for TPG active format -* @mipi: mipi device for corresponding csi channel pads +* @mipi: mipi device for corresponding csi channel pads, or NULL if not applicable (TPG, error) * @pixel_rate: active pixel rate from the sensor on this channel */ struct tegra_csi_channel {
Greg Kroah-Hartman
maintainerPATCH 75/177 staging: media: tegra-video: fix device_node use after free
In reply to Greg Kroah-HartmanFrom: Luca Ceresoli <[email protected]>
commit c4d344163c3a7f90712525f931a6c016bbb35e18 upstream.
At probe time this code path is followed:
* tegra_csi_init
* tegra_csi_channels_alloc
* for_each_child_of_node(node, channel) -- iterates over channels
* automatically gets 'channel'
* tegra_csi_channel_alloc()
* saves into chan->of_node a pointer to the channel OF node
* automatically gets and puts 'channel'
* now the node saved in chan->of_node has refcount 0, can disappear
* tegra_csi_channels_init
* iterates over channels
* tegra_csi_channel_init -- uses chan->of_node
After that, chan->of_node keeps storing the node until the device is removed.
of_node_get() the node and of_node_put() it during teardown to avoid any risk.
--- drivers/staging/media/tegra-video/csi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/staging/media/tegra-video/csi.c +2 -1
@@ -433,7 +433,7 @@ static int tegra_csi_channel_alloc(strucfor (i =0 ; i < chan->numgangports; i++) chan->csi_port_nums[i] = port_num + i *CSI_PORTS_PER_BRICK ; - chan->of_node = node; + chan->of_node =of_node_get (node); chan->numpads = num_pads;if (num_pads &0x2 ) { chan->pads[0 ].flags =MEDIA_PAD_FL_SINK ;
@@ -641,6 +641,7 @@ static void tegra_csi_channels_cleanup(smedia_entity_cleanup (&subdev->entity); } +of_node_put (chan->of_node);list_del (&chan->list);kfree (chan); }
Greg Kroah-Hartman
maintainerPATCH 76/177 arm64: dts: mediatek: mt8195-demo: fix the memory size of node secmon
In reply to Greg Kroah-HartmanFrom: Macpaul Lin <[email protected]>
commit e4a4175201014c0222f6bab1895a17b3d1b92f08 upstream.
The size of device tree node secmon (bl31_secmon_reserved) was incorrect. It should be increased to 2MiB (0x200000).
The origin setting will cause some abnormal behavior due to trusted-firmware-a and related firmware didn't load correctly. The incorrect behavior may vary because of different software stacks. For example, it will cause build error in some Yocto project because it will check if there was enough memory to load trusted-firmware-a to the reserved memory.
When mt8195-demo.dts sent to the upstream, at that time the size of BL31 was small. Because supported functions and modules in BL31 are basic sets when the board was under early development stage.
Now BL31 includes more firmwares of coprocessors and maturer functions so the size has grown bigger in real applications. According to the value reported by customers, we think reserved 2MiB for BL31 might be enough for maybe the following 2 or 3 years.
--- arch/arm64/boot/dts/mediatek/mt8195-demo.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/mediatek/mt8195-demo.dts +2 -2
@@ -56,10 +56,10 @@ reserved-memory { #size-cells = <2>; ranges; - /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ + /* 2 MiB reserved for ARM Trusted Firmware (BL31) */ bl31_secmon_reserved: secmon@54600000 { no-map; - reg = <0 0x54600000 0x0 0x30000>; + reg = <0 0x54600000 0x0 0x200000>; }; /* 12 MiB reserved for OP-TEE (BL32)
Signature · 1 line
2.39.0
Greg Kroah-Hartman
maintainerPATCH 77/177 ARM: 9256/1: NWFPE: avoid compiler-generated __aeabi_uldivmod
In reply to Greg Kroah-HartmanFrom: Nick Desaulniers <[email protected]>
commit 3220022038b9a3845eea762af85f1c5694b9f861 upstream.
clang-15's ability to elide loops completely became more aggressive when it can deduce how a variable is being updated in a loop. Counting down one variable by an increment of another can be replaced by a modulo operation.
For 64b variables on 32b ARM EABI targets, this can result in the compiler generating calls to __aeabi_uldivmod, which it does for a do while loop in float64_rem().
For the kernel, we'd generally prefer that developers not open code 64b division via binary / operators and instead use the more explicit helpers from div64.h. On arm-linux-gnuabi targets, failure to do so can result in linkage failures due to undefined references to __aeabi_uldivmod().
While developers can avoid open coding divisions on 64b variables, the compiler doesn't know that the Linux kernel has a partial implementation of a compiler runtime (--rtlib) to enforce this convention.
It's also undecidable for the compiler whether the code in question would be faster to execute the loop vs elide it and do the 64b division.
While I actively avoid using the internal -mllvm command line flags, I think we get better code than using barrier() here, which will force reloads+spills in the loop for all toolchains.
--- arch/arm/nwfpe/Makefile | 6 ++++++ 1 file changed, 6 insertions(+)
arch/arm/nwfpe/Makefile +6 -0
@@ -11,3 +11,9 @@ nwfpe-y += fpa11.o fpa11_cpdo.o fpa11 entry.o nwfpe-$(CONFIG_FPE_NWFPE_XP) += extended_cpdo.o + +# Try really hard to avoid generating calls to __aeabi_uldivmod() from +# float64_rem() due to loop elision. +ifdef CONFIG_CC_IS_CLANG +CFLAGS_softfloat.o += -mllvm -replexitval=never +endif
Greg Kroah-Hartman
maintainerPATCH 78/177 media: dvb-core: Fix double free in dvb_register_device()
In reply to Greg Kroah-HartmanFrom: Keita Suzuki <[email protected]>
commit 6b0d0477fce747d4137aa65856318b55fba72198 upstream.
In function dvb_register_device() -> dvb_register_media_device() -> dvb_create_media_entity(), dvb->entity is allocated and initialized. If the initialization fails, it frees the dvb->entity, and return an error code. The caller takes the error code and handles the error by calling dvb_media_device_free(), which unregisters the entity and frees the field again if it is not NULL. As dvb->entity may not NULLed in dvb_create_media_entity() when the allocation of dvbdev->pad fails, a double free may occur. This may also cause an Use After free in media_device_unregister_entity().
Fix this by storing NULL to dvb->entity when it is freed.
--- drivers/media/dvb-core/dvbdev.c | 1 + 1 file changed, 1 insertion(+)
drivers/media/dvb-core/dvbdev.c +1 -0
@@ -335,6 +335,7 @@ static int dvb_create_media_entity(struc GFP_KERNEL);if (!dvbdev->pads) {kfree (dvbdev->entity); + dvbdev->entity =NULL ;return -ENOMEM ; } }
Greg Kroah-Hartman
maintainerPATCH 79/177 media: dvb-core: Fix UAF due to refcount races at releasing
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit fd3d91ab1c6ab0628fe642dd570b56302c30a792 upstream.
The dvb-core tries to sync the releases of opened files at dvb_dmxdev_release() with two refcounts: dvbdev->users and dvr_dvbdev->users. A problem is present in those two syncs: when yet another dvb_demux_open() is called during those sync waits, dvb_demux_open() continues to process even if the device is being closed. This includes the increment of the former refcount, resulting in the leftover refcount after the sync of the latter refcount at dvb_dmxdev_release(). It ends up with use-after-free, since the function believes that all usages were gone and releases the resources.
This patch addresses the problem by adding the check of dmxdev->exit flag at dvb_demux_open(), just like dvb_dvr_open() already does. With the exit flag check, the second call of dvb_demux_open() fails, hence the further corruption can be avoided.
Also for avoiding the races of the dmxdev->exit flag reference, this patch serializes the dmxdev->exit set up and the sync waits with the dmxdev->mutex lock at dvb_dmxdev_release(). Without the mutex lock, dvb_demux_open() (or dvb_dvr_open()) may run concurrently with dvb_dmxdev_release(), which allows to skip the exit flag check and continue the open process that is being closed.
CVE-2022-41218 is assigned to those bugs above.
--- drivers/media/dvb-core/dmxdev.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/media/dvb-core/dmxdev.c +8 -0
@@ -790,6 +790,11 @@ static int dvb_demux_open(struct inode *if (mutex_lock_interruptible (&dmxdev->mutex))return -ERESTARTSYS ; +if (dmxdev->exit) { +mutex_unlock (&dmxdev->mutex); +return -ENODEV ; + } +for (i =0 ; i < dmxdev->filternum; i++)if (dmxdev->filter[i].state ==DMXDEV_STATE_FREE )break ;
@@ -1448,7 +1453,10 @@ EXPORT_SYMBOL(dvb_dmxdev_init);void dvb_dmxdev_release (struct dmxdev *dmxdev) { +mutex_lock (&dmxdev->mutex); dmxdev->exit =1 ; +mutex_unlock (&dmxdev->mutex); +if (dmxdev->dvbdev->users >1 ) {wait_event (dmxdev->dvbdev->wait_queue, dmxdev->dvbdev->users ==1 );
Greg Kroah-Hartman
maintainerPATCH 80/177 cifs: fix confusing debug message
In reply to Greg Kroah-HartmanFrom: Paulo Alcantara <[email protected]>
commit a85ceafd41927e41a4103d228a993df7edd8823b upstream.
Since rc was initialised to -ENOMEM in cifs_get_smb_ses(), when an existing smb session was found, free_xid() would be called and then print
CIFS: fs/cifs/connect.c: Existing tcp session with server found
CIFS: fs/cifs/connect.c: VFS: in cifs_get_smb_ses as Xid: 44 with uid: 0
CIFS: fs/cifs/connect.c: Existing smb sess found (status=1)
CIFS: fs/cifs/connect.c: VFS: leaving cifs_get_smb_ses (xid = 44) rc = -12
Fix this by initialising rc to 0 and then let free_xid() print this instead
CIFS: fs/cifs/connect.c: Existing tcp session with server found
CIFS: fs/cifs/connect.c: VFS: in cifs_get_smb_ses as Xid: 14 with uid: 0
CIFS: fs/cifs/connect.c: Existing smb sess found (status=1)
CIFS: fs/cifs/connect.c: VFS: leaving cifs_get_smb_ses (xid = 14) rc = 0
--- fs/cifs/connect.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/cifs/connect.c +3 -1
@@ -2155,7 +2155,7 @@ cifs_set_cifscreds(struct smb3_fs_contexstruct cifs_ses *cifs_get_smb_ses (struct TCP_Server_Info *server,struct smb3_fs_context *ctx) { -int rc = -ENOMEM ; +int rc =0 ;unsigned int xid;struct cifs_ses *ses;struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
@@ -2204,6 +2204,8 @@ cifs_get_smb_ses(struct TCP_Server_Inforeturn ses; } + rc = -ENOMEM ; +cifs_dbg (FYI ,"Existing smb sess not found\n" ); ses =sesInfoAlloc ();if (ses ==NULL )
Greg Kroah-Hartman
maintainerPATCH 81/177 cifs: fix missing display of three mount options
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
commit 2bfd81043e944af0e52835ef6d9b41795af22341 upstream.
Three mount options: "tcpnodelay" and "noautotune" and "noblocksend" were not displayed when passed in on cifs/smb3 mounts (e.g. displayed in /proc/mounts e.g.). No change to defaults so these are not displayed if not specified on mount.
--- fs/cifs/cifsfs.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
fs/cifs/cifsfs.c +7 -1
@@ -678,9 +678,15 @@ cifs_show_options(struct seq_file *s, stseq_printf (s,",echo_interval=%lu" , tcon->ses->server->echo_interval /HZ ); -/* Only display max_credits if it was overridden on mount */ +/* Only display the following if overridden on mount */ if (tcon->ses->server->max_credits !=SMB2_MAX_CREDITS_AVAILABLE )seq_printf (s,",max_credits=%u" , tcon->ses->server->max_credits); +if (tcon->ses->server->tcp_nodelay) +seq_puts (s,",tcpnodelay" ); +if (tcon->ses->server->noautotune) +seq_puts (s,",noautotune" ); +if (tcon->ses->server->noblocksnd) +seq_puts (s,",noblocksend" );if (tcon->snapshot_time)seq_printf (s,",snapshot=%llu" , tcon->snapshot_time);
Greg Kroah-Hartman
maintainerPATCH 82/177 cifs: set correct tcon status after initial tree connect
In reply to Greg Kroah-HartmanFrom: Paulo Alcantara <[email protected]>
commit b248586a49a7729f73c504b1e7b958caea45e927 upstream.
cifs_tcon::status wasn't correctly updated to TID_GOOD after initial tree connect thus staying at TID_NEW as long as it was connected.
--- fs/cifs/connect.c | 1 + 1 file changed, 1 insertion(+)
fs/cifs/connect.c +1 -0
@@ -2600,6 +2600,7 @@ cifs_get_tcon(struct cifs_ses *ses, stru tcon->nodelete = ctx->nodelete; tcon->local_lease = ctx->local_lease;INIT_LIST_HEAD (&tcon->pending_opens); + tcon->status =TID_GOOD ;/* schedule query interfaces poll */ INIT_DELAYED_WORK(&tcon->query_interfaces,
Greg Kroah-Hartman
maintainerPATCH 83/177 cifs: set correct ipc status after initial tree connect
In reply to Greg Kroah-HartmanFrom: Paulo Alcantara <[email protected]>
commit 86fe0fa8747fb1bc4cc44fc1966e0959fe752f38 upstream.
cifs_tcon::status wasn't correctly updated to TID_GOOD after establishing initial IPC connection thus staying at TID_NEW as long as it wasn't reconnected.
--- fs/cifs/connect.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/cifs/connect.c +5 -2
@@ -1870,6 +1870,9 @@ cifs_setup_ipc(struct cifs_ses *ses, strcifs_dbg (FYI ,"IPC tcon rc=%d ipc tid=0x%x\n" , rc, tcon->tid); +spin_lock (&tcon->tc_lock); + tcon->status =TID_GOOD ; +spin_unlock (&tcon->tc_lock); ses->tcon_ipc = tcon; out:return rc;
@@ -2278,10 +2281,10 @@ cifs_get_smb_ses(struct TCP_Server_Infolist_add (&ses->smb_ses_list, &server->smb_ses_list);spin_unlock (&cifs_tcp_ses_lock); -free_xid (xid); -cifs_setup_ipc (ses, ctx); +free_xid (xid); +return ses; get_ses_fail:
Greg Kroah-Hartman
maintainerPATCH 84/177 cifs: set correct status of tcon ipc when reconnecting
In reply to Greg Kroah-HartmanFrom: Paulo Alcantara <[email protected]>
commit 25cf01b7c9200d6ace5a59125d8166435dd9dea7 upstream.
The status of tcon ipcs were not being set to TID_NEED_RECO when marking sessions and tcons to be reconnected, therefore not sending tree connect to those ipcs in cifs_tree_connect() and leaving them disconnected.
--- fs/cifs/connect.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/cifs/connect.c +3 -1
@@ -279,8 +279,10 @@ cifs_mark_tcp_ses_conns_for_reconnect(st tcon->need_reconnect = true; tcon->status =TID_NEED_RECON ; } -if (ses->tcon_ipc) +if (ses->tcon_ipc) { ses->tcon_ipc->need_reconnect = true; + ses->tcon_ipc->status =TID_NEED_RECON ; + } next_session:spin_unlock (&ses->chan_lock);
Greg Kroah-Hartman
maintainerPATCH 85/177 ravb: Fix "failed to switch device to config mode" message during unbind
In reply to Greg Kroah-HartmanFrom: Biju Das <[email protected]>
commit c72a7e42592b2e18d862cf120876070947000d7a upstream.
This patch fixes the error "ravb 11c20000.ethernet eth0: failed to switch device to config mode" during unbind.
We are doing register access after pm_runtime_put_sync().
We usually do cleanup in reverse order of init. Currently in remove(), the "pm_runtime_put_sync" is not in reverse order.
Probe
reset_control_deassert(rstc); pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
remove
pm_runtime_put_sync(&pdev->dev); unregister_netdev(ndev); .. ravb_mdio_release(priv); pm_runtime_disable(&pdev->dev);
Consider the call to unregister_netdev() unregister_netdev->unregister_netdevice_queue->rollback_registered_many that calls the below functions which access the registers after pm_runtime_put_sync()
1) ravb_get_stats
2) ravb_close
--- drivers/net/ethernet/renesas/ravb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/renesas/ravb_main.c +1 -1
@@ -2896,12 +2896,12 @@ static int ravb_remove(struct platform_d priv->desc_bat_dma);/* Set reset mode */ ravb_write (ndev,CCC_OPC_RESET ,CCC ); -pm_runtime_put_sync (&pdev->dev);unregister_netdev (ndev);if (info->nc_queues)netif_napi_del (&priv->napi[RAVB_NC ]);netif_napi_del (&priv->napi[RAVB_BE ]);ravb_mdio_release (priv); +pm_runtime_put_sync (&pdev->dev);pm_runtime_disable (&pdev->dev);reset_control_assert (priv->rstc);free_netdev (ndev);
Greg Kroah-Hartman
maintainerPATCH 86/177 rtc: ds1347: fix value written to century register
In reply to Greg Kroah-HartmanFrom: Ian Abbott <[email protected]>
commit 4dfe05bdc1ade79b943d4979a2e2a8b5ef68fbb5 upstream.
In ds1347_set_time(), the wrong value is being written to the DS1347_CENTURY_REG register. It needs to be converted to BCD. Fix it.
--- drivers/rtc/rtc-ds1347.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/rtc/rtc-ds1347.c +1 -1
@@ -112,7 +112,7 @@ static int ds1347_set_time(struct devicereturn err; century = (dt->tm_year /100 ) +19 ; - err =regmap_write (map,DS1347_CENTURY_REG , century); + err =regmap_write (map,DS1347_CENTURY_REG ,bin2bcd (century));if (err)return err;
Greg Kroah-Hartman
maintainerPATCH 87/177 drm/amdgpu: fix mmhub register base coding error
In reply to Greg Kroah-HartmanFrom: Yang Wang <[email protected]>
commit 347fafe0eb46df941965c355c77ce480e4d49f1f upstream.
fix MMHUB register base coding error.
--- drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c | 2 +- drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c | 2 +- drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c +1 -1
@@ -319,7 +319,7 @@ static void mmhub_v2_0_init_cache_regs(s tmp = mmMMVM_L2_CNTL5_DEFAULT; tmp =REG_SET_FIELD (tmp,MMVM_L2_CNTL5 ,L2_CACHE_SMALLK_FRAGMENT_SIZE ,0 ); -WREG32_SOC15 (GC ,0 , mmMMVM_L2_CNTL5, tmp); +WREG32_SOC15 (MMHUB ,0 , mmMMVM_L2_CNTL5, tmp); }static void mmhub_v2_0_enable_system_domain (struct amdgpu_device *adev)
drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c +1 -1
@@ -243,7 +243,7 @@ static void mmhub_v2_3_init_cache_regs(s tmp = mmMMVM_L2_CNTL5_DEFAULT; tmp =REG_SET_FIELD (tmp,MMVM_L2_CNTL5 ,L2_CACHE_SMALLK_FRAGMENT_SIZE ,0 ); -WREG32_SOC15 (GC ,0 , mmMMVM_L2_CNTL5, tmp); +WREG32_SOC15 (MMHUB ,0 , mmMMVM_L2_CNTL5, tmp); }static void mmhub_v2_3_enable_system_domain (struct amdgpu_device *adev)
drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c +1 -1
@@ -275,7 +275,7 @@ static void mmhub_v3_0_init_cache_regs(s tmp = regMMVM_L2_CNTL5_DEFAULT; tmp =REG_SET_FIELD (tmp,MMVM_L2_CNTL5 ,L2_CACHE_SMALLK_FRAGMENT_SIZE ,0 ); -WREG32_SOC15 (GC ,0 , regMMVM_L2_CNTL5, tmp); +WREG32_SOC15 (MMHUB ,0 , regMMVM_L2_CNTL5, tmp); }static void mmhub_v3_0_enable_system_domain (struct amdgpu_device *adev)
drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c +1 -1
@@ -269,7 +269,7 @@ static void mmhub_v3_0_1_init_cache_regs tmp = regMMVM_L2_CNTL5_DEFAULT; tmp =REG_SET_FIELD (tmp,MMVM_L2_CNTL5 ,L2_CACHE_SMALLK_FRAGMENT_SIZE ,0 ); -WREG32_SOC15 (GC ,0 , regMMVM_L2_CNTL5, tmp); +WREG32_SOC15 (MMHUB ,0 , regMMVM_L2_CNTL5, tmp); }static void mmhub_v3_0_1_enable_system_domain (struct amdgpu_device *adev)
drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c +1 -1
@@ -268,7 +268,7 @@ static void mmhub_v3_0_2_init_cache_regs tmp = regMMVM_L2_CNTL5_DEFAULT; tmp =REG_SET_FIELD (tmp,MMVM_L2_CNTL5 ,L2_CACHE_SMALLK_FRAGMENT_SIZE ,0 ); -WREG32_SOC15 (GC ,0 , regMMVM_L2_CNTL5, tmp); +WREG32_SOC15 (MMHUB ,0 , regMMVM_L2_CNTL5, tmp); }static void mmhub_v3_0_2_enable_system_domain (struct amdgpu_device *adev)
Greg Kroah-Hartman
maintainerPATCH 88/177 block: mq-deadline: Fix dd_finish_request() for zoned devices
In reply to Greg Kroah-HartmanFrom: Damien Le Moal <[email protected]>
commit 2820e5d0820ac4daedff1272616a53d9c7682fd2 upstream.
dd_finish_request() tests if the per prio fifo_list is not empty to determine if request dispatching must be restarted for handling blocked write requests to zoned devices with a call to blk_mq_sched_mark_restart_hctx(). While simple, this implementation has 2 problems:
1) Only the priority level of the completed request is considered. However, writes to a zone may be blocked due to other writes to the same zone using a different priority level. While this is unlikely to happen in practice, as writing a zone with different IO priorirites does not make sense, nothing in the code prevents this from happening.
2) The use of list_empty() is dangerous as dd_finish_request() does not take dd->lock and may run concurrently with the insert and dispatch code.
Fix these 2 problems by testing the write fifo list of all priority levels using the new helper dd_has_write_work(), and by testing each fifo list using list_empty_careful().
--- block/mq-deadline.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
block/mq-deadline.c +15 -2
@@ -789,6 +789,18 @@ static void dd_prepare_request(struct re rq->elv.priv[0 ] =NULL ; } +static bool dd_has_write_work (struct blk_mq_hw_ctx *hctx) +{ +struct deadline_data *dd = hctx->queue->elevator->elevator_data; +enum dd_prio p; + +for (p =0 ; p <=DD_PRIO_MAX ; p++) +if (!list_empty_careful (&dd->per_prio[p].fifo_list[DD_WRITE ])) +return true; + +return false; +} +/* * Callback from inside blk_mq_free_request(). *
@@ -828,9 +840,10 @@ static void dd_finish_request(struct reqspin_lock_irqsave (&dd->zone_lock, flags);blk_req_zone_write_unlock (rq); -if (!list_empty (&per_prio->fifo_list[DD_WRITE ])) -blk_mq_sched_mark_restart_hctx (rq->mq_hctx);spin_unlock_irqrestore (&dd->zone_lock, flags); + +if (dd_has_write_work (rq->mq_hctx)) +blk_mq_sched_mark_restart_hctx (rq->mq_hctx); } }
Greg Kroah-Hartman
maintainerPATCH 89/177 block: mq-deadline: Do not break sequential write streams to zoned HDDs
In reply to Greg Kroah-HartmanFrom: Damien Le Moal <[email protected]>
commit 015d02f48537cf2d1a65eeac50717566f9db6eec upstream.
mq-deadline ensures an in order dispatching of write requests to zoned block devices using a per zone lock (a bit). This implies that for any purely sequential write workload, the drive is exercised most of the time at a maximum queue depth of one.
However, when such sequential write workload crosses a zone boundary (when sequentially writing multiple contiguous zones), zone write locking may prevent the last write to one zone to be issued (as the previous write is still being executed) but allow the first write to the following zone to be issued (as that zone is not yet being writen and not locked). This result in an out of order delivery of the sequential write commands to the device every time a zone boundary is crossed.
While such behavior does not break the sequential write constraint of zoned block devices (and does not generate any write error), some zoned hard-disks react badly to seeing these out of order writes, resulting in lower write throughput.
This problem can be addressed by always dispatching the first request of a stream of sequential write requests, regardless of the zones targeted by these sequential writes. To do so, the function deadline_skip_seq_writes() is introduced and used in deadline_next_request() to select the next write command to issue if the target device is an HDD (blk_queue_nonrot() being false). deadline_fifo_request() is modified using the new deadline_earlier_request() and deadline_is_seq_write() helpers to ignore requests in the fifo list that have a preceding request in lba order that is sequential.
With this fix, a sequential write workload executed with the following fio command:
fio --name=seq-write --filename=/dev/sda --zonemode=zbd --direct=1 \
--size=68719476736 --ioengine=libaio --iodepth=32 --rw=write \
--bs=65536results in an increase from 225 MB/s to 250 MB/s of the write throughput of an SMR HDD (11% increase).
--- block/mq-deadline.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 4 deletions(-)
block/mq-deadline.c +62 -4
@@ -131,6 +131,20 @@ static u8 dd_rq_ioclass(struct request * }/* +* get the request before `rq' in sector-sorted order +*/ +static inline struct request * +deadline_earlier_request (struct request *rq) +{ +struct rb_node *node =rb_prev (&rq->rb_node); + +if (node) +return rb_entry_rq (node); + +return NULL ; +} + +/* * get the request after `rq' in sector-sorted order */ static inline struct request *
@@ -278,6 +292,39 @@ static inline int deadline_check_fifo(st }/* +* Check if rq has a sequential request preceding it. +*/ +static bool deadline_is_seq_writes (struct deadline_data *dd,struct request *rq) +{ +struct request *prev =deadline_earlier_request (rq); + +if (!prev) +return false; + +return blk_rq_pos (prev) +blk_rq_sectors (prev) ==blk_rq_pos (rq); +} + +/* +* Skip all write requests that are sequential from @rq, even if we cross +* a zone boundary. +*/ +static struct request *deadline_skip_seq_writes (struct deadline_data *dd, +struct request *rq) +{ +sector_t pos =blk_rq_pos (rq); +sector_t skipped_sectors =0 ; + +while (rq) { +if (blk_rq_pos (rq) != pos + skipped_sectors) +break ; + skipped_sectors +=blk_rq_sectors (rq); + rq =deadline_latter_request (rq); + } + +return rq; +} + +/* * For the specified data direction, return the next request to * dispatch using arrival ordered lists. */
@@ -297,11 +344,16 @@ deadline_fifo_request(struct deadline_da/* * Look for a write request that can be dispatched, that is one with -* an unlocked target zone. +* an unlocked target zone. For some HDDs, breaking a sequential +* write stream can lead to lower throughput, so make sure to preserve +* sequential write streams, even if that stream crosses into the next +* zones and these zones are unlocked. */ spin_lock_irqsave (&dd->zone_lock, flags);list_for_each_entry (rq, &per_prio->fifo_list[DD_WRITE ], queuelist) { -if (blk_req_can_dispatch_to_zone (rq)) +if (blk_req_can_dispatch_to_zone (rq) && + (blk_queue_nonrot (rq->q) || + !deadline_is_seq_writes (dd, rq))) goto out; } rq =NULL ;
@@ -331,13 +383,19 @@ deadline_next_request(struct deadline_da/* * Look for a write request that can be dispatched, that is one with -* an unlocked target zone. +* an unlocked target zone. For some HDDs, breaking a sequential +* write stream can lead to lower throughput, so make sure to preserve +* sequential write streams, even if that stream crosses into the next +* zones and these zones are unlocked. */ spin_lock_irqsave (&dd->zone_lock, flags);while (rq) {if (blk_req_can_dispatch_to_zone (rq))break ; - rq =deadline_latter_request (rq); +if (blk_queue_nonrot (rq->q)) + rq =deadline_latter_request (rq); +else + rq =deadline_skip_seq_writes (dd, rq); }spin_unlock_irqrestore (&dd->zone_lock, flags);
Greg Kroah-Hartman
maintainerPATCH 90/177 md/bitmap: Fix bitmap chunk size overflow issues
In reply to Greg Kroah-HartmanFrom: Florian-Ewald Mueller <[email protected]>
commit 4555211190798b6b6fa2c37667d175bf67945c78 upstream.
- limit bitmap chunk size internal u64 variable to values not overflowing the u32 bitmap superblock structure variable stored on persistent media
- assign bitmap chunk size internal u64 variable from unsigned values to avoid possible sign extension artifacts when assigning from a s32 value
The bug has been there since at least kernel 4.0.
Steps to reproduce it:
1: mdadm -C /dev/mdx -l 1 --bitmap=internal --bitmap-chunk=256M -e 1.2 -n2 /dev/rnbd1 /dev/rnbd2
2 resize member device rnbd1 and rnbd2 to 8 TB
3 mdadm --grow /dev/mdx --size=max
The bitmap_chunksize will overflow without patch.
--- drivers/md/md-bitmap.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
drivers/md/md-bitmap.c +12 -8
@@ -486,7 +486,7 @@ void md_bitmap_print_sb(struct bitmap *b sb =kmap_atomic (bitmap->storage.sb_page);pr_debug ("%s: bitmap file superblock:\n" ,bmname (bitmap));pr_debug (" magic: %08x\n" ,le32_to_cpu (sb->magic)); -pr_debug (" version: %d\n" ,le32_to_cpu (sb->version)); +pr_debug (" version: %u\n" ,le32_to_cpu (sb->version)); pr_debug(" uuid: %08x.%08x.%08x.%08x\n", le32_to_cpu(*(__le32 *)(sb->uuid+0)), le32_to_cpu(*(__le32 *)(sb->uuid+4)),
@@ -497,11 +497,11 @@ void md_bitmap_print_sb(struct bitmap *bpr_debug ("events cleared: %llu\n" , (unsigned long long )le64_to_cpu (sb->events_cleared));pr_debug (" state: %08x\n" ,le32_to_cpu (sb->state)); -pr_debug (" chunksize: %d B\n" ,le32_to_cpu (sb->chunksize)); -pr_debug (" daemon sleep: %ds\n" ,le32_to_cpu (sb->daemon_sleep)); +pr_debug (" chunksize: %u B\n" ,le32_to_cpu (sb->chunksize)); +pr_debug (" daemon sleep: %us\n" ,le32_to_cpu (sb->daemon_sleep));pr_debug (" sync size: %llu KB\n" , (unsigned long long )le64_to_cpu (sb->sync_size)/2 ); -pr_debug ("max write behind: %d\n" ,le32_to_cpu (sb->write_behind)); +pr_debug ("max write behind: %u\n" ,le32_to_cpu (sb->write_behind));kunmap_atomic (sb); }
@@ -2105,7 +2105,8 @@ int md_bitmap_resize(struct bitmap *bitm bytes =DIV_ROUND_UP (chunks,8 );if (!bitmap->mddev->bitmap_info.external) bytes +=sizeof (bitmap_super_t); - }while (bytes > (space <<9 )); + }while (bytes > (space <<9 ) && (chunkshift +BITMAP_BLOCK_SHIFT ) < + (BITS_PER_BYTE *sizeof (((bitmap_super_t *)0 )->chunksize) -1 )); }else chunkshift =ffz (~chunksize) -BITMAP_BLOCK_SHIFT ;
@@ -2150,7 +2151,7 @@ int md_bitmap_resize(struct bitmap *bitm bitmap->counts.missing_pages = pages; bitmap->counts.chunkshift = chunkshift; bitmap->counts.chunks = chunks; - bitmap->mddev->bitmap_info.chunksize =1 << (chunkshift + + bitmap->mddev->bitmap_info.chunksize =1UL << (chunkshift +BITMAP_BLOCK_SHIFT ); blocks = min(old_counts.chunks << old_counts.chunkshift,
@@ -2176,8 +2177,8 @@ int md_bitmap_resize(struct bitmap *bitm bitmap->counts.missing_pages = old_counts.pages; bitmap->counts.chunkshift = old_counts.chunkshift; bitmap->counts.chunks = old_counts.chunks; - bitmap->mddev->bitmap_info.chunksize =1 << (old_counts.chunkshift + -BITMAP_BLOCK_SHIFT ); + bitmap->mddev->bitmap_info.chunksize = +1UL << (old_counts.chunkshift +BITMAP_BLOCK_SHIFT ); blocks = old_counts.chunks << old_counts.chunkshift;pr_warn ("Could not pre-allocate in-memory bitmap for cluster raid\n" );break ;
@@ -2537,6 +2538,9 @@ chunksize_store(struct mddev *mddev, conif (csize <512 || !is_power_of_2 (csize))return -EINVAL ; +if (BITS_PER_LONG >32 && csize >= (1ULL << (BITS_PER_BYTE * +sizeof (((bitmap_super_t *)0 )->chunksize)))) +return -EOVERFLOW ; mddev->bitmap_info.chunksize = csize;return len; }
Greg Kroah-Hartman
maintainerPATCH 91/177 efi: Add iMac Pro 2017 to uefi skip cert quirk
In reply to Greg Kroah-HartmanFrom: Aditya Garg <[email protected]>
commit 0be56a116220f9e5731a6609e66a11accfe8d8e2 upstream.
The iMac Pro 2017 is also a T2 Mac. Thus add it to the list of uefi skip cert.
--- security/integrity/platform_certs/load_uefi.c | 1 + 1 file changed, 1 insertion(+)
security/integrity/platform_certs/load_uefi.c +1 -0
@@ -35,6 +35,7 @@ static const struct dmi_system_id uefi_s { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") }, { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") }, { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMacPro1,1") }, { } };
Greg Kroah-Hartman
maintainerPATCH 92/177 wifi: wilc1000: sdio: fix module autoloading
In reply to Greg Kroah-HartmanFrom: Michael Walle <[email protected]>
commit 57d545b5a3d6ce3a8fb6b093f02bfcbb908973f3 upstream.
There are no SDIO module aliases included in the driver, therefore, module autoloading isn't working. Add the proper MODULE_DEVICE_TABLE().
--- drivers/net/wireless/microchip/wilc1000/sdio.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/microchip/wilc1000/sdio.c +1 -0
@@ -20,6 +20,7 @@ static const struct sdio_device_id wilc_ { SDIO_DEVICE(SDIO_VENDOR_ID_MICROCHIP_WILC, SDIO_DEVICE_ID_MICROCHIP_WILC1000) }, { }, }; +MODULE_DEVICE_TABLE (sdio, wilc_sdio_ids);#define WILC_SDIO_BLOCK_SIZE 512
Greg Kroah-Hartman
maintainerPATCH 93/177 ASoC: jz4740-i2s: Handle independent FIFO flush bits
In reply to Greg Kroah-HartmanFrom: Aidan MacDonald <[email protected]>
commit 8b3a9ad86239f80ed569e23c3954a311f66481d6 upstream.
On the JZ4740, there is a single bit that flushes (empties) both the transmit and receive FIFO. Later SoCs have independent flush bits for each FIFO.
Independent FIFOs can be flushed before the snd_soc_dai_active() check because it won't disturb other active streams. This ensures that the FIFO we're about to use is always flushed before starting up. With shared FIFOs we can't do that because if another substream is active, flushing its FIFO would cause underrun errors.
This also fixes a bug: since we were only setting the JZ4740's flush bit, which corresponds to the TX FIFO flush bit on other SoCs, other SoCs were not having their RX FIFO flushed at all.
--- sound/soc/jz4740/jz4740-i2s.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-)
sound/soc/jz4740/jz4740-i2s.c +34 -5
@@ -55,7 +55,8 @@#define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)#define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)#define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9) -#define JZ_AIC_CTRL_FLUSH BIT(8) +#define JZ_AIC_CTRL_TFLUSH BIT(8) +#define JZ_AIC_CTRL_RFLUSH BIT(7)#define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)#define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)#define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
@@ -90,6 +91,8 @@ enum jz47xx_i2s_version {struct i2s_soc_info {enum jz47xx_i2s_version version;struct snd_soc_dai_driver *dai; + +bool shared_fifo_flush; };struct jz4740_i2s {
@@ -116,19 +119,44 @@ static inline void jz4740_i2s_write(conswritel (value, i2s->base + reg); } +static inline void jz4740_i2s_set_bits (const struct jz4740_i2s *i2s, +unsigned int reg,uint32_t bits) +{ +uint32_t value =jz4740_i2s_read (i2s, reg); + value |= bits; +jz4740_i2s_write (i2s, reg, value); +} +static int jz4740_i2s_startup (struct snd_pcm_substream *substream,struct snd_soc_dai *dai) {struct jz4740_i2s *i2s =snd_soc_dai_get_drvdata (dai); -uint32_t conf, ctrl; +uint32_t conf;int ret; +/* +* When we can flush FIFOs independently, only flush the FIFO +* that is starting up. We can do this when the DAI is active +* because it does not disturb other active substreams. +*/ +if (!i2s->soc_info->shared_fifo_flush) { +if (substream->stream ==SNDRV_PCM_STREAM_PLAYBACK ) +jz4740_i2s_set_bits (i2s,JZ_REG_AIC_CTRL ,JZ_AIC_CTRL_TFLUSH ); +else +jz4740_i2s_set_bits (i2s,JZ_REG_AIC_CTRL ,JZ_AIC_CTRL_RFLUSH ); + } +if (snd_soc_dai_active (dai))return 0 ; - ctrl =jz4740_i2s_read (i2s,JZ_REG_AIC_CTRL ); - ctrl |=JZ_AIC_CTRL_FLUSH ; -jz4740_i2s_write (i2s,JZ_REG_AIC_CTRL , ctrl); +/* +* When there is a shared flush bit for both FIFOs, the TFLUSH +* bit flushes both FIFOs. Flushing while the DAI is active would +* cause FIFO underruns in other active substreams so we have to +* guard this behind the snd_soc_dai_active() check. +*/ +if (i2s->soc_info->shared_fifo_flush) +jz4740_i2s_set_bits (i2s,JZ_REG_AIC_CTRL ,JZ_AIC_CTRL_TFLUSH ); ret =clk_prepare_enable (i2s->clk_i2s);if (ret)
@@ -443,6 +471,7 @@ static struct snd_soc_dai_driver jz4740_static const struct i2s_soc_info jz4740_i2s_soc_info = { .version =JZ_I2S_JZ4740 , .dai = &jz4740_i2s_dai, + .shared_fifo_flush = true, };static const struct i2s_soc_info jz4760_i2s_soc_info = {
Greg Kroah-Hartman
maintainerPATCH 94/177 ipu3-imgu: Fix NULL pointer dereference in imgu_subdev_set_selection()
In reply to Greg Kroah-HartmanFrom: Maximilian Luz <[email protected]>
commit dc608edf7d45ba0c2ad14c06eccd66474fec7847 upstream.
Calling v4l2_subdev_get_try_crop() and v4l2_subdev_get_try_compose() with a subdev state of NULL leads to a NULL pointer dereference. This can currently happen in imgu_subdev_set_selection() when the state passed in is NULL, as this method first gets pointers to both the "try" and "active" states and only then decides which to use.
The same issue has been addressed for imgu_subdev_get_selection() with commit 30d03a0de650 ("ipu3-imgu: Fix NULL pointer dereference in active selection access"). However the issue still persists in imgu_subdev_set_selection().
Therefore, apply a similar fix as done in the aforementioned commit to imgu_subdev_set_selection(). To keep things a bit cleaner, introduce helper functions for "crop" and "compose" access and use them in both imgu_subdev_set_selection() and imgu_subdev_get_selection().
--- drivers/staging/media/ipu3/ipu3-v4l2.c | 57 +++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 23 deletions(-)
drivers/staging/media/ipu3/ipu3-v4l2.c +34 -23
@@ -188,6 +188,28 @@ static int imgu_subdev_set_fmt(struct v4return 0 ; } +static struct v4l2_rect * +imgu_subdev_get_crop (struct imgu_v4l2_subdev *sd, +struct v4l2_subdev_state *sd_state,unsigned int pad, +enum v4l2_subdev_format_whence which) +{ +if (which ==V4L2_SUBDEV_FORMAT_TRY ) +return v4l2_subdev_get_try_crop (&sd->subdev, sd_state, pad); +else +return &sd->rect.eff; +} + +static struct v4l2_rect * +imgu_subdev_get_compose (struct imgu_v4l2_subdev *sd, +struct v4l2_subdev_state *sd_state,unsigned int pad, +enum v4l2_subdev_format_whence which) +{ +if (which ==V4L2_SUBDEV_FORMAT_TRY ) +return v4l2_subdev_get_try_compose (&sd->subdev, sd_state, pad); +else +return &sd->rect.bds; +} +static int imgu_subdev_get_selection (struct v4l2_subdev *sd,struct v4l2_subdev_state *sd_state,struct v4l2_subdev_selection *sel)
@@ -200,18 +222,12 @@ static int imgu_subdev_get_selection(strswitch (sel->target) {case V4L2_SEL_TGT_CROP : -if (sel->which ==V4L2_SUBDEV_FORMAT_TRY ) - sel->r = *v4l2_subdev_get_try_crop (sd, sd_state, - sel->pad); -else - sel->r = imgu_sd->rect.eff; + sel->r = *imgu_subdev_get_crop (imgu_sd, sd_state, sel->pad, + sel->which);return 0 ;case V4L2_SEL_TGT_COMPOSE : -if (sel->which ==V4L2_SUBDEV_FORMAT_TRY ) - sel->r = *v4l2_subdev_get_try_compose (sd, sd_state, - sel->pad); -else - sel->r = imgu_sd->rect.bds; + sel->r = *imgu_subdev_get_compose (imgu_sd, sd_state, sel->pad, + sel->which);return 0 ;default :return -EINVAL ;
@@ -223,10 +239,9 @@ static int imgu_subdev_set_selection(str struct v4l2_subdev_selection *sel) {struct imgu_device *imgu =v4l2_get_subdevdata (sd); -struct imgu_v4l2_subdev *imgu_sd =container_of (sd, - struct imgu_v4l2_subdev, - subdev); -struct v4l2_rect *rect, *try_sel; +struct imgu_v4l2_subdev *imgu_sd = + container_of(sd, struct imgu_v4l2_subdev, subdev); +struct v4l2_rect *rect; dev_dbg(&imgu->pci_dev->dev, "set subdev %u sel which %u target 0x%4x rect [%ux%u]",
@@ -238,22 +253,18 @@ static int imgu_subdev_set_selection(strswitch (sel->target) {case V4L2_SEL_TGT_CROP : - try_sel =v4l2_subdev_get_try_crop (sd, sd_state, sel->pad); - rect = &imgu_sd->rect.eff; + rect =imgu_subdev_get_crop (imgu_sd, sd_state, sel->pad, + sel->which);break ;case V4L2_SEL_TGT_COMPOSE : - try_sel =v4l2_subdev_get_try_compose (sd, sd_state, sel->pad); - rect = &imgu_sd->rect.bds; + rect =imgu_subdev_get_compose (imgu_sd, sd_state, sel->pad, + sel->which);break ;default :return -EINVAL ; } -if (sel->which ==V4L2_SUBDEV_FORMAT_TRY ) - *try_sel = sel->r; -else - *rect = sel->r; - + *rect = sel->r;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 95/177 ipmi: fix long wait in unload when IPMI disconnect
In reply to Greg Kroah-HartmanFrom: Zhang Yuchen <[email protected]>
commit f6f1234d98cce69578bfac79df147a1f6660596c upstream.
When fixing the problem mentioned in PATCH1, we also found the following problem:
If the IPMI is disconnected and in the sending process, the uninstallation driver will be stuck for a long time.
The main problem is that uninstalling the driver waits for curr_msg to be sent or HOSED. After stopping tasklet, the only place to trigger the timeout mechanism is the circular poll in shutdown_smi.
The poll function delays 10us and calls smi_event_handler(smi_info,10). Smi_event_handler deducts 10us from kcs->ibf_timeout.
But the poll func is followed by schedule_timeout_uninterruptible(1). The time consumed here is not counted in kcs->ibf_timeout.
So when 10us is deducted from kcs->ibf_timeout, at least 1 jiffies has actually passed. The waiting time has increased by more than a hundredfold.
Now instead of calling poll(). call smi_event_handler() directly and calculate the elapsed time.
For verification, you can directly use ebpf to check the kcs-> ibf_timeout for each call to kcs_event() when IPMI is disconnected. Decrement at normal rate before unloading. The decrement rate becomes very slow after unloading.
$ bpftrace -e 'kprobe:kcs_event {printf("kcs->ibftimeout : %d\n",
*(arg0+584));}'Message-Id: <[email protected]>
--- drivers/char/ipmi/ipmi_si_intf.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-)
drivers/char/ipmi/ipmi_si_intf.c +19 -8
@@ -2153,6 +2153,20 @@ skip_fallback_noirq: }module_init (init_ipmi_si); +static void wait_msg_processed (struct smi_info *smi_info) +{ +unsigned long jiffies_now; +long time_diff; + +while (smi_info->curr_msg || (smi_info->si_state !=SI_NORMAL )) { + jiffies_now = jiffies; + time_diff = (((long )jiffies_now - (long )smi_info->last_timeout_jiffies) + *SI_USEC_PER_JIFFY ); +smi_event_handler (smi_info, time_diff); +schedule_timeout_uninterruptible (1 ); + } +} +static void shutdown_smi (void *send_info) {struct smi_info *smi_info = send_info;
@@ -2187,16 +2201,13 @@ static void shutdown_smi(void *send_info* in the BMC. Note that timers and CPU interrupts are off, * so no need for locks. */ -while (smi_info->curr_msg || (smi_info->si_state !=SI_NORMAL )) { -poll (smi_info); -schedule_timeout_uninterruptible (1 ); - } +wait_msg_processed (smi_info); +if (smi_info->handlers)disable_si_irq (smi_info); -while (smi_info->curr_msg || (smi_info->si_state !=SI_NORMAL )) { -poll (smi_info); -schedule_timeout_uninterruptible (1 ); - } + +wait_msg_processed (smi_info); +if (smi_info->handlers) smi_info->handlers->cleanup (smi_info->si_sm);
Greg Kroah-Hartman
maintainerPATCH 96/177 mtd: spi-nor: Check for zero erase size in spi_nor_find_best_erase_type()
In reply to Greg Kroah-HartmanFrom: Alexander Sverdlin <[email protected]>
commit 2ebc336be08160debfe27f87660cf550d710f3e9 upstream.
Erase can be zeroed in spi_nor_parse_4bait() or spi_nor_init_non_uniform_erase_map(). In practice it happened with mt25qu256a, which supports 4K, 32K, 64K erases with 3b address commands, but only 4K and 64K erase with 4b address commands.
--- drivers/mtd/spi-nor/core.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/mtd/spi-nor/core.c +2 -0
@@ -1184,6 +1184,8 @@ spi_nor_find_best_erase_type(const struccontinue ; erase = &map->erase_type[i]; +if (!erase->size) +continue ;/* Alignment is not mandatory for overlaid regions */ if (region->offset & SNOR_OVERLAID_REGION &&
Greg Kroah-Hartman
maintainerPATCH 97/177 ima: Fix a potential NULL pointer access in ima_restore_measurement_list
In reply to Greg Kroah-HartmanFrom: Huaxin Lu <[email protected]>
commit 11220db412edae8dba58853238f53258268bdb88 upstream.
In restore_template_fmt, when kstrdup fails, a non-NULL value will still be returned, which causes a NULL pointer access in template_desc_init_fields.
--- security/integrity/ima/ima_template.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
security/integrity/ima/ima_template.c +4 -1
@@ -340,8 +340,11 @@ static struct ima_template_desc *restore template_desc->name ="" ; template_desc->fmt =kstrdup (template_name,GFP_KERNEL ); -if (!template_desc->fmt) +if (!template_desc->fmt) { +kfree (template_desc); + template_desc =NULL ; goto out; + }spin_lock (&template_list);list_add_tail_rcu (&template_desc->list, &defined_templates);
Greg Kroah-Hartman
maintainerPATCH 98/177 ipmi: fix use after free in _ipmi_destroy_user()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit a92ce570c81dc0feaeb12a429b4bc65686d17967 upstream.
The intf_free() function frees the "intf" pointer so we cannot dereference it again on the next line.
Message-Id: <Y3M8xa1drZv4CToE@kili>
--- drivers/char/ipmi/ipmi_msghandler.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/char/ipmi/ipmi_msghandler.c +3 -1
@@ -1336,6 +1336,7 @@ static void _ipmi_destroy_user(struct ipunsigned long flags;struct cmd_rcvr *rcvr;struct cmd_rcvr *rcvrs =NULL ; +struct module *owner;if (!acquire_ipmi_user (user, &i)) {/*
@@ -1398,8 +1399,9 @@ static void _ipmi_destroy_user(struct ipkfree (rcvr); } + owner = intf->owner;kref_put (&intf->refcount, intf_free); -module_put (intf->owner); +module_put (owner); }int ipmi_destroy_user (struct ipmi_user *user)
Greg Kroah-Hartman
maintainerPATCH 99/177 mtd: spi-nor: gigadevice: gd25q256: replace gd25q256_default_init with gd25q256_post_bfpt
In reply to Greg Kroah-HartmanFrom: Yaliang Wang <[email protected]>
commit 4dc49062a7e9c0c7261807fb855df1c611eb78c3 upstream.
When utilizing PARSE_SFDP to initialize the flash parameter, the deprecated initializing method spi_nor_init_params_deprecated() and the function spi_nor_manufacturer_init_params() within it will never be executed, which results in the default_init hook function will also never be executed.
This is okay for 'D' generation of GD25Q256, because 'D' generation is implementing the JESD216B standards, it has QER field defined in BFPT, parsing the SFDP can properly set the quad_enable function. The 'E' generation also implements the JESD216B standards, and it has the same status register definitions as 'D' generation, parsing the SFDP to set the quad_enable function should also work for 'E' generation.
However, the same thing can't apply to 'C' generation. 'C' generation 'GD25Q256C' implements the JESD216 standards, and it doesn't have the QER field defined in BFPT, since it does have QE bit in status register 1, the quad_enable hook needs to be tweaked to properly set the quad_enable function, this can be done in post_bfpt fixup hook.
--- drivers/mtd/spi-nor/gigadevice.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-)
drivers/mtd/spi-nor/gigadevice.c +17 -7
@@ -8,19 +8,29 @@#include "core.h" -static void gd25q256_default_init (struct spi_nor *nor) +static int +gd25q256_post_bfpt (struct spi_nor *nor, +const struct sfdp_parameter_header *bfpt_header, +const struct sfdp_bfpt *bfpt) {/* -* Some manufacturer like GigaDevice may use different -* bit to set QE on different memories, so the MFR can't -* indicate the quad_enable method for this case, we need -* to set it in the default_init fixup hook. +* GD25Q256C supports the first version of JESD216 which does not define +* the Quad Enable methods. Overwrite the default Quad Enable method. +* +* GD25Q256 GENERATION | SFDP MAJOR VERSION | SFDP MINOR VERSION +* GD25Q256C | SFDP_JESD216_MAJOR | SFDP_JESD216_MINOR +* GD25Q256D | SFDP_JESD216_MAJOR | SFDP_JESD216B_MINOR +* GD25Q256E | SFDP_JESD216_MAJOR | SFDP_JESD216B_MINOR */ - nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; +if (bfpt_header->major ==SFDP_JESD216_MAJOR && + bfpt_header->minor ==SFDP_JESD216_MINOR ) + nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; + +return 0 ; }static const struct spi_nor_fixups gd25q256_fixups = { - .default_init = gd25q256_default_init, + .post_bfpt = gd25q256_post_bfpt, };static const struct flash_info gigadevice_nor_parts[] = {
Greg Kroah-Hartman
maintainerPATCH 100/177 ima: Fix memory leak in __ima_inode_hash()
In reply to Greg Kroah-HartmanFrom: Roberto Sassu <[email protected]>
commit 8c1d6a050a0f16e0a9d32eaf53b965c77279c6f8 upstream.
Commit f3cc6b25dcc5 ("ima: always measure and audit files in policy") lets measurement or audit happen even if the file digest cannot be calculated.
As a result, iint->ima_hash could have been allocated despite ima_collect_measurement() returning an error.
Since ima_hash belongs to a temporary inode metadata structure, declared at the beginning of __ima_inode_hash(), just add a kfree() call if ima_collect_measurement() returns an error different from -ENOMEM (in that case, ima_hash should not have been allocated).
--- security/integrity/ima/ima_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
security/integrity/ima/ima_main.c +6 -1
@@ -542,8 +542,13 @@ static int __ima_inode_hash(struct inode *inode, struct file *file, char *buf, rc =ima_collect_measurement (&tmp_iint, file,NULL ,0 , ima_hash_algo,NULL ); -if (rc <0 ) +if (rc <0 ) { +/* ima_hash could be allocated in case of failure. */ +if (rc != -ENOMEM ) +kfree (tmp_iint.ima_hash); +return -EOPNOTSUPP ; + } iint = &tmp_iint;mutex_lock (&iint->mutex);
Signature · 1 line
2.39.0
Greg Kroah-Hartman
maintainerPATCH 101/177 crypto: ccree,hisilicon - Fix dependencies to correct algorithm
In reply to Greg Kroah-HartmanFrom: Tianjia Zhang <[email protected]>
commit 2ae6feb1a1f6678fe11864f1b6920ed10b09ad6a upstream.
Commit d2825fa9365d ("crypto: sm3,sm4 - move into crypto directory") moves the SM3 and SM4 stand-alone library and the algorithm implementation for the Crypto API into the same directory, and the corresponding relationship of Kconfig is modified, CONFIG_CRYPTO_SM3/4 corresponds to the stand-alone library of SM3/4, and CONFIG_CRYPTO_SM3/4_GENERIC corresponds to the algorithm implementation for the Crypto API. Therefore, it is necessary for this module to depend on the correct algorithm.
--- drivers/crypto/Kconfig | 4 ++-- drivers/crypto/hisilicon/Kconfig | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/crypto/Kconfig +2 -2
@@ -790,8 +790,8 @@ config CRYPTO_DEV_CCREE select CRYPTO_ECB select CRYPTO_CTR select CRYPTO_XTS - select CRYPTO_SM4 - select CRYPTO_SM3 + select CRYPTO_SM4_GENERIC + select CRYPTO_SM3_GENERIC help Say 'Y' to enable a driver for the REE interface of the Arm TrustZone CryptoCell family of processors. Currently the
drivers/crypto/hisilicon/Kconfig +1 -1
@@ -26,7 +26,7 @@ config CRYPTO_DEV_HISI_SEC2 select CRYPTO_SHA1 select CRYPTO_SHA256 select CRYPTO_SHA512 - select CRYPTO_SM4 + select CRYPTO_SM4_GENERIC depends on PCI && PCI_MSI depends on UACCE || UACCE=n depends on ARM64 || (COMPILE_TEST && 64BIT)
Greg Kroah-Hartman
maintainerPATCH 102/177 PCI: Fix pci_device_is_present() for VFs by checking PF
In reply to Greg Kroah-HartmanFrom: Michael S. Tsirkin <[email protected]>
commit 98b04dd0b4577894520493d96bc4623387767445 upstream.
pci_device_is_present() previously didn't work for VFs because it reads the Vendor and Device ID, which are 0xffff for VFs, which looks like they aren't present. Check the PF instead.
Wei Gong reported that if virtio I/O is in progress when the driver is unbound or "0" is written to /sys/.../sriov_numvfs, the virtio I/O operation hangs, which may result in output like this:
task:bash state:D stack: 0 pid: 1773 ppid: 1241 flags:0x00004002
Call Trace: schedule+0x4f/0xc0 blk_mq_freeze_queue_wait+0x69/0xa0 blk_mq_freeze_queue+0x1b/0x20 blk_cleanup_queue+0x3d/0xd0 virtblk_remove+0x3c/0xb0 [virtio_blk] virtio_dev_remove+0x4b/0x80 ... device_unregister+0x1b/0x60 unregister_virtio_device+0x18/0x30 virtio_pci_remove+0x41/0x80 pci_device_remove+0x3e/0xb0
This happened because pci_device_is_present(VF) returned "false" in virtio_pci_remove(), so it called virtio_break_device(). The broken vq meant that vring_interrupt() skipped the vq.callback() that would have completed the virtio I/O operation via virtblk_done().
--- drivers/pci/pci.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pci/pci.c +2 -0
@@ -6462,6 +6462,8 @@ bool pci_device_is_present(struct pci_de {u32 v; +/* Check PF if pdev is a VF, since VF Vendor/Device IDs are 0xffff */ + pdev =pci_physfn (pdev);if (pci_dev_is_disconnected (pdev))return false;return pci_bus_read_dev_vendor_id (pdev->bus, pdev->devfn, &v,0 );
Greg Kroah-Hartman
maintainerPATCH 103/177 PCI/sysfs: Fix double free in error path
In reply to Greg Kroah-HartmanFrom: Sascha Hauer <[email protected]>
commit aa382ffa705bea9931ec92b6f3c70e1fdb372195 upstream.
When pci_create_attr() fails, pci_remove_resource_files() is called which will iterate over the res_attr[_wc] arrays and frees every non NULL entry. To avoid a double free here set the array entry only after it's clear we successfully initialized it.
--- drivers/pci/pci-sysfs.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/pci/pci-sysfs.c +9 -4
@@ -1174,11 +1174,9 @@ static int pci_create_attr(struct pci_desysfs_bin_attr_init (res_attr);if (write_combine) { - pdev->res_attr_wc[num] = res_attr;sprintf (res_attr_name,"resource%d_wc" , num); res_attr->mmap = pci_mmap_resource_wc; }else { - pdev->res_attr[num] = res_attr;sprintf (res_attr_name,"resource%d" , num);if (pci_resource_flags (pdev, num) &IORESOURCE_IO ) { res_attr->read = pci_read_resource_io;
@@ -1196,10 +1194,17 @@ static int pci_create_attr(struct pci_de res_attr->size =pci_resource_len (pdev, num); res_attr->private = (void *)(unsigned long )num; retval =sysfs_create_bin_file (&pdev->dev.kobj, res_attr); -if (retval) +if (retval) {kfree (res_attr); +return retval; + } + +if (write_combine) + pdev->res_attr_wc[num] = res_attr; +else + pdev->res_attr[num] = res_attr; -return retval; +return 0 ; }/**
Greg Kroah-Hartman
maintainerPATCH 104/177 RISC-V: kexec: Fix memory leak of fdt buffer
In reply to Greg Kroah-HartmanFrom: Li Huafei <[email protected]>
commit 96df59b1ae23f5c11698c3c2159aeb2ecd4944a4 upstream.
This is reported by kmemleak detector:
unreferenced object 0xff60000082864000 (size 9588):
comm "kexec", pid 146, jiffies 4294900634 (age 64.788s) hex dump (first 32 bytes):
d0 0d fe ed 00 00 12 ed 00 00 00 48 00 00 11 40 ...........H...@
00 00 00 28 00 00 00 11 00 00 00 02 00 00 00 00 ...(............
backtrace:
[<00000000f95b17c4>] kmemleak_alloc+0x34/0x3e
[<00000000b9ec8e3e>] kmalloc_order+0x9c/0xc4
[<00000000a95cf02e>] kmalloc_order_trace+0x34/0xb6
[<00000000f01e68b4>] __kmalloc+0x5c2/0x62a
[<000000002bd497b2>] kvmalloc_node+0x66/0xd6
[<00000000906542fa>] of_kexec_alloc_and_setup_fdt+0xa6/0x6ea
[<00000000e1166bde>] elf_kexec_load+0x206/0x4ec
[<0000000036548e09>] kexec_image_load_default+0x40/0x4c
[<0000000079fbe1b4>] sys_kexec_file_load+0x1c4/0x322
[<0000000040c62c03>] ret_from_syscall+0x0/0x2In elf_kexec_load(), a buffer is allocated via kvmalloc() to store fdt. While it's not freed back to system when kexec kernel is reloaded or unloaded. Then memory leak is caused. Fix it by introducing riscv specific function arch_kimage_file_post_load_cleanup(), and freeing the buffer there.
--- arch/riscv/include/asm/kexec.h | 5 +++++ arch/riscv/kernel/elf_kexec.c | 10 ++++++++++ 2 files changed, 15 insertions(+)
arch/riscv/include/asm/kexec.h +5 -0
@@ -39,6 +39,7 @@ crash_setup_regs(struct pt_regs *newregs,#define ARCH_HAS_KIMAGE_ARCH struct kimage_arch { +void *fdt;/* For CONFIG_KEXEC_FILE */ unsigned long fdt_addr; };
@@ -62,6 +63,10 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,const Elf_Shdr *relsec, const Elf_Shdr *symtab);#define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add + +struct kimage ; +int arch_kimage_file_post_load_cleanup (struct kimage *image); +#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup#endif #endif
arch/riscv/kernel/elf_kexec.c +10 -0
@@ -21,6 +21,14 @@#include <linux/memblock.h> #include <asm/setup.h> +int arch_kimage_file_post_load_cleanup (struct kimage *image) +{ +kvfree (image->arch.fdt); + image->arch.fdt =NULL ; + +return kexec_image_post_load_cleanup_default (image); +} +static int riscv_kexec_elf_load (struct kimage *image,struct elfhdr *ehdr,struct kexec_elf_info *elf_info,unsigned long old_pbase,unsigned long new_pbase)
@@ -298,6 +306,8 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,pr_err ("Error add DTB kbuf ret=%d\n" , ret); goto out_free_fdt; } +/* Cache the fdt buffer address for memory cleanup */ + image->arch.fdt = fdt;pr_notice ("Loaded device tree at 0x%lx\n" , kbuf.mem); goto out;
Signature · 1 line
2.39.0
Greg Kroah-Hartman
maintainerPATCH 105/177 riscv: Fixup compile error with !MMU
In reply to Greg Kroah-HartmanFrom: Guo Ren <[email protected]>
commit c528ef0888b75f673f7d48022de8d31d5b451e8c upstream.
Current nommu_virt_defconfig can't compile:
In file included from arch/riscv/kernel/crash_core.c:3:arch/riscv/kernel/crash_core.c:
In function 'arch_crash_save_vmcoreinfo':arch/riscv/kernel/crash_core.c:8:27:
error: 'VA_BITS' undeclared (first use in this function)
8 | VMCOREINFO_NUMBER(VA_BITS);
| ^~~~~~~Add MMU dependency for KEXEC_FILE.
--- arch/riscv/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/Kconfig +1 -1
@@ -493,7 +493,7 @@ config KEXEC_FILE select KEXEC_CORE select KEXEC_ELF select HAVE_IMA_KEXEC if IMA - depends on 64BIT + depends on 64BIT && MMU help This is new version of kexec system call. This system call is file based and takes file descriptors as system call argument
Greg Kroah-Hartman
maintainerPATCH 106/177 RISC-V: kexec: Fix memory leak of elf header buffer
In reply to Greg Kroah-HartmanFrom: Li Huafei <[email protected]>
commit cbc32023ddbdf4baa3d9dc513a2184a84080a5a2 upstream.
This is reported by kmemleak detector:
unreferenced object 0xff2000000403d000 (size 4096):
comm "kexec", pid 146, jiffies 4294900633 (age 64.792s) hex dump (first 32 bytes):
7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 .ELF............
04 00 f3 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<00000000566ca97c>] kmemleak_vmalloc+0x3c/0xbe
[<00000000979283d8>] __vmalloc_node_range+0x3ac/0x560
[<00000000b4b3712a>] __vmalloc_node+0x56/0x62
[<00000000854f75e2>] vzalloc+0x2c/0x34
[<00000000e9a00db9>] crash_prepare_elf64_headers+0x80/0x30c
[<0000000067e8bf48>] elf_kexec_load+0x3e8/0x4ec
[<0000000036548e09>] kexec_image_load_default+0x40/0x4c
[<0000000079fbe1b4>] sys_kexec_file_load+0x1c4/0x322
[<0000000040c62c03>] ret_from_syscall+0x0/0x2In elf_kexec_load(), a buffer is allocated via vzalloc() to store elf headers. While it's not freed back to system when kdump kernel is reloaded or unloaded, or when image->elf_header is successfully set and then fails to load kdump kernel for some reason. Fix it by freeing the buffer in arch_kimage_file_post_load_cleanup().
--- arch/riscv/kernel/elf_kexec.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/riscv/kernel/elf_kexec.c +4 -0
@@ -26,6 +26,10 @@ int arch_kimage_file_post_load_cleanup(skvfree (image->arch.fdt); image->arch.fdt =NULL ; +vfree (image->elf_headers); + image->elf_headers =NULL ; + image->elf_headers_sz =0 ; +return kexec_image_post_load_cleanup_default (image); }
Greg Kroah-Hartman
maintainerPATCH 107/177 riscv: stacktrace: Fixup ftrace_graph_ret_addr retp argument
In reply to Greg Kroah-HartmanFrom: Guo Ren <[email protected]>
commit 5c3022e4a616d800cf5f4c3a981d7992179e44a1 upstream.
The 'retp' is a pointer to the return address on the stack, so we must pass the current return address pointer as the 'retp' argument to ftrace_push_return_trace(). Not parent function's return address on the stack.
--- arch/riscv/kernel/stacktrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/kernel/stacktrace.c +1 -1
@@ -58,7 +58,7 @@ void notrace walk_stackframe(struct task }else { fp = frame->fp; pc =ftrace_graph_ret_addr (current,NULL , frame->ra, - (unsigned long *)(fp -8 )); + &frame->ra); } }
Greg Kroah-Hartman
maintainerPATCH 108/177 riscv: mm: notify remote harts about mmu cache updates
In reply to Greg Kroah-HartmanFrom: Sergey Matyukevich <[email protected]>
commit 4bd1d80efb5af640f99157f39b50fb11326ce641 upstream.
Current implementation of update_mmu_cache function performs local TLB flush. It does not take into account ASID information. Besides, it does not take into account other harts currently running the same mm context or possible migration of the running context to other harts. Meanwhile TLB flush is not performed for every context switch if ASID support is enabled.
Patch [1] proposed to add ASID support to update_mmu_cache to avoid flushing local TLB entirely. This patch takes into account other harts currently running the same mm context as well as possible migration of this context to other harts.
For this purpose the approach from flush_icache_mm is reused. Remote harts currently running the same mm context are informed via SBI calls that they need to flush their local TLBs. All the other harts are marked as needing a deferred TLB flush when this mm context runs on them.
[1] https://lore.kernel.org/linux-riscv/[email protected]/
--- arch/riscv/include/asm/mmu.h | 2 ++ arch/riscv/include/asm/pgtable.h | 2 +- arch/riscv/include/asm/tlbflush.h | 18 ++++++++++++++++++ arch/riscv/mm/context.c | 10 ++++++++++ arch/riscv/mm/tlbflush.c | 28 +++++++++++----------------- 5 files changed, 42 insertions(+), 18 deletions(-)
arch/riscv/include/asm/mmu.h +2 -0
@@ -19,6 +19,8 @@ typedef struct {#ifdef CONFIG_SMP /* A local icache flush is needed before user execution can resume. */ cpumask_t icache_stale_mask; +/* A local tlb flush is needed before user execution can resume. */ +cpumask_t tlb_stale_mask;#endif } mm_context_t;
arch/riscv/include/asm/pgtable.h +1 -1
@@ -415,7 +415,7 @@ static inline void update_mmu_cache(stru* Relying on flush_tlb_fix_spurious_fault would suffice, but * the extra traps reduce performance. So, eagerly SFENCE.VMA. */ -local_flush_tlb_page (address); +flush_tlb_page (vma, address); } static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
arch/riscv/include/asm/tlbflush.h +18 -0
@@ -22,6 +22,24 @@ static inline void local_flush_tlb_page( {ALT_FLUSH_TLB_PAGE (__asm__ __volatile__ ("sfence.vma %0" : :"r" (addr) :"memory" )); } + +static inline void local_flush_tlb_all_asid (unsigned long asid) +{ + __asm__ __volatile__ ("sfence.vma x0, %0" + : + :"r" (asid) + :"memory" ); +} + +static inline void local_flush_tlb_page_asid (unsigned long addr, +unsigned long asid) +{ + __asm__ __volatile__ ("sfence.vma %0, %1" + : + :"r" (addr),"r" (asid) + :"memory" ); +} +#else /* CONFIG_MMU */ #define local_flush_tlb_all () do { } while (0)#define local_flush_tlb_page (addr) do { } while (0)
arch/riscv/mm/context.c +10 -0
@@ -196,6 +196,16 @@ switch_mm_fast:if (need_flush_tlb)local_flush_tlb_all (); +#ifdef CONFIG_SMP + else { +cpumask_t *mask = &mm->context.tlb_stale_mask; + +if (cpumask_test_cpu (cpu, mask)) { +cpumask_clear_cpu (cpu, mask); +local_flush_tlb_all_asid (cntx & asid_mask); + } + } +#endif }static void set_mm_noasid (struct mm_struct *mm)
arch/riscv/mm/tlbflush.c +11 -17
@@ -5,23 +5,7 @@#include <linux/sched.h> #include <asm/sbi.h> #include <asm/mmu_context.h> - -static inline void local_flush_tlb_all_asid (unsigned long asid) -{ - __asm__ __volatile__ ("sfence.vma x0, %0" - : - :"r" (asid) - :"memory" ); -} - -static inline void local_flush_tlb_page_asid (unsigned long addr, -unsigned long asid) -{ - __asm__ __volatile__ ("sfence.vma %0, %1" - : - :"r" (addr),"r" (asid) - :"memory" ); -} +#include <asm/tlbflush.h> void flush_tlb_all (void ) {
@@ -31,6 +15,7 @@ void flush_tlb_all(void)static void __sbi_tlb_flush_range (struct mm_struct *mm,unsigned long start,unsigned long size,unsigned long stride) { +struct cpumask *pmask = &mm->context.tlb_stale_mask;struct cpumask *cmask =mm_cpumask (mm);unsigned int cpuid;bool broadcast;
@@ -44,6 +29,15 @@ static void __sbi_tlb_flush_range(structif (static_branch_unlikely (&use_asid_allocator)) {unsigned long asid =atomic_long_read (&mm->context.id); +/* +* TLB will be immediately flushed on harts concurrently +* executing this MM context. TLB flush on other harts +* is deferred until this MM context migrates there. +*/ +cpumask_setall (pmask); +cpumask_clear_cpu (cpuid, pmask); +cpumask_andnot (pmask, pmask, cmask); +if (broadcast) {sbi_remote_sfence_vma_asid (cmask, start, size, asid); }else if (size <= stride) {
Greg Kroah-Hartman
maintainerPATCH 109/177 crypto: n2 - add missing hash statesize
In reply to Greg Kroah-HartmanFrom: Corentin Labbe <[email protected]>
commit 76a4e874593543a2dff91d249c95bac728df2774 upstream.
Add missing statesize to hash templates.
This is mandatory otherwise no algorithms can be registered as the core requires statesize to be set.
--- drivers/crypto/n2_core.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/crypto/n2_core.c +6 -0
@@ -1229,6 +1229,7 @@ struct n2_hash_tmpl {const u8 *hash_init;u8 hw_op_hashsz;u8 digest_size; +u8 statesize;u8 block_size;u8 auth_type;u8 hmac_type;
@@ -1260,6 +1261,7 @@ static const struct n2_hash_tmpl hash_tm .hmac_type = AUTH_TYPE_HMAC_MD5, .hw_op_hashsz = MD5_DIGEST_SIZE, .digest_size = MD5_DIGEST_SIZE, + .statesize = sizeof(struct md5_state), .block_size = MD5_HMAC_BLOCK_SIZE }, { .name = "sha1", .hash_zero = sha1_zero_message_hash,
@@ -1268,6 +1270,7 @@ static const struct n2_hash_tmpl hash_tm .hmac_type = AUTH_TYPE_HMAC_SHA1, .hw_op_hashsz = SHA1_DIGEST_SIZE, .digest_size = SHA1_DIGEST_SIZE, + .statesize = sizeof(struct sha1_state), .block_size = SHA1_BLOCK_SIZE }, { .name = "sha256", .hash_zero = sha256_zero_message_hash,
@@ -1276,6 +1279,7 @@ static const struct n2_hash_tmpl hash_tm .hmac_type = AUTH_TYPE_HMAC_SHA256, .hw_op_hashsz = SHA256_DIGEST_SIZE, .digest_size = SHA256_DIGEST_SIZE, + .statesize = sizeof(struct sha256_state), .block_size = SHA256_BLOCK_SIZE }, { .name = "sha224", .hash_zero = sha224_zero_message_hash,
@@ -1284,6 +1288,7 @@ static const struct n2_hash_tmpl hash_tm .hmac_type = AUTH_TYPE_RESERVED, .hw_op_hashsz = SHA256_DIGEST_SIZE, .digest_size = SHA224_DIGEST_SIZE, + .statesize = sizeof(struct sha256_state), .block_size = SHA224_BLOCK_SIZE }, };#define NUM_HASH_TMPLS ARRAY_SIZE(hash_tmpls)
@@ -1424,6 +1429,7 @@ static int __n2_register_one_ahash(const halg = &ahash->halg; halg->digestsize = tmpl->digest_size; + halg->statesize = tmpl->statesize; base = &halg->base;snprintf (base->cra_name,CRYPTO_MAX_ALG_NAME ,"%s" , tmpl->name);
Greg Kroah-Hartman
maintainerPATCH 110/177 crypto: ccp - Add support for TEE for PCI ID 0x14CA
In reply to Greg Kroah-HartmanFrom: Mario Limonciello <[email protected]>
commit 10da230a4df1dfe32a58eb09246f5ffe82346f27 upstream.
SoCs containing 0x14CA are present both in datacenter parts that support SEV as well as client parts that support TEE.
--- drivers/crypto/ccp/sp-pci.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/crypto/ccp/sp-pci.c +10 -1
@@ -381,6 +381,15 @@ static const struct psp_vdata pspv3 = { .inten_reg = 0x10690, .intsts_reg = 0x10694, }; + +static const struct psp_vdata pspv4 = { + .sev = &sevv2, + .tee = &teev1, + .feature_reg =0x109fc , + .inten_reg =0x10690 , + .intsts_reg =0x10694 , +}; +#endif static const struct sp_dev_vdata dev_vdata[] = {
@@ -426,7 +435,7 @@ static const struct sp_dev_vdata dev_vda {/* 5 */ .bar = 2, #ifdef CONFIG_CRYPTO_DEV_SP_PSP - .psp_vdata = &pspv2, + .psp_vdata = &pspv4,#endif }, {/* 6 */
Greg Kroah-Hartman
maintainerPATCH 111/177 driver core: Fix bus_type.match() error handling in __driver_attach()
In reply to Greg Kroah-HartmanFrom: Isaac J. Manjarres <[email protected]>
commit 27c0d217340e47ec995557f61423ef415afba987 upstream.
When a driver registers with a bus, it will attempt to match with every device on the bus through the __driver_attach() function. Currently, if the bus_type.match() function encounters an error that is not -EPROBE_DEFER, __driver_attach() will return a negative error code, which causes the driver registration logic to stop trying to match with the remaining devices on the bus.
This behavior is not correct; a failure while matching a driver to a device does not mean that the driver won't be able to match and bind with other devices on the bus. Update the logic in __driver_attach() to reflect this.
--- drivers/base/dd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/base/dd.c +5 -1
@@ -1162,7 +1162,11 @@ static int __driver_attach(struct devicereturn 0 ; }else if (ret <0 ) {dev_dbg (dev,"Bus failed to match device: %d\n" , ret); -return ret; +/* +* Driver could not match with device, but may match with +* another device on the bus. +*/ +return 0 ; }/* ret > 0 means positive match */ if (driver_allows_async_probing (drv)) {
Greg Kroah-Hartman
maintainerPATCH 112/177 bus: mhi: host: Fix race between channel preparation and M0 event
In reply to Greg Kroah-HartmanFrom: Qiang Yu <[email protected]>
commit 869a99907faea6d1835b0bd0d0422ae3519c6ea9 upstream.
There is a race condition where mhi_prepare_channel() updates the read and write pointers as the base address and in parallel, if an M0 transition occurs, the tasklet goes ahead and rings doorbells for all channels with a delta in TRE rings assuming they are already enabled. This causes a null pointer access. Fix it by adding a channel enabled check before ringing channel doorbells.
--- drivers/bus/mhi/host/pm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/bus/mhi/host/pm.c +2 -1
@@ -301,7 +301,8 @@ int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl)read_lock_irq (&mhi_chan->lock);/* Only ring DB if ring is not empty */ -if (tre_ring->base && tre_ring->wp != tre_ring->rp) +if (tre_ring->base && tre_ring->wp != tre_ring->rp && + mhi_chan->ch_state ==MHI_CH_STATE_ENABLED )mhi_ring_chan_db (mhi_cntrl, mhi_chan);read_unlock_irq (&mhi_chan->lock); }
Signature · 1 line
2.39.0
Greg Kroah-Hartman
maintainerPATCH 113/177 phy: qcom-qmp-combo: fix sc8180x reset
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 910dd4883d757af5faac92590f33f0f7da963032 upstream.
The SC8180X has two resets but the DP configuration erroneously described only one.
In case the DP part of the PHY is initialised before the USB part (e.g. depending on probe order), then only the first reset would be asserted.
--- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/phy/qualcomm/phy-qcom-qmp-combo.c +2 -2
@@ -959,8 +959,8 @@ static const struct qmp_phy_cfg sc8180x_ .clk_list = qmp_v3_phy_clk_l, .num_clks = ARRAY_SIZE(qmp_v3_phy_clk_l), - .reset_list = sc7180_usb3phy_reset_l, - .num_resets = ARRAY_SIZE(sc7180_usb3phy_reset_l), + .reset_list = msm8996_usb3phy_reset_l, + .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = qmp_v3_usb3phy_regs_layout,
Greg Kroah-Hartman
maintainerPATCH 114/177 iommu/amd: Fix ivrs_acpihid cmdline parsing code
In reply to Greg Kroah-HartmanFrom: Kim Phillips <[email protected]>
commit 5f18e9f8868c6d4eae71678e7ebd4977b7d8c8cf upstream.
The second (UID) strcmp in acpi_dev_hid_uid_match considers "0" and "00" different, which can prevent device registration.
Have the AMD IOMMU driver's ivrs_acpihid parsing code remove any leading zeroes to make the UID strcmp succeed. Now users can safely specify "AMDxxxxx:00" or "AMDxxxxx:0" and expect the same behaviour.
--- drivers/iommu/amd/init.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/iommu/amd/init.c +7 -0
@@ -3471,6 +3471,13 @@ static int __init parse_ivrs_acpihid(chareturn 1 ; } +/* +* Ignore leading zeroes after ':', so e.g., AMDI0095:00 +* will match AMDI0095:0 in the second strcmp in acpi_dev_hid_uid_match +*/ +while (*uid =='0' && *(uid +1 )) + uid++; + i = early_acpihid_map_size++;memcpy (early_acpihid_map[i].hid, hid,strlen (hid));memcpy (early_acpihid_map[i].uid, uid,strlen (uid));
Greg Kroah-Hartman
maintainerPATCH 115/177 iommu/amd: Fix ill-formed ivrs_ioapic, ivrs_hpet and ivrs_acpihid options
In reply to Greg Kroah-HartmanFrom: Kim Phillips <[email protected]>
commit 1198d2316dc4265a97d0e8445a22c7a6d17580a4 upstream.
Currently, these options cause the following libkmod error:
libkmod: ERROR ../libkmod/libkmod-config.c:489 kcmdline_parse_result: \ Ignoring bad option on kernel command line while parsing module \ name: 'ivrs_xxxx[XX:XX'
Fix by introducing a new parameter format for these options and throw a warning for the deprecated format.
Users are still allowed to omit the PCI Segment if zero.
Adding a Link: to the reason why we're modding the syntax parsing in the driver and not in libkmod.
--- Documentation/admin-guide/kernel-parameters.txt | 27 ++++++-- drivers/iommu/amd/init.c | 77 ++++++++++++++++-------- 2 files changed, 75 insertions(+), 29 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +22 -5
@@ -2294,7 +2294,13 @@ Provide an override to the IOAPIC-ID<->DEVICE-ID mapping provided in the IVRS ACPI table. By default, PCI segment is 0, and can be omitted. - For example: + + For example, to map IOAPIC-ID decimal 10 to + PCI segment 0x1 and PCI device 00:14.0, + write the parameter as: + ivrs_ioapic=10@0001:00:14.0 + + Deprecated formats: * To map IOAPIC-ID decimal 10 to PCI device 00:14.0 write the parameter as: ivrs_ioapic[10]=00:14.0
@@ -2306,7 +2312,13 @@ Provide an override to the HPET-ID<->DEVICE-ID mapping provided in the IVRS ACPI table. By default, PCI segment is 0, and can be omitted. - For example: + + For example, to map HPET-ID decimal 10 to + PCI segment 0x1 and PCI device 00:14.0, + write the parameter as: + ivrs_hpet=10@0001:00:14.0 + + Deprecated formats: * To map HPET-ID decimal 0 to PCI device 00:14.0 write the parameter as: ivrs_hpet[0]=00:14.0
@@ -2317,15 +2329,20 @@ ivrs_acpihid [HW,X86-64] Provide an override to the ACPI-HID:UID<->DEVICE-ID mapping provided in the IVRS ACPI table. + By default, PCI segment is 0, and can be omitted. For example, to map UART-HID:UID AMD0020:0 to PCI segment 0x1 and PCI device ID 00:14.5, write the parameter as: - ivrs_acpihid[0001:00:14.5]=AMD0020:0 + ivrs_acpihid=AMD0020:0@0001:00:14.5 - By default, PCI segment is 0, and can be omitted. - For example, PCI device 00:14.5 write the parameter as: + Deprecated formats: + * To map UART-HID:UID AMD0020:0 to PCI segment is 0, + PCI device ID 00:14.5, write the parameter as: ivrs_acpihid[00:14.5]=AMD0020:0 + * To map UART-HID:UID AMD0020:0 to PCI segment 0x1 and + PCI device ID 00:14.5, write the parameter as: + ivrs_acpihid[0001:00:14.5]=AMD0020:0 js= [HW,JOY] Analog joystick See Documentation/input/joydev/joystick.rst.
drivers/iommu/amd/init.c +53 -24
108 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 116/177 test_kprobes: Fix implicit declaration error of test_kprobes
In reply to Greg Kroah-HartmanFrom: Li Hua <[email protected]>
commit 63a4dc0a0bb0e9bfeb2c88ccda81abdde4cdd6b8 upstream.
If KPROBES_SANITY_TEST and ARCH_CORRECT_STACKTRACE_ON_KRETPROBE is enabled, but STACKTRACE is not set. Build failed as below:
lib/test_kprobes.c: In function ‘stacktrace_return_handler’:lib/test_kprobes.c:228:8: error: implicit declaration of function ‘stack_trace_save’; did you mean ‘stacktrace_driver’? [-Werror=implicit-function-declaration]
ret = stack_trace_save(stack_buf, STACK_BUF_SIZE, 0);
^~~~~~~~~~~~~~~~
stacktrace_drivercc1: all warnings being treated as errors scripts/Makefile.build:250: recipe for target 'lib/test_kprobes.o' failed make[2]: *** [lib/test_kprobes.o] Error 1
To fix this error, Select STACKTRACE if ARCH_CORRECT_STACKTRACE_ON_KRETPROBE is enabled.
--- lib/Kconfig.debug | 1 + 1 file changed, 1 insertion(+)
lib/Kconfig.debug +1 -0
@@ -2080,6 +2080,7 @@ config TEST_MIN_HEAP config TEST_SORT tristate "Array-based sort test" if !KUNIT_ALL_TESTS depends on KUNIT + select STACKTRACE if ARCH_CORRECT_STACKTRACE_ON_KRETPROBE default KUNIT_ALL_TESTS help This option enables the self-test function of 'sort()' at boot,
Greg Kroah-Hartman
maintainerPATCH 117/177 remoteproc: imx_dsp_rproc: Add mutex protection for workqueue
In reply to Greg Kroah-HartmanFrom: Shengjiu Wang <[email protected]>
commit 47e6ab07018edebf94ce873cf50a05ec76ff2dde upstream.
The workqueue may execute late even after remoteproc is stopped or stopping, some resources (rpmsg device and endpoint) have been released in rproc_stop_subdevices(), then rproc_vq_interrupt() accessing these resources will cause kennel dump.
Call trace: virtqueue_add_split+0x1ac/0x560 virtqueue_add_inbuf+0x4c/0x60 rpmsg_recv_done+0x15c/0x294 vring_interrupt+0x6c/0xa4 rproc_vq_interrupt+0x30/0x50 imx_dsp_rproc_vq_work+0x24/0x40 [imx_dsp_rproc] process_one_work+0x1d0/0x354 worker_thread+0x13c/0x470 kthread+0x154/0x160 ret_from_fork+0x10/0x20
Add mutex protection in imx_dsp_rproc_vq_work(), if the state is not running, then just skip calling rproc_vq_interrupt().
Also the flush workqueue operation can't be added in rproc stop for the same reason. The call sequence is
rproc_shutdown
-> rproc_stop
->rproc_stop_subdevices
->rproc->ops->stop()
->imx_dsp_rproc_stop
->flush_work
-> rproc_vq_interruptThe resource needed by rproc_vq_interrupt has been released in rproc_stop_subdevices, so flush_work is not safe to be called in imx_dsp_rproc_stop.
--- drivers/remoteproc/imx_dsp_rproc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/remoteproc/imx_dsp_rproc.c +9 -3
@@ -347,9 +347,6 @@ static int imx_dsp_rproc_stop(struct rprstruct device *dev = rproc->dev.parent;int ret =0 ; -/* Make sure work is finished */ -flush_work (&priv->rproc_work); -if (rproc->state ==RPROC_CRASHED ) { priv->flags &= ~REMOTE_IS_READY ;return 0 ;
@@ -432,9 +429,18 @@ static void imx_dsp_rproc_vq_work(struct { struct imx_dsp_rproc *priv = container_of(work, struct imx_dsp_rproc, rproc_work); +struct rproc *rproc = priv->rproc; + +mutex_lock (&rproc->lock); + +if (rproc->state !=RPROC_RUNNING ) + goto unlock_mutex;rproc_vq_interrupt (priv->rproc,0 );rproc_vq_interrupt (priv->rproc,1 ); + +unlock_mutex: +mutex_unlock (&rproc->lock); }/**
Greg Kroah-Hartman
maintainerPATCH 118/177 remoteproc: core: Do pm_relax when in RPROC_OFFLINE state
In reply to Greg Kroah-HartmanFrom: Maria Yu <[email protected]>
commit 11c7f9e3131ad14b27a957496088fa488b153a48 upstream.
Make sure that pm_relax() happens even when the remoteproc is stopped before the crash handler work is scheduled.
--- drivers/remoteproc/remoteproc_core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/remoteproc/remoteproc_core.c +8 -1
@@ -1954,12 +1954,18 @@ static void rproc_crash_handler_work(strmutex_lock (&rproc->lock); -if (rproc->state ==RPROC_CRASHED || rproc->state ==RPROC_OFFLINE ) { +if (rproc->state ==RPROC_CRASHED ) {/* handle only the first crash detected */ mutex_unlock (&rproc->lock);return ; } +if (rproc->state ==RPROC_OFFLINE ) { +/* Don't recover if the remote processor was stopped */ +mutex_unlock (&rproc->lock); + goto out; + } + rproc->state =RPROC_CRASHED ;dev_err (dev,"handling crash #%u in %s\n" , ++rproc->crash_cnt, rproc->name);
@@ -1969,6 +1975,7 @@ static void rproc_crash_handler_work(strif (!rproc->recovery_disabled)rproc_trigger_recovery (rproc); +out:pm_relax (rproc->dev.parent); }
Greg Kroah-Hartman
maintainerPATCH 119/177 remoteproc: imx_rproc: Correct i.MX93 DRAM mapping
In reply to Greg Kroah-HartmanFrom: Peng Fan <[email protected]>
commit ee18f2715e85f4ef051851a0c4831ee7ad7d83b3 upstream.
According to updated reference mannual, the M33 DRAM view of 0x[C,D]0000000 maps to A55 0xC0000000, so correct it.
--- drivers/remoteproc/imx_rproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/remoteproc/imx_rproc.c +2 -2
@@ -113,8 +113,8 @@ static const struct imx_rproc_att imx_rp { 0x80000000, 0x80000000, 0x10000000, 0 }, { 0x90000000, 0x80000000, 0x10000000, 0 }, - { 0xC0000000, 0xa0000000, 0x10000000, 0 }, - { 0xD0000000, 0xa0000000, 0x10000000, 0 }, + { 0xC0000000, 0xC0000000, 0x10000000, 0 }, + { 0xD0000000, 0xC0000000, 0x10000000, 0 }, }; static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
Greg Kroah-Hartman
maintainerPATCH 120/177 parisc: led: Fix potential null-ptr-deref in start_task()
In reply to Greg Kroah-HartmanFrom: Shang XiaoJing <[email protected]>
commit 41f563ab3c33698bdfc3403c7c2e6c94e73681e4 upstream.
start_task() calls create_singlethread_workqueue() and not checked the ret value, which may return NULL. And a null-ptr-deref may happen:
start_task()
create_singlethread_workqueue() # failed, led_wq is NULL queue_delayed_work()
queue_delayed_work_on()
__queue_delayed_work() # warning here, but continue
__queue_work() # access wq->flags, null-ptr-deref
Check the ret value and return -ENOMEM if it is NULL.
--- drivers/parisc/led.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/parisc/led.c +3 -0
@@ -137,6 +137,9 @@ static int start_task(void)/* Create the work queue and queue the LED task */ led_wq =create_singlethread_workqueue ("led_wq" ); +if (!led_wq) +return -ENOMEM ; +queue_delayed_work (led_wq, &led_task,0 );return 0 ;
Greg Kroah-Hartman
maintainerPATCH 121/177 parisc: Fix locking in pdc_iodc_print() firmware call
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit 7236aae5f81f3efbd93d0601e74fc05994bc2580 upstream.
Utilize pdc_lock spinlock to protect parallel modifications of the iodc_dbuf[] buffer, check length to prevent buffer overflow of iodc_dbuf[], drop the iodc_retbuf[] buffer and fix some wrong indentings.
--- arch/parisc/kernel/firmware.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
arch/parisc/kernel/firmware.c +13 -11
@@ -1288,9 +1288,8 @@ void pdc_io_reset_devices(void)#endif /* defined(BOOTLOADER) */ -/* locked by pdc_console_lock */ -static int __attribute__((aligned (8 ))) iodc_retbuf[32 ]; -static char __attribute__((aligned (64 ))) iodc_dbuf[4096 ]; +/* locked by pdc_lock */ +static char iodc_dbuf[4096] __page_aligned_bss;/** * pdc_iodc_print - Console print using IODC.
@@ -1307,6 +1306,9 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)unsigned int i;unsigned long flags; + count = min_t(unsigned int, count, sizeof(iodc_dbuf)); + +spin_lock_irqsave (&pdc_lock, flags);for (i =0 ; i < count;) {switch (str[i]) {case '\n' :
@@ -1322,12 +1324,11 @@ int pdc_iodc_print(const unsigned char *str, unsigned count) } print: -spin_lock_irqsave (&pdc_lock, flags); -real32_call (PAGE0 ->mem_cons.iodc_io, - (unsigned long )PAGE0 ->mem_cons.hpa,ENTRY_IO_COUT , -PAGE0 ->mem_cons.spa,__pa (PAGE0 ->mem_cons.dp.layers), -__pa (iodc_retbuf),0 ,__pa (iodc_dbuf), i,0 ); -spin_unlock_irqrestore (&pdc_lock, flags); +real32_call (PAGE0 ->mem_cons.iodc_io, + (unsigned long )PAGE0 ->mem_cons.hpa,ENTRY_IO_COUT , +PAGE0 ->mem_cons.spa,__pa (PAGE0 ->mem_cons.dp.layers), +__pa (pdc_result),0 ,__pa (iodc_dbuf), i,0 ); +spin_unlock_irqrestore (&pdc_lock, flags);return i; }
@@ -1354,10 +1355,11 @@ int pdc_iodc_getc(void)real32_call (PAGE0 ->mem_kbd.iodc_io, (unsigned long )PAGE0 ->mem_kbd.hpa,ENTRY_IO_CIN ,PAGE0 ->mem_kbd.spa,__pa (PAGE0 ->mem_kbd.dp.layers), -__pa (iodc_retbuf),0 ,__pa (iodc_dbuf),1 ,0 ); +__pa (pdc_result),0 ,__pa (iodc_dbuf),1 ,0 ); ch = *iodc_dbuf; - status = *iodc_retbuf; +/* like convert_to_wide() but for first return value only: */ + status = *(int *)&pdc_result;spin_unlock_irqrestore (&pdc_lock, flags);if (status ==0 )
Signature · 1 line
2.39.0
Greg Kroah-Hartman
maintainerPATCH 122/177 parisc: Add missing FORCE prerequisites in Makefile
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit 9086e6017957c5cd6ea28d94b70e0d513d6b7800 upstream.
Fix those make warnings:
arch/parisc/kernel/vdso32/Makefile:30: FORCE prerequisite is missing arch/parisc/kernel/vdso64/Makefile:30: FORCE prerequisite is missing
Add the missing FORCE prerequisites for all build targets identified by "make help".
--- arch/parisc/kernel/vdso32/Makefile | 4 ++-- arch/parisc/kernel/vdso64/Makefile | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
arch/parisc/kernel/vdso32/Makefile +2 -2
@@ -26,7 +26,7 @@ $(obj)/vdso32_wrapper.o : $(obj)/vdso32. # Force dependency (incbin is bad) # link rule for the .so file, .lds has to be first -$(obj)/vdso32.so: $(src)/vdso32.lds $(obj-vdso32) $(obj-cvdso32) $(VDSO_LIBGCC) +$(obj)/vdso32.so: $(src)/vdso32.lds $(obj-vdso32) $(obj-cvdso32) $(VDSO_LIBGCC) FORCE $(call if_changed,vdso32ld) # assembly rules for the .S files
@@ -38,7 +38,7 @@ $(obj-cvdso32): %.o: %.c FORCE # actual build commands quiet_cmd_vdso32ld = VDSO32L $@ - cmd_vdso32ld = $(CROSS32CC) $(c_flags) -Wl,-T $^ -o $@ + cmd_vdso32ld = $(CROSS32CC) $(c_flags) -Wl,-T $(filter-out FORCE, $^) -o $@ quiet_cmd_vdso32as = VDSO32A $@ cmd_vdso32as = $(CROSS32CC) $(a_flags) -c -o $@ $< quiet_cmd_vdso32cc = VDSO32C $@
arch/parisc/kernel/vdso64/Makefile +2 -2
@@ -26,7 +26,7 @@ $(obj)/vdso64_wrapper.o : $(obj)/vdso64. # Force dependency (incbin is bad) # link rule for the .so file, .lds has to be first -$(obj)/vdso64.so: $(src)/vdso64.lds $(obj-vdso64) $(VDSO_LIBGCC) +$(obj)/vdso64.so: $(src)/vdso64.lds $(obj-vdso64) $(VDSO_LIBGCC) FORCE $(call if_changed,vdso64ld) # assembly rules for the .S files
@@ -35,7 +35,7 @@ $(obj-vdso64): %.o: %.S FORCE # actual build commands quiet_cmd_vdso64ld = VDSO64L $@ - cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $^ -o $@ + cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $(filter-out FORCE, $^) -o $@ quiet_cmd_vdso64as = VDSO64A $@ cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
Greg Kroah-Hartman
maintainerPATCH 123/177 parisc: Drop PMD_SHIFT from calculation in pgtable.h
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit fe94cb1a614d2df2764d49ac959d8b7e4cb98e15 upstream.
PMD_SHIFT isn't defined if CONFIG_PGTABLE_LEVELS == 3, and as such the kernel test robot found this warning:
In file included from include/linux/pgtable.h:6,
from arch/parisc/kernel/head.S:23:
arch/parisc/include/asm/pgtable.h:169:32: warning: "PMD_SHIFT" is not defined, evaluates to 0 [-Wundef]
169 | #if (KERNEL_INITIAL_ORDER) >= (PMD_SHIFT)
Avoid the warning by using PLD_SHIFT and BITS_PER_PTE.
--- arch/parisc/include/asm/pgtable.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/parisc/include/asm/pgtable.h +2 -2
@@ -166,8 +166,8 @@ extern void __update_cache(pte_t pte);/* This calculates the number of initial pages we need for the initial * page tables */ -#if (KERNEL_INITIAL_ORDER ) >= (PMD_SHIFT ) -# define PT_INITIAL (1 << (KERNEL_INITIAL_ORDER - PMD_SHIFT)) +#if (KERNEL_INITIAL_ORDER ) >= (PLD_SHIFT +BITS_PER_PTE ) +# define PT_INITIAL (1 << (KERNEL_INITIAL_ORDER - PLD_SHIFT - BITS_PER_PTE))#else # define PT_INITIAL (1)/* all initial PTEs fit into one page */ #endif
Signature · 1 line
2.39.0
Greg Kroah-Hartman
maintainerPATCH 124/177 device_cgroup: Roll back to original exceptions after copy failure
In reply to Greg Kroah-HartmanFrom: Wang Weiyang <[email protected]>
commit e68bfbd3b3c3a0ec3cf8c230996ad8cabe90322f upstream.
When add the 'a *:* rwm' entry to devcgroup A's whitelist, at first A's exceptions will be cleaned and A's behavior is changed to DEVCG_DEFAULT_ALLOW. Then parent's exceptions will be copyed to A's whitelist. If copy failure occurs, just return leaving A to grant permissions to all devices. And A may grant more permissions than parent.
Backup A's whitelist and recover original exceptions after copy failure.
--- security/device_cgroup.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-)
security/device_cgroup.c +29 -4
@@ -82,6 +82,17 @@ free_and_exit:return -ENOMEM ; } +static void dev_exceptions_move (struct list_head *dest,struct list_head *orig) +{ +struct dev_exception_item *ex, *tmp; + +lockdep_assert_held (&devcgroup_mutex); + +list_for_each_entry_safe (ex, tmp, orig, list) { +list_move_tail (&ex->list, dest); + } +} +/* * called under devcgroup_mutex */
@@ -604,11 +615,13 @@ static int devcgroup_update_access(strucint count, rc =0 ;struct dev_exception_item ex;struct dev_cgroup *parent =css_to_devcgroup (devcgroup->css.parent); +struct dev_cgroup tmp_devcgrp;if (!capable (CAP_SYS_ADMIN ))return -EPERM ;memset (&ex,0 ,sizeof (ex)); +memset (&tmp_devcgrp,0 ,sizeof (tmp_devcgrp)); b = buffer;switch (*b) {
@@ -620,15 +633,27 @@ static int devcgroup_update_access(strucif (!may_allow_all (parent))return -EPERM ; -dev_exception_clean (devcgroup); - devcgroup->behavior =DEVCG_DEFAULT_ALLOW ; -if (!parent) +if (!parent) { + devcgroup->behavior =DEVCG_DEFAULT_ALLOW ; +dev_exception_clean (devcgroup);break ; + } +INIT_LIST_HEAD (&tmp_devcgrp.exceptions); + rc =dev_exceptions_copy (&tmp_devcgrp.exceptions, + &devcgroup->exceptions); +if (rc) +return rc; +dev_exception_clean (devcgroup); rc =dev_exceptions_copy (&devcgroup->exceptions, &parent->exceptions); -if (rc) +if (rc) { +dev_exceptions_move (&devcgroup->exceptions, + &tmp_devcgrp.exceptions);return rc; + } + devcgroup->behavior =DEVCG_DEFAULT_ALLOW ; +dev_exception_clean (&tmp_devcgrp);break ;case DEVCG_DENY :if (css_has_online_children (&devcgroup->css))
Greg Kroah-Hartman
maintainerPATCH 125/177 drm/connector: send hotplug uevent on connector cleanup
In reply to Greg Kroah-HartmanFrom: Simon Ser <[email protected]>
commit 6fdc2d490ea1369d17afd7e6eb66fecc5b7209bc upstream.
A typical DP-MST unplug removes a KMS connector. However care must be taken to properly synchronize with user-space. The expected sequence of events is the following:
1. The kernel notices that the DP-MST port is gone.
2. The kernel marks the connector as disconnected, then sends a uevent to make user-space re-scan the connector list.
3. User-space notices the connector goes from connected to disconnected, disables it.
4. Kernel handles the IOCTL disabling the connector. On success, the very last reference to the struct drm_connector is dropped and drm_connector_cleanup() is called.
5. The connector is removed from the list, and a uevent is sent to tell user-space that the connector disappeared.
The very last step was missing. As a result, user-space thought the connector still existed and could try to disable it again. Since the kernel no longer knows about the connector, that would end up with EINVAL and confused user-space.
Fix this by sending a hotplug uevent from drm_connector_cleanup().
--- drivers/gpu/drm/drm_connector.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/drm_connector.c +3 -0
@@ -505,6 +505,9 @@ void drm_connector_cleanup(struct drm_comutex_destroy (&connector->mutex);memset (connector,0 ,sizeof (*connector)); + +if (dev->registered) +drm_sysfs_hotplug_event (dev); }EXPORT_SYMBOL (drm_connector_cleanup);
Greg Kroah-Hartman
maintainerPATCH 126/177 drm/vmwgfx: Validate the box size for the snooped cursor
In reply to Greg Kroah-HartmanFrom: Zack Rusin <[email protected]>
commit 4cf949c7fafe21e085a4ee386bb2dade9067316e upstream.
Invalid userspace dma surface copies could potentially overflow the memcpy from the surface to the snooped image leading to crashes. To fix it the dimensions of the copybox have to be validated against the expected size of the snooped cursor.
--- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +2 -1
@@ -309,7 +309,8 @@ void vmw_kms_cursor_snoop(struct vmw_surif (cmd->dma.guest.ptr.offset %PAGE_SIZE || box->x !=0 || box->y !=0 || box->z !=0 || box->srcx !=0 || box->srcy !=0 || box->srcz !=0 || - box->d !=1 || box_count !=1 ) { + box->d !=1 || box_count !=1 || + box->w >64 || box->h >64 ) {/* TODO handle none page aligned offsets */ /* TODO handle more dst & src != 0 */ /* TODO handle more then one copy */
Greg Kroah-Hartman
maintainerPATCH 127/177 drm/etnaviv: move idle mapping reaping into separate function
In reply to Greg Kroah-HartmanFrom: Lucas Stach <[email protected]>
commit 5a40837debaa9dcc71765d32ce1a15be068b6cc2 upstream.
The same logic is already used in two different places and now it will also be needed outside of the compilation unit, so split it into a separate function.
--- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 23 +++++++++++++++-------- drivers/gpu/drm/etnaviv/etnaviv_mmu.h | 1 + 2 files changed, 16 insertions(+), 8 deletions(-)
drivers/gpu/drm/etnaviv/etnaviv_mmu.c +15 -8
@@ -135,6 +135,19 @@ static void etnaviv_iommu_remove_mapping(struct etnaviv_iommu_context *context,drm_mm_remove_node (&mapping->vram_node); } +void etnaviv_iommu_reap_mapping (struct etnaviv_vram_mapping *mapping) +{ +struct etnaviv_iommu_context *context = mapping->context; + +lockdep_assert_held (&context->lock); +WARN_ON (mapping->use); + +etnaviv_iommu_remove_mapping (context, mapping); +etnaviv_iommu_context_put (mapping->context); + mapping->context =NULL ; +list_del_init (&mapping->mmu_node); +} +static int etnaviv_iommu_find_iova (struct etnaviv_iommu_context *context,struct drm_mm_node *node,size_t size) {
@@ -202,10 +215,7 @@ static int etnaviv_iommu_find_iova(struct etnaviv_iommu_context *context,* this mapping. */ list_for_each_entry_safe (m, n, &list, scan_node) { -etnaviv_iommu_remove_mapping (context, m); -etnaviv_iommu_context_put (m->context); - m->context =NULL ; -list_del_init (&m->mmu_node); +etnaviv_iommu_reap_mapping (m);list_del_init (&m->scan_node); }
@@ -257,10 +267,7 @@ static int etnaviv_iommu_insert_exact(struct etnaviv_iommu_context *context, }list_for_each_entry_safe (m, n, &scan_list, scan_node) { -etnaviv_iommu_remove_mapping (context, m); -etnaviv_iommu_context_put (m->context); - m->context =NULL ; -list_del_init (&m->mmu_node); +etnaviv_iommu_reap_mapping (m);list_del_init (&m->scan_node); }
drivers/gpu/drm/etnaviv/etnaviv_mmu.h +1 -0
@@ -91,6 +91,7 @@ int etnaviv_iommu_map_gem(struct etnaviv_iommu_context *context, struct etnaviv_vram_mapping *mapping, u64 va);void etnaviv_iommu_unmap_gem (struct etnaviv_iommu_context *context,struct etnaviv_vram_mapping *mapping); +void etnaviv_iommu_reap_mapping (struct etnaviv_vram_mapping *mapping); int etnaviv_iommu_get_suballoc_va(struct etnaviv_iommu_context *ctx, struct etnaviv_vram_mapping *mapping,
Signature · 1 line
2.39.0
Greg Kroah-Hartman
maintainerPATCH 128/177 drm/i915/dsi: fix VBT send packet port selection for dual link DSI
In reply to Greg Kroah-HartmanFrom: Mikko Kovanen <[email protected]>
commit f9cdf4130671d767071607d0a7568c9bd36a68d0 upstream.
intel_dsi->ports contains bitmask of enabled ports and correspondingly logic for selecting port for VBT packet sending must use port specific bitmask when deciding appropriate port.
--- drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/display/intel_dsi_vbt.c +2 -2
@@ -137,9 +137,9 @@ static enum port intel_dsi_seq_port_to_preturn ffs (intel_dsi->ports) -1 ;if (seq_port) { -if (intel_dsi->ports &PORT_B ) +if (intel_dsi->ports &BIT (PORT_B ))return PORT_B ; -else if (intel_dsi->ports &PORT_C ) +else if (intel_dsi->ports &BIT (PORT_C ))return PORT_C ; }
Greg Kroah-Hartman
maintainerPATCH 129/177 drm/ingenic: Fix missing platform_driver_unregister() call in ingenic_drm_init()
In reply to Greg Kroah-HartmanFrom: Yuan Can <[email protected]>
commit 47078311b8efebdefd5b3b2f87e2b02b14f49c66 upstream.
A problem about modprobe ingenic-drm failed is triggered with the following log given:
[ 303.561088] Error: Driver 'ingenic-ipu' is already registered, aborting... modprobe: ERROR: could not insert 'ingenic_drm': Device or resource busy
The reason is that ingenic_drm_init() returns platform_driver_register() directly without checking its return value, if platform_driver_register() failed, it returns without unregistering ingenic_ipu_driver_ptr, resulting the ingenic-drm can never be installed later.
A simple call graph is shown as below:
ingenic_drm_init()
platform_driver_register() # ingenic_ipu_driver_ptr are registered platform_driver_register()
driver_register()
bus_add_driver()
priv = kzalloc(...) # OOM happened
# return without unregister ingenic_ipu_driver_ptr
Fixing this problem by checking the return value of platform_driver_register() and do platform_unregister_drivers() if error happened.
--- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/ingenic/ingenic-drm-drv.c +5 -1
@@ -1601,7 +1601,11 @@ static int ingenic_drm_init(void)return err; } -return platform_driver_register (&ingenic_drm_driver); + err =platform_driver_register (&ingenic_drm_driver); +if (IS_ENABLED (CONFIG_DRM_INGENIC_IPU ) && err) +platform_driver_unregister (ingenic_ipu_driver_ptr); + +return err; }module_init (ingenic_drm_init);
Greg Kroah-Hartman
maintainerPATCH 130/177 drm/etnaviv: reap idle mapping if it doesnt match the softpin address
In reply to Greg Kroah-HartmanFrom: Lucas Stach <[email protected]>
commit 332f847212e43d584019a8264895f25cf92aa647 upstream.
When a idle BO, which is held open by another process, gets freed by userspace and subsequently referenced again by e.g. importing it again, userspace may assign a different softpin VA than the last time around. As the kernel GEM object still exists, we likely have a idle mapping with the old VA still cached, if it hasn't been reaped in the meantime.
As the context matches, we then simply try to resurrect this mapping by increasing the refcount. As the VA in this mapping does not match the new softpin address, we consequently fail the otherwise valid submit. Instead of failing, reap the idle mapping.
--- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/etnaviv/etnaviv_gem.c +6 -1
@@ -258,7 +258,12 @@ struct etnaviv_vram_mapping *etnaviv_gemif (mapping->use ==0 ) {mutex_lock (&mmu_context->lock);if (mapping->context == mmu_context) - mapping->use +=1 ; +if (va && mapping->iova != va) { +etnaviv_iommu_reap_mapping (mapping); + mapping =NULL ; + }else { + mapping->use +=1 ; + }else mapping =NULL ;mutex_unlock (&mmu_context->lock);
Greg Kroah-Hartman
maintainerPATCH 131/177 arm64: efi: Execute runtime services from a dedicated stack
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
commit ff7a167961d1b97e0e205f245f806e564d3505e7 upstream.
With the introduction of PRMT in the ACPI subsystem, the EFI rts workqueue is no longer the only caller of efi_call_virt_pointer() in the kernel. This means the EFI runtime services lock is no longer sufficient to manage concurrent calls into firmware, but also that firmware calls may occur that are not marshalled via the workqueue mechanism, but originate directly from the caller context.
For added robustness, and to ensure that the runtime services have 8 KiB of stack space available as per the EFI spec, introduce a spinlock protected EFI runtime stack of 8 KiB, where the spinlock also ensures serialization between the EFI rts workqueue (which itself serializes EFI runtime calls) and other callers of efi_call_virt_pointer().
While at it, use the stack pivot to avoid reloading the shadow call stack pointer from the ordinary stack, as doing so could produce a gadget to defeat it.
--- arch/arm64/include/asm/efi.h | 3 +++ arch/arm64/kernel/efi-rt-wrapper.S | 13 ++++++++++++- arch/arm64/kernel/efi.c | 27 +++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-)
arch/arm64/include/asm/efi.h +3 -0
@@ -25,6 +25,7 @@ int efi_set_mapping_permissions(struct m ({ \efi_virtmap_load (); \__efi_fpsimd_begin (); \ +spin_lock (&efi_rt_lock); \ })#undef arch_efi_call_virt
@@ -33,10 +34,12 @@ int efi_set_mapping_permissions(struct m#define arch_efi_call_virt_teardown () \ ({ \ + spin_unlock(&efi_rt_lock); \ __efi_fpsimd_end(); \ efi_virtmap_unload(); \ }) +extern spinlock_t efi_rt_lock;efi_status_t __efi_rt_asm_wrapper (void *,const char *, ...);#define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
arch/arm64/kernel/efi-rt-wrapper.S +12 -1
@@ -16,6 +16,12 @@ SYM_FUNC_START(__efi_rt_asm_wrapper) */ stp x1, x18, [sp, #16] + ldr_l x16, efi_rt_stack_top + mov sp, x16 +#ifdef CONFIG_SHADOW_CALL_STACK + str x18, [sp, #-16]! +#endif + /* * We are lucky enough that no EFI runtime services take more than * 5 arguments, so all are passed in registers rather than via the
@@ -29,6 +35,7 @@ SYM_FUNC_START(__efi_rt_asm_wrapper) mov x4, x6 blr x8 + mov sp, x29 ldp x1, x2, [sp, #16] cmp x2, x18 ldp x29, x30, [sp], #32
@@ -42,6 +49,10 @@ SYM_FUNC_START(__efi_rt_asm_wrapper) * called with preemption disabled and a separate shadow stack is used * for interrupts. */ - mov x18, x2 +#ifdef CONFIG_SHADOW_CALL_STACK + ldr_l x18, efi_rt_stack_top + ldr x18, [x18, #-16] +#endif + b efi_handle_corrupted_x18 // tail call SYM_FUNC_END(__efi_rt_asm_wrapper)
arch/arm64/kernel/efi.c +27 -0
@@ -144,3 +144,30 @@ asmlinkage efi_status_t efi_handle_corrupr_err_ratelimited (FW_BUG "register x18 corrupted by EFI %s\n" , f);return s; } + +DEFINE_SPINLOCK (efi_rt_lock); + +asmlinkage u64 *efi_rt_stack_top __ro_after_init; + +/* EFI requires 8 KiB of stack space for runtime services */ +static_assert (THREAD_SIZE >=SZ_8K ); + +static int __init arm64_efi_rt_init (void ) +{ +void *p; + +if (!efi_enabled (EFI_RUNTIME_SERVICES )) +return 0 ; + + p =__vmalloc_node (THREAD_SIZE ,THREAD_ALIGN ,GFP_KERNEL , +NUMA_NO_NODE , &&l); +l:if (!p) { +pr_warn ("Failed to allocate EFI runtime stack\n" ); +clear_bit (EFI_RUNTIME_SERVICES , &efi.flags); +return -ENOMEM ; + } + + efi_rt_stack_top = p +THREAD_SIZE ; +return 0 ; +} +core_initcall (arm64_efi_rt_init);
Greg Kroah-Hartman
maintainerPATCH 132/177 ext4: silence the warning when evicting inode with dioread_nolock
In reply to Greg Kroah-HartmanFrom: Zhang Yi <[email protected]>
commit bc12ac98ea2e1b70adc6478c8b473a0003b659d3 upstream.
When evicting an inode with default dioread_nolock, it could be raced by the unwritten extents converting kworker after writeback some new allocated dirty blocks. It convert unwritten extents to written, the extents could be merged to upper level and free extent blocks, so it could mark the inode dirty again even this inode has been marked I_FREEING. But the inode->i_io_list check and warning in ext4_evict_inode() missing this corner case. Fortunately, ext4_evict_inode() will wait all extents converting finished before this check, so it will not lead to inode use-after-free problem, every thing is OK besides this warning. The WARN_ON_ONCE was originally designed for finding inode use-after-free issues in advance, but if we add current dioread_nolock case in, it will become not quite useful, so fix this warning by just remove this check.
======
WARNING: CPU: 7 PID: 1092 at fs/ext4/inode.c:227 ext4_evict_inode+0x875/0xc60 ... RIP: 0010:ext4_evict_inode+0x875/0xc60 ... Call Trace: <TASK> evict+0x11c/0x2b0 iput+0x236/0x3a0 do_unlinkat+0x1b4/0x490 __x64_sys_unlinkat+0x4c/0xb0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x46/0xb0 RIP: 0033:0x7fa933c1115b ======
rm kworker
ext4_end_io_end()
vfs_unlink()
ext4_unlink()
ext4_convert_unwritten_io_end_vec()
ext4_convert_unwritten_extents()
ext4_map_blocks()
ext4_ext_map_blocks()
ext4_ext_try_to_merge_up()
__mark_inode_dirty()
check !I_FREEING
locked_inode_to_wb_and_lock_list()
iput()
iput_final()
evict()
ext4_evict_inode()
truncate_inode_pages_final() //wait release io_end
inode_io_list_move_locked()
ext4_release_io_end()
trigger WARN_ON_ONCE()--- fs/ext4/inode.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
fs/ext4/inode.c +5 -5
@@ -222,13 +222,13 @@ void ext4_evict_inode(struct inode *inod/* * For inodes with journalled data, transaction commit could have -* dirtied the inode. Flush worker is ignoring it because of I_FREEING -* flag but we still need to remove the inode from the writeback lists. +* dirtied the inode. And for inodes with dioread_nolock, unwritten +* extents converting worker could merge extents and also have dirtied +* the inode. Flush worker is ignoring it because of I_FREEING flag but +* we still need to remove the inode from the writeback lists. */ -if (!list_empty_careful (&inode->i_io_list)) { -WARN_ON_ONCE (!ext4_should_journal_data (inode)); +if (!list_empty_careful (&inode->i_io_list))inode_io_list_del (inode); - }/* * Protect us against freezing - iput() caller didn't have to have any
Greg Kroah-Hartman
maintainerPATCH 133/177 ext4: add inode table check in __ext4_get_inode_loc to aovid possible infinite loop
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
commit eee22187b53611e173161e38f61de1c7ecbeb876 upstream.
In do_writepages, if the value returned by ext4_writepages is "-ENOMEM" and "wbc->sync_mode == WB_SYNC_ALL", retry until the condition is not met.
In __ext4_get_inode_loc, if the bh returned by sb_getblk is NULL, the function returns -ENOMEM.
In __getblk_slow, if the return value of grow_buffers is less than 0, the function returns NULL.
When the three processes are connected in series like the following stack, an infinite loop may occur:
do_writepages <--- keep retrying
ext4_writepages
mpage_map_and_submit_extent
mpage_map_one_extent
ext4_map_blocks
ext4_ext_map_blocks
ext4_ext_handle_unwritten_extents
ext4_ext_convert_to_initialized
ext4_split_extent
ext4_split_extent_at
__ext4_ext_dirty
__ext4_mark_inode_dirty
ext4_reserve_inode_write
ext4_get_inode_loc
__ext4_get_inode_loc <--- return -ENOMEM
sb_getblk
__getblk_gfp
__getblk_slow <--- return NULL
grow_buffers
grow_dev_page <--- return -ENXIO
ret = (block < end_block) ? 1 : -ENXIO;In this issue, bg_inode_table_hi is overwritten as an incorrect value. As a result, block < end_block cannot be met in grow_dev_page. Therefore, __ext4_get_inode_loc always returns '-ENOMEM' and do_writepages keeps retrying. As a result, the writeback process is in the D state due to an infinite loop.
Add a check on inode table block in the __ext4_get_inode_loc function by referring to ext4_read_inode_bitmap to avoid this infinite loop.
--- fs/ext4/inode.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
fs/ext4/inode.c +9 -1
@@ -4473,9 +4473,17 @@ static int __ext4_get_inode_loc(struct s inodes_per_block =EXT4_SB (sb)->s_inodes_per_block; inode_offset = ((ino -1 ) %EXT4_INODES_PER_GROUP (sb)); - block =ext4_inode_table (sb, gdp) + (inode_offset / inodes_per_block); iloc->offset = (inode_offset % inodes_per_block) *EXT4_INODE_SIZE (sb); + block =ext4_inode_table (sb, gdp); +if ((block <=le32_to_cpu (EXT4_SB (sb)->s_es->s_first_data_block)) || + (block >=ext4_blocks_count (EXT4_SB (sb)->s_es))) { +ext4_error (sb,"Invalid inode table block %llu in " +"block_group %u" , block, iloc->block_group); +return -EFSCORRUPTED ; + } + block += (inode_offset / inodes_per_block); + bh =sb_getblk (sb, block);if (unlikely (!bh))return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 134/177 ext4: remove trailing newline from ext4_msg() message
In reply to Greg Kroah-HartmanFrom: Luís Henriques <[email protected]>
commit 78742d4d056df7d2fad241c90185d281bf924844 upstream.
The ext4_msg() function adds a new line to the message. Remove extra '\n' from call to ext4_msg() in ext4_orphan_cleanup().
--- fs/ext4/orphan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/orphan.c +1 -1
@@ -412,7 +412,7 @@ void ext4_orphan_cleanup(struct super_bl/* don't clear list on RO mount w/ errors */ if (es->s_last_orphan && !(s_flags &SB_RDONLY )) {ext4_msg (sb,KERN_INFO ,"Errors on filesystem, " -"clearing orphan list.\n" ); +"clearing orphan list." ); es->s_last_orphan =0 ; }ext4_debug ("Skipping orphan recovery on fs with errors.\n" );
Greg Kroah-Hartman
maintainerPATCH 135/177 fs: ext4: initialize fsdata in pagecache_write()
In reply to Greg Kroah-HartmanFrom: Alexander Potapenko <[email protected]>
commit 956510c0c7439e90b8103aaeaf4da92878c622f0 upstream.
When aops->write_begin() does not initialize fsdata, KMSAN reports an error passing the latter to aops->write_end().
Fix this by unconditionally initializing fsdata.
--- fs/ext4/verity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/verity.c +1 -1
@@ -79,7 +79,7 @@ static int pagecache_write(struct inodesize_t n =min_t (size_t, count,PAGE_SIZE -offset_in_page (pos));struct page *page; -void *fsdata; +void *fsdata =NULL ;int res; res = aops->write_begin (NULL , mapping, pos, n, &page, &fsdata);
Greg Kroah-Hartman
maintainerPATCH 136/177 ext4: fix use-after-free in ext4_orphan_cleanup
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
commit a71248b1accb2b42e4980afef4fa4a27fa0e36f5 upstream.
I caught a issue as follows:
==================================================================
BUG: KASAN: use-after-free in __list_add_valid+0x28/0x1a0 Read of size 8 at addr ffff88814b13f378 by task mount/710 CPU: 1 PID: 710 Comm: mount Not tainted 6.1.0-rc3-next #370 Call Trace: <TASK> dump_stack_lvl+0x73/0x9f print_report+0x25d/0x759 kasan_report+0xc0/0x120 __asan_load8+0x99/0x140 __list_add_valid+0x28/0x1a0 ext4_orphan_cleanup+0x564/0x9d0 [ext4] __ext4_fill_super+0x48e2/0x5300 [ext4] ext4_fill_super+0x19f/0x3a0 [ext4] get_tree_bdev+0x27b/0x450 ext4_get_tree+0x19/0x30 [ext4] vfs_get_tree+0x49/0x150 path_mount+0xaae/0x1350 do_mount+0xe2/0x110 __x64_sys_mount+0xf0/0x190 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd </TASK> [...] ==================================================================
Above issue may happen as follows:
-------------------------------------ext4_fill_super
ext4_orphan_cleanup
--- loop1: assume last_orphan is 12 ---
list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan)
ext4_truncate --> return 0
ext4_inode_attach_jinode --> return -ENOMEM
iput(inode) --> free inode<12>
--- loop2: last_orphan is still 12 ---
list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan);
// use inode<12> and trigger UAFTo solve this issue, we need to propagate the return value of ext4_inode_attach_jinode() appropriately.
--- fs/ext4/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ext4/inode.c +2 -1
@@ -4225,7 +4225,8 @@ int ext4_truncate(struct inode *inode)/* If we zero-out tail of the page, we have to create jinode for jbd2 */ if (inode->i_size & (inode->i_sb->s_blocksize -1 )) { -if (ext4_inode_attach_jinode (inode) <0 ) + err =ext4_inode_attach_jinode (inode); +if (err) goto out_trace; }
Greg Kroah-Hartman
maintainerPATCH 137/177 ext4: fix undefined behavior in bit shift for ext4_check_flag_values
In reply to Greg Kroah-HartmanFrom: Gaosheng Cui <[email protected]>
commit 3bf678a0f9c017c9ba7c581541dbc8453452a7ae upstream.
Shifting signed 32-bit value by 31 bits is undefined, so changing significant bit to unsigned. The UBSAN warning calltrace like below:
UBSAN: shift-out-of-bounds in fs/ext4/ext4.h:591:2 left shift of 1 by 31 places cannot be represented in type 'int' Call Trace: <TASK> dump_stack_lvl+0x7d/0xa5 dump_stack+0x15/0x1b ubsan_epilogue+0xe/0x4e __ubsan_handle_shift_out_of_bounds+0x1e7/0x20c ext4_init_fs+0x5a/0x277 do_one_initcall+0x76/0x430 kernel_init_freeable+0x3b3/0x422 kernel_init+0x24/0x1e0 ret_from_fork+0x1f/0x30 </TASK>
--- fs/ext4/ext4.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/ext4.h +1 -1
@@ -558,7 +558,7 @@ enum {* * It's not paranoia if the Murphy's Law really *is* out to get you. :-) */ -#define TEST_FLAG_VALUE (FLAG ) (EXT4_##FLAG##_FL == (1 << EXT4_INODE_##FLAG)) +#define TEST_FLAG_VALUE (FLAG ) (EXT4_##FLAG##_FL == (1U << EXT4_INODE_##FLAG))#define CHECK_FLAG_VALUE (FLAG ) BUILD_BUG_ON(!TEST_FLAG_VALUE(FLAG))static inline void ext4_check_flag_values (void )
Greg Kroah-Hartman
maintainerPATCH 138/177 ext4: add EXT4_IGET_BAD flag to prevent unexpected bad inode
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
commit 63b1e9bccb71fe7d7e3ddc9877dbdc85e5d2d023 upstream.
There are many places that will get unhappy (and crash) when ext4_iget() returns a bad inode. However, if iget the boot loader inode, allows a bad inode to be returned, because the inode may not be initialized. This mechanism can be used to bypass some checks and cause panic. To solve this problem, we add a special iget flag EXT4_IGET_BAD. Only with this flag we'd be returning bad inode from ext4_iget(), otherwise we always return the error code if the inode is bad inode.(suggested by Jan Kara)
--- fs/ext4/ext4.h | 3 ++- fs/ext4/inode.c | 8 +++++++- fs/ext4/ioctl.c | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-)
fs/ext4/ext4.h +2 -1
@@ -2964,7 +2964,8 @@ int do_journal_get_write_access(handle_ttypedef enum {EXT4_IGET_NORMAL =0 ,EXT4_IGET_SPECIAL =0x0001 ,/* OK to iget a system inode */ -EXT4_IGET_HANDLE =0x0002 /* Inode # is from a handle */ +EXT4_IGET_HANDLE =0x0002 ,/* Inode # is from a handle */ +EXT4_IGET_BAD =0x0004 /* Allow to iget a bad inode */ }ext4_iget_flags ; extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
fs/ext4/inode.c +7 -1
@@ -5053,8 +5053,14 @@ struct inode *__ext4_iget(struct super_bif (IS_CASEFOLDED (inode) && !ext4_has_feature_casefold (inode->i_sb))ext4_error_inode (inode, function, line,0 ,"casefold flag without casefold feature" ); -brelse (iloc.bh); +if (is_bad_inode (inode) && !(flags &EXT4_IGET_BAD )) { +ext4_error_inode (inode, function, line,0 , +"bad inode without EXT4_IGET_BAD flag" ); + ret = -EUCLEAN ; + goto bad_inode; + } +brelse (iloc.bh);unlock_new_inode (inode);return inode;
fs/ext4/ioctl.c +2 -1
@@ -374,7 +374,8 @@ static long swap_inode_boot_loader(strucblkcnt_t blocks;unsigned short bytes; - inode_bl =ext4_iget (sb,EXT4_BOOT_LOADER_INO ,EXT4_IGET_SPECIAL ); + inode_bl =ext4_iget (sb,EXT4_BOOT_LOADER_INO , +EXT4_IGET_SPECIAL |EXT4_IGET_BAD );if (IS_ERR (inode_bl))return PTR_ERR (inode_bl); ei_bl =EXT4_I (inode_bl);
Greg Kroah-Hartman
maintainerPATCH 139/177 ext4: add helper to check quota inums
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
commit 07342ec259df2a35d6a34aebce010567a80a0e15 upstream.
Before quota is enabled, a check on the preset quota inums in ext4_super_block is added to prevent wrong quota inodes from being loaded. In addition, when the quota fails to be enabled, the quota type and quota inum are printed to facilitate fault locating.
--- fs/ext4/super.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-)
fs/ext4/super.c +25 -3
@@ -6743,6 +6743,20 @@ static int ext4_quota_on(struct super_blreturn err; } +static inline bool ext4_check_quota_inum (int type,unsigned long qf_inum) +{ +switch (type) { +case USRQUOTA : +return qf_inum ==EXT4_USR_QUOTA_INO ; +case GRPQUOTA : +return qf_inum ==EXT4_GRP_QUOTA_INO ; +case PRJQUOTA : +return qf_inum >=EXT4_GOOD_OLD_FIRST_INO ; +default : +BUG (); + } +} +static int ext4_quota_enable (struct super_block *sb,int type,int format_id,unsigned int flags) {
@@ -6759,9 +6773,16 @@ static int ext4_quota_enable(struct supeif (!qf_inums[type])return -EPERM ; +if (!ext4_check_quota_inum (type, qf_inums[type])) { +ext4_error (sb,"Bad quota inum: %lu, type: %d" , + qf_inums[type], type); +return -EUCLEAN ; + } + qf_inode =ext4_iget (sb, qf_inums[type],EXT4_IGET_SPECIAL );if (IS_ERR (qf_inode)) { -ext4_error (sb,"Bad quota inode # %lu" , qf_inums[type]); +ext4_error (sb,"Bad quota inode: %lu, type: %d" , + qf_inums[type], type);return PTR_ERR (qf_inode); }
@@ -6800,8 +6821,9 @@ int ext4_enable_quotas(struct super_blocif (err) {ext4_warning (sb,"Failed to enable quota tracking " -"(type=%d, err=%d). Please run " -"e2fsck to fix." , type, err); +"(type=%d, err=%d, ino=%lu). " +"Please run e2fsck to fix." , type, + err, qf_inums[type]);for (type--; type >=0 ; type--) {struct inode *inode;
Greg Kroah-Hartman
maintainerPATCH 140/177 ext4: fix bug_on in __es_tree_search caused by bad quota inode
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
commit d323877484765aaacbb2769b06e355c2041ed115 upstream.
We got a issue as fllows:
==================================================================
kernel BUG at fs/ext4/extents_status.c:202!
invalid opcode: 0000 [#1] PREEMPT SMP
CPU: 1 PID: 810 Comm: mount Not tainted 6.1.0-rc1-next-g9631525255e3 #352 RIP: 0010:__es_tree_search.isra.0+0xb8/0xe0 RSP: 0018:ffffc90001227900 EFLAGS: 00010202 RAX: 0000000000000000 RBX: 0000000077512a0f RCX: 0000000000000000 RDX: 0000000000000002 RSI: 0000000000002a10 RDI: ffff8881004cd0c8 RBP: ffff888177512ac8 R08: 47ffffffffffffff R09: 0000000000000001 R10: 0000000000000001 R11: 00000000000679af R12: 0000000000002a10 R13: ffff888177512d88 R14: 0000000077512a10 R15: 0000000000000000 FS: 00007f4bd76dbc40(0000)GS:ffff88842fd00000(0000)knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00005653bf993cf8 CR3: 000000017bfdf000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ext4_es_cache_extent+0xe2/0x210 ext4_cache_extents+0xd2/0x110 ext4_find_extent+0x5d5/0x8c0 ext4_ext_map_blocks+0x9c/0x1d30 ext4_map_blocks+0x431/0xa50 ext4_getblk+0x82/0x340 ext4_bread+0x14/0x110 ext4_quota_read+0xf0/0x180 v2_read_header+0x24/0x90 v2_check_quota_file+0x2f/0xa0 dquot_load_quota_sb+0x26c/0x760 dquot_load_quota_inode+0xa5/0x190 ext4_enable_quotas+0x14c/0x300 __ext4_fill_super+0x31cc/0x32c0 ext4_fill_super+0x115/0x2d0 get_tree_bdev+0x1d2/0x360 ext4_get_tree+0x19/0x30 vfs_get_tree+0x26/0xe0 path_mount+0x81d/0xfc0 do_mount+0x8d/0xc0 __x64_sys_mount+0xc0/0x160 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd </TASK> ==================================================================
Above issue may happen as follows:
-------------------------------------ext4_fill_super
ext4_orphan_cleanup
ext4_enable_quotas
ext4_quota_enable
ext4_iget --> get error inode <5>
ext4_ext_check_inode --> Wrong imode makes it escape inspection
make_bad_inode(inode) --> EXT4_BOOT_LOADER_INO set imode
dquot_load_quota_inode
vfs_setup_quota_inode --> check pass
dquot_load_quota_sb
v2_check_quota_file
v2_read_header
ext4_quota_read
ext4_bread
ext4_getblk
ext4_map_blocks
ext4_ext_map_blocks
ext4_find_extent
ext4_cache_extents
ext4_es_cache_extent
__es_tree_search.isra.0
ext4_es_end --> Wrong extents trigger BUG_ONIn the above issue, s_usr_quota_inum is set to 5, but inode<5> contains incorrect imode and disordered extents. Because 5 is EXT4_BOOT_LOADER_INO, the ext4_ext_check_inode check in the ext4_iget function can be bypassed, finally, the extents that are not checked trigger the BUG_ON in the __es_tree_search function. To solve this issue, check whether the inode is bad_inode in vfs_setup_quota_inode().
--- fs/quota/dquot.c | 2 ++ 1 file changed, 2 insertions(+)
fs/quota/dquot.c +2 -0
@@ -2324,6 +2324,8 @@ static int vfs_setup_quota_inode(structstruct super_block *sb = inode->i_sb;struct quota_info *dqopt =sb_dqopt (sb); +if (is_bad_inode (inode)) +return -EUCLEAN ;if (!S_ISREG (inode->i_mode))return -EACCES ;if (IS_RDONLY (inode))
Greg Kroah-Hartman
maintainerPATCH 141/177 ext4: fix reserved cluster accounting in __es_remove_extent()
In reply to Greg Kroah-HartmanFrom: Ye Bin <[email protected]>
commit 1da18e38cb97e9521e93d63034521a9649524f64 upstream.
When bigalloc is enabled, reserved cluster accounting for delayed allocation is handled in extent_status.c. With a corrupted file system, it's possible for this accounting to be incorrect, dsicovered by Syzbot:
EXT4-fs error (device loop0): ext4_validate_block_bitmap:398: comm rep:
bg 0: block 5: invalid block bitmap
EXT4-fs (loop0): Delayed block allocation failed for inode 18 at logical
offset 0 with max blocks 32 with error 28
EXT4-fs (loop0): This should not happen!! Data will be lost
EXT4-fs (loop0): Total free blocks count 0
EXT4-fs (loop0): Free/Dirty block details
EXT4-fs (loop0): free_blocks=0
EXT4-fs (loop0): dirty_blocks=32
EXT4-fs (loop0): Block reservation details
EXT4-fs (loop0): i_reserved_data_blocks=2
EXT4-fs (loop0): Inode 18 (00000000845cd634):
i_reserved_data_blocks (1) not cleared!
Above issue happens as follows:
Assume:sbi->s_cluster_ratio = 16
Step1:
Insert delay block [0, 31] -> ei->i_reserved_data_blocks=2 Step2:ext4_writepages
mpage_map_and_submit_extent -> return failed mpage_release_unused_pages -> to release [0, 30]
ext4_es_remove_extent -> remove lblk=0 end=30
__es_remove_extent -> len1=0 len2=31-30=1
__es_remove_extent:
...
if (len2 > 0) {
...
if (len1 > 0) {
...
} else {
es->es_lblk = end + 1;
es->es_len = len2;
...
}
if (count_reserved)
count_rsvd(inode, lblk, ...);
goto out; -> will return but didn't calculate 'reserved' ...
Step3:ext4_destroy_inode -> trigger "i_reserved_data_blocks (1) not cleared!"
To solve above issue if 'len2>0' call 'get_rsvd()' before goto out.
--- fs/ext4/extents_status.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/ext4/extents_status.c +2 -1
@@ -1372,7 +1372,7 @@ retry:if (count_reserved)count_rsvd (inode, lblk, orig_es.es_len - len1 - len2, &orig_es, &rc); - goto out; + goto out_get_reserved; }if (len1 >0 ) {
@@ -1414,6 +1414,7 @@ retry: } } +out_get_reserved:if (count_reserved) *reserved =get_rsvd (inode, end, es, &rc); out:
Greg Kroah-Hartman
maintainerPATCH 142/177 ext4: journal_path mount options should follow links
In reply to Greg Kroah-HartmanFrom: Lukas Czerner <[email protected]>
commit e3ea75ee651daf5e434afbfdb7dbf75e200ea1f6 upstream.
Before the commit 461c3af045d3 ("ext4: Change handle_mount_opt() to use fs_parameter") ext4 mount option journal_path did follow links in the provided path.
Bring this behavior back by allowing to pass pathwalk flags to fs_lookup_param().
--- Documentation/filesystems/mount_api.rst | 1 + fs/ext4/super.c | 2 +- fs/fs_parser.c | 3 ++- include/linux/fs_parser.h | 1 + 4 files changed, 5 insertions(+), 2 deletions(-)
Documentation/filesystems/mount_api.rst +1 -0
@@ -814,6 +814,7 @@ process the parameters it is given. int fs_lookup_param(struct fs_context *fc, struct fs_parameter *value, bool want_bdev, + unsigned int flags, struct path *_path); This takes a parameter that carries a string or filename type and attempts
fs/ext4/super.c +1 -1
@@ -2260,7 +2260,7 @@ static int ext4_parse_param(struct fs_coreturn -EINVAL ; } - error =fs_lookup_param (fc, param,1 , &path); + error =fs_lookup_param (fc, param,1 ,LOOKUP_FOLLOW , &path);if (error) {ext4_msg (NULL ,KERN_ERR ,"error: could not find " "journal device path" );
fs/fs_parser.c +2 -1
@@ -138,15 +138,16 @@ EXPORT_SYMBOL(__fs_parse);* @fc: The filesystem context to log errors through. * @param: The parameter. * @want_bdev: T if want a blockdev +* @flags: Pathwalk flags passed to filename_lookup() * @_path: The result of the lookup */ int fs_lookup_param (struct fs_context *fc,struct fs_parameter *param,bool want_bdev, +unsigned int flags,struct path *_path) {struct filename *f; -unsigned int flags =0 ;bool put_f;int ret;
include/linux/fs_parser.h +1 -0
@@ -76,6 +76,7 @@ static inline int fs_parse(struct fs_conextern int fs_lookup_param (struct fs_context *fc,struct fs_parameter *param,bool want_bdev, +unsigned int flags,struct path *_path);extern int lookup_constant (const struct constant_table tbl[],const char *name,int not_found);
Greg Kroah-Hartman
maintainerPATCH 143/177 ext4: check and assert if marking an no_delete evicting inode dirty
In reply to Greg Kroah-HartmanFrom: Zhang Yi <[email protected]>
commit 318cdc822c63b6e2befcfdc2088378ae6fa18def upstream.
In ext4_evict_inode(), if we evicting an inode in the 'no_delete' path, it cannot be raced by another mark_inode_dirty(). If it happens, someone else may accidentally dirty it without holding inode refcount and probably cause use-after-free issues in the writeback procedure. It's indiscoverable and hard to debug, so add an WARN_ON_ONCE() to check and detect this issue in advance.
--- fs/ext4/inode.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/ext4/inode.c +6 -0
@@ -335,6 +335,12 @@ stop_handle:ext4_xattr_inode_array_free (ea_inode_array);return ; no_delete: +/* +* Check out some where else accidentally dirty the evicting inode, +* which may probably cause inode use-after-free issues later. +*/ +WARN_ON_ONCE (!list_empty_careful (&inode->i_io_list)); +if (!list_empty (&EXT4_I (inode)->i_fc_list))ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_NOMEM ,NULL );ext4_clear_inode (inode);/* We must guarantee clearing of inode... */
Greg Kroah-Hartman
maintainerPATCH 144/177 ext4: fix bug_on in __es_tree_search caused by bad boot loader inode
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
commit 991ed014de0840c5dc405b679168924afb2952ac upstream.
We got a issue as fllows:
==================================================================
kernel BUG at fs/ext4/extents_status.c:203!
invalid opcode: 0000 [#1] PREEMPT SMP
CPU: 1 PID: 945 Comm: cat Not tainted 6.0.0-next-20221007-dirty #349 RIP: 0010:ext4_es_end.isra.0+0x34/0x42 RSP: 0018:ffffc9000143b768 EFLAGS: 00010203 RAX: 0000000000000000 RBX: ffff8881769cd0b8 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffff8fc27cf7 RDI: 00000000ffffffff RBP: ffff8881769cd0bc R08: 0000000000000000 R09: ffffc9000143b5f8 R10: 0000000000000001 R11: 0000000000000001 R12: ffff8881769cd0a0 R13: ffff8881768e5668 R14: 00000000768e52f0 R15: 0000000000000000 FS: 00007f359f7f05c0(0000)GS:ffff88842fd00000(0000)knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f359f5a2000 CR3: 000000017130c000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> __es_tree_search.isra.0+0x6d/0xf5 ext4_es_cache_extent+0xfa/0x230 ext4_cache_extents+0xd2/0x110 ext4_find_extent+0x5d5/0x8c0 ext4_ext_map_blocks+0x9c/0x1d30 ext4_map_blocks+0x431/0xa50 ext4_mpage_readpages+0x48e/0xe40 ext4_readahead+0x47/0x50 read_pages+0x82/0x530 page_cache_ra_unbounded+0x199/0x2a0 do_page_cache_ra+0x47/0x70 page_cache_ra_order+0x242/0x400 ondemand_readahead+0x1e8/0x4b0 page_cache_sync_ra+0xf4/0x110 filemap_get_pages+0x131/0xb20 filemap_read+0xda/0x4b0 generic_file_read_iter+0x13a/0x250 ext4_file_read_iter+0x59/0x1d0 vfs_read+0x28f/0x460 ksys_read+0x73/0x160 __x64_sys_read+0x1e/0x30 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd </TASK> ==================================================================
In the above issue, ioctl invokes the swap_inode_boot_loader function to swap inode<5> and inode<12>. However, inode<5> contain incorrect imode and disordered extents, and i_nlink is set to 1. The extents check for inode in the ext4_iget function can be bypassed bacause 5 is EXT4_BOOT_LOADER_INO. While links_count is set to 1, the extents are not initialized in swap_inode_boot_loader. After the ioctl command is executed successfully, the extents are swapped to inode<12>, in this case, run the cat command to view inode<12>. And Bug_ON is triggered due to the incorrect extents.
When the boot loader inode is not initialized, its imode can be one of the following:
1) the imode is a bad type, which is marked as bad_inode in ext4_iget and set to S_IFREG.
2) the imode is good type but not S_IFREG.
3) the imode is S_IFREG.
The BUG_ON may be triggered by bypassing the check in cases 1 and 2. Therefore, when the boot loader inode is bad_inode or its imode is not S_IFREG, initialize the inode to avoid triggering the BUG.
--- fs/ext4/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/ioctl.c +1 -1
@@ -425,7 +425,7 @@ static long swap_inode_boot_loader(struc/* Protect extent tree against block allocations via delalloc */ ext4_double_down_write_data_sem (inode, inode_bl); -if (inode_bl->i_nlink ==0 ) { +if (is_bad_inode (inode_bl) || !S_ISREG (inode_bl->i_mode)) {/* this inode has never been used as a BOOT_LOADER */ set_nlink (inode_bl,1 );i_uid_write (inode_bl,0 );
Greg Kroah-Hartman
maintainerPATCH 145/177 ext4: dont allow journal inode to have encrypt flag
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 105c78e12468413e426625831faa7db4284e1fec upstream.
Mounting a filesystem whose journal inode has the encrypt flag causes a NULL dereference in fscrypt_limit_io_blocks() when the 'inlinecrypt' mount option is used.
The problem is that when jbd2_journal_init_inode() calls bmap(), it eventually finds its way into ext4_iomap_begin(), which calls fscrypt_limit_io_blocks(). fscrypt_limit_io_blocks() requires that if the inode is encrypted, then its encryption key must already be set up. That's not the case here, since the journal inode is never "opened" like a normal file would be. Hence the crash.
A reproducer is:
mkfs.ext4 -F /dev/vdb
debugfs -w /dev/vdb -R "set_inode_field <8> flags 0x80808" mount /dev/vdb /mnt -o inlinecrypt
To fix this, make ext4 consider journal inodes with the encrypt flag to be invalid. (Note, maybe other flags should be rejected on the journal inode too. For now, this is just the minimal fix for the above issue.)
I've marked this as fixing the commit that introduced the call to fscrypt_limit_io_blocks(), since that's what made an actual crash start being possible. But this fix could be applied to any version of ext4 that supports the encrypt feature.
--- fs/ext4/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/super.c +1 -1
@@ -5580,7 +5580,7 @@ static struct inode *ext4_get_journal_inext4_debug ("Journal inode found at %p: %lld bytes\n" , journal_inode, journal_inode->i_size); -if (!S_ISREG (journal_inode->i_mode)) { +if (!S_ISREG (journal_inode->i_mode) ||IS_ENCRYPTED (journal_inode)) {ext4_msg (sb,KERN_ERR ,"invalid journal inode" );iput (journal_inode);return NULL ;
Greg Kroah-Hartman
maintainerPATCH 146/177 ext4: disable fast-commit of encrypted dir operations
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 0fbcb5251fc81b58969b272c4fb7374a7b922e3e upstream.
fast-commit of create, link, and unlink operations in encrypted directories is completely broken because the unencrypted filenames are being written to the fast-commit journal instead of the encrypted filenames. These operations can't be replayed, as encryption keys aren't present at journal replay time. It is also an information leak.
Until if/when we can get this working properly, make encrypted directory operations ineligible for fast-commit.
Note that fast-commit operations on encrypted regular files continue to be allowed, as they seem to work.
--- fs/ext4/fast_commit.c | 41 +++++++++++++++++++++++++---------------- fs/ext4/fast_commit.h | 1 + include/trace/events/ext4.h | 7 +++++-- 3 files changed, 31 insertions(+), 18 deletions(-)
fs/ext4/fast_commit.c +25 -16
@@ -418,25 +418,34 @@ static int __track_dentry_update(structstruct __track_dentry_update_args *dentry_update = (struct __track_dentry_update_args *)arg;struct dentry *dentry = dentry_update->dentry; -struct ext4_sb_info *sbi =EXT4_SB (inode->i_sb); +struct inode *dir = dentry->d_parent->d_inode; +struct super_block *sb = inode->i_sb; +struct ext4_sb_info *sbi =EXT4_SB (sb);mutex_unlock (&ei->i_fc_lock); + +if (IS_ENCRYPTED (dir)) { +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_ENCRYPTED_FILENAME , +NULL ); +mutex_lock (&ei->i_fc_lock); +return -EOPNOTSUPP ; + } + node =kmem_cache_alloc (ext4_fc_dentry_cachep,GFP_NOFS );if (!node) { -ext4_fc_mark_ineligible (inode->i_sb,EXT4_FC_REASON_NOMEM ,NULL ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_NOMEM ,NULL );mutex_lock (&ei->i_fc_lock);return -ENOMEM ; } node->fcd_op = dentry_update->op; - node->fcd_parent = dentry->d_parent->d_inode->i_ino; + node->fcd_parent = dir->i_ino; node->fcd_ino = inode->i_ino;if (dentry->d_name.len >DNAME_INLINE_LEN ) { node->fcd_name.name =kmalloc (dentry->d_name.len,GFP_NOFS );if (!node->fcd_name.name) {kmem_cache_free (ext4_fc_dentry_cachep, node); -ext4_fc_mark_ineligible (inode->i_sb, -EXT4_FC_REASON_NOMEM ,NULL ); +ext4_fc_mark_ineligible (sb,EXT4_FC_REASON_NOMEM ,NULL );mutex_lock (&ei->i_fc_lock);return -ENOMEM ; }
@@ -2258,17 +2267,17 @@ void ext4_fc_init(struct super_block *sb journal->j_fc_cleanup_callback = ext4_fc_cleanup; } -static const char *fc_ineligible_reasons[] = { -"Extended attributes changed" , -"Cross rename" , -"Journal flag changed" , -"Insufficient memory" , -"Swap boot" , -"Resize" , -"Dir renamed" , -"Falloc range op" , -"Data journalling" , -"FC Commit Failed" +static const char *const fc_ineligible_reasons[] = { + [EXT4_FC_REASON_XATTR ] ="Extended attributes changed" , + [EXT4_FC_REASON_CROSS_RENAME ] ="Cross rename" , + [EXT4_FC_REASON_JOURNAL_FLAG_CHANGE ] ="Journal flag changed" , + [EXT4_FC_REASON_NOMEM ] ="Insufficient memory" , + [EXT4_FC_REASON_SWAP_BOOT ] ="Swap boot" , + [EXT4_FC_REASON_RESIZE ] ="Resize" , + [EXT4_FC_REASON_RENAME_DIR ] ="Dir renamed" , + [EXT4_FC_REASON_FALLOC_RANGE ] ="Falloc range op" , + [EXT4_FC_REASON_INODE_JOURNAL_DATA ] ="Data journalling" , + [EXT4_FC_REASON_ENCRYPTED_FILENAME ] ="Encrypted filename" , };int ext4_fc_info_show (struct seq_file *seq,void *v)
fs/ext4/fast_commit.h +1 -0
@@ -96,6 +96,7 @@ enum {EXT4_FC_REASON_RENAME_DIR ,EXT4_FC_REASON_FALLOC_RANGE ,EXT4_FC_REASON_INODE_JOURNAL_DATA , +EXT4_FC_REASON_ENCRYPTED_FILENAME , EXT4_FC_REASON_MAX };
include/trace/events/ext4.h +5 -2
@@ -104,6 +104,7 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_RESIZE)TRACE_DEFINE_ENUM (EXT4_FC_REASON_RENAME_DIR );TRACE_DEFINE_ENUM (EXT4_FC_REASON_FALLOC_RANGE );TRACE_DEFINE_ENUM (EXT4_FC_REASON_INODE_JOURNAL_DATA ); +TRACE_DEFINE_ENUM (EXT4_FC_REASON_ENCRYPTED_FILENAME );TRACE_DEFINE_ENUM (EXT4_FC_REASON_MAX );#define show_fc_reason (reason) \
@@ -116,7 +117,8 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX); { EXT4_FC_REASON_RESIZE, "RESIZE"}, \ { EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, \ { EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"}, \ - { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}) + { EXT4_FC_REASON_INODE_JOURNAL_DATA, "INODE_JOURNAL_DATA"}, \ + { EXT4_FC_REASON_ENCRYPTED_FILENAME, "ENCRYPTED_FILENAME"}) TRACE_EVENT(ext4_other_inode_update_time, TP_PROTO(struct inode *inode, ino_t orig_ino),
@@ -2764,7 +2766,7 @@ TRACE_EVENT(ext4_fc_stats, ), TP_printk("dev %d,%d fc ineligible reasons:\n" - "%s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u " + "%s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u" "num_commits:%lu, ineligible: %lu, numblks: %lu", MAJOR(__entry->dev), MINOR(__entry->dev), FC_REASON_NAME_STAT(EXT4_FC_REASON_XATTR),
@@ -2776,6 +2778,7 @@ TRACE_EVENT(ext4_fc_stats,FC_REASON_NAME_STAT (EXT4_FC_REASON_RENAME_DIR ),FC_REASON_NAME_STAT (EXT4_FC_REASON_FALLOC_RANGE ),FC_REASON_NAME_STAT (EXT4_FC_REASON_INODE_JOURNAL_DATA ), +FC_REASON_NAME_STAT (EXT4_FC_REASON_ENCRYPTED_FILENAME ), __entry->fc_commits, __entry->fc_ineligible_commits, __entry->fc_numblks) );
Greg Kroah-Hartman
maintainerPATCH 147/177 ext4: fix leaking uninitialized memory in fast-commit journal
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 594bc43b410316d70bb42aeff168837888d96810 upstream.
When space at the end of fast-commit journal blocks is unused, make sure to zero it out so that uninitialized memory is not leaked to disk.
--- fs/ext4/fast_commit.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/ext4/fast_commit.c +5 -0
@@ -745,6 +745,9 @@ static u8 *ext4_fc_reserve_space(struct *crc =ext4_chksum (sbi, *crc, tl,EXT4_FC_TAG_BASE_LEN );if (pad_len >0 )ext4_fc_memzero (sb, tl +1 , pad_len, crc); +/* Don't leak uninitialized memory in the unused last byte. */ + *((u8 *)(tl +1 ) + pad_len) =0 ; +ext4_fc_submit_bh (sb, false); ret =jbd2_fc_get_buf (EXT4_SB (sb)->s_journal, &bh);
@@ -801,6 +804,8 @@ static int ext4_fc_write_tail(struct sup dst +=sizeof (tail.fc_tid); tail.fc_crc =cpu_to_le32 (crc);ext4_fc_memcpy (sb, dst, &tail.fc_crc,sizeof (tail.fc_crc),NULL ); + dst +=sizeof (tail.fc_crc); +memset (dst,0 , bsize - off);/* Don't leak uninitialized memory. */ ext4_fc_submit_bh (sb, true);
Greg Kroah-Hartman
maintainerPATCH 148/177 ext4: dont set up encryption key during jbd2 transaction
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 4c0d5778385cb3618ff26a561ce41de2b7d9de70 upstream.
Commit a80f7fcf1867 ("ext4: fixup ext4_fc_track_* functions' signature") extended the scope of the transaction in ext4_unlink() too far, making it include the call to ext4_find_entry(). However, ext4_find_entry() can deadlock when called from within a transaction because it may need to set up the directory's encryption key.
Fix this by restoring the transaction to its original scope.
--- fs/ext4/ext4.h | 4 ++-- fs/ext4/fast_commit.c | 2 +- fs/ext4/namei.c | 44 ++++++++++++++++++++++++-------------------- 3 files changed, 27 insertions(+), 23 deletions(-)
fs/ext4/ext4.h +2 -2
@@ -3622,8 +3622,8 @@ extern void ext4_initialize_dirent_tail( unsigned int blocksize);extern int ext4_handle_dirty_dirblock (handle_t *handle,struct inode *inode,struct buffer_head *bh); -extern int __ext4_unlink (handle_t *handle,struct inode *dir,const struct qstr *d_name, -struct inode *inode); +extern int __ext4_unlink (struct inode *dir,const struct qstr *d_name, +struct inode *inode,struct dentry *dentry);extern int __ext4_link (struct inode *dir,struct inode *inode,struct dentry *dentry);
fs/ext4/fast_commit.c +1 -1
@@ -1410,7 +1410,7 @@ static int ext4_fc_replay_unlink(structreturn 0 ; } - ret =__ext4_unlink (NULL , old_parent, &entry, inode); + ret =__ext4_unlink (old_parent, &entry, inode,NULL );/* -ENOENT ok coz it might not exist anymore. */ if (ret == -ENOENT ) ret =0 ;
fs/ext4/namei.c +24 -20
96 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 149/177 ext4: add missing validation of fast-commit record lengths
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 64b4a25c3de81a69724e888ec2db3533b43816e2 upstream.
Validate the inode and filename lengths in fast-commit journal records so that a malicious fast-commit journal cannot cause a crash by having invalid values for these. Also validate EXT4_FC_TAG_DEL_RANGE.
--- fs/ext4/fast_commit.c | 38 +++++++++++++++++++------------------- fs/ext4/fast_commit.h | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-)
fs/ext4/fast_commit.c +19 -19
@@ -2000,32 +2000,31 @@ void ext4_fc_replay_cleanup(struct superkfree (sbi->s_fc_replay_state.fc_modified_inodes); } -static inline bool ext4_fc_tag_len_isvalid (struct ext4_fc_tl *tl, -u8 *val,u8 *end) +static bool ext4_fc_value_len_isvalid (struct ext4_sb_info *sbi, +int tag,int len) { -if (val + tl->fc_len > end) -return false; - -/* Here only check ADD_RANGE/TAIL/HEAD which will read data when do -* journal rescan before do CRC check. Other tags length check will -* rely on CRC check. -*/ -switch (tl->fc_tag) { +switch (tag) {case EXT4_FC_TAG_ADD_RANGE : -return (sizeof (struct ext4_fc_add_range ) == tl->fc_len); -case EXT4_FC_TAG_TAIL : -return (sizeof (struct ext4_fc_tail ) <= tl->fc_len); -case EXT4_FC_TAG_HEAD : -return (sizeof (struct ext4_fc_head ) == tl->fc_len); +return len ==sizeof (struct ext4_fc_add_range );case EXT4_FC_TAG_DEL_RANGE : +return len ==sizeof (struct ext4_fc_del_range ); +case EXT4_FC_TAG_CREAT :case EXT4_FC_TAG_LINK :case EXT4_FC_TAG_UNLINK : -case EXT4_FC_TAG_CREAT : + len -=sizeof (struct ext4_fc_dentry_info ); +return len >=1 && len <=EXT4_NAME_LEN ;case EXT4_FC_TAG_INODE : + len -=sizeof (struct ext4_fc_inode ); +return len >=EXT4_GOOD_OLD_INODE_SIZE && + len <= sbi->s_inode_size;case EXT4_FC_TAG_PAD : -default : -return true; +return true;/* padding can have any length */ +case EXT4_FC_TAG_TAIL : +return len >=sizeof (struct ext4_fc_tail ); +case EXT4_FC_TAG_HEAD : +return len ==sizeof (struct ext4_fc_head ); } +return false; }/*
@@ -2088,7 +2087,8 @@ static int ext4_fc_replay_scan(journal_t cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) {ext4_fc_get_tl (&tl, cur); val = cur +EXT4_FC_TAG_BASE_LEN ; -if (!ext4_fc_tag_len_isvalid (&tl, val, end)) { +if (tl.fc_len > end - val || + !ext4_fc_value_len_isvalid (sbi, tl.fc_tag, tl.fc_len)) { ret = state->fc_replay_num_tags ?JBD2_FC_REPLAY_STOP : -ECANCELED ; goto out_err;
fs/ext4/fast_commit.h +1 -1
@@ -58,7 +58,7 @@ struct ext4_fc_dentry_info {__u8 fc_dname[]; }; -/* Value structure for EXT4_FC_TAG_INODE and EXT4_FC_TAG_INODE_PARTIAL. */ +/* Value structure for EXT4_FC_TAG_INODE. */ struct ext4_fc_inode {__le32 fc_ino;__u8 fc_raw_inode[];
Greg Kroah-Hartman
maintainerPATCH 150/177 ext4: fix unaligned memory access in ext4_fc_reserve_space()
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 8415ce07ecf0cc25efdd5db264a7133716e503cf upstream.
As is done elsewhere in the file, build the struct ext4_fc_tl on the stack and memcpy() it into the buffer, rather than directly writing it to a potentially-unaligned location in the buffer.
--- fs/ext4/fast_commit.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-)
fs/ext4/fast_commit.c +21 -18
@@ -683,6 +683,15 @@ static void ext4_fc_submit_bh(struct sup/* Ext4 commit path routines */ +/* memcpy to fc reserved space and update CRC */ +static void *ext4_fc_memcpy (struct super_block *sb,void *dst,const void *src, +int len,u32 *crc) +{ +if (crc) + *crc =ext4_chksum (EXT4_SB (sb), *crc, src, len); +return memcpy (dst, src, len); +} +/* memzero and update CRC */ static void *ext4_fc_memzero (struct super_block *sb,void *dst,int len,u32 *crc)
@@ -708,12 +717,13 @@ static void *ext4_fc_memzero(struct supe*/ static u8 *ext4_fc_reserve_space (struct super_block *sb,int len,u32 *crc) { -struct ext4_fc_tl *tl; +struct ext4_fc_tl tl;struct ext4_sb_info *sbi =EXT4_SB (sb);struct buffer_head *bh;int bsize = sbi->s_journal->j_blocksize;int ret, off = sbi->s_fc_bytes % bsize;int pad_len; +u8 *dst;/* * After allocating len, we should have space at least for a 0 byte
@@ -737,16 +747,18 @@ static u8 *ext4_fc_reserve_space(structreturn sbi->s_fc_bh->b_data + off; }/* Need to add PAD tag */ - tl = (struct ext4_fc_tl *)(sbi->s_fc_bh->b_data + off); - tl->fc_tag =cpu_to_le16 (EXT4_FC_TAG_PAD ); + dst = sbi->s_fc_bh->b_data + off; + tl.fc_tag =cpu_to_le16 (EXT4_FC_TAG_PAD ); pad_len = bsize - off -1 -EXT4_FC_TAG_BASE_LEN ; - tl->fc_len =cpu_to_le16 (pad_len); -if (crc) - *crc =ext4_chksum (sbi, *crc, tl,EXT4_FC_TAG_BASE_LEN ); -if (pad_len >0 ) -ext4_fc_memzero (sb, tl +1 , pad_len, crc); + tl.fc_len =cpu_to_le16 (pad_len); +ext4_fc_memcpy (sb, dst, &tl,EXT4_FC_TAG_BASE_LEN , crc); + dst +=EXT4_FC_TAG_BASE_LEN ; +if (pad_len >0 ) { +ext4_fc_memzero (sb, dst, pad_len, crc); + dst += pad_len; + }/* Don't leak uninitialized memory in the unused last byte. */ - *((u8 *)(tl +1 ) + pad_len) =0 ; + *dst =0 ;ext4_fc_submit_bh (sb, false);
@@ -758,15 +770,6 @@ static u8 *ext4_fc_reserve_space(structreturn sbi->s_fc_bh->b_data; } -/* memcpy to fc reserved space and update CRC */ -static void *ext4_fc_memcpy (struct super_block *sb,void *dst,const void *src, -int len,u32 *crc) -{ -if (crc) - *crc =ext4_chksum (EXT4_SB (sb), *crc, src, len); -return memcpy (dst, src, len); -} -/* * Complete a fast commit by writing tail tag. *
Greg Kroah-Hartman
maintainerPATCH 151/177 ext4: fix off-by-one errors in fast-commit block filling
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit 48a6a66db82b8043d298a630f22c62d43550cae5 upstream.
Due to several different off-by-one errors, or perhaps due to a late change in design that wasn't fully reflected in the code that was actually merged, there are several very strange constraints on how fast-commit blocks are filled with tlv entries:
- tlvs must start at least 10 bytes before the end of the block, even though the minimum tlv length is 8. Otherwise, the replay code will ignore them. (BUG: ext4_fc_reserve_space() could violate this requirement if called with a len of blocksize - 9 or blocksize - 8. Fortunately, this doesn't seem to happen currently.)
- tlvs must end at least 1 byte before the end of the block. Otherwise the replay code will consider them to be invalid. This quirk contributed to a bug (fixed by an earlier commit) where uninitialized memory was being leaked to disk in the last byte of blocks.
Also, strangely these constraints don't apply to the replay code in e2fsprogs, which will accept any tlvs in the blocks (with no bounds checks at all, but that is a separate issue...).
Given that this all seems to be a bug, let's fix it by just filling blocks with tlv entries in the natural way.
Note that old kernels will be unable to replay fast-commit journals created by kernels that have this commit.
--- fs/ext4/fast_commit.c | 66 +++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 33 deletions(-)
fs/ext4/fast_commit.c +33 -33
@@ -722,43 +722,43 @@ static u8 *ext4_fc_reserve_space(structstruct buffer_head *bh;int bsize = sbi->s_journal->j_blocksize;int ret, off = sbi->s_fc_bytes % bsize; -int pad_len; +int remaining;u8 *dst;/* -* After allocating len, we should have space at least for a 0 byte -* padding. +* If 'len' is too long to fit in any block alongside a PAD tlv, then we +* cannot fulfill the request. */ -if (len +EXT4_FC_TAG_BASE_LEN > bsize) +if (len > bsize -EXT4_FC_TAG_BASE_LEN )return NULL ; -if (bsize - off -1 > len +EXT4_FC_TAG_BASE_LEN ) { -/* -* Only allocate from current buffer if we have enough space for -* this request AND we have space to add a zero byte padding. -*/ -if (!sbi->s_fc_bh) { - ret =jbd2_fc_get_buf (EXT4_SB (sb)->s_journal, &bh); -if (ret) -return NULL ; - sbi->s_fc_bh = bh; - } - sbi->s_fc_bytes += len; -return sbi->s_fc_bh->b_data + off; +if (!sbi->s_fc_bh) { + ret =jbd2_fc_get_buf (EXT4_SB (sb)->s_journal, &bh); +if (ret) +return NULL ; + sbi->s_fc_bh = bh; } -/* Need to add PAD tag */ dst = sbi->s_fc_bh->b_data + off; + +/* +* Allocate the bytes in the current block if we can do so while still +* leaving enough space for a PAD tlv. +*/ + remaining = bsize -EXT4_FC_TAG_BASE_LEN - off; +if (len <= remaining) { + sbi->s_fc_bytes += len; +return dst; + } + +/* +* Else, terminate the current block with a PAD tlv, then allocate a new +* block and allocate the bytes at the start of that new block. +*/ + tl.fc_tag =cpu_to_le16 (EXT4_FC_TAG_PAD ); - pad_len = bsize - off -1 -EXT4_FC_TAG_BASE_LEN ; - tl.fc_len =cpu_to_le16 (pad_len); + tl.fc_len =cpu_to_le16 (remaining);ext4_fc_memcpy (sb, dst, &tl,EXT4_FC_TAG_BASE_LEN , crc); - dst +=EXT4_FC_TAG_BASE_LEN ; -if (pad_len >0 ) { -ext4_fc_memzero (sb, dst, pad_len, crc); - dst += pad_len; - } -/* Don't leak uninitialized memory in the unused last byte. */ - *dst =0 ; +ext4_fc_memzero (sb, dst +EXT4_FC_TAG_BASE_LEN , remaining, crc);ext4_fc_submit_bh (sb, false);
@@ -766,7 +766,7 @@ static u8 *ext4_fc_reserve_space(structif (ret)return NULL ; sbi->s_fc_bh = bh; - sbi->s_fc_bytes = (sbi->s_fc_bytes / bsize +1 ) * bsize + len; + sbi->s_fc_bytes += bsize - off + len;return sbi->s_fc_bh->b_data; }
@@ -797,7 +797,7 @@ static int ext4_fc_write_tail(struct sup off = sbi->s_fc_bytes % bsize; tl.fc_tag =cpu_to_le16 (EXT4_FC_TAG_TAIL ); - tl.fc_len =cpu_to_le16 (bsize - off -1 +sizeof (struct ext4_fc_tail )); + tl.fc_len =cpu_to_le16 (bsize - off +sizeof (struct ext4_fc_tail )); sbi->s_fc_bytes =round_up (sbi->s_fc_bytes, bsize);ext4_fc_memcpy (sb, dst, &tl,EXT4_FC_TAG_BASE_LEN , &crc);
@@ -2065,7 +2065,7 @@ static int ext4_fc_replay_scan(journal_t state = &sbi->s_fc_replay_state; start = (u8 *)bh->b_data; - end = (__u8 *)bh->b_data + journal->j_blocksize -1 ; + end = start + journal->j_blocksize;if (state->fc_replay_expected_off ==0 ) { state->fc_cur_tag =0 ;
@@ -2086,7 +2086,7 @@ static int ext4_fc_replay_scan(journal_t } state->fc_replay_expected_off++; -for (cur = start; cur < end -EXT4_FC_TAG_BASE_LEN ; +for (cur = start; cur <= end -EXT4_FC_TAG_BASE_LEN ; cur = cur +EXT4_FC_TAG_BASE_LEN + tl.fc_len) {ext4_fc_get_tl (&tl, cur); val = cur +EXT4_FC_TAG_BASE_LEN ;
@@ -2204,9 +2204,9 @@ static int ext4_fc_replay(journal_t *jou#endif start = (u8 *)bh->b_data; - end = (__u8 *)bh->b_data + journal->j_blocksize -1 ; + end = start + journal->j_blocksize; -for (cur = start; cur < end -EXT4_FC_TAG_BASE_LEN ; +for (cur = start; cur <= end -EXT4_FC_TAG_BASE_LEN ; cur = cur +EXT4_FC_TAG_BASE_LEN + tl.fc_len) {ext4_fc_get_tl (&tl, cur); val = cur +EXT4_FC_TAG_BASE_LEN ;
Greg Kroah-Hartman
maintainerPATCH 152/177 ext4: fix uninititialized value in ext4_evict_inode
In reply to Greg Kroah-HartmanFrom: Ye Bin <[email protected]>
commit 7ea71af94eaaaf6d9aed24bc94a05b977a741cb9 upstream.
Syzbot found the following issue:
=====================================================
BUG: KMSAN: uninit-value in ext4_evict_inode+0xdd/0x26b0 fs/ext4/inode.c:180 ext4_evict_inode+0xdd/0x26b0 fs/ext4/inode.c:180 evict+0x365/0x9a0 fs/inode.c:664 iput_final fs/inode.c:1747 [inline] iput+0x985/0xdd0 fs/inode.c:1773 __ext4_new_inode+0xe54/0x7ec0 fs/ext4/ialloc.c:1361 ext4_mknod+0x376/0x840 fs/ext4/namei.c:2844 vfs_mknod+0x79d/0x830 fs/namei.c:3914 do_mknodat+0x47d/0xaa0 __do_sys_mknodat fs/namei.c:3992 [inline] __se_sys_mknodat fs/namei.c:3989 [inline] __ia32_sys_mknodat+0xeb/0x150 fs/namei.c:3989 do_syscall_32_irqs_on arch/x86/entry/common.c:112 [inline] __do_fast_syscall_32+0xa2/0x100 arch/x86/entry/common.c:178 do_fast_syscall_32+0x33/0x70 arch/x86/entry/common.c:203 do_SYSENTER_32+0x1b/0x20 arch/x86/entry/common.c:246 entry_SYSENTER_compat_after_hwframe+0x70/0x82
Uninit was created at:
__alloc_pages+0x9f1/0xe80 mm/page_alloc.c:5578 alloc_pages+0xaae/0xd80 mm/mempolicy.c:2285 alloc_slab_page mm/slub.c:1794 [inline] allocate_slab+0x1b5/0x1010 mm/slub.c:1939 new_slab mm/slub.c:1992 [inline] ___slab_alloc+0x10c3/0x2d60 mm/slub.c:3180 __slab_alloc mm/slub.c:3279 [inline] slab_alloc_node mm/slub.c:3364 [inline] slab_alloc mm/slub.c:3406 [inline] __kmem_cache_alloc_lru mm/slub.c:3413 [inline] kmem_cache_alloc_lru+0x6f3/0xb30 mm/slub.c:3429 alloc_inode_sb include/linux/fs.h:3117 [inline] ext4_alloc_inode+0x5f/0x860 fs/ext4/super.c:1321 alloc_inode+0x83/0x440 fs/inode.c:259 new_inode_pseudo fs/inode.c:1018 [inline] new_inode+0x3b/0x430 fs/inode.c:1046 __ext4_new_inode+0x2a7/0x7ec0 fs/ext4/ialloc.c:959 ext4_mkdir+0x4d5/0x1560 fs/ext4/namei.c:2992 vfs_mkdir+0x62a/0x870 fs/namei.c:4035 do_mkdirat+0x466/0x7b0 fs/namei.c:4060 __do_sys_mkdirat fs/namei.c:4075 [inline] __se_sys_mkdirat fs/namei.c:4073 [inline] __ia32_sys_mkdirat+0xc4/0x120 fs/namei.c:4073 do_syscall_32_irqs_on arch/x86/entry/common.c:112 [inline] __do_fast_syscall_32+0xa2/0x100 arch/x86/entry/common.c:178 do_fast_syscall_32+0x33/0x70 arch/x86/entry/common.c:203 do_SYSENTER_32+0x1b/0x20 arch/x86/entry/common.c:246 entry_SYSENTER_compat_after_hwframe+0x70/0x82 CPU: 1 PID: 4625 Comm: syz-executor.2 Not tainted 6.1.0-rc4-syzkaller-62821-gcb231e2f67ec #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 =====================================================
Now, 'ext4_alloc_inode()' didn't init 'ei->i_flags'. If new inode failed before set 'ei->i_flags' in '__ext4_new_inode()', then do 'iput()'. As after 6bc0d63dad7f commit will access 'ei->i_flags' in 'ext4_evict_inode()' which will lead to access uninit-value.
To solve above issue just init 'ei->i_flags' in 'ext4_alloc_inode()'.
--- fs/ext4/super.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/super.c +1 -0
@@ -1323,6 +1323,7 @@ static struct inode *ext4_alloc_inode(streturn NULL ;inode_set_iversion (&ei->vfs_inode,1 ); + ei->i_flags =0 ;spin_lock_init (&ei->i_raw_lock);INIT_LIST_HEAD (&ei->i_prealloc_list);atomic_set (&ei->i_prealloc_active,0 );
Greg Kroah-Hartman
maintainerPATCH 153/177 ext4: init quota for old.inode in ext4_rename
In reply to Greg Kroah-HartmanFrom: Ye Bin <[email protected]>
commit fae381a3d79bb94aa2eb752170d47458d778b797 upstream.
Syzbot found the following issue:ext4_parse_param: s_want_extra_isize=128ext4_inode_info_init: s_want_extra_isize=32ext4_rename: old.inode=ffff88823869a2c8 old.dir=ffff888238699828 new.inode=ffff88823869d7e8 new.dir=ffff888238699828 __ext4_mark_inode_dirty: inode=ffff888238699828 ea_isize=32 want_ea_size=128 __ext4_mark_inode_dirty: inode=ffff88823869a2c8 ea_isize=32 want_ea_size=128ext4_xattr_block_set: inode=ffff88823869a2c8
------------[ cut here ]------------ WARNING: CPU: 13 PID: 2234 at fs/ext4/xattr.c:2070 ext4_xattr_block_set.cold+0x22/0x980 Modules linked in: RIP: 0010:ext4_xattr_block_set.cold+0x22/0x980 RSP: 0018:ffff888227d3f3b0 EFLAGS: 00010202 RAX: 0000000000000001 RBX: ffff88823007a000 RCX: 0000000000000000 RDX: 0000000000000a03 RSI: 0000000000000040 RDI: ffff888230078178 RBP: 0000000000000000 R08: 000000000000002c R09: ffffed1075c7df8e R10: ffff8883ae3efc6b R11: ffffed1075c7df8d R12: 0000000000000000 R13: ffff88823869a2c8 R14: ffff8881012e0460 R15: dffffc0000000000 FS: 00007f350ac1f740(0000) GS:ffff8883ae200000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f350a6ed6a0 CR3: 0000000237456000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ? ext4_xattr_set_entry+0x3b7/0x2320 ? ext4_xattr_block_set+0x0/0x2020 ? ext4_xattr_set_entry+0x0/0x2320 ? ext4_xattr_check_entries+0x77/0x310 ? ext4_xattr_ibody_set+0x23b/0x340 ext4_xattr_move_to_block+0x594/0x720 ext4_expand_extra_isize_ea+0x59a/0x10f0 __ext4_expand_extra_isize+0x278/0x3f0 __ext4_mark_inode_dirty.cold+0x347/0x410 ext4_rename+0xed3/0x174f vfs_rename+0x13a7/0x2510 do_renameat2+0x55d/0x920 __x64_sys_rename+0x7d/0xb0 do_syscall_64+0x3b/0xa0 entry_SYSCALL_64_after_hwframe+0x72/0xdc
As 'ext4_rename' will modify 'old.inode' ctime and mark inode dirty, which may trigger expand 'extra_isize' and allocate block. If inode didn't init quota will lead to warning. To solve above issue, init 'old.inode' firstly in 'ext4_rename'.
--- fs/ext4/namei.c | 3 +++ 1 file changed, 3 insertions(+)
fs/ext4/namei.c +3 -0
@@ -3798,6 +3798,9 @@ static int ext4_rename(struct user_names retval =dquot_initialize (old.dir);if (retval)return retval; + retval =dquot_initialize (old.inode); +if (retval) +return retval; retval =dquot_initialize (new.dir);if (retval)return retval;
Greg Kroah-Hartman
maintainerPATCH 154/177 ext4: dont fail GETFSUUID when the caller provides a long buffer
In reply to Greg Kroah-HartmanFrom: Darrick J. Wong <[email protected]>
commit a7e9d977e031fceefe1e7cd69ebd7202d5758b56 upstream.
If userspace provides a longer UUID buffer than is required, we shouldn't fail the call with EINVAL -- rather, we can fill the caller's buffer with the bytes we /can/ fill, and update the length field to reflect what we copied. This doesn't break the UAPI since we're enabling a case that currently fails, and so far Ted hasn't released a version of e2fsprogs that uses the new ext4 ioctl.
--- fs/ext4/ioctl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/ext4/ioctl.c +4 -2
@@ -1162,14 +1162,16 @@ static int ext4_ioctl_getuuid(struct extreturn -EINVAL ; } -if (fsuuid.fsu_len !=UUID_SIZE || fsuuid.fsu_flags !=0 ) +if (fsuuid.fsu_len <UUID_SIZE || fsuuid.fsu_flags !=0 )return -EINVAL ;lock_buffer (sbi->s_sbh);memcpy (uuid, sbi->s_es->s_uuid,UUID_SIZE );unlock_buffer (sbi->s_sbh); -if (copy_to_user (&ufsuuid->fsu_uuid[0 ], uuid,UUID_SIZE )) + fsuuid.fsu_len =UUID_SIZE ; +if (copy_to_user (ufsuuid, &fsuuid,sizeof (fsuuid)) || +copy_to_user (&ufsuuid->fsu_uuid[0 ], uuid,UUID_SIZE ))return -EFAULT ;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 155/177 ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline
In reply to Greg Kroah-HartmanFrom: Eric Whitney <[email protected]>
commit 131294c35ed6f777bd4e79d42af13b5c41bf2775 upstream.
When converting files with inline data to extents, delayed allocations made on a file system created with both the bigalloc and inline options can result in invalid extent status cache content, incorrect reserved cluster counts, kernel memory leaks, and potential kernel panics.
With bigalloc, the code that determines whether a block must be delayed allocated searches the extent tree to see if that block maps to a previously allocated cluster. If not, the block is delayed allocated, and otherwise, it isn't. However, if the inline option is also used, and if the file containing the block is marked as able to store data inline, there isn't a valid extent tree associated with the file. The current code in ext4_clu_mapped() calls ext4_find_extent() to search the non-existent tree for a previously allocated cluster anyway, which typically finds nothing, as desired. However, a side effect of the search can be to cache invalid content from the non-existent tree (garbage) in the extent status tree, including bogus entries in the pending reservation tree.
To fix this, avoid searching the extent tree when allocating blocks for bigalloc + inline files that are being converted from inline to extent mapped.
--- fs/ext4/extents.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/ext4/extents.c +8 -0
@@ -5803,6 +5803,14 @@ int ext4_clu_mapped(struct inode *inode,struct ext4_extent *extent;ext4_lblk_t first_lblk, first_lclu, last_lclu; +/* +* if data can be stored inline, the logical cluster isn't +* mapped - no physical clusters have been allocated, and the +* file has no extents +*/ +if (ext4_test_inode_state (inode,EXT4_STATE_MAY_INLINE_DATA )) +return 0 ; +/* search for the extent closest to the first block in the cluster */ path =ext4_find_extent (inode,EXT4_C2B (sbi, lclu),NULL ,0 );if (IS_ERR (path)) {
Greg Kroah-Hartman
maintainerPATCH 156/177 ext4: fix corruption when online resizing a 1K bigalloc fs
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
commit 0aeaa2559d6d53358fca3e3fce73807367adca74 upstream.
When a backup superblock is updated in update_backups(), the primary superblock's offset in the group (that is, sbi->s_sbh->b_blocknr) is used as the backup superblock's offset in its group. However, when the block size is 1K and bigalloc is enabled, the two offsets are not equal. This causes the backup group descriptors to be overwritten by the superblock in update_backups(). Moreover, if meta_bg is enabled, the file system will be corrupted because this feature uses backup group descriptors.
To solve this issue, we use a more accurate ext4_group_first_block_no() as the offset of the backup superblock in its group.
--- fs/ext4/resize.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/ext4/resize.c +3 -3
@@ -1596,8 +1596,8 @@ exit_journal:int meta_bg =ext4_has_feature_meta_bg (sb);sector_t old_gdb =0 ; -update_backups (sb, sbi->s_sbh->b_blocknr, (char *)es, -sizeof (struct ext4_super_block ),0 ); +update_backups (sb,ext4_group_first_block_no (sb,0 ), + (char *)es,sizeof (struct ext4_super_block ),0 );for (; gdb_num <= gdb_num_end; gdb_num++) {struct buffer_head *gdb_bh;
@@ -1808,7 +1808,7 @@ errout:if (test_opt (sb,DEBUG ))printk (KERN_DEBUG "EXT4-fs: extended group to %llu " "blocks\n" ,ext4_blocks_count (es)); -update_backups (sb,EXT4_SB (sb)->s_sbh->b_blocknr, +update_backups (sb,ext4_group_first_block_no (sb,0 ), (char *)es,sizeof (struct ext4_super_block ),0 ); }return err;
Greg Kroah-Hartman
maintainerPATCH 157/177 ext4: fix error code return to user-space in ext4_get_branch()
In reply to Greg Kroah-HartmanFrom: Luís Henriques <[email protected]>
commit 26d75a16af285a70863ba6a81f85d81e7e65da50 upstream.
If a block is out of range in ext4_get_branch(), -ENOMEM will be returned to user-space. Obviously, this error code isn't really useful. This patch fixes it by making sure the right error code (-EFSCORRUPTED) is propagated to user-space. EUCLEAN is more informative than ENOMEM.
--- fs/ext4/indirect.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/ext4/indirect.c +8 -1
@@ -148,6 +148,7 @@ static Indirect *ext4_get_branch(structstruct super_block *sb = inode->i_sb;Indirect *p = chain;struct buffer_head *bh; +unsigned int key;int ret = -EIO ; *err =0 ;
@@ -156,7 +157,13 @@ static Indirect *ext4_get_branch(structif (!p->key) goto no_block;while (--depth) { - bh =sb_getblk (sb,le32_to_cpu (p->key)); + key =le32_to_cpu (p->key); +if (key >ext4_blocks_count (EXT4_SB (sb)->s_es)) { +/* the block was out of range */ + ret = -EFSCORRUPTED ; + goto failure; + } + bh =sb_getblk (sb, key);if (unlikely (!bh)) { ret = -ENOMEM ; goto failure;
Greg Kroah-Hartman
maintainerPATCH 158/177 ext4: fix bad checksum after online resize
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
commit a408f33e895e455f16cf964cb5cd4979b658db7b upstream.
When online resizing is performed twice consecutively, the error message "Superblock checksum does not match superblock" is displayed for the second time. Here's the reproducer:
mkfs.ext4 -F /dev/sdb 100M
mount /dev/sdb /tmp/test
resize2fs /dev/sdb 5G
resize2fs /dev/sdb 6G
To solve this issue, we moved the update of the checksum after the es->s_overhead_clusters is updated.
--- fs/ext4/resize.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/ext4/resize.c +2 -2
@@ -1476,8 +1476,6 @@ static void ext4_update_super(struct sup* active. */ ext4_r_blocks_count_set (es,ext4_r_blocks_count (es) + reserved_blocks); -ext4_superblock_csum_set (sb); -unlock_buffer (sbi->s_sbh);/* Update the free space counts */ percpu_counter_add(&sbi->s_freeclusters_counter,
@@ -1513,6 +1511,8 @@ static void ext4_update_super(struct supext4_calculate_overhead (sb); es->s_overhead_clusters =cpu_to_le32 (sbi->s_overhead); +ext4_superblock_csum_set (sb); +unlock_buffer (sbi->s_sbh);if (test_opt (sb,DEBUG )) printk(KERN_DEBUG "EXT4-fs: added group %u:" "%llu blocks(%llu free %llu reserved)\n", flex_gd->count,
Greg Kroah-Hartman
maintainerPATCH 159/177 ext4: dont return EINVAL from GETFSUUID when reporting UUID length
In reply to Greg Kroah-HartmanFrom: Darrick J. Wong <[email protected]>
commit b76abb5157468756163fe7e3431c9fe32cba57ca upstream.
If userspace calls this ioctl with fsu_length (the length of the fsuuid.fsu_uuid array) set to zero, ext4 copies the desired uuid length out to userspace. The kernel call returned a result from a valid input, so the return value here should be zero, not EINVAL.
While we're at it, fix the copy_to_user call to make it clear that we're only copying out fsu_len.
--- fs/ext4/ioctl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/ext4/ioctl.c +3 -2
@@ -1157,9 +1157,10 @@ static int ext4_ioctl_getuuid(struct extif (fsuuid.fsu_len ==0 ) { fsuuid.fsu_len =UUID_SIZE ; -if (copy_to_user (ufsuuid, &fsuuid,sizeof (fsuuid.fsu_len))) +if (copy_to_user (&ufsuuid->fsu_len, &fsuuid.fsu_len, +sizeof (fsuuid.fsu_len)))return -EFAULT ; -return -EINVAL ; +return 0 ; }if (fsuuid.fsu_len <UUID_SIZE || fsuuid.fsu_flags !=0 )
Greg Kroah-Hartman
maintainerPATCH 160/177 ext4: fix corrupt backup group descriptors after online resize
In reply to Greg Kroah-HartmanFrom: Baokun Li <[email protected]>
commit 8f49ec603ae3e213bfab2799182724e3abac55a1 upstream.
In commit 9a8c5b0d0615 ("ext4: update the backup superblock's at the end of the online resize"), it is assumed that update_backups() only updates backup superblocks, so each b_data is treated as a backupsuper block to update its s_block_group_nr and s_checksum. However, update_backups() also updates the backup group descriptors, which causes the backup group descriptors to be corrupted.
The above commit fixes the problem of invalid checksum of the backup superblock. The root cause of this problem is that the checksum of ext4_update_super() is not set correctly. This problem has been fixed in the previous patch ("ext4: fix bad checksum after online resize").
However, we do need to set block_group_nr for the backup superblock in update_backups(). When a block is in a group that contains a backup superblock, and the block is the first block in the group, the block is definitely a superblock. We add a helper function that includes setting s_block_group_nr and updating checksum, and then call it only when the above conditions are met to prevent the backup group descriptors from being incorrectly modified.
--- fs/ext4/resize.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
fs/ext4/resize.c +15 -7
@@ -1110,6 +1110,16 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode,return err; } +static inline void ext4_set_block_group_nr (struct super_block *sb,char *data, +ext4_group_t group) +{ +struct ext4_super_block *es = (struct ext4_super_block *) data; + + es->s_block_group_nr =cpu_to_le16 (group); +if (ext4_has_metadata_csum (sb)) + es->s_checksum =ext4_superblock_csum (sb, es); +} +/* * Update the backup copies of the ext4 metadata. These don't need to be part * of the main resize transaction, because e2fsck will re-write them if there
@@ -1158,7 +1168,8 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,while (group < sbi->s_groups_count) {struct buffer_head *bh;ext4_fsblk_t backup_block; -struct ext4_super_block *es; +int has_super =ext4_bg_has_super (sb, group); +ext4_fsblk_t first_block =ext4_group_first_block_no (sb, group);/* Out of journal space, and can't get more - abort - so sad */ err =ext4_resize_ensure_credits_batch (handle,1 );
@@ -1168,8 +1179,7 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,if (meta_bg ==0 ) backup_block = ((ext4_fsblk_t )group) * bpg + blk_off;else - backup_block = (ext4_group_first_block_no (sb, group) + -ext4_bg_has_super (sb, group)); + backup_block = first_block + has_super; bh =sb_getblk (sb, backup_block);if (unlikely (!bh)) {
@@ -1187,10 +1197,8 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,memcpy (bh->b_data, data, size);if (rest)memset (bh->b_data + size,0 , rest); - es = (struct ext4_super_block *) bh->b_data; - es->s_block_group_nr =cpu_to_le16 (group); -if (ext4_has_metadata_csum (sb)) - es->s_checksum =ext4_superblock_csum (sb, es); +if (has_super && (backup_block == first_block)) +ext4_set_block_group_nr (sb, bh->b_data, group);set_buffer_uptodate (bh);unlock_buffer (bh); err =ext4_handle_dirty_metadata (handle,NULL , bh);
Signature · 1 line
2.39.0
Greg Kroah-Hartman
maintainerPATCH 161/177 ext4: avoid BUG_ON when creating xattrs
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
commit b40ebaf63851b3a401b0dc9263843538f64f5ce6 upstream.
Commit fb0a387dcdcd ("ext4: limit block allocations for indirect-block files to < 2^32") added code to try to allocate xattr block with 32-bit block number for indirect block based files on the grounds that these files cannot use larger block numbers. It also added BUG_ON when allocated block could not fit into 32 bits. This is however bogus reasoning because xattr block is stored in inode->i_file_acl and inode->i_file_acl_hi and as such even indirect block based files can happily use full 48 bits for xattr block number. The proper handling seems to be there basically since 64-bit block number support was added. So remove the bogus limitation and BUG_ON.
--- fs/ext4/xattr.c | 8 -------- 1 file changed, 8 deletions(-)
fs/ext4/xattr.c +0 -8
@@ -2070,19 +2070,11 @@ inserted: goal =ext4_group_first_block_no (sb,EXT4_I (inode)->i_block_group); - -/* non-extent files can't have physical blocks past 2^32 */ -if (!(ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS ))) - goal = goal &EXT4_MAX_BLOCK_FILE_PHYS ; - block =ext4_new_meta_blocks (handle, inode, goal,0 ,NULL , &error);if (error) goto cleanup; -if (!(ext4_test_inode_flag (inode,EXT4_INODE_EXTENTS ))) -BUG_ON (block >EXT4_MAX_BLOCK_FILE_PHYS ); -ea_idebug (inode,"creating block %llu" , (unsigned long long )block);