This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 5.10.36-rc1
Lukasz Luba lukasz.luba@arm.com thermal/core/fair share: Lock the thermal zone while looping over instances
brian-sy yang brian-sy.yang@mediatek.com thermal/drivers/cpufreq_cooling: Fix slab OOB issue
Rasmus Villemoes linux@rasmusvillemoes.dk lib/vsprintf.c: remove leftover 'f' and 'F' cases from bstr_printf()
Benjamin Block bblock@linux.ibm.com dm rq: fix double free of blk_mq_tag_set in dev remove after table load fails
Tian Tao tiantao6@hisilicon.com dm integrity: fix missing goto in bitmap_flush_interval error handling
Joe Thornber ejt@redhat.com dm space map common: fix division bug in sm_ll_find_free_block()
Joe Thornber ejt@redhat.com dm persistent data: packed struct should have an aligned() attribute too
Steven Rostedt (VMware) rostedt@goodmis.org tracing: Restructure trace_clock_global() to never block
Steven Rostedt (VMware) rostedt@goodmis.org tracing: Map all PIDs to command lines
Calvin Walton calvin.walton@kepstin.ca tools/power turbostat: Fix offset overflow issue in index converting
Marek Vasut marex@denx.de rsi: Use resume_noirq for SDIO
Pavel Skripkin paskripkin@gmail.com tty: fix memory leak in vc_deallocate
Artur Petrosyan Arthur.Petrosyan@synopsys.com usb: dwc2: Fix session request interrupt handler
Yu Chen chenyu56@huawei.com usb: dwc3: core: Do core softreset when switch mode
Thinh Nguyen Thinh.Nguyen@synopsys.com usb: dwc3: gadget: Fix START_TRANSFER link state check
Thinh Nguyen Thinh.Nguyen@synopsys.com usb: dwc3: gadget: Remove FS bInterval_m1 limitation
Dean Anderson dean@sensoray.com usb: gadget/function/f_fs string table fix for multiple languages
Hemant Kumar hemantk@codeaurora.org usb: gadget: Fix double free of device descriptor pointers
Anirudh Rayabharam mail@anirudhrb.com usb: gadget: dummy_hcd: fix gpf in gadget_setup
Stanimir Varbanov stanimir.varbanov@linaro.org media: venus: hfi_parser: Don't initialize parser on v1
Hans Verkuil hverkuil-cisco@xs4all.nl media: v4l2-ctrls: fix reference to freed memory
Ricardo Ribalda ribalda@chromium.org media: staging/intel-ipu3: Fix race condition during set_fmt
Ricardo Ribalda ribalda@chromium.org media: staging/intel-ipu3: Fix set_fmt error handling
Ricardo Ribalda ribalda@chromium.org media: staging/intel-ipu3: Fix memory leak in imu_fmt
Takashi Iwai tiwai@suse.de media: dvb-usb: Fix memory leak at error in dvb_usb_device_init()
Takashi Iwai tiwai@suse.de media: dvb-usb: Fix use-after-free access
Peilin Ye yepeilin.cs@gmail.com media: dvbdev: Fix memory leak in dvb_media_device_free()
Jan Kara jack@suse.cz ext4: Fix occasional generic/418 failure
Theodore Ts'o tytso@mit.edu ext4: allow the dax flag to be set and cleared on inline directories
Xu Yihang xuyihang@huawei.com ext4: fix error return code in ext4_fc_perform_commit()
Ye Bin yebin10@huawei.com ext4: fix ext4_error_err save negative errno into superblock
Fengnan Chang changfengnan@vivo.com ext4: fix error code in ext4_commit_super
Zhang Yi yi.zhang@huawei.com ext4: do not set SB_ACTIVE in ext4_orphan_cleanup()
Zhang Yi yi.zhang@huawei.com ext4: fix check to prevent false positive report of incorrect used inodes
Jan Kara jack@suse.cz ext4: annotate data race in jbd2_journal_dirty_metadata()
Jan Kara jack@suse.cz ext4: annotate data race in start_this_handle()
Masahiro Yamada masahiroy@kernel.org kbuild: update config_data.gz only when the content of .config is changed
Sean Christopherson seanjc@google.com x86/cpu: Initialize MSR_TSC_AUX if RDTSCP *or* RDPID is supported
Thomas Gleixner tglx@linutronix.de futex: Do not apply time namespace adjustment on FUTEX_LOCK_PI
Thomas Gleixner tglx@linutronix.de Revert 337f13046ff0 ("futex: Allow FUTEX_CLOCK_REALTIME with FUTEX_WAIT op")
Steve French stfrench@microsoft.com smb3: do not attempt multichannel to server which does not support it
Steve French stfrench@microsoft.com smb3: when mounting with multichannel include it in requested capabilities
Yang Yang yang.yang29@zte.com.cn jffs2: check the validity of dstlen in jffs2_zlib_compress()
Linus Torvalds torvalds@linux-foundation.org Fix misc new gcc warnings
Arnd Bergmann arnd@arndb.de security: commoncap: fix -Wstringop-overread warning
Edward Cree ecree.xilinx@gmail.com sfc: farch: fix TX queue lookup in TX event handling
Edward Cree ecree.xilinx@gmail.com sfc: farch: fix TX queue lookup in TX flush done handling
Hyeongseok Kim hyeongseok@gmail.com exfat: fix erroneous discard when clear cluster bit
Vivek Goyal vgoyal@redhat.com fuse: fix write deadlock
Heinz Mauelshagen heinzm@redhat.com dm raid: fix inconclusive reshape layout on fast raid4/5/6 table reload sequences
Paul Clements paul.clements@us.sios.com md/raid1: properly indicate failure when ending a failed write request
Eric Biggers ebiggers@google.com crypto: rng - fix crypto_rng_reset() refcounting when !CRYPTO_STATS
Nathan Chancellor nathan@kernel.org crypto: arm/curve25519 - Move '.fpu' after '.arch'
Stefan Berger stefanb@linux.ibm.com tpm: vtpm_proxy: Avoid reading host log when using a virtual device
Stefan Berger stefanb@linux.ibm.com tpm: efi: Use local variable for calculating final log size
Alexander Shishkin alexander.shishkin@linux.intel.com intel_th: pci: Add Alder Lake-M support
Tony Ambardar tony.ambardar@gmail.com powerpc: fix EDEADLOCK redefinition error in uapi/asm/errno.h
Christophe Leroy christophe.leroy@csgroup.eu powerpc/32: Fix boot failure with CONFIG_STACKPROTECTOR
Sourabh Jain sourabhjain@linux.ibm.com powerpc/kexec_file: Use current CPU info while setting up FDT
Mahesh Salgaonkar mahesh@linux.ibm.com powerpc/eeh: Fix EEH handling for hugepages in ioremap space.
Nicholas Piggin npiggin@gmail.com powerpc/powernv: Enable HAIL (HV AIL) for ISA v3.1 processors
Joel Stanley joel@jms.id.au jffs2: Hook up splice_write callback
lizhe lizhe67@huawei.com jffs2: Fix kasan slab-out-of-bounds problem
Hansem Ro hansemro@outlook.com Input: ili210x - add missing negation for touch indication on ili210x
Trond Myklebust trond.myklebust@hammerspace.com NFSv4: Don't discard segments marked for return in _pnfs_return_layout()
Trond Myklebust trond.myklebust@hammerspace.com NFS: Don't discard pNFS layout segments that are marked for return
Randy Dunlap rdunlap@infradead.org NFS: fs_context: validate UDP retrans to prevent shift out-of-bounds
Marc Zyngier maz@kernel.org ACPI: GTDT: Don't corrupt interrupt mappings on watchdow probe failure
Davide Caratti dcaratti@redhat.com openvswitch: fix stack OOB read while fragmenting IPv4 packets
Ido Schimmel idosch@nvidia.com mlxsw: spectrum_mr: Update egress RIF list before route's action
Chao Yu chao@kernel.org f2fs: fix to avoid out-of-bounds memory access
Eric Biggers ebiggers@google.com f2fs: fix error handling in f2fs_end_enable_verity()
Guochun Mao guochun.mao@mediatek.com ubifs: Only check replay with inode type to judge if inode linked
Marco Elver elver@google.com kcsan, debugfs: Move debugfs file creation out of early init
Luis Henriques lhenriques@suse.de virtiofs: fix memory leak in virtio_fs_probe()
Theodore Ts'o tytso@mit.edu fs: fix reporting supported extra file attributes for statx()
Nathan Chancellor nathan@kernel.org Makefile: Move -Wno-unused-but-set-variable out of GCC only block
Bill Wendling morbo@google.com arm64/vdso: Discard .note.gnu.property sections in vDSO
Filipe Manana fdmanana@suse.com btrfs: fix race when picking most recent mod log operation for an old root
Bas Nieuwenhuizen bas@basnieuwenhuizen.nl tools/power/turbostat: Fix turbostat for AMD Zen CPUs
Eckhart Mohr e.mohr@tuxedocomputers.com ALSA: hda/realtek: Add quirk for Intel Clevo PCx0Dx
Sami Loone sami@loone.fi ALSA: hda/realtek: fix static noise on ALC285 Lenovo laptops
Kailang Yang kailang@realtek.com ALSA: hda/realtek - Headset Mic issue on HP platform
Phil Calvin phil@philcalvin.com ALSA: hda/realtek: fix mic boost on Intel NUC 8
Luke D Jones luke@ljones.dev ALSA: hda/realtek: GA503 use same quirks as GA401
Jonas Witschel diabonas@archlinux.org ALSA: hda/realtek: fix mute/micmute LEDs for HP ProBook 445 G7
Timo Gurr timo.gurr@gmail.com ALSA: usb-audio: Add dB range mapping for Sennheiser Communications Headset PC 8
Takashi Iwai tiwai@suse.de ALSA: usb-audio: Explicitly set up the clock selector
Lv Yunlong lyl2019@mail.ustc.edu.cn ALSA: sb: Fix two use after free in snd_sb_qsound_build
Takashi Iwai tiwai@suse.de ALSA: hda/conexant: Re-order CX5066 quirk table entries
Lv Yunlong lyl2019@mail.ustc.edu.cn ALSA: emu8000: Fix a use after free in snd_emu8000_create_mixer
Guangqing Zhu zhuguangqing83@gmail.com power: supply: cpcap-battery: fix invalid usage of list cursor
Charan Teja Reddy charante@codeaurora.org sched,psi: Handle potential task count underflow bugs more gracefully
Harald Freudenberger freude@linux.ibm.com s390/archrandom: add parameter check for s390_arch_random_generate
Gioh Kim gi-oh.kim@cloud.ionos.com block/rnbd-clt: Fix missing a memory free when unloading the module
Peter Zijlstra peterz@infradead.org sched,fair: Alternative sched_slice()
Peter Zijlstra peterz@infradead.org perf: Rework perf_event_exit_event()
Bart Van Assche bvanassche@acm.org scsi: libfc: Fix a format specifier
Dinghao Liu dinghao.liu@zju.edu.cn mfd: arizona: Fix rumtime PM imbalance on error
Hubert Streidl hubert.streidl@de.bosch.com mfd: da9063: Support SMBus and I2C mode
Xu Yilun yilun.xu@intel.com mfd: intel-m10-bmc: Fix the register access range
James Smart jsmart2021@gmail.com scsi: lpfc: Remove unsupported mbox PORT_CAPABILITIES logic
James Smart jsmart2021@gmail.com scsi: lpfc: Fix error handling for mailboxes completed in MBX_POLL mode
James Smart jsmart2021@gmail.com scsi: lpfc: Fix crash when a REG_RPI mailbox fails triggering a LOGO response
Guchun Chen guchun.chen@amd.com drm/amdgpu: fix NULL pointer dereference
Werner Sembach wse@tuxedocomputers.com drm/amd/display: Try YCbCr420 color when YCbCr444 fails
Arnd Bergmann arnd@arndb.de amdgpu: avoid incorrect %hu format string
Qu Huang jinsdb@126.com drm/amdkfd: Fix cat debugfs hang_hws file causes system crash bug
Anson Jacob Anson.Jacob@amd.com drm/amd/display: Fix UBSAN: shift-out-of-bounds warning
Fangzhi Zuo Jerry.Zuo@amd.com drm/amd/display: Fix debugfs link_settings entry
Daniel Gomez daniel@qtec.com drm/radeon/ttm: Fix memory leak userptr pages
Daniel Gomez daniel@qtec.com drm/amdgpu/ttm: Fix memory leak userptr pages
Marijn Suijten marijn.suijten@somainline.org drm/msm/mdp5: Do not multiply vclk line count by 100
Marijn Suijten marijn.suijten@somainline.org drm/msm/mdp5: Configure PP_SYNC_HEIGHT to double the vtotal
Lingutla Chandrasekhar clingutla@codeaurora.org sched/fair: Ignore percpu threads for imbalance pulls
Hans Verkuil hverkuil-cisco@xs4all.nl media: gscpa/stv06xx: fix memory leak
Pavel Skripkin paskripkin@gmail.com media: dvb-usb: fix memory leak in dvb_usb_adapter_init
Dinghao Liu dinghao.liu@zju.edu.cn media: sun8i-di: Fix runtime PM imbalance in deinterlace_start_streaming
Dinghao Liu dinghao.liu@zju.edu.cn media: platform: sti: Fix runtime PM imbalance in regs_show
Yang Yingliang yangyingliang@huawei.com media: i2c: adv7842: fix possible use-after-free in adv7842_remove()
Yang Yingliang yangyingliang@huawei.com media: i2c: tda1997: Fix possible use-after-free in tda1997x_remove()
Yang Yingliang yangyingliang@huawei.com media: i2c: adv7511-v4l2: fix possible use-after-free in adv7511_remove()
Yang Yingliang yangyingliang@huawei.com media: adv7604: fix possible use-after-free in adv76xx_remove()
Yang Yingliang yangyingliang@huawei.com media: tc358743: fix possible use-after-free in tc358743_remove()
Yang Yingliang yangyingliang@huawei.com power: supply: s3c_adc_battery: fix possible use-after-free in s3c_adc_bat_remove()
Yang Yingliang yangyingliang@huawei.com power: supply: generic-adc-battery: fix possible use-after-free in gab_remove()
Colin Ian King colin.king@canonical.com clk: socfpga: arria10: Fix memory leak of socfpga_clk on error return
Abhinav Kumar abhinavk@codeaurora.org drm/msm/dp: Fix incorrect NULL check kbot warnings in DP driver
Hans Verkuil hverkuil-cisco@xs4all.nl media: vivid: update EDID
Muhammad Usama Anjum musamaanjum@gmail.com media: em28xx: fix memory leak
Ewan D. Milne emilne@redhat.com scsi: scsi_dh_alua: Remove check for ASC 24h in alua_rtpg()
Kevin Barnett kevin.barnett@microchip.com scsi: smartpqi: Add new PCI IDs
Murthy Bhat Murthy.Bhat@microchip.com scsi: smartpqi: Correct request leakage during reset operations
Don Brace don.brace@microchip.com scsi: smartpqi: Use host-wide tag space
Carl Philipp Klemm philipp@uvos.xyz power: supply: cpcap-charger: Add usleep to cpcap charger to avoid usb plug bounce
Fenghua Yu fenghua.yu@intel.com selftests/resctrl: Fix checking for < 0 for unsigned values
Fenghua Yu fenghua.yu@intel.com selftests/resctrl: Fix incorrect parsing of iMC counters
Fenghua Yu fenghua.yu@intel.com selftests/resctrl: Use resctrl/info for feature detection
Fenghua Yu fenghua.yu@intel.com selftests/resctrl: Fix missing options "-n" and "-p"
Fenghua Yu fenghua.yu@intel.com selftests/resctrl: Clean up resctrl features check
Fenghua Yu fenghua.yu@intel.com selftests/resctrl: Fix compilation issues for other global variables
Fenghua Yu fenghua.yu@intel.com selftests/resctrl: Fix compilation issues for global variables
Fenghua Yu fenghua.yu@intel.com selftests/resctrl: Enable gcc checks to detect buffer overflows
Hou Pu houpu.main@gmail.com nvmet: return proper error code from discovery ctrl
Carsten Haitzler carsten.haitzler@arm.com drm/komeda: Fix bit check to import to value of proper type
Xingui Yang yangxingui@huawei.com ata: ahci: Disable SXS for Hisilicon Kunpeng920
Al Cooper alcooperx@gmail.com mmc: sdhci-brcmstb: Remove CQE quirk
Adrian Hunter adrian.hunter@intel.com mmc: sdhci-pci: Add PCI IDs for Intel LKF
Peng Fan peng.fan@nxp.com mmc: sdhci-esdhc-imx: validate pinctrl before use it
Quinn Tran qutran@marvell.com scsi: qla2xxx: Fix use after free in bsg
Dmitry Vyukov dvyukov@google.com drm/vkms: fix misuse of WARN_ON
Bart Van Assche bvanassche@acm.org scsi: qla2xxx: Always check the return value of qla24xx_get_isp_stats()
Dmytro Laktyushkin Dmytro.Laktyushkin@amd.com drm/amd/display: fix dml prefetch validation
Aric Cyr aric.cyr@amd.com drm/amd/display: DCHUB underflow counter increasing in some scenarios
Anson Jacob Anson.Jacob@amd.com drm/amd/display: Fix UBSAN warning for not a valid value for type '_Bool'
Kenneth Feng kenneth.feng@amd.com drm/amd/pm: fix workload mismatch on vega10
shaoyunl shaoyun.liu@amd.com drm/amdgpu : Fix asic reset regression issue introduce by 8f211fe8ac7c4f
Anson Jacob Anson.Jacob@amd.com drm/amdkfd: Fix UBSAN shift-out-of-bounds warning
Jonathan Kim jonathan.kim@amd.com drm/amdgpu: mask the xgmi number of hops reported from psp to kfd
Kiran Gunda kgunda@codeaurora.org backlight: qcom-wled: Fix FSC update issue for WLED5
Obeida Shamoun oshmoun100@googlemail.com backlight: qcom-wled: Use sink_addr for sync toggle
dongjian dongjian@yulong.com power: supply: Use IRQF_ONESHOT
Hans Verkuil hverkuil-cisco@xs4all.nl media: gspca/sq905.c: fix uninitialized variable
Daniel Niv danielniv3@gmail.com media: media/saa7164: fix saa7164_encoder_register() memory leak bugs
Hans de Goede hdegoede@redhat.com extcon: arizona: Fix various races on driver unbind
Hans de Goede hdegoede@redhat.com extcon: arizona: Fix some issues when HPDET IRQ fires after the jack has been unplugged
Matthias Schiffer matthias.schiffer@ew.tq-group.com power: supply: bq27xxx: fix power_avg for newer ICs
Mauro Carvalho Chehab mchehab+huawei@kernel.org atomisp: don't let it go past pipes array
Laurent Pinchart laurent.pinchart@ideasonboard.com media: imx: capture: Return -EPIPE from __capture_legacy_try_fmt()
Julian Braha julianbraha@gmail.com media: drivers: media: pci: sta2x11: fix Kconfig dependency on GPIOLIB
Sean Young sean@mess.org media: ite-cir: check for receive overflow
Chaitanya Kulkarni chaitanya.kulkarni@wdc.com scsi: target: pscsi: Fix warning in pscsi_complete_cmd()
Uladzislau Rezki (Sony) urezki@gmail.com kvfree_rcu: Use same set of GFP flags as does single-argument
Vincent Donnefort vincent.donnefort@arm.com sched/pelt: Fix task util_est update filtering
Emily Deng Emily.Deng@amd.com drm/amdgpu: Fix some unload driver issues
James Smart jsmart2021@gmail.com scsi: lpfc: Fix pt2pt connection does not recover after LOGO
James Smart jsmart2021@gmail.com scsi: lpfc: Fix incorrect dbde assignment when building target abts wqe
Lee Jones lee.jones@linaro.org drm/amd/display/dc/dce/dce_aux: Remove duplicate line causing 'field overwritten' issue
Xiaogang Chen xiaogang.chen@amd.com drm/amdgpu/display: buffer INTERRUPT_LOW_IRQ_CONTEXT interrupt work
Aric Cyr aric.cyr@amd.com drm/amd/display: Don't optimize bandwidth before disabling planes
Eryk Brol eryk.brol@amd.com drm/amd/display: Check for DSC support instead of ASIC revision
Tong Zhang ztong0001@gmail.com drm/ast: fix memory leak when unload the driver
Martin Leung martin.leung@amd.com drm/amd/display: changing sr exit latency
Thomas Zimmermann tzimmermann@suse.de drm/ast: Fix invalid usage of AST_MAX_HWC_WIDTH in cursor atomic_check
Gerd Hoffmann kraxel@redhat.com drm/qxl: release shadow on shutdown
Tong Zhang ztong0001@gmail.com drm/qxl: do not run release if qxl failed to init
Jared Baldridge jrb@expunge.us drm: Added orientation quirk for OneGX1 Pro
Josef Bacik josef@toxicpanda.com btrfs: convert logic BUG_ON()'s in replace_path to ASSERT()'s
Josef Bacik josef@toxicpanda.com btrfs: do proper error handling in btrfs_update_reloc_root
Josef Bacik josef@toxicpanda.com btrfs: do proper error handling in create_reloc_root
David Bauer mail@david-bauer.net spi: sync up initial chipselect state
David E. Box david.e.box@linux.intel.com platform/x86: intel_pmc_core: Don't use global pmcdev in quirks
Shixin Liu liushixin2@huawei.com crypto: omap-aes - Fix PM reference leak on omap-aes.c
Shixin Liu liushixin2@huawei.com crypto: sa2ul - Fix PM reference leak in sa_ul_probe()
Shixin Liu liushixin2@huawei.com crypto: stm32/cryp - Fix PM reference leak on stm32-cryp.c
Shixin Liu liushixin2@huawei.com crypto: stm32/hash - Fix PM reference leak on stm32-hash.c
Shixin Liu liushixin2@huawei.com crypto: sun8i-ce - Fix PM reference leak in sun8i_ce_probe()
Shixin Liu liushixin2@huawei.com crypto: sun8i-ss - Fix PM reference leak when pm_runtime_get_sync() fails
Yang Yingliang yangyingliang@huawei.com phy: phy-twl4030-usb: Fix possible use-after-free in twl4030_usb_remove()
Pavel Machek pavel@ucw.cz intel_th: Consistency and off-by-one fix
Hillf Danton hdanton@sina.com tty: n_gsm: check error while registering tty devices
Thinh Nguyen Thinh.Nguyen@synopsys.com usb: dwc3: gadget: Check for disabled LPM quirk
Bixuan Cui cuibixuan@huawei.com usb: core: hub: Fix PM reference leak in usb_port_resume()
Bixuan Cui cuibixuan@huawei.com usb: musb: fix PM reference leak in musb_irq_work()
Yang Yingliang yangyingliang@huawei.com usb: gadget: tegra-xudc: Fix possible use-after-free in tegra_xudc_remove()
Wang Li wangli74@huawei.com spi: qup: fix PM reference leak in spi_qup_remove()
Wei Yongjun weiyongjun1@huawei.com spi: omap-100k: Fix reference leak to master
Wei Yongjun weiyongjun1@huawei.com spi: dln2: Fix reference leak to master
Srinivas Pandruvada srinivas.pandruvada@linux.intel.com platform/x86: ISST: Account for increased timeout in some cases
Srinivas Pandruvada srinivas.pandruvada@linux.intel.com tools/power/x86/intel-speed-select: Increase string size
Ludovic Desroches ludovic.desroches@microchip.com ARM: dts: at91: change the key code of the gpio key
Bhaumik Bhatt bbhatt@codeaurora.org bus: mhi: core: Clear context for stopped channels from remove()
Mathias Nyman mathias.nyman@linux.intel.com xhci: fix potential array out of bounds with several interrupters
Mathias Nyman mathias.nyman@linux.intel.com xhci: check control context is valid before dereferencing it.
Mathias Nyman mathias.nyman@linux.intel.com xhci: check port array allocation was successful before dereferencing it
Russ Weight russell.h.weight@intel.com fpga: dfl: pci: add DID for D5005 PAC cards
Chunfeng Yun chunfeng.yun@mediatek.com usb: xhci-mtk: support quirk to disable usb2 lpm
Eric Biggers ebiggers@google.com random: initialize ChaCha20 constants with correct endianness
Robin Murphy robin.murphy@arm.com perf/arm_pmu_platform: Fix error handling
Robin Murphy robin.murphy@arm.com perf/arm_pmu_platform: Use dev_err_probe() for IRQ errors
Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com soundwire: cadence: only prepare attached devices on clock stop
Jerome Forissier jerome@forissier.org tee: optee: do not check memref size on return from Secure World
Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm arm64: dts: imx8mq-librem5-r3: Mark buck3 as always on
Dmitry Osipenko digetx@gmail.com soc/tegra: pmc: Fix completion of power-gate toggling
Nathan Chancellor nathan@kernel.org efi/libstub: Add $(CLANG_FLAGS) to x86 flags
Nathan Chancellor nathan@kernel.org x86/boot: Add $(CLANG_FLAGS) to compressed KBUILD_CFLAGS
John Millikin john@john-millikin.com x86/build: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)
Linus Walleij linus.walleij@linaro.org ARM: dts: ux500: Fix up TVK R3 sensors
Rafał Miłecki rafal@milecki.pl ARM: dts: BCM5301X: fix "reg" formatting in /memory node
Andre Przywara andre.przywara@arm.com kselftest/arm64: mte: Fix MTE feature detection
Rafael J. Wysocki rafael.j.wysocki@intel.com PCI: PM: Do not read power state in pci_enable_device_flags()
Dmitry Osipenko digetx@gmail.com ARM: tegra: acer-a500: Rename avdd to vdda of touchscreen node
Andre Przywara andre.przywara@arm.com kselftest/arm64: mte: Fix compilation with native compiler
Thinh Nguyen Thinh.Nguyen@synopsys.com usb: xhci: Fix port minor revision
Wesley Cheng wcheng@codeaurora.org usb: dwc3: gadget: Ignore EP queue requests during bus reset
Ruslan Bilovol ruslan.bilovol@gmail.com usb: gadget: f_uac1: validate input parameters
Ruslan Bilovol ruslan.bilovol@gmail.com usb: gadget: f_uac2: validate input parameters
Vitaly Kuznetsov vkuznets@redhat.com genirq/matrix: Prevent allocation counter corruption
Longfang Liu liulongfang@huawei.com crypto: hisilicon/sec - fixes a printing error
Joerg Roedel jroedel@suse.de x86/sev: Do not require Hypervisor CPUID bit for SEV guests
Pawel Laszczak pawell@cadence.com usb: webcam: Invalid size of Processing Unit Descriptor
Pawel Laszczak pawell@cadence.com usb: gadget: uvc: add bInterval checking for HS mode
Hui Tang tanghui20@huawei.com crypto: qat - fix unmap invalid dma address
Ard Biesheuvel ardb@kernel.org crypto: api - check for ERR pointers in crypto_destroy_tfm()
Bhaumik Bhatt bbhatt@codeaurora.org bus: mhi: core: Destroy SBL devices when moving to mission mode
David Bauer mail@david-bauer.net spi: ath79: remove spi-master setup and cleanup assignment
David Bauer mail@david-bauer.net spi: ath79: always call chipselect function
karthik alapati mail@karthek.com staging: wimax/i2400m: fix byte-order issue
Tony Lindgren tony@atomide.com bus: ti-sysc: Probe for l4_wkup and l4_cfg interconnect devices first
Dmitry Osipenko digetx@gmail.com cpuidle: tegra: Fix C7 idling state on Tegra114
Phillip Potter phil@philpotter.co.uk fbdev: zero-fill colormap in fbcmap.c
Chen Jun chenjun102@huawei.com posix-timers: Preserve return value in clock_adjtime32()
Filipe Manana fdmanana@suse.com btrfs: fix race between transaction aborts and fsyncs leading to use-after-free
Alexander Shishkin alexander.shishkin@linux.intel.com intel_th: pci: Add Rocket Lake CPU support
Filipe Manana fdmanana@suse.com btrfs: fix metadata extent leak after failure to create subvolume
Maciej W. Rozycki macro@orcam.me.uk x86/build: Disable HIGHMEM64G selection for M486SX
Qu Wenruo wqu@suse.com btrfs: handle remount to no compress during compression
Aurelien Aptel aaptel@suse.com smb2: fix use-after-free in smb2_ioctl_query_info()
Shyam Prasad N sprasad@microsoft.com cifs: detect dead connections only when echoes are enabled.
Eugene Korenevsky ekorenevsky@astralinux.ru cifs: fix out-of-bound memory access when calling smb3_notify() at mount point
Paul Aurich paul@darkrain42.org cifs: Return correct error code from smb2_get_enc_key
He Ying heying24@huawei.com irqchip/gic-v3: Do not enable irqs when handling spurious interrups
Ulf Hansson ulf.hansson@linaro.org mmc: core: Fix hanging on I/O during system suspend for removable cards
Seunghui Lee sh043.lee@samsung.com mmc: core: Set read only for SD cards with permanent write protect bit
DooHyun Hwang dh0421.hwang@samsung.com mmc: core: Do a power cycle when the CMD11 fails
Avri Altman avri.altman@wdc.com mmc: block: Issue a cache flush only when it's enabled
Avri Altman avri.altman@wdc.com mmc: block: Update ext_csd.cache_ctrl if it was written
Aniruddha Tvs Rao anrao@nvidia.com mmc: sdhci-tegra: Add required callbacks to set/clear CQE_EN bit
Adrian Hunter adrian.hunter@intel.com mmc: sdhci-pci: Fix initialization of some SD cards for Intel BYT-based controllers
Pradeep P V K pragalla@codeaurora.org mmc: sdhci: Check for reset prior to DMA address unmap
Christophe JAILLET christophe.jaillet@wanadoo.fr mmc: uniphier-sd: Fix a resource leak in the remove function
Christophe JAILLET christophe.jaillet@wanadoo.fr mmc: uniphier-sd: Fix an error handling path in uniphier_sd_probe()
Sreekanth Reddy sreekanth.reddy@broadcom.com scsi: mpt3sas: Block PCI config access from userspace during reset
Arun Easi aeasi@marvell.com scsi: qla2xxx: Fix crash in qla2xxx_mqueuecommand()
Tudor Ambarus tudor.ambarus@microchip.com spi: spi-ti-qspi: Free DMA resources
Christophe Kerello christophe.kerello@foss.st.com spi: stm32-qspi: fix pm_runtime usage_count counter
Gao Xiang hsiangkao@redhat.com erofs: add unsupported inode i_format check
Gustavo A. R. Silva gustavoars@kernel.org mtd: physmap: physmap-bt1-rom: Fix unintentional stack access
Kai Stuhlemmer (ebee Engineering) kai.stuhlemmer@ebee.de mtd: rawnand: atmel: Update ecc_stats.corrected counter
Alexander Lobakin alobakin@pm.me mtd: spinand: core: add missing MODULE_DEVICE_TABLE()
Tudor Ambarus tudor.ambarus@microchip.com Revert "mtd: spi-nor: macronix: Add support for mx25l51245g"
Xiang Chen chenxiang66@hisilicon.com mtd: spi-nor: core: Fix an issue of releasing resources during read/write
Davidlohr Bueso dave@stgolabs.net fs/epoll: restore waking from ep_done_scan()
Jeffrey Mitchell jeffrey.mitchell@starlab.io ecryptfs: fix kernel panic with null dev_name
Chunfeng Yun chunfeng.yun@mediatek.com arm64: dts: mt8173: fix property typo of 'phys' in dsi node
Marek Behún kabel@kernel.org arm64: dts: marvell: armada-37xx: add syscon compatible to NB clk node
Ard Biesheuvel ardb@kernel.org ARM: 9056/1: decompressor: fix BSS size calculation for LLVM ld.lld
Steven Rostedt (VMware) rostedt@goodmis.org ftrace: Handle commands when closing set_ftrace_filter file
Mark Langsdorf mlangsdo@redhat.com ACPI: custom_method: fix a possible memory leak
Mark Langsdorf mlangsdo@redhat.com ACPI: custom_method: fix potential use-after-free issue
Stefan Berger stefanb@linux.ibm.com tpm: acpi: Check eventlog signature before using it
Jason Wang jasowang@redhat.com vhost-vdpa: fix vm_flags for virtqueue doorbell mapping
Harald Freudenberger freude@linux.ibm.com s390/zcrypt: fix zcard and zqueue hot-unplug memleak
Vasily Gorbik gor@linux.ibm.com s390/disassembler: increase ebpf disasm buffer size
Shuo Chen shuochen@google.com dyndbg: fix parsing file query without a line-range suffix
Mathias Krause minipli@grsecurity.net nitro_enclaves: Fix stale file descriptors on failed usercopy
Jeffrey Hugo jhugo@codeaurora.org bus: mhi: core: Sanity check values from remote device before use
Bhaumik Bhatt bbhatt@codeaurora.org bus: mhi: core: Clear configuration from channel context during reset
Jeffrey Hugo jhugo@codeaurora.org bus: mhi: core: Fix check for syserr at power_up
-------------
Diffstat:
Makefile | 12 +- arch/arm/boot/compressed/Makefile | 4 +- arch/arm/boot/dts/at91-sam9x60ek.dts | 3 +- arch/arm/boot/dts/at91-sama5d27_som1_ek.dts | 3 +- arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts | 3 +- arch/arm/boot/dts/at91-sama5d2_icp.dts | 3 +- arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts | 3 +- arch/arm/boot/dts/at91-sama5d2_xplained.dts | 3 +- arch/arm/boot/dts/at91-sama5d3_xplained.dts | 3 +- arch/arm/boot/dts/at91sam9260ek.dts | 3 +- arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 3 +- arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts | 4 +- arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts | 4 +- arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 4 +- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 4 +- arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts | 4 +- arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 4 +- arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts | 4 +- arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 4 +- arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 4 +- arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 4 +- arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 4 +- arch/arm/boot/dts/bcm4709-linksys-ea9200.dts | 4 +- arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 4 +- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 4 +- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 4 +- arch/arm/boot/dts/bcm47094-linksys-panamera.dts | 4 +- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 4 +- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 4 +- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 4 +- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 4 +- arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 4 +- arch/arm/boot/dts/bcm47094-netgear-r8500.dts | 4 +- arch/arm/boot/dts/bcm47094-phicomm-k3.dts | 4 +- arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi | 73 ++++++--- arch/arm/boot/dts/tegra20-acer-a500-picasso.dts | 2 +- arch/arm/crypto/curve25519-core.S | 2 +- .../arm64/boot/dts/freescale/imx8mq-librem5-r3.dts | 4 + arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 3 +- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 2 +- arch/arm64/kernel/vdso/vdso.lds.S | 8 +- arch/powerpc/include/asm/reg.h | 1 + arch/powerpc/include/uapi/asm/errno.h | 1 + arch/powerpc/kernel/eeh.c | 11 +- arch/powerpc/kernel/setup_64.c | 19 ++- arch/powerpc/kexec/file_load_64.c | 92 +++++++++++ arch/powerpc/lib/Makefile | 3 + arch/s390/crypto/arch_random.c | 4 + arch/s390/kernel/dis.c | 2 +- arch/x86/Kconfig | 2 +- arch/x86/Makefile | 1 + arch/x86/boot/compressed/Makefile | 1 + arch/x86/boot/compressed/mem_encrypt.S | 6 - arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/sev-es-shared.c | 6 +- arch/x86/mm/mem_encrypt_identity.c | 35 +++-- crypto/api.c | 2 +- crypto/rng.c | 10 +- drivers/acpi/arm64/gtdt.c | 10 +- drivers/acpi/custom_method.c | 4 +- drivers/ata/ahci.c | 5 + drivers/ata/ahci.h | 1 + drivers/ata/libahci.c | 5 + drivers/block/rnbd/rnbd-clt-sysfs.c | 10 +- drivers/bus/mhi/core/init.c | 16 +- drivers/bus/mhi/core/main.c | 110 +++++++++++-- drivers/bus/mhi/core/pm.c | 5 +- drivers/bus/ti-sysc.c | 49 ++++++ drivers/char/random.c | 4 +- drivers/char/tpm/eventlog/acpi.c | 33 +++- drivers/char/tpm/eventlog/common.c | 3 + drivers/char/tpm/eventlog/efi.c | 29 +++- drivers/clk/socfpga/clk-gate-a10.c | 1 + drivers/cpuidle/cpuidle-tegra.c | 12 +- drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c | 2 +- .../crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 2 +- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 2 +- drivers/crypto/hisilicon/sec2/sec_crypto.c | 2 +- drivers/crypto/omap-aes.c | 6 +- drivers/crypto/qat/qat_common/qat_algs.c | 11 +- drivers/crypto/sa2ul.c | 2 +- drivers/crypto/stm32/stm32-cryp.c | 4 +- drivers/crypto/stm32/stm32-hash.c | 8 +- drivers/extcon/extcon-arizona.c | 57 +++---- drivers/firmware/efi/libstub/Makefile | 3 +- drivers/fpga/dfl-pci.c | 18 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 8 +- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 9 +- drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c | 7 +- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 17 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 17 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 14 +- .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 15 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 115 +++++++++----- .../amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c | 4 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 +- drivers/gpu/drm/amd/display/dc/dce/dce_aux.h | 1 - .../gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 2 +- .../amd/display/dc/dml/dcn20/display_mode_vba_20.c | 1 + .../display/dc/dml/dcn20/display_mode_vba_20v2.c | 1 + .../display/dc/dml/dcn20/display_rq_dlg_calc_20.c | 28 +++- .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c | 28 +++- .../display/dc/dml/dcn21/display_rq_dlg_calc_21.c | 28 +++- .../display/dc/dml/dcn30/display_rq_dlg_calc_30.c | 28 +++- .../amd/display/dc/dml/dml1_display_rq_dlg_calc.c | 28 +++- .../gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 2 +- drivers/gpu/drm/arm/display/include/malidp_utils.h | 3 - .../gpu/drm/arm/display/komeda/komeda_pipeline.c | 16 +- .../drm/arm/display/komeda/komeda_pipeline_state.c | 19 ++- drivers/gpu/drm/ast/ast_drv.c | 2 + drivers/gpu/drm/ast/ast_mode.c | 2 +- drivers/gpu/drm/drm_panel_orientation_quirks.c | 14 ++ drivers/gpu/drm/i915/intel_pm.c | 2 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c | 18 ++- drivers/gpu/drm/msm/dp/dp_hpd.c | 4 +- drivers/gpu/drm/qxl/qxl_display.c | 4 + drivers/gpu/drm/qxl/qxl_drv.c | 2 + drivers/gpu/drm/radeon/radeon_ttm.c | 5 +- drivers/gpu/drm/vkms/vkms_crtc.c | 3 +- drivers/hwtracing/intel_th/gth.c | 4 +- drivers/hwtracing/intel_th/pci.c | 10 ++ drivers/input/touchscreen/ili210x.c | 2 +- drivers/irqchip/irq-gic-v3.c | 8 +- drivers/md/dm-integrity.c | 1 + drivers/md/dm-raid.c | 34 +++- drivers/md/dm-rq.c | 2 + drivers/md/persistent-data/dm-btree-internal.h | 4 +- drivers/md/persistent-data/dm-space-map-common.c | 2 + drivers/md/persistent-data/dm-space-map-common.h | 8 +- drivers/md/raid1.c | 2 + drivers/media/dvb-core/dvbdev.c | 1 + drivers/media/i2c/adv7511-v4l2.c | 2 +- drivers/media/i2c/adv7604.c | 2 +- drivers/media/i2c/adv7842.c | 2 +- drivers/media/i2c/tc358743.c | 2 +- drivers/media/i2c/tda1997x.c | 2 +- drivers/media/pci/saa7164/saa7164-encoder.c | 20 +-- drivers/media/pci/sta2x11/Kconfig | 1 + drivers/media/platform/qcom/venus/hfi_parser.c | 6 +- drivers/media/platform/sti/bdisp/bdisp-debug.c | 2 +- drivers/media/platform/sunxi/sun8i-di/sun8i-di.c | 2 +- drivers/media/rc/ite-cir.c | 8 +- drivers/media/test-drivers/vivid/vivid-core.c | 6 +- drivers/media/usb/dvb-usb/dvb-usb-init.c | 90 +++++++---- drivers/media/usb/dvb-usb/dvb-usb.h | 2 +- drivers/media/usb/em28xx/em28xx-dvb.c | 1 + drivers/media/usb/gspca/gspca.c | 2 + drivers/media/usb/gspca/gspca.h | 1 + drivers/media/usb/gspca/sq905.c | 2 +- drivers/media/usb/gspca/stv06xx/stv06xx.c | 9 ++ drivers/media/v4l2-core/v4l2-ctrls.c | 137 ++++++++-------- drivers/mfd/arizona-irq.c | 2 +- drivers/mfd/da9063-i2c.c | 10 ++ drivers/mmc/core/block.c | 16 ++ drivers/mmc/core/core.c | 76 +-------- drivers/mmc/core/core.h | 17 +- drivers/mmc/core/host.c | 40 ++++- drivers/mmc/core/mmc.c | 7 + drivers/mmc/core/mmc_ops.c | 4 +- drivers/mmc/core/sd.c | 6 + drivers/mmc/core/sdio.c | 28 +++- drivers/mmc/host/sdhci-brcmstb.c | 1 - drivers/mmc/host/sdhci-esdhc-imx.c | 2 +- drivers/mmc/host/sdhci-pci-core.c | 29 ++++ drivers/mmc/host/sdhci-pci.h | 2 + drivers/mmc/host/sdhci-tegra.c | 32 ++++ drivers/mmc/host/sdhci.c | 60 +++---- drivers/mmc/host/uniphier-sd.c | 5 +- drivers/mtd/maps/physmap-bt1-rom.c | 2 +- drivers/mtd/nand/raw/atmel/nand-controller.c | 6 +- drivers/mtd/nand/spi/core.c | 2 + drivers/mtd/spi-nor/core.c | 33 ++++ drivers/mtd/spi-nor/macronix.c | 3 - drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 30 ++-- drivers/net/ethernet/sfc/farch.c | 16 +- drivers/net/wimax/i2400m/op-rfkill.c | 2 +- drivers/net/wireless/rsi/rsi_91x_sdio.c | 2 +- drivers/nvme/target/discovery.c | 6 +- drivers/pci/pci.c | 16 +- drivers/perf/arm_pmu_platform.c | 9 +- drivers/phy/ti/phy-twl4030-usb.c | 2 +- drivers/platform/x86/intel_pmc_core.c | 19 ++- .../x86/intel_speed_select_if/isst_if_mbox_pci.c | 33 ++-- drivers/power/supply/bq27xxx_battery.c | 51 +++--- drivers/power/supply/cpcap-battery.c | 2 +- drivers/power/supply/cpcap-charger.c | 3 + drivers/power/supply/generic-adc-battery.c | 2 +- drivers/power/supply/lp8788-charger.c | 2 +- drivers/power/supply/pm2301_charger.c | 2 +- drivers/power/supply/s3c_adc_battery.c | 2 +- drivers/power/supply/tps65090-charger.c | 2 +- drivers/power/supply/tps65217_charger.c | 2 +- drivers/s390/crypto/zcrypt_card.c | 1 + drivers/s390/crypto/zcrypt_queue.c | 1 + drivers/scsi/device_handler/scsi_dh_alua.c | 5 +- drivers/scsi/libfc/fc_lport.c | 2 +- drivers/scsi/lpfc/lpfc_attr.c | 75 +++++---- drivers/scsi/lpfc/lpfc_crtn.h | 3 - drivers/scsi/lpfc/lpfc_hw4.h | 174 +-------------------- drivers/scsi/lpfc/lpfc_init.c | 112 +------------ drivers/scsi/lpfc/lpfc_mbox.c | 36 ----- drivers/scsi/lpfc/lpfc_nportdisc.c | 11 +- drivers/scsi/lpfc/lpfc_nvmet.c | 1 - drivers/scsi/lpfc/lpfc_sli.c | 43 ++--- drivers/scsi/mpt3sas/mpt3sas_base.c | 4 + drivers/scsi/qla2xxx/qla_attr.c | 8 +- drivers/scsi/qla2xxx/qla_bsg.c | 3 +- drivers/scsi/qla2xxx/qla_os.c | 7 - drivers/scsi/smartpqi/smartpqi_init.c | 161 +++++++++++++++++++ drivers/soc/tegra/pmc.c | 70 ++++++++- drivers/soundwire/cadence_master.c | 10 +- drivers/spi/spi-ath79.c | 3 +- drivers/spi/spi-dln2.c | 2 +- drivers/spi/spi-omap-100k.c | 6 +- drivers/spi/spi-qup.c | 2 +- drivers/spi/spi-stm32-qspi.c | 18 ++- drivers/spi/spi-ti-qspi.c | 20 ++- drivers/spi/spi.c | 16 +- drivers/staging/media/atomisp/pci/atomisp_fops.c | 3 + drivers/staging/media/imx/imx-media-capture.c | 2 +- drivers/staging/media/ipu3/ipu3-v4l2.c | 36 +++-- drivers/target/target_core_pscsi.c | 3 +- drivers/tee/optee/core.c | 10 -- drivers/thermal/cpufreq_cooling.c | 2 +- drivers/thermal/gov_fair_share.c | 4 + drivers/tty/n_gsm.c | 14 +- drivers/tty/vt/vt.c | 1 + drivers/usb/core/hub.c | 2 +- drivers/usb/dwc2/core_intr.c | 8 + drivers/usb/dwc3/core.c | 29 ++++ drivers/usb/dwc3/core.h | 9 +- drivers/usb/dwc3/gadget.c | 41 +++-- drivers/usb/gadget/config.c | 4 + drivers/usb/gadget/function/f_fs.c | 3 +- drivers/usb/gadget/function/f_uac1.c | 43 +++++ drivers/usb/gadget/function/f_uac2.c | 39 ++++- drivers/usb/gadget/function/f_uvc.c | 8 +- drivers/usb/gadget/legacy/webcam.c | 1 + drivers/usb/gadget/udc/dummy_hcd.c | 23 ++- drivers/usb/gadget/udc/tegra-xudc.c | 2 +- drivers/usb/host/xhci-mem.c | 12 ++ drivers/usb/host/xhci-mtk.c | 3 + drivers/usb/host/xhci-mtk.h | 1 + drivers/usb/host/xhci.c | 14 +- drivers/usb/musb/musb_core.c | 2 +- drivers/vhost/vdpa.c | 1 + drivers/video/backlight/qcom-wled.c | 29 +++- drivers/video/fbdev/core/fbcmap.c | 8 +- drivers/virt/nitro_enclaves/ne_misc_dev.c | 43 ++--- fs/btrfs/compression.c | 11 +- fs/btrfs/ctree.c | 20 +++ fs/btrfs/ioctl.c | 18 ++- fs/btrfs/relocation.c | 46 ++++-- fs/btrfs/transaction.c | 12 +- fs/cifs/connect.c | 1 + fs/cifs/sess.c | 6 + fs/cifs/smb2ops.c | 18 +-- fs/cifs/smb2pdu.c | 5 + fs/ecryptfs/main.c | 6 + fs/erofs/erofs_fs.h | 3 + fs/erofs/inode.c | 7 + fs/eventpoll.c | 6 + fs/exfat/balloc.c | 11 +- fs/ext4/fast_commit.c | 4 +- fs/ext4/file.c | 25 ++- fs/ext4/ialloc.c | 51 ++++-- fs/ext4/ioctl.c | 6 + fs/ext4/mmp.c | 2 +- fs/ext4/super.c | 9 +- fs/f2fs/node.c | 3 + fs/f2fs/verity.c | 75 ++++++--- fs/fuse/file.c | 41 +++-- fs/fuse/fuse_i.h | 1 + fs/fuse/virtio_fs.c | 1 + fs/jbd2/transaction.c | 15 +- fs/jffs2/compr_rtime.c | 3 + fs/jffs2/file.c | 1 + fs/jffs2/scan.c | 2 +- fs/nfs/fs_context.c | 12 ++ fs/nfs/pnfs.c | 7 +- fs/stat.c | 8 + fs/ubifs/replay.c | 3 +- include/crypto/acompress.h | 2 + include/crypto/aead.h | 2 + include/crypto/akcipher.h | 2 + include/crypto/chacha.h | 9 +- include/crypto/hash.h | 4 + include/crypto/kpp.h | 2 + include/crypto/rng.h | 2 + include/crypto/skcipher.h | 2 + include/linux/mfd/da9063/registers.h | 3 + include/linux/mfd/intel-m10-bmc.h | 2 +- include/linux/mmc/host.h | 3 - include/linux/perf_event.h | 1 + include/linux/power/bq27xxx_battery.h | 1 - include/media/v4l2-ctrls.h | 12 +- include/scsi/libfcoe.h | 2 +- include/uapi/linux/usb/video.h | 3 +- kernel/.gitignore | 1 + kernel/Makefile | 9 +- kernel/events/core.c | 142 +++++++++-------- kernel/futex.c | 7 +- kernel/irq/matrix.c | 4 +- kernel/kcsan/core.c | 2 - kernel/kcsan/debugfs.c | 4 +- kernel/kcsan/kcsan.h | 5 - kernel/rcu/tree.c | 2 +- kernel/sched/fair.c | 31 +++- kernel/sched/features.h | 3 + kernel/sched/psi.c | 5 +- kernel/time/posix-timers.c | 4 +- kernel/trace/ftrace.c | 5 +- kernel/trace/trace.c | 41 ++--- kernel/trace/trace_clock.c | 44 ++++-- lib/dynamic_debug.c | 2 +- lib/vsprintf.c | 2 - net/bluetooth/ecdh_helper.h | 2 +- net/openvswitch/actions.c | 8 +- security/commoncap.c | 2 +- sound/isa/sb/emu8000.c | 4 +- sound/isa/sb/sb16_csp.c | 8 +- sound/pci/hda/patch_conexant.c | 14 +- sound/pci/hda/patch_realtek.c | 52 +++++- sound/usb/clock.c | 18 ++- sound/usb/mixer_maps.c | 12 ++ tools/power/x86/intel-speed-select/isst-display.c | 12 +- tools/power/x86/turbostat/turbostat.c | 19 ++- tools/testing/selftests/arm64/mte/Makefile | 2 - .../testing/selftests/arm64/mte/mte_common_util.c | 13 +- tools/testing/selftests/resctrl/Makefile | 2 +- tools/testing/selftests/resctrl/cache.c | 8 +- tools/testing/selftests/resctrl/cat_test.c | 12 +- tools/testing/selftests/resctrl/cqm_test.c | 14 +- tools/testing/selftests/resctrl/fill_buf.c | 4 +- tools/testing/selftests/resctrl/mba_test.c | 2 +- tools/testing/selftests/resctrl/mbm_test.c | 2 +- tools/testing/selftests/resctrl/resctrl.h | 21 ++- tools/testing/selftests/resctrl/resctrl_tests.c | 14 +- tools/testing/selftests/resctrl/resctrl_val.c | 85 ++++++---- tools/testing/selftests/resctrl/resctrlfs.c | 79 +++++++--- 344 files changed, 3031 insertions(+), 1640 deletions(-)
From: Jeffrey Hugo jhugo@codeaurora.org
commit 6403298c58d4858d93648f553abf0bcbd2dfaca2 upstream.
The check to see if we have reset the device after detecting syserr at power_up is inverted. wait_for_event_timeout() returns 0 on failure, and a positive value on success. The check is looking for non-zero as a failure, which is likely to incorrectly cause a device init failure if syserr was detected at power_up. Fix this.
Fixes: e18d4e9fa79b ("bus: mhi: core: Handle syserr during power_up") Signed-off-by: Jeffrey Hugo jhugo@codeaurora.org Reviewed-by: Loic Poulain loic.poulain@linaro.org Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Link: https://lore.kernel.org/r/1613165243-23359-1-git-send-email-jhugo@codeaurora... Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/bus/mhi/core/pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/bus/mhi/core/pm.c +++ b/drivers/bus/mhi/core/pm.c @@ -992,7 +992,7 @@ int mhi_async_power_up(struct mhi_contro &val) || !val, msecs_to_jiffies(mhi_cntrl->timeout_ms)); - if (ret) { + if (!ret) { ret = -EIO; dev_info(dev, "Failed to reset MHI due to syserr state\n"); goto error_bhi_offset;
From: Bhaumik Bhatt bbhatt@codeaurora.org
commit 47705c08465931923e2f2b506986ca0bdf80380d upstream.
When clearing up the channel context after client drivers are done using channels, the configuration is currently not being reset entirely. Ensure this is done to appropriately handle issues where clients unaware of the context state end up calling functions which expect a context.
Signed-off-by: Bhaumik Bhatt bbhatt@codeaurora.org Reviewed-by: Hemant Kumar hemantk@codeaurora.org Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Link: https://lore.kernel.org/r/1617311778-1254-7-git-send-email-bbhatt@codeaurora... Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/bus/mhi/core/init.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
--- a/drivers/bus/mhi/core/init.c +++ b/drivers/bus/mhi/core/init.c @@ -544,6 +544,7 @@ void mhi_deinit_chan_ctxt(struct mhi_con struct mhi_ring *buf_ring; struct mhi_ring *tre_ring; struct mhi_chan_ctxt *chan_ctxt; + u32 tmp;
buf_ring = &mhi_chan->buf_ring; tre_ring = &mhi_chan->tre_ring; @@ -554,7 +555,19 @@ void mhi_deinit_chan_ctxt(struct mhi_con vfree(buf_ring->base);
buf_ring->base = tre_ring->base = NULL; + tre_ring->ctxt_wp = NULL; chan_ctxt->rbase = 0; + chan_ctxt->rlen = 0; + chan_ctxt->rp = 0; + chan_ctxt->wp = 0; + + tmp = chan_ctxt->chcfg; + tmp &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); + chan_ctxt->chcfg = tmp; + + /* Update to all cores */ + smp_wmb(); }
int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl,
Hi!
From: Bhaumik Bhatt bbhatt@codeaurora.org
commit 47705c08465931923e2f2b506986ca0bdf80380d upstream.
When clearing up the channel context after client drivers are done using channels, the configuration is currently not being reset entirely. Ensure this is done to appropriately handle issues where clients unaware of the context state end up calling functions which expect a context.
+++ b/drivers/bus/mhi/core/init.c @@ -544,6 +544,7 @@ void mhi_deinit_chan_ctxt(struct mhi_con
- u32 tmp;
@@ -554,7 +555,19 @@ void mhi_deinit_chan_ctxt(struct mhi_con
...
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
- /* Update to all cores */
- smp_wmb();
}
This is really interesting code; author was careful to make sure chcfg is updated atomically, but C compiler is free to undo that. Plus, this will make all kinds of checkers angry.
Does the file need to use READ_ONCE and WRITE_ONCE?
Best regards, Pavel
Hi Pavel,
On Mon, May 10, 2021 at 10:56:50PM +0200, Pavel Machek wrote:
Hi!
From: Bhaumik Bhatt bbhatt@codeaurora.org
commit 47705c08465931923e2f2b506986ca0bdf80380d upstream.
When clearing up the channel context after client drivers are done using channels, the configuration is currently not being reset entirely. Ensure this is done to appropriately handle issues where clients unaware of the context state end up calling functions which expect a context.
+++ b/drivers/bus/mhi/core/init.c @@ -544,6 +544,7 @@ void mhi_deinit_chan_ctxt(struct mhi_con
- u32 tmp;
@@ -554,7 +555,19 @@ void mhi_deinit_chan_ctxt(struct mhi_con
...
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
- /* Update to all cores */
- smp_wmb();
}
This is really interesting code; author was careful to make sure chcfg is updated atomically, but C compiler is free to undo that. Plus, this will make all kinds of checkers angry.
Does the file need to use READ_ONCE and WRITE_ONCE?
Thanks for looking into this.
I agree that the order could be mangled between chcfg read & write and using READ_ONCE & WRITE_ONCE seems to be a good option.
Bhaumik, can you please submit a patch and tag stable?
Thanks, Mani
Best regards, Pavel -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
On 2021-05-10 11:17 PM, Manivannan Sadhasivam wrote:
Hi Pavel,
On Mon, May 10, 2021 at 10:56:50PM +0200, Pavel Machek wrote:
Hi!
From: Bhaumik Bhatt bbhatt@codeaurora.org
commit 47705c08465931923e2f2b506986ca0bdf80380d upstream.
When clearing up the channel context after client drivers are done using channels, the configuration is currently not being reset entirely. Ensure this is done to appropriately handle issues where clients unaware of the context state end up calling functions which expect a context.
+++ b/drivers/bus/mhi/core/init.c @@ -544,6 +544,7 @@ void mhi_deinit_chan_ctxt(struct mhi_con
- u32 tmp;
@@ -554,7 +555,19 @@ void mhi_deinit_chan_ctxt(struct mhi_con
...
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
- /* Update to all cores */
- smp_wmb();
}
This is really interesting code; author was careful to make sure chcfg is updated atomically, but C compiler is free to undo that. Plus, this will make all kinds of checkers angry.
Does the file need to use READ_ONCE and WRITE_ONCE?
Thanks for looking into this.
I agree that the order could be mangled between chcfg read & write and using READ_ONCE & WRITE_ONCE seems to be a good option.
Bhaumik, can you please submit a patch and tag stable?
Thanks, Mani
Best regards, Pavel -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Hi Pavel/Mani,
Hemant and I went over this patch and we noticed this particular function is already being called with the channel mutex lock held. This would take care of the atomicity and we also probably don't need the smp_wmb() barrier as the mutex unlock will implicitly take care of it.
To the point of compiler re-ordering, we would need some help to understand the purpose of READ_ONCE()/WRITE_ONCE() for these dependent statements:
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
Since RMW operation means that the chan_ctxt->chcfg is copied to a local variable (tmp) and the _same_ is being written back to chan_ctxt->chcfg, can compiler reorder these dependent statements and cause a different result?
Thanks, Bhaumik --- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
On Fri, May 21, 2021 at 10:50:33AM -0700, Bhaumik Bhatt wrote:
On 2021-05-10 11:17 PM, Manivannan Sadhasivam wrote:
Hi Pavel,
On Mon, May 10, 2021 at 10:56:50PM +0200, Pavel Machek wrote:
Hi!
From: Bhaumik Bhatt bbhatt@codeaurora.org
commit 47705c08465931923e2f2b506986ca0bdf80380d upstream.
When clearing up the channel context after client drivers are done using channels, the configuration is currently not being reset entirely. Ensure this is done to appropriately handle issues where clients unaware of the context state end up calling functions which expect a context.
+++ b/drivers/bus/mhi/core/init.c @@ -544,6 +544,7 @@ void mhi_deinit_chan_ctxt(struct mhi_con
- u32 tmp;
@@ -554,7 +555,19 @@ void mhi_deinit_chan_ctxt(struct mhi_con
...
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
- /* Update to all cores */
- smp_wmb();
}
This is really interesting code; author was careful to make sure chcfg is updated atomically, but C compiler is free to undo that. Plus, this will make all kinds of checkers angry.
Does the file need to use READ_ONCE and WRITE_ONCE?
Thanks for looking into this.
I agree that the order could be mangled between chcfg read & write and using READ_ONCE & WRITE_ONCE seems to be a good option.
Bhaumik, can you please submit a patch and tag stable?
Thanks, Mani
Best regards, Pavel -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Hi Pavel/Mani,
Hemant and I went over this patch and we noticed this particular function is already being called with the channel mutex lock held. This would take care of the atomicity and we also probably don't need the smp_wmb() barrier as the mutex unlock will implicitly take care of it.
okay
To the point of compiler re-ordering, we would need some help to understand the purpose of READ_ONCE()/WRITE_ONCE() for these dependent statements:
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
Since RMW operation means that the chan_ctxt->chcfg is copied to a local variable (tmp) and the _same_ is being written back to chan_ctxt->chcfg, can compiler reorder these dependent statements and cause a different result?
Well, I agree that there is a minimal guarantee with modern day CPUs on not breaking the order of dependent memory accesses (like here tmp variable is the one which gets read and written) but we want to make sure that this won't break on future CPUs as well. So IMO using READ_ONCE and WRITE_ONCE adds extra level of safety.
Thanks, Mani
Thanks, Bhaumik
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
On 5/23/2021 10:19 PM, Manivannan Sadhasivam wrote:
On Fri, May 21, 2021 at 10:50:33AM -0700, Bhaumik Bhatt wrote:
On 2021-05-10 11:17 PM, Manivannan Sadhasivam wrote:
Hi Pavel,
On Mon, May 10, 2021 at 10:56:50PM +0200, Pavel Machek wrote:
Hi!
From: Bhaumik Bhatt bbhatt@codeaurora.org
commit 47705c08465931923e2f2b506986ca0bdf80380d upstream.
When clearing up the channel context after client drivers are done using channels, the configuration is currently not being reset entirely. Ensure this is done to appropriately handle issues where clients unaware of the context state end up calling functions which expect a context.
+++ b/drivers/bus/mhi/core/init.c @@ -544,6 +544,7 @@ void mhi_deinit_chan_ctxt(struct mhi_con
- u32 tmp;
@@ -554,7 +555,19 @@ void mhi_deinit_chan_ctxt(struct mhi_con
...
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
- /* Update to all cores */
- smp_wmb(); }
This is really interesting code; author was careful to make sure chcfg is updated atomically, but C compiler is free to undo that. Plus, this will make all kinds of checkers angry.
Does the file need to use READ_ONCE and WRITE_ONCE?
Thanks for looking into this.
I agree that the order could be mangled between chcfg read & write and using READ_ONCE & WRITE_ONCE seems to be a good option.
Bhaumik, can you please submit a patch and tag stable?
Thanks, Mani
Best regards, Pavel -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Hi Pavel/Mani,
Hemant and I went over this patch and we noticed this particular function is already being called with the channel mutex lock held. This would take care of the atomicity and we also probably don't need the smp_wmb() barrier as the mutex unlock will implicitly take care of it.
okay
To the point of compiler re-ordering, we would need some help to understand the purpose of READ_ONCE()/WRITE_ONCE() for these dependent statements:
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
Since RMW operation means that the chan_ctxt->chcfg is copied to a local variable (tmp) and the _same_ is being written back to chan_ctxt->chcfg, can compiler reorder these dependent statements and cause a different result?
Well, I agree that there is a minimal guarantee with modern day CPUs on not breaking the order of dependent memory accesses (like here tmp variable is the one which gets read and written) but we want to make sure that this won't break on future CPUs as well. So IMO using READ_ONCE and WRITE_ONCE adds extra level of safety.
?
I'm sorry, but this argument is non-sense to me, and so I want to understand more.
I've talked to our CPU designers from time to time, but cannot speak for other vendors. A modern CPU can easily reorder accesses all it wants, so long as it does not change the end result. This is typically identified via "data dependencies", where the CPU identifies that the result of a previous instruction is required to be known before processing the current instruction (or any instructions in flight in the pipeline, the instructions don't need to be adjacent). These data dependencies can be "read" or "write".
The typical reason barriers are needed is because the CPU cannot detect these dependencies when we are talking about different "memory". For example, a write to a register in some hardware block to program some mode, and then a write to another register to activate the hardware block based on that mode. In this example, there is no data dependency that the CPU can detect, although you and I as the software writer knows there is a specific order to these operations. Thus, a barrier is required.
Your argument is that we need to protect against some hypothetical future CPU where these data dependencies are ignored, and so the CPU reorders things. Except that means that the end result is (possibly) changed, meaning the contract between software and hardware is no longer valid. It breaks the entire memory model for the C language.
In the above code snippet, you are saying this is valid for some future CPU to do:
tmp = chan_ctxt->chcfg; chan_ctxt->chcfg = tmp; //probably optimized out because this now obviously has no effect tmp &= ~CHAN_CTX_CHSTATE_MASK; tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
That is clearly wrong (I seriously hope you agree), and while I've seen hardware designers do some boneheaded things to the point where I don't trust them a lot of the time, I have a hard time believing they would think that is acceptable.
That fundamentally breaks all of software to the point where the only recourse is to have a literal barrier between every line of code. That doubles the line count of Linux and kills all performance. Its plainly not tenable.
So, seriously, please explain your view in great detail because it feels like we are talking past each-other and not coming to common ground. As I understand it, adding an explicit barrier in a patch cannot be done "just because" and requires a good documented reason (in a comment next to the barrier) for why the barrier is required. It seems like the same level of scrutiny should be applied for READ_ONCE/WRITE_ONCE, but your reason for adding them, "using READ_ONCE and WRITE_ONCE adds extra level of safety", reads like the reason to use them is "just because" to me.
On Tue, May 25, 2021 at 10:23:49AM -0600, Jeffrey Hugo wrote:
On 5/23/2021 10:19 PM, Manivannan Sadhasivam wrote:
On Fri, May 21, 2021 at 10:50:33AM -0700, Bhaumik Bhatt wrote:
On 2021-05-10 11:17 PM, Manivannan Sadhasivam wrote:
Hi Pavel,
On Mon, May 10, 2021 at 10:56:50PM +0200, Pavel Machek wrote:
Hi!
From: Bhaumik Bhatt bbhatt@codeaurora.org
commit 47705c08465931923e2f2b506986ca0bdf80380d upstream.
When clearing up the channel context after client drivers are done using channels, the configuration is currently not being reset entirely. Ensure this is done to appropriately handle issues where clients unaware of the context state end up calling functions which expect a context.
+++ b/drivers/bus/mhi/core/init.c @@ -544,6 +544,7 @@ void mhi_deinit_chan_ctxt(struct mhi_con
- u32 tmp;
@@ -554,7 +555,19 @@ void mhi_deinit_chan_ctxt(struct mhi_con
...
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
- /* Update to all cores */
- smp_wmb(); }
This is really interesting code; author was careful to make sure chcfg is updated atomically, but C compiler is free to undo that. Plus, this will make all kinds of checkers angry.
Does the file need to use READ_ONCE and WRITE_ONCE?
Thanks for looking into this.
I agree that the order could be mangled between chcfg read & write and using READ_ONCE & WRITE_ONCE seems to be a good option.
Bhaumik, can you please submit a patch and tag stable?
Thanks, Mani
Best regards, Pavel -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Hi Pavel/Mani,
Hemant and I went over this patch and we noticed this particular function is already being called with the channel mutex lock held. This would take care of the atomicity and we also probably don't need the smp_wmb() barrier as the mutex unlock will implicitly take care of it.
okay
To the point of compiler re-ordering, we would need some help to understand the purpose of READ_ONCE()/WRITE_ONCE() for these dependent statements:
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
Since RMW operation means that the chan_ctxt->chcfg is copied to a local variable (tmp) and the _same_ is being written back to chan_ctxt->chcfg, can compiler reorder these dependent statements and cause a different result?
Well, I agree that there is a minimal guarantee with modern day CPUs on not breaking the order of dependent memory accesses (like here tmp variable is the one which gets read and written) but we want to make sure that this won't break on future CPUs as well. So IMO using READ_ONCE and WRITE_ONCE adds extra level of safety.
?
I'm sorry, but this argument is non-sense to me, and so I want to understand more.
I've talked to our CPU designers from time to time, but cannot speak for other vendors. A modern CPU can easily reorder accesses all it wants, so long as it does not change the end result. This is typically identified via "data dependencies", where the CPU identifies that the result of a previous instruction is required to be known before processing the current instruction (or any instructions in flight in the pipeline, the instructions don't need to be adjacent). These data dependencies can be "read" or "write".
The typical reason barriers are needed is because the CPU cannot detect these dependencies when we are talking about different "memory". For example, a write to a register in some hardware block to program some mode, and then a write to another register to activate the hardware block based on that mode. In this example, there is no data dependency that the CPU can detect, although you and I as the software writer knows there is a specific order to these operations. Thus, a barrier is required.
Your argument is that we need to protect against some hypothetical future CPU where these data dependencies are ignored, and so the CPU reorders things. Except that means that the end result is (possibly) changed, meaning the contract between software and hardware is no longer valid. It breaks the entire memory model for the C language.
Jeff, I do understand your point here and I completely agree. I just went with the question raised by Pavel and was trying to be on the safe side (which might not be a valid thing as you said).
Let's hear from Pavel on what exactly his concern is! Maybe I went in the wrong direction.
Thanks for your views.
Thanks, Mani
In the above code snippet, you are saying this is valid for some future CPU to do:
tmp = chan_ctxt->chcfg; chan_ctxt->chcfg = tmp; //probably optimized out because this now obviously has no effect tmp &= ~CHAN_CTX_CHSTATE_MASK; tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
That is clearly wrong (I seriously hope you agree), and while I've seen hardware designers do some boneheaded things to the point where I don't trust them a lot of the time, I have a hard time believing they would think that is acceptable.
That fundamentally breaks all of software to the point where the only recourse is to have a literal barrier between every line of code. That doubles the line count of Linux and kills all performance. Its plainly not tenable.
So, seriously, please explain your view in great detail because it feels like we are talking past each-other and not coming to common ground. As I understand it, adding an explicit barrier in a patch cannot be done "just because" and requires a good documented reason (in a comment next to the barrier) for why the barrier is required. It seems like the same level of scrutiny should be applied for READ_ONCE/WRITE_ONCE, but your reason for adding them, "using READ_ONCE and WRITE_ONCE adds extra level of safety", reads like the reason to use them is "just because" to me.
Hi!
commit 47705c08465931923e2f2b506986ca0bdf80380d upstream.
When clearing up the channel context after client drivers are done using channels, the configuration is currently not being reset entirely. Ensure this is done to appropriately handle issues where clients unaware of the context state end up calling functions which expect a context.
+++ b/drivers/bus/mhi/core/init.c @@ -544,6 +544,7 @@ void mhi_deinit_chan_ctxt(struct mhi_con
- u32 tmp;
@@ -554,7 +555,19 @@ void mhi_deinit_chan_ctxt(struct mhi_con
...
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
- /* Update to all cores */
- smp_wmb();
}
This is really interesting code; author was careful to make sure chcfg is updated atomically, but C compiler is free to undo that. Plus, this will make all kinds of checkers angry.
Does the file need to use READ_ONCE and WRITE_ONCE?
Thanks for looking into this.
I agree that the order could be mangled between chcfg read & write and using READ_ONCE & WRITE_ONCE seems to be a good option.
Bhaumik, can you please submit a patch and tag stable?
Hemant and I went over this patch and we noticed this particular function is already being called with the channel mutex lock held. This would take care of the atomicity and we also probably don't need the smp_wmb() barrier as the mutex unlock will implicitly take care of it.
okay
To the point of compiler re-ordering, we would need some help to understand the purpose of READ_ONCE()/WRITE_ONCE() for these dependent statements:
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
Since RMW operation means that the chan_ctxt->chcfg is copied to a local variable (tmp) and the _same_ is being written back to chan_ctxt->chcfg, can compiler reorder these dependent statements and cause a different result?
Well, I agree that there is a minimal guarantee with modern day CPUs on not breaking the order of dependent memory accesses (like here tmp variable is the one which gets read and written) but we want to make sure that this won't break on future CPUs as well. So IMO using READ_ONCE and WRITE_ONCE adds extra level of safety.
Umm, if this is protected by locking, already, we really should not add READ_ONCE. Code should be clear, not having "extra safety levels".
I assumed it was running unlocked due to the way it was written.
Best regards, Pavel
On 2021-05-28 01:52 AM, Pavel Machek wrote:
Hi!
commit 47705c08465931923e2f2b506986ca0bdf80380d upstream.
When clearing up the channel context after client drivers are done using channels, the configuration is currently not being reset entirely. Ensure this is done to appropriately handle issues where clients unaware of the context state end up calling functions which expect a context.
+++ b/drivers/bus/mhi/core/init.c @@ -544,6 +544,7 @@ void mhi_deinit_chan_ctxt(struct mhi_con
- u32 tmp;
@@ -554,7 +555,19 @@ void mhi_deinit_chan_ctxt(struct mhi_con
...
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
- /* Update to all cores */
- smp_wmb();
}
This is really interesting code; author was careful to make sure chcfg is updated atomically, but C compiler is free to undo that. Plus, this will make all kinds of checkers angry.
Does the file need to use READ_ONCE and WRITE_ONCE?
Thanks for looking into this.
I agree that the order could be mangled between chcfg read & write and using READ_ONCE & WRITE_ONCE seems to be a good option.
Bhaumik, can you please submit a patch and tag stable?
Hemant and I went over this patch and we noticed this particular function is already being called with the channel mutex lock held. This would take care of the atomicity and we also probably don't need the smp_wmb() barrier as the mutex unlock will implicitly take care of it.
okay
To the point of compiler re-ordering, we would need some help to understand the purpose of READ_ONCE()/WRITE_ONCE() for these dependent statements:
- tmp = chan_ctxt->chcfg;
- tmp &= ~CHAN_CTX_CHSTATE_MASK;
- tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT);
- chan_ctxt->chcfg = tmp;
Since RMW operation means that the chan_ctxt->chcfg is copied to a local variable (tmp) and the _same_ is being written back to chan_ctxt->chcfg, can compiler reorder these dependent statements and cause a different result?
Well, I agree that there is a minimal guarantee with modern day CPUs on not breaking the order of dependent memory accesses (like here tmp variable is the one which gets read and written) but we want to make sure that this won't break on future CPUs as well. So IMO using READ_ONCE and WRITE_ONCE adds extra level of safety.
Umm, if this is protected by locking, already, we really should not add READ_ONCE. Code should be clear, not having "extra safety levels".
I assumed it was running unlocked due to the way it was written.
Best regards, Pavel
Thanks for the confirmation Pavel.
Thanks, Bhaumik --- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
From: Jeffrey Hugo jhugo@codeaurora.org
commit ec32332df7645e0ba463a08d483fe97665167071 upstream.
When parsing the structures in the shared memory, there are values which come from the remote device. For example, a transfer completion event will have a pointer to the tre in the relevant channel's transfer ring. As another example, event ring elements may specify a channel in which the event occurred, however the specified channel value may not be valid as no channel is defined at that index even though the index may be less than the maximum allowed index. Such values should be considered to be untrusted, and validated before use. If we blindly use such values, we may access invalid data or crash if the values are corrupted.
If validation fails, drop the relevant event.
Signed-off-by: Jeffrey Hugo jhugo@codeaurora.org Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Hemant Kumar hemantk@codeaurora.org Link: https://lore.kernel.org/r/1615411855-15053-1-git-send-email-jhugo@codeaurora... Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/bus/mhi/core/main.c | 81 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 7 deletions(-)
--- a/drivers/bus/mhi/core/main.c +++ b/drivers/bus/mhi/core/main.c @@ -220,6 +220,11 @@ static void mhi_del_ring_element(struct smp_wmb(); }
+static bool is_valid_ring_ptr(struct mhi_ring *ring, dma_addr_t addr) +{ + return addr >= ring->iommu_base && addr < ring->iommu_base + ring->len; +} + int mhi_destroy_device(struct device *dev, void *data) { struct mhi_device *mhi_dev; @@ -349,7 +354,16 @@ irqreturn_t mhi_irq_handler(int irq_numb struct mhi_event_ctxt *er_ctxt = &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index]; struct mhi_ring *ev_ring = &mhi_event->ring; - void *dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); + dma_addr_t ptr = er_ctxt->rp; + void *dev_rp; + + if (!is_valid_ring_ptr(ev_ring, ptr)) { + dev_err(&mhi_cntrl->mhi_dev->dev, + "Event ring rp points outside of the event ring\n"); + return IRQ_HANDLED; + } + + dev_rp = mhi_to_virtual(ev_ring, ptr);
/* Only proceed if event ring has pending events */ if (ev_ring->rp == dev_rp) @@ -498,6 +512,11 @@ static int parse_xfer_event(struct mhi_c struct mhi_buf_info *buf_info; u16 xfer_len;
+ if (!is_valid_ring_ptr(tre_ring, ptr)) { + dev_err(&mhi_cntrl->mhi_dev->dev, + "Event element points outside of the tre ring\n"); + break; + } /* Get the TRB this event points to */ ev_tre = mhi_to_virtual(tre_ring, ptr);
@@ -657,6 +676,12 @@ static void mhi_process_cmd_completion(s struct mhi_chan *mhi_chan; u32 chan;
+ if (!is_valid_ring_ptr(mhi_ring, ptr)) { + dev_err(&mhi_cntrl->mhi_dev->dev, + "Event element points outside of the cmd ring\n"); + return; + } + cmd_pkt = mhi_to_virtual(mhi_ring, ptr);
chan = MHI_TRE_GET_CMD_CHID(cmd_pkt); @@ -681,6 +706,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_ struct device *dev = &mhi_cntrl->mhi_dev->dev; u32 chan; int count = 0; + dma_addr_t ptr = er_ctxt->rp;
/* * This is a quick check to avoid unnecessary event processing @@ -690,7 +716,13 @@ int mhi_process_ctrl_ev_ring(struct mhi_ if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state))) return -EIO;
- dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); + if (!is_valid_ring_ptr(ev_ring, ptr)) { + dev_err(&mhi_cntrl->mhi_dev->dev, + "Event ring rp points outside of the event ring\n"); + return -EIO; + } + + dev_rp = mhi_to_virtual(ev_ring, ptr); local_rp = ev_ring->rp;
while (dev_rp != local_rp) { @@ -801,6 +833,8 @@ int mhi_process_ctrl_ev_ring(struct mhi_ */ if (chan < mhi_cntrl->max_chan) { mhi_chan = &mhi_cntrl->mhi_chan[chan]; + if (!mhi_chan->configured) + break; parse_xfer_event(mhi_cntrl, local_rp, mhi_chan); event_quota--; } @@ -812,7 +846,15 @@ int mhi_process_ctrl_ev_ring(struct mhi_
mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring); local_rp = ev_ring->rp; - dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); + + ptr = er_ctxt->rp; + if (!is_valid_ring_ptr(ev_ring, ptr)) { + dev_err(&mhi_cntrl->mhi_dev->dev, + "Event ring rp points outside of the event ring\n"); + return -EIO; + } + + dev_rp = mhi_to_virtual(ev_ring, ptr); count++; }
@@ -835,11 +877,18 @@ int mhi_process_data_event_ring(struct m int count = 0; u32 chan; struct mhi_chan *mhi_chan; + dma_addr_t ptr = er_ctxt->rp;
if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state))) return -EIO;
- dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); + if (!is_valid_ring_ptr(ev_ring, ptr)) { + dev_err(&mhi_cntrl->mhi_dev->dev, + "Event ring rp points outside of the event ring\n"); + return -EIO; + } + + dev_rp = mhi_to_virtual(ev_ring, ptr); local_rp = ev_ring->rp;
while (dev_rp != local_rp && event_quota > 0) { @@ -853,7 +902,8 @@ int mhi_process_data_event_ring(struct m * Only process the event ring elements whose channel * ID is within the maximum supported range. */ - if (chan < mhi_cntrl->max_chan) { + if (chan < mhi_cntrl->max_chan && + mhi_cntrl->mhi_chan[chan].configured) { mhi_chan = &mhi_cntrl->mhi_chan[chan];
if (likely(type == MHI_PKT_TYPE_TX_EVENT)) { @@ -867,7 +917,15 @@ int mhi_process_data_event_ring(struct m
mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring); local_rp = ev_ring->rp; - dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); + + ptr = er_ctxt->rp; + if (!is_valid_ring_ptr(ev_ring, ptr)) { + dev_err(&mhi_cntrl->mhi_dev->dev, + "Event ring rp points outside of the event ring\n"); + return -EIO; + } + + dev_rp = mhi_to_virtual(ev_ring, ptr); count++; } read_lock_bh(&mhi_cntrl->pm_lock); @@ -1394,6 +1452,7 @@ static void mhi_mark_stale_events(struct struct mhi_ring *ev_ring; struct device *dev = &mhi_cntrl->mhi_dev->dev; unsigned long flags; + dma_addr_t ptr;
dev_dbg(dev, "Marking all events for chan: %d as stale\n", chan);
@@ -1401,7 +1460,15 @@ static void mhi_mark_stale_events(struct
/* mark all stale events related to channel as STALE event */ spin_lock_irqsave(&mhi_event->lock, flags); - dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); + + ptr = er_ctxt->rp; + if (!is_valid_ring_ptr(ev_ring, ptr)) { + dev_err(&mhi_cntrl->mhi_dev->dev, + "Event ring rp points outside of the event ring\n"); + dev_rp = ev_ring->rp; + } else { + dev_rp = mhi_to_virtual(ev_ring, ptr); + }
local_rp = ev_ring->rp; while (dev_rp != local_rp) {
From: Mathias Krause minipli@grsecurity.net
commit f1ce3986baa62cffc3c5be156994de87524bab99 upstream.
A failing usercopy of the slot uid will lead to a stale entry in the file descriptor table as put_unused_fd() won't release it. This enables userland to refer to a dangling 'file' object through that still valid file descriptor, leading to all kinds of use-after-free exploitation scenarios.
Exchanging put_unused_fd() for close_fd(), ksys_close() or alike won't solve the underlying issue, as the file descriptor might have been replaced in the meantime, e.g. via userland calling close() on it (leading to a NULL pointer dereference in the error handling code as 'fget(enclave_fd)' will return a NULL pointer) or by dup2()'ing a completely different file object to that very file descriptor, leading to the same situation: a dangling file descriptor pointing to a freed object -- just in this case to a file object of user's choosing.
Generally speaking, after the call to fd_install() the file descriptor is live and userland is free to do whatever with it. We cannot rely on it to still refer to our enclave object afterwards. In fact, by abusing userfaultfd() userland can hit the condition without any racing and abuse the error handling in the nitro code as it pleases.
To fix the above issues, defer the call to fd_install() until all possible errors are handled. In this case it's just the usercopy, so do it directly in ne_create_vm_ioctl() itself.
Signed-off-by: Mathias Krause minipli@grsecurity.net Signed-off-by: Andra Paraschiv andraprs@amazon.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20210429165941.27020-2-andraprs@amazon.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/virt/nitro_enclaves/ne_misc_dev.c | 43 +++++++++++------------------- 1 file changed, 17 insertions(+), 26 deletions(-)
--- a/drivers/virt/nitro_enclaves/ne_misc_dev.c +++ b/drivers/virt/nitro_enclaves/ne_misc_dev.c @@ -1524,7 +1524,8 @@ static const struct file_operations ne_e * enclave file descriptor to be further used for enclave * resources handling e.g. memory regions and CPUs. * @ne_pci_dev : Private data associated with the PCI device. - * @slot_uid: Generated unique slot id associated with an enclave. + * @slot_uid: User pointer to store the generated unique slot id + * associated with an enclave to. * * Context: Process context. This function is called with the ne_pci_dev enclave * mutex held. @@ -1532,7 +1533,7 @@ static const struct file_operations ne_e * * Enclave fd on success. * * Negative return value on failure. */ -static int ne_create_vm_ioctl(struct ne_pci_dev *ne_pci_dev, u64 *slot_uid) +static int ne_create_vm_ioctl(struct ne_pci_dev *ne_pci_dev, u64 __user *slot_uid) { struct ne_pci_dev_cmd_reply cmd_reply = {}; int enclave_fd = -1; @@ -1634,7 +1635,18 @@ static int ne_create_vm_ioctl(struct ne_
list_add(&ne_enclave->enclave_list_entry, &ne_pci_dev->enclaves_list);
- *slot_uid = ne_enclave->slot_uid; + if (copy_to_user(slot_uid, &ne_enclave->slot_uid, sizeof(ne_enclave->slot_uid))) { + /* + * As we're holding the only reference to 'enclave_file', fput() + * will call ne_enclave_release() which will do a proper cleanup + * of all so far allocated resources, leaving only the unused fd + * for us to free. + */ + fput(enclave_file); + put_unused_fd(enclave_fd); + + return -EFAULT; + }
fd_install(enclave_fd, enclave_file);
@@ -1671,34 +1683,13 @@ static long ne_ioctl(struct file *file, switch (cmd) { case NE_CREATE_VM: { int enclave_fd = -1; - struct file *enclave_file = NULL; struct ne_pci_dev *ne_pci_dev = ne_devs.ne_pci_dev; - int rc = -EINVAL; - u64 slot_uid = 0; + u64 __user *slot_uid = (void __user *)arg;
mutex_lock(&ne_pci_dev->enclaves_list_mutex); - - enclave_fd = ne_create_vm_ioctl(ne_pci_dev, &slot_uid); - if (enclave_fd < 0) { - rc = enclave_fd; - - mutex_unlock(&ne_pci_dev->enclaves_list_mutex); - - return rc; - } - + enclave_fd = ne_create_vm_ioctl(ne_pci_dev, slot_uid); mutex_unlock(&ne_pci_dev->enclaves_list_mutex);
- if (copy_to_user((void __user *)arg, &slot_uid, sizeof(slot_uid))) { - enclave_file = fget(enclave_fd); - /* Decrement file refs to have release() called. */ - fput(enclave_file); - fput(enclave_file); - put_unused_fd(enclave_fd); - - return -EFAULT; - } - return enclave_fd; }
From: Shuo Chen shuochen@google.com
commit 7b1ae248279bea33af9e797a93c35f49601cb8a0 upstream.
Query like 'file tcp_input.c line 1234 +p' was broken by commit aaebe329bff0 ("dyndbg: accept 'file foo.c:func1' and 'file foo.c:10-100'") because a file name without a ':' now makes the loop in ddebug_parse_query() exits early before parsing the 'line 1234' part. As a result, all pr_debug() in tcp_input.c will be enabled, instead of only the one on line 1234. Changing 'break' to 'continue' fixes this.
Fixes: aaebe329bff0 ("dyndbg: accept 'file foo.c:func1' and 'file foo.c:10-100'") Cc: stable stable@vger.kernel.org Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: Shuo Chen shuochen@google.com Acked-by: Jason Baron jbaron@akamai.com Link: https://lore.kernel.org/r/20210414212400.2927281-1-giantchen@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- lib/dynamic_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -396,7 +396,7 @@ static int ddebug_parse_query(char *word /* tail :$info is function or line-range */ fline = strchr(query->filename, ':'); if (!fline) - break; + continue; *fline++ = '\0'; if (isalpha(*fline) || *fline == '*' || *fline == '?') { /* take as function name */
From: Vasily Gorbik gor@linux.ibm.com
commit 6f3353c2d2b3eb4de52e9704cb962712033db181 upstream.
Current ebpf disassembly buffer size of 64 is too small. E.g. this line takes 65 bytes: 01fffff8005822e: ec8100ed8065\tclgrj\t%r8,%r1,8,001fffff80058408\n\0
Double the buffer size like it is done for the kernel disassembly buffer.
Fixes the following KASAN finding:
UG: KASAN: stack-out-of-bounds in print_fn_code+0x34c/0x380 Write of size 1 at addr 001fff800ad5f970 by task test_progs/853
CPU: 53 PID: 853 Comm: test_progs Not tainted 5.12.0-rc7-23786-g23457d86b1f0-dirty #19 Hardware name: IBM 3906 M04 704 (LPAR) Call Trace: [<0000000cd8e0538a>] show_stack+0x17a/0x1668 [<0000000cd8e2a5d8>] dump_stack+0x140/0x1b8 [<0000000cd8e16e74>] print_address_description.constprop.0+0x54/0x260 [<0000000cd75a8698>] kasan_report+0xc8/0x130 [<0000000cd6e26da4>] print_fn_code+0x34c/0x380 [<0000000cd6ea0f4e>] bpf_int_jit_compile+0xe3e/0xe58 [<0000000cd72c4c88>] bpf_prog_select_runtime+0x5b8/0x9c0 [<0000000cd72d1bf8>] bpf_prog_load+0xa78/0x19c0 [<0000000cd72d7ad6>] __do_sys_bpf.part.0+0x18e/0x768 [<0000000cd6e0f392>] do_syscall+0x12a/0x220 [<0000000cd8e333f8>] __do_syscall+0x98/0xc8 [<0000000cd8e54834>] system_call+0x6c/0x94 1 lock held by test_progs/853: #0: 0000000cd9bf7460 (report_lock){....}-{2:2}, at: kasan_report+0x96/0x130
addr 001fff800ad5f970 is located in stack of task test_progs/853 at offset 96 in frame: print_fn_code+0x0/0x380 this frame has 1 object: [32, 96) 'buffer'
Memory state around the buggy address: 001fff800ad5f800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 001fff800ad5f880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
001fff800ad5f900: 00 00 f1 f1 f1 f1 00 00 00 00 00 00 00 00 f3 f3
^ 001fff800ad5f980: f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 001fff800ad5fa00: 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00 00
Cc: stable@vger.kernel.org Reviewed-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/kernel/dis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c @@ -563,7 +563,7 @@ void show_code(struct pt_regs *regs)
void print_fn_code(unsigned char *code, unsigned long len) { - char buffer[64], *ptr; + char buffer[128], *ptr; int opsize, i;
while (len) {
From: Harald Freudenberger freude@linux.ibm.com
commit 70fac8088cfad9f3b379c9082832b4d7532c16c2 upstream.
Tests with kvm and a kmemdebug kernel showed, that on hot unplug the zcard and zqueue structs for the unplugged card or queue are not properly freed because of a mismatch with get/put for the embedded kref counter.
This fix now adjusts the handling of the kref counters. With init the kref counter starts with 1. This initial value needs to drop to zero with the unregister of the card or queue to trigger the release and free the object.
Fixes: 29c2680fd2bf ("s390/ap: fix ap devices reference counting") Reported-by: Marc Hartmayer mhartmay@linux.ibm.com Signed-off-by: Harald Freudenberger freude@linux.ibm.com Cc: stable@vger.kernel.org Reviewed-by: Julian Wiedmann jwi@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/crypto/zcrypt_card.c | 1 + drivers/s390/crypto/zcrypt_queue.c | 1 + 2 files changed, 2 insertions(+)
--- a/drivers/s390/crypto/zcrypt_card.c +++ b/drivers/s390/crypto/zcrypt_card.c @@ -192,5 +192,6 @@ void zcrypt_card_unregister(struct zcryp spin_unlock(&zcrypt_list_lock); sysfs_remove_group(&zc->card->ap_dev.device.kobj, &zcrypt_card_attr_group); + zcrypt_card_put(zc); } EXPORT_SYMBOL(zcrypt_card_unregister); --- a/drivers/s390/crypto/zcrypt_queue.c +++ b/drivers/s390/crypto/zcrypt_queue.c @@ -223,5 +223,6 @@ void zcrypt_queue_unregister(struct zcry sysfs_remove_group(&zq->queue->ap_dev.device.kobj, &zcrypt_queue_attr_group); zcrypt_card_put(zc); + zcrypt_queue_put(zq); } EXPORT_SYMBOL(zcrypt_queue_unregister);
From: Jason Wang jasowang@redhat.com
commit 3a3e0fad16d40a2aa68ddf7eea4acdf48b22dd44 upstream.
The virtqueue doorbell is usually implemented via registeres but we don't provide the necessary vma->flags like VM_PFNMAP. This may cause several issues e.g when userspace tries to map the doorbell via vhost IOTLB, kernel may panic due to the page is not backed by page structure. This patch fixes this by setting the necessary vm_flags. With this patch, try to map doorbell via IOTLB will fail with bad address.
Cc: stable@vger.kernel.org Fixes: ddd89d0a059d ("vhost_vdpa: support doorbell mapping via mmap") Signed-off-by: Jason Wang jasowang@redhat.com Link: https://lore.kernel.org/r/20210413091557.29008-1-jasowang@redhat.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/vhost/vdpa.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/vhost/vdpa.c +++ b/drivers/vhost/vdpa.c @@ -997,6 +997,7 @@ static int vhost_vdpa_mmap(struct file * if (vma->vm_end - vma->vm_start != notify.size) return -ENOTSUPP;
+ vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; vma->vm_ops = &vhost_vdpa_vm_ops; return 0; }
From: Stefan Berger stefanb@linux.ibm.com
commit 3dcd15665aca80197333500a4be3900948afccc1 upstream.
Check the eventlog signature before using it. This avoids using an empty log, as may be the case when QEMU created the ACPI tables, rather than probing the EFI log next. This resolves an issue where the EFI log was empty since an empty ACPI log was used.
Cc: stable@vger.kernel.org Fixes: 85467f63a05c ("tpm: Add support for event log pointer found in TPM2 ACPI table") Signed-off-by: Stefan Berger stefanb@linux.ibm.com Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/tpm/eventlog/acpi.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-)
--- a/drivers/char/tpm/eventlog/acpi.c +++ b/drivers/char/tpm/eventlog/acpi.c @@ -41,6 +41,27 @@ struct acpi_tcpa { }; };
+/* Check that the given log is indeed a TPM2 log. */ +static bool tpm_is_tpm2_log(void *bios_event_log, u64 len) +{ + struct tcg_efi_specid_event_head *efispecid; + struct tcg_pcr_event *event_header; + int n; + + if (len < sizeof(*event_header)) + return false; + len -= sizeof(*event_header); + event_header = bios_event_log; + + if (len < sizeof(*efispecid)) + return false; + efispecid = (struct tcg_efi_specid_event_head *)event_header->event; + + n = memcmp(efispecid->signature, TCG_SPECID_SIG, + sizeof(TCG_SPECID_SIG)); + return n == 0; +} + /* read binary bios log */ int tpm_read_log_acpi(struct tpm_chip *chip) { @@ -52,6 +73,7 @@ int tpm_read_log_acpi(struct tpm_chip *c struct acpi_table_tpm2 *tbl; struct acpi_tpm2_phy *tpm2_phy; int format; + int ret;
log = &chip->log;
@@ -112,6 +134,7 @@ int tpm_read_log_acpi(struct tpm_chip *c
log->bios_event_log_end = log->bios_event_log + len;
+ ret = -EIO; virt = acpi_os_map_iomem(start, len); if (!virt) goto err; @@ -119,11 +142,19 @@ int tpm_read_log_acpi(struct tpm_chip *c memcpy_fromio(log->bios_event_log, virt, len);
acpi_os_unmap_iomem(virt, len); + + if (chip->flags & TPM_CHIP_FLAG_TPM2 && + !tpm_is_tpm2_log(log->bios_event_log, len)) { + /* try EFI log next */ + ret = -ENODEV; + goto err; + } + return format;
err: kfree(log->bios_event_log); log->bios_event_log = NULL; - return -EIO; + return ret;
}
From: Mark Langsdorf mlangsdo@redhat.com
commit e483bb9a991bdae29a0caa4b3a6d002c968f94aa upstream.
In cm_write(), buf is always freed when reaching the end of the function. If the requested count is less than table.length, the allocated buffer will be freed but subsequent calls to cm_write() will still try to access it.
Remove the unconditional kfree(buf) at the end of the function and set the buf to NULL in the -EINVAL error path to match the rest of function.
Fixes: 03d1571d9513 ("ACPI: custom_method: fix memory leaks") Signed-off-by: Mark Langsdorf mlangsdo@redhat.com Cc: 5.4+ stable@vger.kernel.org # 5.4+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/acpi/custom_method.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/acpi/custom_method.c +++ b/drivers/acpi/custom_method.c @@ -55,6 +55,7 @@ static ssize_t cm_write(struct file *fil (*ppos + count < count) || (count > uncopied_bytes)) { kfree(buf); + buf = NULL; return -EINVAL; }
@@ -76,7 +77,6 @@ static ssize_t cm_write(struct file *fil add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE); }
- kfree(buf); return count; }
From: Mark Langsdorf mlangsdo@redhat.com
commit 1cfd8956437f842836e8a066b40d1ec2fc01f13e upstream.
In cm_write(), if the 'buf' is allocated memory but not fully consumed, it is possible to reallocate the buffer without freeing it by passing '*ppos' as 0 on a subsequent call.
Add an explicit kfree() before kzalloc() to prevent the possible memory leak.
Fixes: 526b4af47f44 ("ACPI: Split out custom_method functionality into an own driver") Signed-off-by: Mark Langsdorf mlangsdo@redhat.com Cc: 5.4+ stable@vger.kernel.org # 5.4+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/acpi/custom_method.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/acpi/custom_method.c +++ b/drivers/acpi/custom_method.c @@ -42,6 +42,8 @@ static ssize_t cm_write(struct file *fil sizeof(struct acpi_table_header))) return -EFAULT; uncopied_bytes = max_size = table.length; + /* make sure the buf is not allocated */ + kfree(buf); buf = kzalloc(max_size, GFP_KERNEL); if (!buf) return -ENOMEM;
From: Steven Rostedt (VMware) rostedt@goodmis.org
commit 8c9af478c06bb1ab1422f90d8ecbc53defd44bc3 upstream.
# echo switch_mm:traceoff > /sys/kernel/tracing/set_ftrace_filter
will cause switch_mm to stop tracing by the traceoff command.
# echo -n switch_mm:traceoff > /sys/kernel/tracing/set_ftrace_filter
does nothing.
The reason is that the parsing in the write function only processes commands if it finished parsing (there is white space written after the command). That's to handle:
write(fd, "switch_mm:", 10); write(fd, "traceoff", 8);
cases, where the command is broken over multiple writes.
The problem is if the file descriptor is closed, then the write call is not processed, and the command needs to be processed in the release code. The release code can handle matching of functions, but does not handle commands.
Cc: stable@vger.kernel.org Fixes: eda1e32855656 ("tracing: handle broken names in ftrace filter") Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ftrace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -5632,7 +5632,10 @@ int ftrace_regex_release(struct inode *i
parser = &iter->parser; if (trace_parser_loaded(parser)) { - ftrace_match_records(iter->hash, parser->buffer, parser->idx); + int enable = !(iter->flags & FTRACE_ITER_NOTRACE); + + ftrace_process_regex(iter, parser->buffer, + parser->idx, enable); }
trace_parser_put(parser);
From: Ard Biesheuvel ardb@kernel.org
commit c4e792d1acce31c2eb7b9193ab06ab94de05bf42 upstream.
The LLVM ld.lld linker uses a different symbol type for __bss_start, resulting in the calculation of KBSS_SZ to be thrown off. Up until now, this has gone unnoticed as it only affects the appended DTB case, but pending changes for ARM in the way the decompressed kernel is cleaned from the caches has uncovered this problem.
On a ld.lld build:
$ nm vmlinux |grep bss_ c1c22034 D __bss_start c1c86e98 B __bss_stop
resulting in
$ readelf -s arch/arm/boot/compressed/vmlinux | grep bss_size 433: c1c86e98 0 NOTYPE GLOBAL DEFAULT ABS _kernel_bss_size
which is obviously incorrect, and may cause the cache clean to access unmapped memory, or cause the size calculation to wrap, resulting in no cache clean to be performed at all.
Fix this by updating the sed regex to take D type symbols into account.
Link: https://lore.kernel.org/linux-arm-kernel/6c65bcef-d4e7-25fa-43cf-2c435bb61bb... Link: https://lore.kernel.org/linux-arm-kernel/20210205085220.31232-1-ardb@kernel....
Cc: stable@vger.kernel.org # v4.19+ Reviewed-by: Nick Desaulniers ndesaulniers@google.com Tested-by: Nick Desaulniers ndesaulniers@google.com Reported-by: Guillaume Tucker guillaume.tucker@collabora.com Reported-by: "kernelci.org bot" bot@kernelci.org Signed-off-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/boot/compressed/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -114,8 +114,8 @@ asflags-y := -DZIMAGE
# Supply kernel BSS size to the decompressor via a linker symbol. KBSS_SZ = $(shell echo $$(($$($(NM) $(obj)/../../../../vmlinux | \ - sed -n -e 's/^([^ ]*) [AB] __bss_start$$/-0x\1/p' \ - -e 's/^([^ ]*) [AB] __bss_stop$$/+0x\1/p') )) ) + sed -n -e 's/^([^ ]*) [ABD] __bss_start$$/-0x\1/p' \ + -e 's/^([^ ]*) [ABD] __bss_stop$$/+0x\1/p') )) ) LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ) # Supply ZRELADDR to the decompressor via a linker symbol. ifneq ($(CONFIG_AUTO_ZRELADDR),y)
From: Marek Behún kabel@kernel.org
commit 1d88358a89dbac9c7d4559548b9a44840456e6fb upstream.
Add "syscon" compatible to the North Bridge clocks node to allow the cpufreq driver to access these registers via syscon API.
This is needed for a fix of cpufreq driver.
Signed-off-by: Marek Behún kabel@kernel.org Fixes: e8d66e7927b2 ("arm64: dts: marvell: armada-37xx: add nodes...") Cc: stable@vger.kernel.org Cc: Gregory CLEMENT gregory.clement@free-electrons.com Cc: Miquel Raynal miquel.raynal@bootlin.com Signed-off-by: Gregory CLEMENT gregory.clement@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi @@ -156,7 +156,8 @@ };
nb_periph_clk: nb-periph-clk@13000 { - compatible = "marvell,armada-3700-periph-clock-nb"; + compatible = "marvell,armada-3700-periph-clock-nb", + "syscon"; reg = <0x13000 0x100>; clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, <&tbg 3>, <&xtalclk>;
From: Chunfeng Yun chunfeng.yun@mediatek.com
commit e4e5d030bd779fb8321d3b8bd65406fbe0827037 upstream.
Use 'phys' instead of 'phy'.
Fixes: 81ad4dbaf7af ("arm64: dts: mt8173: Add display subsystem related nodes") Signed-off-by: Chunfeng Yun chunfeng.yun@mediatek.com Reviewed-by: Chun-Kuang Hu chunkuang.hu@kernel.org Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20210316092232.9806-5-chunfeng.yun@mediatek.com Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -1169,7 +1169,7 @@ <&mmsys CLK_MM_DSI1_DIGITAL>, <&mipi_tx1>; clock-names = "engine", "digital", "hs"; - phy = <&mipi_tx1>; + phys = <&mipi_tx1>; phy-names = "dphy"; status = "disabled"; };
From: Jeffrey Mitchell jeffrey.mitchell@starlab.io
commit 9046625511ad8dfbc8c6c2de16b3532c43d68d48 upstream.
When mounting eCryptfs, a null "dev_name" argument to ecryptfs_mount() causes a kernel panic if the parsed options are valid. The easiest way to reproduce this is to call mount() from userspace with an existing eCryptfs mount's options and a "source" argument of 0.
Error out if "dev_name" is null in ecryptfs_mount()
Fixes: 237fead61998 ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig") Cc: stable@vger.kernel.org Signed-off-by: Jeffrey Mitchell jeffrey.mitchell@starlab.io Signed-off-by: Tyler Hicks code@tyhicks.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ecryptfs/main.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -492,6 +492,12 @@ static struct dentry *ecryptfs_mount(str goto out; }
+ if (!dev_name) { + rc = -EINVAL; + err = "Device name cannot be null"; + goto out; + } + rc = ecryptfs_parse_options(sbi, raw_data, &check_ruid); if (rc) { err = "Error parsing options";
From: Davidlohr Bueso dave@stgolabs.net
commit 7fab29e356309ff93a4b30ecc466129682ec190b upstream.
Commit 339ddb53d373 ("fs/epoll: remove unnecessary wakeups of nested epoll") changed the userspace visible behavior of exclusive waiters blocked on a common epoll descriptor upon a single event becoming ready.
Previously, all tasks doing epoll_wait would awake, and now only one is awoken, potentially causing missed wakeups on applications that rely on this behavior, such as Apache Qpid.
While the aforementioned commit aims at having only a wakeup single path in ep_poll_callback (with the exceptions of epoll_ctl cases), we need to restore the wakeup in what was the old ep_scan_ready_list() such that the next thread can be awoken, in a cascading style, after the waker's corresponding ep_send_events().
Link: https://lkml.kernel.org/r/20210405231025.33829-3-dave@stgolabs.net Fixes: 339ddb53d373 ("fs/epoll: remove unnecessary wakeups of nested epoll") Signed-off-by: Davidlohr Bueso dbueso@suse.de Cc: Al Viro viro@zeniv.linux.org.uk Cc: Jason Baron jbaron@akamai.com Cc: Roman Penyaev rpenyaev@suse.de Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/eventpoll.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -746,6 +746,12 @@ static __poll_t ep_scan_ready_list(struc */ list_splice(&txlist, &ep->rdllist); __pm_relax(ep->ws); + + if (!list_empty(&ep->rdllist)) { + if (waitqueue_active(&ep->wq)) + wake_up(&ep->wq); + } + write_unlock_irq(&ep->lock);
if (!ep_locked)
From: Xiang Chen chenxiang66@hisilicon.com
commit be94215be1ab19e5d38f50962f611c88d4bfc83a upstream.
If rmmod the driver during read or write, the driver will release the resources which are used during read or write, so it is possible to refer to NULL pointer.
Use the testcase "mtd_debug read /dev/mtd0 0xc00000 0x400000 dest_file & sleep 0.5;rmmod spi_hisi_sfc_v3xx.ko", the issue can be reproduced in hisi_sfc_v3xx driver.
To avoid the issue, fill the interface _get_device and _put_device of mtd_info to grab the reference to the spi controller driver module, so the request of rmmod the driver is rejected before read/write is finished.
Fixes: b199489d37b2 ("mtd: spi-nor: add the framework for SPI NOR") Signed-off-by: Xiang Chen chenxiang66@hisilicon.com Signed-off-by: Yicong Yang yangyicong@hisilicon.com Signed-off-by: Tudor Ambarus tudor.ambarus@microchip.com Tested-by: Michael Walle michael@walle.cc Tested-by: Tudor Ambarus tudor.ambarus@microchip.com Reviewed-by: Michael Walle michael@walle.cc Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/1617262486-4223-1-git-send-email-yangyicong@hisili... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/spi-nor/core.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
--- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2981,6 +2981,37 @@ static void spi_nor_resume(struct mtd_in dev_err(dev, "resume() failed\n"); }
+static int spi_nor_get_device(struct mtd_info *mtd) +{ + struct mtd_info *master = mtd_get_master(mtd); + struct spi_nor *nor = mtd_to_spi_nor(master); + struct device *dev; + + if (nor->spimem) + dev = nor->spimem->spi->controller->dev.parent; + else + dev = nor->dev; + + if (!try_module_get(dev->driver->owner)) + return -ENODEV; + + return 0; +} + +static void spi_nor_put_device(struct mtd_info *mtd) +{ + struct mtd_info *master = mtd_get_master(mtd); + struct spi_nor *nor = mtd_to_spi_nor(master); + struct device *dev; + + if (nor->spimem) + dev = nor->spimem->spi->controller->dev.parent; + else + dev = nor->dev; + + module_put(dev->driver->owner); +} + void spi_nor_restore(struct spi_nor *nor) { /* restore the addressing mode */ @@ -3157,6 +3188,8 @@ int spi_nor_scan(struct spi_nor *nor, co mtd->_erase = spi_nor_erase; mtd->_read = spi_nor_read; mtd->_resume = spi_nor_resume; + mtd->_get_device = spi_nor_get_device; + mtd->_put_device = spi_nor_put_device;
if (nor->params->locking_ops) { mtd->_lock = spi_nor_lock;
From: Tudor Ambarus tudor.ambarus@microchip.com
commit 46094049a49be777f12a9589798f7c70b90cd03f upstream.
This reverts commit 04b8edad262eec0d153005973dfbdd83423c0dcb.
mx25l51245g and mx66l51235l have the same flash ID. The flash detection returns the first entry in the flash_info array that matches the flash ID that was read, thus for the 0xc2201a ID, mx25l51245g was always hit, introducing a regression for mx66l51235l.
If one wants to differentiate the flash names, a better fix would be to differentiate between the two at run-time, depending on SFDP, and choose the correct name from a list of flash names, depending on the SFDP differentiator.
Fixes: 04b8edad262e ("mtd: spi-nor: macronix: Add support for mx25l51245g") Signed-off-by: Tudor Ambarus tudor.ambarus@microchip.com Acked-by: Pratyush Yadav p.yadav@ti.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210402082031.19055-2-tudor.ambarus@microchip.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/spi-nor/macronix.c | 3 --- 1 file changed, 3 deletions(-)
--- a/drivers/mtd/spi-nor/macronix.c +++ b/drivers/mtd/spi-nor/macronix.c @@ -73,9 +73,6 @@ static const struct flash_info macronix_ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, - { "mx25l51245g", INFO(0xc2201a, 0, 64 * 1024, 1024, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_4B_OPCODES) }, { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
From: Alexander Lobakin alobakin@pm.me
commit 25fefc88c71f47db0466570335e3f75f10952e7a upstream.
The module misses MODULE_DEVICE_TABLE() for both SPI and OF ID tables and thus never autoloads on ID matches. Add the missing declarations. Present since day-0 of spinand framework introduction.
Fixes: 7529df465248 ("mtd: nand: Add core infrastructure to support SPI NANDs") Cc: stable@vger.kernel.org # 4.19+ Signed-off-by: Alexander Lobakin alobakin@pm.me Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210323173714.317884-1-alobakin@pm.me Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/spi/core.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -1173,12 +1173,14 @@ static const struct spi_device_id spinan { .name = "spi-nand" }, { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(spi, spinand_ids);
#ifdef CONFIG_OF static const struct of_device_id spinand_of_ids[] = { { .compatible = "spi-nand" }, { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(of, spinand_of_ids); #endif
static struct spi_mem_driver spinand_drv = {
From: Kai Stuhlemmer (ebee Engineering) kai.stuhlemmer@ebee.de
commit 33cebf701e98dd12b01d39d1c644387b27c1a627 upstream.
Update MTD ECC statistics with the number of corrected bits.
Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver") Cc: stable@vger.kernel.org Signed-off-by: Kai Stuhlemmer (ebee Engineering) kai.stuhlemmer@ebee.de Signed-off-by: Tudor Ambarus tudor.ambarus@microchip.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210322150714.101585-1-tudor.ambarus@micr... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/atmel/nand-controller.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -883,10 +883,12 @@ static int atmel_nand_pmecc_correct_data NULL, 0, chip->ecc.strength);
- if (ret >= 0) + if (ret >= 0) { + mtd->ecc_stats.corrected += ret; max_bitflips = max(ret, max_bitflips); - else + } else { mtd->ecc_stats.failed++; + }
databuf += chip->ecc.size; eccbuf += chip->ecc.bytes;
From: Gustavo A. R. Silva gustavoars@kernel.org
commit 683313993dbe1651c7aa00bb42a041d70e914925 upstream.
Cast &data to (char *) in order to avoid unintentionally accessing the stack.
Notice that data is of type u32, so any increment to &data will be in the order of 4-byte chunks, and this piece of code is actually intended to be a byte offset.
Fixes: b3e79e7682e0 ("mtd: physmap: Add Baikal-T1 physically mapped ROM support") Addresses-Coverity-ID: 1497765 ("Out-of-bounds access") Cc: stable@vger.kernel.org Signed-off-by: Gustavo A. R. Silva gustavoars@kernel.org Acked-by: Serge Semin fancer.lancer@gmail.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210212104022.GA242669@embeddedor Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/maps/physmap-bt1-rom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mtd/maps/physmap-bt1-rom.c +++ b/drivers/mtd/maps/physmap-bt1-rom.c @@ -79,7 +79,7 @@ static void __xipram bt1_rom_map_copy_fr if (shift) { chunk = min_t(ssize_t, 4 - shift, len); data = readl_relaxed(src - shift); - memcpy(to, &data + shift, chunk); + memcpy(to, (char *)&data + shift, chunk); src += chunk; to += chunk; len -= chunk;
From: Gao Xiang hsiangkao@redhat.com
commit 24a806d849c0b0c1d0cd6a6b93ba4ae4c0ec9f08 upstream.
If any unknown i_format fields are set (may be of some new incompat inode features), mark such inode as unsupported.
Just in case of any new incompat i_format fields added in the future.
Link: https://lore.kernel.org/r/20210329003614.6583-1-hsiangkao@aol.com Fixes: 431339ba9042 ("staging: erofs: add inode operations") Cc: stable@vger.kernel.org # 4.19+ Signed-off-by: Gao Xiang hsiangkao@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/erofs/erofs_fs.h | 3 +++ fs/erofs/inode.c | 7 +++++++ 2 files changed, 10 insertions(+)
--- a/fs/erofs/erofs_fs.h +++ b/fs/erofs/erofs_fs.h @@ -75,6 +75,9 @@ static inline bool erofs_inode_is_data_c #define EROFS_I_VERSION_BIT 0 #define EROFS_I_DATALAYOUT_BIT 1
+#define EROFS_I_ALL \ + ((1 << (EROFS_I_DATALAYOUT_BIT + EROFS_I_DATALAYOUT_BITS)) - 1) + /* 32-byte reduced form of an ondisk inode */ struct erofs_inode_compact { __le16 i_format; /* inode format hints */ --- a/fs/erofs/inode.c +++ b/fs/erofs/inode.c @@ -44,6 +44,13 @@ static struct page *erofs_read_inode(str dic = page_address(page) + *ofs; ifmt = le16_to_cpu(dic->i_format);
+ if (ifmt & ~EROFS_I_ALL) { + erofs_err(inode->i_sb, "unsupported i_format %u of nid %llu", + ifmt, vi->nid); + err = -EOPNOTSUPP; + goto err_out; + } + vi->datalayout = erofs_inode_datalayout(ifmt); if (vi->datalayout >= EROFS_INODE_DATALAYOUT_MAX) { erofs_err(inode->i_sb, "unsupported datalayout %u of nid %llu",
From: Christophe Kerello christophe.kerello@foss.st.com
commit 102e9d1936569d43f55dd1ea89be355ad207143c upstream.
pm_runtime usage_count counter is not well managed. pm_runtime_put_autosuspend callback drops the usage_counter but this one has never been increased. Add pm_runtime_get_sync callback to bump up the usage counter. It is also needed to use pm_runtime_force_suspend and pm_runtime_force_resume APIs to handle properly the clock.
Fixes: 9d282c17b023 ("spi: stm32-qspi: Add pm_runtime support") Signed-off-by: Christophe Kerello christophe.kerello@foss.st.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210419121541.11617-2-patrice.chotard@foss.st.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/spi/spi-stm32-qspi.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
--- a/drivers/spi/spi-stm32-qspi.c +++ b/drivers/spi/spi-stm32-qspi.c @@ -727,21 +727,31 @@ static int __maybe_unused stm32_qspi_sus { pinctrl_pm_select_sleep_state(dev);
- return 0; + return pm_runtime_force_suspend(dev); }
static int __maybe_unused stm32_qspi_resume(struct device *dev) { struct stm32_qspi *qspi = dev_get_drvdata(dev); + int ret; + + ret = pm_runtime_force_resume(dev); + if (ret < 0) + return ret;
pinctrl_pm_select_default_state(dev); - clk_prepare_enable(qspi->clk); + + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + return ret; + }
writel_relaxed(qspi->cr_reg, qspi->io_base + QSPI_CR); writel_relaxed(qspi->dcr_reg, qspi->io_base + QSPI_DCR);
- pm_runtime_mark_last_busy(qspi->dev); - pm_runtime_put_autosuspend(qspi->dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev);
return 0; }
From: Tudor Ambarus tudor.ambarus@microchip.com
commit 1d309cd688a76fb733f0089d36dc630327b32d59 upstream.
Release the RX channel and free the dma coherent memory when devm_spi_register_master() fails.
Fixes: 5720ec0a6d26 ("spi: spi-ti-qspi: Add DMA support for QSPI mmap read") Cc: stable@vger.kernel.org Signed-off-by: Tudor Ambarus tudor.ambarus@microchip.com Link: https://lore.kernel.org/r/20210218130950.90155-1-tudor.ambarus@microchip.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/spi/spi-ti-qspi.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
--- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -733,6 +733,17 @@ static int ti_qspi_runtime_resume(struct return 0; }
+static void ti_qspi_dma_cleanup(struct ti_qspi *qspi) +{ + if (qspi->rx_bb_addr) + dma_free_coherent(qspi->dev, QSPI_DMA_BUFFER_SIZE, + qspi->rx_bb_addr, + qspi->rx_bb_dma_addr); + + if (qspi->rx_chan) + dma_release_channel(qspi->rx_chan); +} + static const struct of_device_id ti_qspi_match[] = { {.compatible = "ti,dra7xxx-qspi" }, {.compatible = "ti,am4372-qspi" }, @@ -886,6 +897,8 @@ no_dma: if (!ret) return 0;
+ ti_qspi_dma_cleanup(qspi); + pm_runtime_disable(&pdev->dev); free_master: spi_master_put(master); @@ -904,12 +917,7 @@ static int ti_qspi_remove(struct platfor pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev);
- if (qspi->rx_bb_addr) - dma_free_coherent(qspi->dev, QSPI_DMA_BUFFER_SIZE, - qspi->rx_bb_addr, - qspi->rx_bb_dma_addr); - if (qspi->rx_chan) - dma_release_channel(qspi->rx_chan); + ti_qspi_dma_cleanup(qspi);
return 0; }
From: Arun Easi aeasi@marvell.com
commit 6641df81ab799f28a5d564f860233dd26cca0d93 upstream.
RIP: 0010:kmem_cache_free+0xfa/0x1b0 Call Trace: qla2xxx_mqueuecommand+0x2b5/0x2c0 [qla2xxx] scsi_queue_rq+0x5e2/0xa40 __blk_mq_try_issue_directly+0x128/0x1d0 blk_mq_request_issue_directly+0x4e/0xb0
Fix incorrect call to free srb in qla2xxx_mqueuecommand(), as srb is now allocated by upper layers. This fixes smatch warning of srb unintended free.
Link: https://lore.kernel.org/r/20210329085229.4367-7-njavali@marvell.com Fixes: af2a0c51b120 ("scsi: qla2xxx: Fix SRB leak on switch command timeout") Cc: stable@vger.kernel.org # 5.5 Reported-by: Laurence Oberman loberman@redhat.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Arun Easi aeasi@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_os.c | 7 ------- 1 file changed, 7 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1008,8 +1008,6 @@ qla2xxx_mqueuecommand(struct Scsi_Host * if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3078, "Start scsi failed rval=%d for cmd=%p.\n", rval, cmd); - if (rval == QLA_INTERFACE_ERROR) - goto qc24_free_sp_fail_command; goto qc24_host_busy_free_sp; }
@@ -1021,11 +1019,6 @@ qc24_host_busy_free_sp: qc24_target_busy: return SCSI_MLQUEUE_TARGET_BUSY;
-qc24_free_sp_fail_command: - sp->free(sp); - CMD_SP(cmd) = NULL; - qla2xxx_rel_qpair_sp(sp->qpair, sp); - qc24_fail_command: cmd->scsi_done(cmd);
From: Sreekanth Reddy sreekanth.reddy@broadcom.com
commit 3c8604691d2acc7b7d4795d9695070de9eaa5828 upstream.
While diag reset is in progress there is short duration where all access to controller's PCI config space from the host needs to be blocked. This is due to a hardware limitation of the IOC controllers.
Block all access to controller's config space from userland applications by calling pci_cfg_access_lock() while diag reset is in progress and unlocking it again after the controller comes back to ready state.
Link: https://lore.kernel.org/r/20210330105137.20728-1-sreekanth.reddy@broadcom.co... Cc: stable@vger.kernel.org #v5.4.108+ Signed-off-by: Sreekanth Reddy sreekanth.reddy@broadcom.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/mpt3sas/mpt3sas_base.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -6804,6 +6804,8 @@ _base_diag_reset(struct MPT3SAS_ADAPTER
ioc_info(ioc, "sending diag reset !!\n");
+ pci_cfg_access_lock(ioc->pdev); + drsprintk(ioc, ioc_info(ioc, "clear interrupts\n"));
count = 0; @@ -6894,10 +6896,12 @@ _base_diag_reset(struct MPT3SAS_ADAPTER goto out; }
+ pci_cfg_access_unlock(ioc->pdev); ioc_info(ioc, "diag reset: SUCCESS\n"); return 0;
out: + pci_cfg_access_unlock(ioc->pdev); ioc_err(ioc, "diag reset: FAILED\n"); return -EFAULT; }
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
commit b03aec1c1f337dfdae44cdb0645ecac34208ae0a upstream.
A 'uniphier_sd_clk_enable()' call should be balanced by a corresponding 'uniphier_sd_clk_disable()' call. This is done in the remove function, but not in the error handling path of the probe.
Add the missing call.
Fixes: 3fd784f745dd ("mmc: uniphier-sd: add UniPhier SD/eMMC controller driver") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Masahiro Yamada masahiroy@kernel.org Link: https://lore.kernel.org/r/20210220142935.918554-1-christophe.jaillet@wanadoo... Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/host/uniphier-sd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/mmc/host/uniphier-sd.c +++ b/drivers/mmc/host/uniphier-sd.c @@ -636,7 +636,7 @@ static int uniphier_sd_probe(struct plat
ret = tmio_mmc_host_probe(host); if (ret) - goto free_host; + goto disable_clk;
ret = devm_request_irq(dev, irq, tmio_mmc_irq, IRQF_SHARED, dev_name(dev), host); @@ -647,6 +647,8 @@ static int uniphier_sd_probe(struct plat
remove_host: tmio_mmc_host_remove(host); +disable_clk: + uniphier_sd_clk_disable(host); free_host: tmio_mmc_host_free(host);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
commit e29c84857e2d51aa017ce04284b962742fb97d9e upstream.
A 'tmio_mmc_host_free()' call is missing in the remove function, in order to balance a 'tmio_mmc_host_alloc()' call in the probe. This is done in the error handling path of the probe, but not in the remove function.
Add the missing call.
Fixes: 3fd784f745dd ("mmc: uniphier-sd: add UniPhier SD/eMMC controller driver") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Masahiro Yamada masahiroy@kernel.org Link: https://lore.kernel.org/r/20210220142953.918608-1-christophe.jaillet@wanadoo... Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/host/uniphier-sd.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/mmc/host/uniphier-sd.c +++ b/drivers/mmc/host/uniphier-sd.c @@ -661,6 +661,7 @@ static int uniphier_sd_remove(struct pla
tmio_mmc_host_remove(host); uniphier_sd_clk_disable(host); + tmio_mmc_host_free(host);
return 0; }
From: Pradeep P V K pragalla@codeaurora.org
commit 21e35e898aa9ef7781632959db8613a5380f2eae upstream.
For data read commands, SDHC may initiate data transfers even before it completely process the command response. In case command itself fails, driver un-maps the memory associated with data transfer but this memory can still be accessed by SDHC for the already initiated data transfer. This scenario can lead to un-mapped memory access error.
To avoid this scenario, reset SDHC (when command fails) prior to un-mapping memory. Resetting SDHC ensures that all in-flight data transfers are either aborted or completed. So we don't run into this scenario.
Swap the reset, un-map steps sequence in sdhci_request_done().
Suggested-by: Veerabhadrarao Badiganti vbadigan@codeaurora.org Signed-off-by: Pradeep P V K pragalla@codeaurora.org Acked-by: Adrian Hunter adrian.hunter@intel.com Link: https://lore.kernel.org/r/1614760331-43499-1-git-send-email-pragalla@qti.qua... Cc: stable@vger.kernel.org # v4.9+ Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/host/sdhci.c | 60 ++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 29 deletions(-)
--- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2998,6 +2998,37 @@ static bool sdhci_request_done(struct sd }
/* + * The controller needs a reset of internal state machines + * upon error conditions. + */ + if (sdhci_needs_reset(host, mrq)) { + /* + * Do not finish until command and data lines are available for + * reset. Note there can only be one other mrq, so it cannot + * also be in mrqs_done, otherwise host->cmd and host->data_cmd + * would both be null. + */ + if (host->cmd || host->data_cmd) { + spin_unlock_irqrestore(&host->lock, flags); + return true; + } + + /* Some controllers need this kick or reset won't work here */ + if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) + /* This is to force an update */ + host->ops->set_clock(host, host->clock); + + /* + * Spec says we should do both at the same time, but Ricoh + * controllers do not like that. + */ + sdhci_do_reset(host, SDHCI_RESET_CMD); + sdhci_do_reset(host, SDHCI_RESET_DATA); + + host->pending_reset = false; + } + + /* * Always unmap the data buffers if they were mapped by * sdhci_prepare_data() whenever we finish with a request. * This avoids leaking DMA mappings on error. @@ -3060,35 +3091,6 @@ static bool sdhci_request_done(struct sd } }
- /* - * The controller needs a reset of internal state machines - * upon error conditions. - */ - if (sdhci_needs_reset(host, mrq)) { - /* - * Do not finish until command and data lines are available for - * reset. Note there can only be one other mrq, so it cannot - * also be in mrqs_done, otherwise host->cmd and host->data_cmd - * would both be null. - */ - if (host->cmd || host->data_cmd) { - spin_unlock_irqrestore(&host->lock, flags); - return true; - } - - /* Some controllers need this kick or reset won't work here */ - if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) - /* This is to force an update */ - host->ops->set_clock(host, host->clock); - - /* Spec says we should do both at the same time, but Ricoh - controllers do not like that. */ - sdhci_do_reset(host, SDHCI_RESET_CMD); - sdhci_do_reset(host, SDHCI_RESET_DATA); - - host->pending_reset = false; - } - host->mrqs_done[i] = NULL;
spin_unlock_irqrestore(&host->lock, flags);
From: Adrian Hunter adrian.hunter@intel.com
commit 2970134b927834e9249659a70aac48e62dff804a upstream.
Bus power may control card power, but the full reset done by SDHCI at initialization still may not reset the power, whereas a direct write to SDHCI_POWER_CONTROL can. That might be needed to initialize correctly, if the card was left powered on previously.
Signed-off-by: Adrian Hunter adrian.hunter@intel.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210331081752.23621-1-adrian.hunter@intel.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/host/sdhci-pci-core.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
--- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -516,6 +516,7 @@ struct intel_host { int drv_strength; bool d3_retune; bool rpm_retune_ok; + bool needs_pwr_off; u32 glk_rx_ctrl1; u32 glk_tun_val; u32 active_ltr; @@ -643,9 +644,25 @@ out: static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode, unsigned short vdd) { + struct sdhci_pci_slot *slot = sdhci_priv(host); + struct intel_host *intel_host = sdhci_pci_priv(slot); int cntr; u8 reg;
+ /* + * Bus power may control card power, but a full reset still may not + * reset the power, whereas a direct write to SDHCI_POWER_CONTROL can. + * That might be needed to initialize correctly, if the card was left + * powered on previously. + */ + if (intel_host->needs_pwr_off) { + intel_host->needs_pwr_off = false; + if (mode != MMC_POWER_OFF) { + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); + usleep_range(10000, 12500); + } + } + sdhci_set_power(host, mode, vdd);
if (mode == MMC_POWER_OFF) @@ -1135,6 +1152,14 @@ static int byt_sdio_probe_slot(struct sd return 0; }
+static void byt_needs_pwr_off(struct sdhci_pci_slot *slot) +{ + struct intel_host *intel_host = sdhci_pci_priv(slot); + u8 reg = sdhci_readb(slot->host, SDHCI_POWER_CONTROL); + + intel_host->needs_pwr_off = reg & SDHCI_POWER_ON; +} + static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) { byt_probe_slot(slot); @@ -1152,6 +1177,8 @@ static int byt_sd_probe_slot(struct sdhc slot->chip->pdev->subsystem_device == PCI_SUBDEVICE_ID_NI_78E3) slot->host->mmc->caps2 |= MMC_CAP2_AVOID_3_3V;
+ byt_needs_pwr_off(slot); + return 0; }
From: Aniruddha Tvs Rao anrao@nvidia.com
commit 5ec6fa5a6dc5e42a4aa782f3a81d5f08b0fac1e6 upstream.
CMD8 is not supported with Command Queue Enabled. Add required callback to clear CQE_EN and CQE_INTR fields in the host controller register before sending CMD8. Add corresponding callback in the CQHCI resume path to re-enable CQE_EN and CQE_INTR fields.
Reported-by: Kamal Mostafa kamal@canonical.com Tested-by: Kamal Mostafa kamal@canonical.com Signed-off-by: Aniruddha Tvs Rao anrao@nvidia.com Signed-off-by: Jon Hunter jonathanh@nvidia.com Acked-by: Adrian Hunter adrian.hunter@intel.com Acked-by: Thierry Reding treding@nvidia.com Link: https://lore.kernel.org/r/20210407094617.770495-1-jonathanh@nvidia.com Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/host/sdhci-tegra.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
--- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -119,6 +119,10 @@ /* SDMMC CQE Base Address for Tegra Host Ver 4.1 and Higher */ #define SDHCI_TEGRA_CQE_BASE_ADDR 0xF000
+#define SDHCI_TEGRA_CQE_TRNS_MODE (SDHCI_TRNS_MULTI | \ + SDHCI_TRNS_BLK_CNT_EN | \ + SDHCI_TRNS_DMA) + struct sdhci_tegra_soc_data { const struct sdhci_pltfm_data *pdata; u64 dma_mask; @@ -1156,6 +1160,7 @@ static void tegra_sdhci_voltage_switch(s static void tegra_cqhci_writel(struct cqhci_host *cq_host, u32 val, int reg) { struct mmc_host *mmc = cq_host->mmc; + struct sdhci_host *host = mmc_priv(mmc); u8 ctrl; ktime_t timeout; bool timed_out; @@ -1170,6 +1175,7 @@ static void tegra_cqhci_writel(struct cq */ if (reg == CQHCI_CTL && !(val & CQHCI_HALT) && cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT) { + sdhci_writew(host, SDHCI_TEGRA_CQE_TRNS_MODE, SDHCI_TRANSFER_MODE); sdhci_cqe_enable(mmc); writel(val, cq_host->mmio + reg); timeout = ktime_add_us(ktime_get(), 50); @@ -1205,6 +1211,7 @@ static void sdhci_tegra_update_dcmd_desc static void sdhci_tegra_cqe_enable(struct mmc_host *mmc) { struct cqhci_host *cq_host = mmc->cqe_private; + struct sdhci_host *host = mmc_priv(mmc); u32 val;
/* @@ -1218,6 +1225,7 @@ static void sdhci_tegra_cqe_enable(struc if (val & CQHCI_ENABLE) cqhci_writel(cq_host, (val & ~CQHCI_ENABLE), CQHCI_CFG); + sdhci_writew(host, SDHCI_TEGRA_CQE_TRNS_MODE, SDHCI_TRANSFER_MODE); sdhci_cqe_enable(mmc); if (val & CQHCI_ENABLE) cqhci_writel(cq_host, val, CQHCI_CFG); @@ -1281,12 +1289,36 @@ static void tegra_sdhci_set_timeout(stru __sdhci_set_timeout(host, cmd); }
+static void sdhci_tegra_cqe_pre_enable(struct mmc_host *mmc) +{ + struct cqhci_host *cq_host = mmc->cqe_private; + u32 reg; + + reg = cqhci_readl(cq_host, CQHCI_CFG); + reg |= CQHCI_ENABLE; + cqhci_writel(cq_host, reg, CQHCI_CFG); +} + +static void sdhci_tegra_cqe_post_disable(struct mmc_host *mmc) +{ + struct cqhci_host *cq_host = mmc->cqe_private; + struct sdhci_host *host = mmc_priv(mmc); + u32 reg; + + reg = cqhci_readl(cq_host, CQHCI_CFG); + reg &= ~CQHCI_ENABLE; + cqhci_writel(cq_host, reg, CQHCI_CFG); + sdhci_writew(host, 0x0, SDHCI_TRANSFER_MODE); +} + static const struct cqhci_host_ops sdhci_tegra_cqhci_ops = { .write_l = tegra_cqhci_writel, .enable = sdhci_tegra_cqe_enable, .disable = sdhci_cqe_disable, .dumpregs = sdhci_tegra_dumpregs, .update_dcmd_desc = sdhci_tegra_update_dcmd_desc, + .pre_enable = sdhci_tegra_cqe_pre_enable, + .post_disable = sdhci_tegra_cqe_post_disable, };
static int tegra_sdhci_set_dma_mask(struct sdhci_host *host)
From: Avri Altman avri.altman@wdc.com
commit aea0440ad023ab0662299326f941214b0d7480bd upstream.
The cache function can be turned ON and OFF by writing to the CACHE_CTRL byte (EXT_CSD byte [33]). However, card->ext_csd.cache_ctrl is only set on init if cache size > 0.
Fix that by explicitly setting ext_csd.cache_ctrl on ext-csd write.
Signed-off-by: Avri Altman avri.altman@wdc.com Acked-by: Adrian Hunter adrian.hunter@intel.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210420134641.57343-3-avri.altman@wdc.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/core/block.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
--- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -572,6 +572,18 @@ static int __mmc_blk_ioctl_cmd(struct mm }
/* + * Make sure to update CACHE_CTRL in case it was changed. The cache + * will get turned back on if the card is re-initialized, e.g. + * suspend/resume or hw reset in recovery. + */ + if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_CACHE_CTRL) && + (cmd.opcode == MMC_SWITCH)) { + u8 value = MMC_EXTRACT_VALUE_FROM_ARG(cmd.arg) & 1; + + card->ext_csd.cache_ctrl = value; + } + + /* * According to the SD specs, some commands require a delay after * issuing the command. */
From: Avri Altman avri.altman@wdc.com
commit 97fce126e279690105ee15be652b465fd96f9997 upstream.
In command queueing mode, the cache isn't flushed via the mmc_flush_cache() function, but instead by issuing a CMDQ_TASK_MGMT (CMD48) with a FLUSH_CACHE opcode. In this path, we need to check if cache has been enabled, before deciding to flush the cache, along the lines of what's being done in mmc_flush_cache().
To fix this problem, let's add a new bus ops callback ->cache_enabled() and implement it for the mmc bus type. In this way, the mmc block device driver can call it to know whether cache flushing should be done.
Fixes: 1e8e55b67030 (mmc: block: Add CQE support) Cc: stable@vger.kernel.org Reported-by: Brendan Peter bpeter@lytx.com Signed-off-by: Avri Altman avri.altman@wdc.com Tested-by: Brendan Peter bpeter@lytx.com Acked-by: Adrian Hunter adrian.hunter@intel.com Link: https://lore.kernel.org/r/20210425060207.2591-2-avri.altman@wdc.com Link: https://lore.kernel.org/r/20210425060207.2591-3-avri.altman@wdc.com [Ulf: Squashed the two patches and made some minor updates] Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/core/block.c | 4 ++++ drivers/mmc/core/core.h | 9 +++++++++ drivers/mmc/core/mmc.c | 7 +++++++ drivers/mmc/core/mmc_ops.c | 4 +--- 4 files changed, 21 insertions(+), 3 deletions(-)
--- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -2233,6 +2233,10 @@ enum mmc_issued mmc_blk_mq_issue_rq(stru case MMC_ISSUE_ASYNC: switch (req_op(req)) { case REQ_OP_FLUSH: + if (!mmc_cache_enabled(host)) { + blk_mq_end_request(req, BLK_STS_OK); + return MMC_REQ_FINISHED; + } ret = mmc_blk_cqe_issue_flush(mq, req); break; case REQ_OP_READ: --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -29,6 +29,7 @@ struct mmc_bus_ops { int (*shutdown)(struct mmc_host *); int (*hw_reset)(struct mmc_host *); int (*sw_reset)(struct mmc_host *); + bool (*cache_enabled)(struct mmc_host *); };
void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); @@ -171,4 +172,12 @@ static inline void mmc_post_req(struct m host->ops->post_req(host, mrq, err); }
+static inline bool mmc_cache_enabled(struct mmc_host *host) +{ + if (host->bus_ops->cache_enabled) + return host->bus_ops->cache_enabled(host); + + return false; +} + #endif --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -2033,6 +2033,12 @@ static void mmc_detect(struct mmc_host * } }
+static bool _mmc_cache_enabled(struct mmc_host *host) +{ + return host->card->ext_csd.cache_size > 0 && + host->card->ext_csd.cache_ctrl & 1; +} + static int _mmc_suspend(struct mmc_host *host, bool is_suspend) { int err = 0; @@ -2212,6 +2218,7 @@ static const struct mmc_bus_ops mmc_ops .alive = mmc_alive, .shutdown = mmc_shutdown, .hw_reset = _mmc_hw_reset, + .cache_enabled = _mmc_cache_enabled, };
/* --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -988,9 +988,7 @@ int mmc_flush_cache(struct mmc_card *car { int err = 0;
- if (mmc_card_mmc(card) && - (card->ext_csd.cache_size > 0) && - (card->ext_csd.cache_ctrl & 1)) { + if (mmc_cache_enabled(card->host)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_FLUSH_CACHE, 1, MMC_CACHE_FLUSH_TIMEOUT_MS);
From: DooHyun Hwang dh0421.hwang@samsung.com
commit 147186f531ae49c18b7a9091a2c40e83b3d95649 upstream.
A CMD11 is sent to the SD/SDIO card to start the voltage switch procedure into 1.8V I/O. According to the SD spec a power cycle is needed of the card, if it turns out that the CMD11 fails. Let's fix this, to allow a retry of the initialization without the voltage switch, to succeed.
Note that, whether it makes sense to also retry with the voltage switch after the power cycle is a bit more difficult to know. At this point, we treat it like the CMD11 isn't supported and therefore we skip it when retrying.
Signed-off-by: DooHyun Hwang dh0421.hwang@samsung.com Link: https://lore.kernel.org/r/20210210045936.7809-1-dh0421.hwang@samsung.com Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/core/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1204,7 +1204,7 @@ int mmc_set_uhs_voltage(struct mmc_host
err = mmc_wait_for_cmd(host, &cmd, 0); if (err) - return err; + goto power_cycle;
if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) return -EIO;
From: Seunghui Lee sh043.lee@samsung.com
commit 917a5336f2c27928be270226ab374ed0cbf3805d upstream.
Some of SD cards sets permanent write protection bit in their CSD register, due to lifespan or internal problem. To avoid unnecessary I/O write operations, let's parse the bits in the CSD during initialization and mark the card as read only for this case.
Signed-off-by: Seunghui Lee sh043.lee@samsung.com Link: https://lore.kernel.org/r/20210222083156.19158-1-sh043.lee@samsung.com Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/core/sd.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -135,6 +135,9 @@ static int mmc_decode_csd(struct mmc_car csd->erase_size = UNSTUFF_BITS(resp, 39, 7) + 1; csd->erase_size <<= csd->write_blkbits - 9; } + + if (UNSTUFF_BITS(resp, 13, 1)) + mmc_card_set_readonly(card); break; case 1: /* @@ -169,6 +172,9 @@ static int mmc_decode_csd(struct mmc_car csd->write_blkbits = 9; csd->write_partial = 0; csd->erase_size = 1; + + if (UNSTUFF_BITS(resp, 13, 1)) + mmc_card_set_readonly(card); break; default: pr_err("%s: unrecognised CSD structure version %d\n",
From: Ulf Hansson ulf.hansson@linaro.org
commit 17a17bf50612e6048a9975450cf1bd30f93815b5 upstream.
The mmc core uses a PM notifier to temporarily during system suspend, turn off the card detection mechanism for removal/insertion of (e)MMC/SD/SDIO cards. Additionally, the notifier may be used to remove an SDIO card entirely, if a corresponding SDIO functional driver don't have the system suspend/resume callbacks assigned. This behaviour has been around for a very long time.
However, a recent bug report tells us there are problems with this approach. More precisely, when receiving the PM_SUSPEND_PREPARE notification, we may end up hanging on I/O to be completed, thus also preventing the system from getting suspended.
In the end what happens, is that the cancel_delayed_work_sync() in mmc_pm_notify() ends up waiting for mmc_rescan() to complete - and since mmc_rescan() wants to claim the host, it needs to wait for the I/O to be completed first.
Typically, this problem is triggered in Android, if there is ongoing I/O while the user decides to suspend, resume and then suspend the system again. This due to that after the resume, an mmc_rescan() work gets punted to the workqueue, which job is to verify that the card remains inserted after the system has resumed.
To fix this problem, userspace needs to become frozen to suspend the I/O, prior to turning off the card detection mechanism. Therefore, let's drop the PM notifiers for mmc subsystem altogether and rely on the card detection to be turned off/on as a part of the system_freezable_wq, that we are already using.
Moreover, to allow and SDIO card to be removed during system suspend, let's manage this from a ->prepare() callback, assigned at the mmc_host_class level. In this way, we can use the parent device (the mmc_host_class device), to remove the card device that is the child, in the device_prepare() phase.
Reported-by: Kiwoong Kim kwmad.kim@samsung.com Cc: stable@vger.kernel.org # v4.5+ Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Reviewed-by: Linus Walleij linus.walleij@linaro.org Link: https://lore.kernel.org/r/20210310152900.149380-1-ulf.hansson@linaro.org Reviewed-by: Kiwoong Kim kwmad.kim@samsung.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/core/core.c | 74 ----------------------------------------------- drivers/mmc/core/core.h | 8 ----- drivers/mmc/core/host.c | 40 +++++++++++++++++++++++-- drivers/mmc/core/sdio.c | 28 +++++++++++++---- include/linux/mmc/host.h | 3 - 5 files changed, 59 insertions(+), 94 deletions(-)
--- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2355,80 +2355,6 @@ void mmc_stop_host(struct mmc_host *host mmc_release_host(host); }
-#ifdef CONFIG_PM_SLEEP -/* Do the card removal on suspend if card is assumed removeable - * Do that in pm notifier while userspace isn't yet frozen, so we will be able - to sync the card. -*/ -static int mmc_pm_notify(struct notifier_block *notify_block, - unsigned long mode, void *unused) -{ - struct mmc_host *host = container_of( - notify_block, struct mmc_host, pm_notify); - unsigned long flags; - int err = 0; - - switch (mode) { - case PM_HIBERNATION_PREPARE: - case PM_SUSPEND_PREPARE: - case PM_RESTORE_PREPARE: - spin_lock_irqsave(&host->lock, flags); - host->rescan_disable = 1; - spin_unlock_irqrestore(&host->lock, flags); - cancel_delayed_work_sync(&host->detect); - - if (!host->bus_ops) - break; - - /* Validate prerequisites for suspend */ - if (host->bus_ops->pre_suspend) - err = host->bus_ops->pre_suspend(host); - if (!err) - break; - - if (!mmc_card_is_removable(host)) { - dev_warn(mmc_dev(host), - "pre_suspend failed for non-removable host: " - "%d\n", err); - /* Avoid removing non-removable hosts */ - break; - } - - /* Calling bus_ops->remove() with a claimed host can deadlock */ - host->bus_ops->remove(host); - mmc_claim_host(host); - mmc_detach_bus(host); - mmc_power_off(host); - mmc_release_host(host); - host->pm_flags = 0; - break; - - case PM_POST_SUSPEND: - case PM_POST_HIBERNATION: - case PM_POST_RESTORE: - - spin_lock_irqsave(&host->lock, flags); - host->rescan_disable = 0; - spin_unlock_irqrestore(&host->lock, flags); - _mmc_detect_change(host, 0, false); - - } - - return 0; -} - -void mmc_register_pm_notifier(struct mmc_host *host) -{ - host->pm_notify.notifier_call = mmc_pm_notify; - register_pm_notifier(&host->pm_notify); -} - -void mmc_unregister_pm_notifier(struct mmc_host *host) -{ - unregister_pm_notifier(&host->pm_notify); -} -#endif - static int __init mmc_init(void) { int ret; --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -94,14 +94,6 @@ int mmc_execute_tuning(struct mmc_card * int mmc_hs200_to_hs400(struct mmc_card *card); int mmc_hs400_to_hs200(struct mmc_card *card);
-#ifdef CONFIG_PM_SLEEP -void mmc_register_pm_notifier(struct mmc_host *host); -void mmc_unregister_pm_notifier(struct mmc_host *host); -#else -static inline void mmc_register_pm_notifier(struct mmc_host *host) { } -static inline void mmc_unregister_pm_notifier(struct mmc_host *host) { } -#endif - void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq); bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq);
--- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -34,6 +34,42 @@
static DEFINE_IDA(mmc_host_ida);
+#ifdef CONFIG_PM_SLEEP +static int mmc_host_class_prepare(struct device *dev) +{ + struct mmc_host *host = cls_dev_to_mmc_host(dev); + + /* + * It's safe to access the bus_ops pointer, as both userspace and the + * workqueue for detecting cards are frozen at this point. + */ + if (!host->bus_ops) + return 0; + + /* Validate conditions for system suspend. */ + if (host->bus_ops->pre_suspend) + return host->bus_ops->pre_suspend(host); + + return 0; +} + +static void mmc_host_class_complete(struct device *dev) +{ + struct mmc_host *host = cls_dev_to_mmc_host(dev); + + _mmc_detect_change(host, 0, false); +} + +static const struct dev_pm_ops mmc_host_class_dev_pm_ops = { + .prepare = mmc_host_class_prepare, + .complete = mmc_host_class_complete, +}; + +#define MMC_HOST_CLASS_DEV_PM_OPS (&mmc_host_class_dev_pm_ops) +#else +#define MMC_HOST_CLASS_DEV_PM_OPS NULL +#endif + static void mmc_host_classdev_release(struct device *dev) { struct mmc_host *host = cls_dev_to_mmc_host(dev); @@ -45,6 +81,7 @@ static void mmc_host_classdev_release(st static struct class mmc_host_class = { .name = "mmc_host", .dev_release = mmc_host_classdev_release, + .pm = MMC_HOST_CLASS_DEV_PM_OPS, };
int mmc_register_host_class(void) @@ -493,8 +530,6 @@ int mmc_add_host(struct mmc_host *host) #endif
mmc_start_host(host); - mmc_register_pm_notifier(host); - return 0; }
@@ -510,7 +545,6 @@ EXPORT_SYMBOL(mmc_add_host); */ void mmc_remove_host(struct mmc_host *host) { - mmc_unregister_pm_notifier(host); mmc_stop_host(host);
#ifdef CONFIG_DEBUG_FS --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -985,21 +985,37 @@ out: */ static int mmc_sdio_pre_suspend(struct mmc_host *host) { - int i, err = 0; + int i;
for (i = 0; i < host->card->sdio_funcs; i++) { struct sdio_func *func = host->card->sdio_func[i]; if (func && sdio_func_present(func) && func->dev.driver) { const struct dev_pm_ops *pmops = func->dev.driver->pm; - if (!pmops || !pmops->suspend || !pmops->resume) { + if (!pmops || !pmops->suspend || !pmops->resume) /* force removal of entire card in that case */ - err = -ENOSYS; - break; - } + goto remove; } }
- return err; + return 0; + +remove: + if (!mmc_card_is_removable(host)) { + dev_warn(mmc_dev(host), + "missing suspend/resume ops for non-removable SDIO card\n"); + /* Don't remove a non-removable card - we can't re-detect it. */ + return 0; + } + + /* Remove the SDIO card and let it be re-detected later on. */ + mmc_sdio_remove(host); + mmc_claim_host(host); + mmc_detach_bus(host); + mmc_power_off(host); + mmc_release_host(host); + host->pm_flags = 0; + + return 0; }
/* --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -285,9 +285,6 @@ struct mmc_host { u32 ocr_avail_sdio; /* SDIO-specific OCR */ u32 ocr_avail_sd; /* SD-specific OCR */ u32 ocr_avail_mmc; /* MMC-specific OCR */ -#ifdef CONFIG_PM_SLEEP - struct notifier_block pm_notify; -#endif struct wakeup_source *ws; /* Enable consume of uevents */ u32 max_current_330; u32 max_current_300;
From: He Ying heying24@huawei.com
commit a97709f563a078e259bf0861cd259aa60332890a upstream.
We triggered the following error while running our 4.19 kernel with the pseudo-NMI patches backported to it:
[ 14.816231] ------------[ cut here ]------------ [ 14.816231] kernel BUG at irq.c:99! [ 14.816232] Internal error: Oops - BUG: 0 [#1] SMP [ 14.816232] Process swapper/0 (pid: 0, stack limit = 0x(____ptrval____)) [ 14.816233] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 4.19.95.aarch64 #14 [ 14.816233] Hardware name: evb (DT) [ 14.816234] pstate: 80400085 (Nzcv daIf +PAN -UAO) [ 14.816234] pc : asm_nmi_enter+0x94/0x98 [ 14.816235] lr : asm_nmi_enter+0x18/0x98 [ 14.816235] sp : ffff000008003c50 [ 14.816235] pmr_save: 00000070 [ 14.816237] x29: ffff000008003c50 x28: ffff0000095f56c0 [ 14.816238] x27: 0000000000000000 x26: ffff000008004000 [ 14.816239] x25: 00000000015e0000 x24: ffff8008fb916000 [ 14.816240] x23: 0000000020400005 x22: ffff0000080817cc [ 14.816241] x21: ffff000008003da0 x20: 0000000000000060 [ 14.816242] x19: 00000000000003ff x18: ffffffffffffffff [ 14.816243] x17: 0000000000000008 x16: 003d090000000000 [ 14.816244] x15: ffff0000095ea6c8 x14: ffff8008fff5ab40 [ 14.816244] x13: ffff8008fff58b9d x12: 0000000000000000 [ 14.816245] x11: ffff000008c8a200 x10: 000000008e31fca5 [ 14.816246] x9 : ffff000008c8a208 x8 : 000000000000000f [ 14.816247] x7 : 0000000000000004 x6 : ffff8008fff58b9e [ 14.816248] x5 : 0000000000000000 x4 : 0000000080000000 [ 14.816249] x3 : 0000000000000000 x2 : 0000000080000000 [ 14.816250] x1 : 0000000000120000 x0 : ffff0000095f56c0 [ 14.816251] Call trace: [ 14.816251] asm_nmi_enter+0x94/0x98 [ 14.816251] el1_irq+0x8c/0x180 (IRQ C) [ 14.816252] gic_handle_irq+0xbc/0x2e4 [ 14.816252] el1_irq+0xcc/0x180 (IRQ B) [ 14.816253] arch_timer_handler_virt+0x38/0x58 [ 14.816253] handle_percpu_devid_irq+0x90/0x240 [ 14.816253] generic_handle_irq+0x34/0x50 [ 14.816254] __handle_domain_irq+0x68/0xc0 [ 14.816254] gic_handle_irq+0xf8/0x2e4 [ 14.816255] el1_irq+0xcc/0x180 (IRQ A) [ 14.816255] arch_cpu_idle+0x34/0x1c8 [ 14.816255] default_idle_call+0x24/0x44 [ 14.816256] do_idle+0x1d0/0x2c8 [ 14.816256] cpu_startup_entry+0x28/0x30 [ 14.816256] rest_init+0xb8/0xc8 [ 14.816257] start_kernel+0x4c8/0x4f4 [ 14.816257] Code: 940587f1 d5384100 b9401001 36a7fd01 (d4210000) [ 14.816258] Modules linked in: start_dp(O) smeth(O) [ 15.103092] ---[ end trace 701753956cb14aa8 ]--- [ 15.103093] Kernel panic - not syncing: Fatal exception in interrupt [ 15.103099] SMP: stopping secondary CPUs [ 15.103100] Kernel Offset: disabled [ 15.103100] CPU features: 0x36,a2400218 [ 15.103100] Memory Limit: none
which is cause by a 'BUG_ON(in_nmi())' in nmi_enter().
From the call trace, we can find three interrupts (noted A, B, C above):
interrupt (A) is preempted by (B), which is further interrupted by (C).
Subsequent investigations show that (B) results in nmi_enter() being called, but that it actually is a spurious interrupt. Furthermore, interrupts are reenabled in the context of (B), and (C) fires with NMI priority. We end-up with a nested NMI situation, something we definitely do not want to (and cannot) handle.
The bug here is that spurious interrupts should never result in any state change, and we should just return to the interrupted context. Moving the handling of spurious interrupts as early as possible in the GICv3 handler fixes this issue.
Fixes: 3f1f3234bc2d ("irqchip/gic-v3: Switch to PMR masking before calling IRQ handler") Acked-by: Mark Rutland mark.rutland@arm.com Signed-off-by: He Ying heying24@huawei.com [maz: rewrote commit message, corrected Fixes: tag] Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20210423083516.170111-1-heying24@huawei.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/irqchip/irq-gic-v3.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -648,6 +648,10 @@ static asmlinkage void __exception_irq_e
irqnr = gic_read_iar();
+ /* Check for special IDs first */ + if ((irqnr >= 1020 && irqnr <= 1023)) + return; + if (gic_supports_nmi() && unlikely(gic_read_rpr() == GICD_INT_NMI_PRI)) { gic_handle_nmi(irqnr, regs); @@ -659,10 +663,6 @@ static asmlinkage void __exception_irq_e gic_arch_enable_irqs(); }
- /* Check for special IDs first */ - if ((irqnr >= 1020 && irqnr <= 1023)) - return; - if (static_branch_likely(&supports_deactivate_key)) gic_write_eoir(irqnr); else
From: Paul Aurich paul@darkrain42.org
commit 83728cbf366e334301091d5b808add468ab46b27 upstream.
Avoid a warning if the error percolates back up:
[440700.376476] CIFS VFS: \otters.example.com crypt_message: Could not get encryption key [440700.386947] ------------[ cut here ]------------ [440700.386948] err = 1 [440700.386977] WARNING: CPU: 11 PID: 2733 at /build/linux-hwe-5.4-p6lk6L/linux-hwe-5.4-5.4.0/lib/errseq.c:74 errseq_set+0x5c/0x70 ... [440700.397304] CPU: 11 PID: 2733 Comm: tar Tainted: G OE 5.4.0-70-generic #78~18.04.1-Ubuntu ... [440700.397334] Call Trace: [440700.397346] __filemap_set_wb_err+0x1a/0x70 [440700.397419] cifs_writepages+0x9c7/0xb30 [cifs] [440700.397426] do_writepages+0x4b/0xe0 [440700.397444] __filemap_fdatawrite_range+0xcb/0x100 [440700.397455] filemap_write_and_wait+0x42/0xa0 [440700.397486] cifs_setattr+0x68b/0xf30 [cifs] [440700.397493] notify_change+0x358/0x4a0 [440700.397500] utimes_common+0xe9/0x1c0 [440700.397510] do_utimes+0xc5/0x150 [440700.397520] __x64_sys_utimensat+0x88/0xd0
Fixes: 61cfac6f267d ("CIFS: Fix possible use after free in demultiplex thread") Signed-off-by: Paul Aurich paul@darkrain42.org CC: stable@vger.kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/smb2ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -4076,7 +4076,7 @@ smb2_get_enc_key(struct TCP_Server_Info } spin_unlock(&cifs_tcp_ses_lock);
- return 1; + return -EAGAIN; } /* * Encrypt or decrypt @rqst message. @rqst[0] has the following format:
From: Eugene Korenevsky ekorenevsky@astralinux.ru
commit a637f4ae037e1e0604ac008564934d63261a8fd1 upstream.
If smb3_notify() is called at mount point of CIFS, build_path_from_dentry() returns the pointer to kmalloc-ed memory with terminating zero (this is empty FileName to be passed to SMB2 CREATE request). This pointer is assigned to the `path` variable. Then `path + 1` (to skip first backslash symbol) is passed to cifs_convert_path_to_utf16(). This is incorrect for empty path and causes out-of-bound memory access.
Get rid of this "increase by one". cifs_convert_path_to_utf16() already contains the check for leading backslash in the path.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=212693 CC: stable@vger.kernel.org # v5.6+ Signed-off-by: Eugene Korenevsky ekorenevsky@astralinux.ru Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/smb2ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -2174,7 +2174,7 @@ smb3_notify(const unsigned int xid, stru
cifs_sb = CIFS_SB(inode->i_sb);
- utf16_path = cifs_convert_path_to_utf16(path + 1, cifs_sb); + utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); if (utf16_path == NULL) { rc = -ENOMEM; goto notify_exit;
From: Shyam Prasad N sprasad@microsoft.com
commit f4916649f98e2c7bdba38c6597a98c456c17317d upstream.
We can detect server unresponsiveness only if echoes are enabled. Echoes can be disabled under two scenarios: 1. The connection is low on credits, so we've disabled echoes/oplocks. 2. The connection has not seen any request till now (other than negotiate/sess-setup), which is when we enable these two, based on the credits available.
So this fix will check for dead connection, only when echo is enabled.
Signed-off-by: Shyam Prasad N sprasad@microsoft.com CC: stable@vger.kernel.org # v5.8+ Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/connect.c | 1 + 1 file changed, 1 insertion(+)
--- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -663,6 +663,7 @@ server_unresponsive(struct TCP_Server_In */ if ((server->tcpStatus == CifsGood || server->tcpStatus == CifsNeedNegotiate) && + (!server->ops->can_echo || server->ops->can_echo(server)) && time_after(jiffies, server->lstrp + 3 * server->echo_interval)) { cifs_server_dbg(VFS, "has not responded in %lu seconds. Reconnecting...\n", (3 * server->echo_interval) / HZ);
From: Aurelien Aptel aaptel@suse.com
commit ccd48ec3d4a6cc595b2d9c5146e63b6c23546701 upstream.
* rqst[1,2,3] is allocated in vars * each rqst->rq_iov is also allocated in vars or using pooled memory
SMB2_open_free, SMB2_ioctl_free, SMB2_query_info_free are iterating on each rqst after vars has been freed (use-after-free), and they are freeing the kvec a second time (double-free).
How to trigger:
* compile with KASAN * mount a share
$ smbinfo quota /mnt/foo Segmentation fault $ dmesg
================================================================== BUG: KASAN: use-after-free in SMB2_open_free+0x1c/0xa0 Read of size 8 at addr ffff888007b10c00 by task python3/1200
CPU: 2 PID: 1200 Comm: python3 Not tainted 5.12.0-rc6+ #107 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.14.0-0-g155821a-rebuilt.opensuse.org 04/01/2014 Call Trace: dump_stack+0x93/0xc2 print_address_description.constprop.0+0x18/0x130 ? SMB2_open_free+0x1c/0xa0 ? SMB2_open_free+0x1c/0xa0 kasan_report.cold+0x7f/0x111 ? smb2_ioctl_query_info+0x240/0x990 ? SMB2_open_free+0x1c/0xa0 SMB2_open_free+0x1c/0xa0 smb2_ioctl_query_info+0x2bf/0x990 ? smb2_query_reparse_tag+0x600/0x600 ? cifs_mapchar+0x250/0x250 ? rcu_read_lock_sched_held+0x3f/0x70 ? cifs_strndup_to_utf16+0x12c/0x1c0 ? rwlock_bug.part.0+0x60/0x60 ? rcu_read_lock_sched_held+0x3f/0x70 ? cifs_convert_path_to_utf16+0xf8/0x140 ? smb2_check_message+0x6f0/0x6f0 cifs_ioctl+0xf18/0x16b0 ? smb2_query_reparse_tag+0x600/0x600 ? cifs_readdir+0x1800/0x1800 ? selinux_bprm_creds_for_exec+0x4d0/0x4d0 ? do_user_addr_fault+0x30b/0x950 ? __x64_sys_openat+0xce/0x140 __x64_sys_ioctl+0xb9/0xf0 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7fdcf1f4ba87 Code: b3 66 90 48 8b 05 11 14 2c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e1 13 2c 00 f7 d8 64 89 01 48 RSP: 002b:00007ffef1ce7748 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00000000c018cf07 RCX: 00007fdcf1f4ba87 RDX: 0000564c467c5590 RSI: 00000000c018cf07 RDI: 0000000000000003 RBP: 00007ffef1ce7770 R08: 00007ffef1ce7420 R09: 00007fdcf0e0562b R10: 0000000000000100 R11: 0000000000000246 R12: 0000000000004018 R13: 0000000000000001 R14: 0000000000000003 R15: 0000564c467c5590
Allocated by task 1200: kasan_save_stack+0x1b/0x40 __kasan_kmalloc+0x7a/0x90 smb2_ioctl_query_info+0x10e/0x990 cifs_ioctl+0xf18/0x16b0 __x64_sys_ioctl+0xb9/0xf0 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xae
Freed by task 1200: kasan_save_stack+0x1b/0x40 kasan_set_track+0x1c/0x30 kasan_set_free_info+0x20/0x30 __kasan_slab_free+0xe5/0x110 slab_free_freelist_hook+0x53/0x130 kfree+0xcc/0x320 smb2_ioctl_query_info+0x2ad/0x990 cifs_ioctl+0xf18/0x16b0 __x64_sys_ioctl+0xb9/0xf0 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xae
The buggy address belongs to the object at ffff888007b10c00 which belongs to the cache kmalloc-512 of size 512 The buggy address is located 0 bytes inside of 512-byte region [ffff888007b10c00, ffff888007b10e00) The buggy address belongs to the page: page:0000000044e14b75 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x7b10 head:0000000044e14b75 order:2 compound_mapcount:0 compound_pincount:0 flags: 0x100000000010200(slab|head) raw: 0100000000010200 ffffea000015f500 0000000400000004 ffff888001042c80 raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff888007b10b00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff888007b10b80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff888007b10c00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^ ffff888007b10c80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888007b10d00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ==================================================================
Signed-off-by: Aurelien Aptel aaptel@suse.com CC: stable@vger.kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/smb2ops.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
--- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -1705,18 +1705,14 @@ smb2_ioctl_query_info(const unsigned int }
iqinf_exit: - kfree(vars); - kfree(buffer); - SMB2_open_free(&rqst[0]); - if (qi.flags & PASSTHRU_FSCTL) - SMB2_ioctl_free(&rqst[1]); - else - SMB2_query_info_free(&rqst[1]); - - SMB2_close_free(&rqst[2]); + cifs_small_buf_release(rqst[0].rq_iov[0].iov_base); + cifs_small_buf_release(rqst[1].rq_iov[0].iov_base); + cifs_small_buf_release(rqst[2].rq_iov[0].iov_base); free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); + kfree(vars); + kfree(buffer); return rc;
e_fault:
From: Qu Wenruo wqu@suse.com
commit 1d8ba9e7e785b6625f4d8e978e8a284b144a7077 upstream.
[BUG] When running btrfs/071 with inode_need_compress() removed from compress_file_range(), we got the following crash:
BUG: kernel NULL pointer dereference, address: 0000000000000018 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page Workqueue: btrfs-delalloc btrfs_work_helper [btrfs] RIP: 0010:compress_file_range+0x476/0x7b0 [btrfs] Call Trace: ? submit_compressed_extents+0x450/0x450 [btrfs] async_cow_start+0x16/0x40 [btrfs] btrfs_work_helper+0xf2/0x3e0 [btrfs] process_one_work+0x278/0x5e0 worker_thread+0x55/0x400 ? process_one_work+0x5e0/0x5e0 kthread+0x168/0x190 ? kthread_create_worker_on_cpu+0x70/0x70 ret_from_fork+0x22/0x30 ---[ end trace 65faf4eae941fa7d ]---
This is already after the patch "btrfs: inode: fix NULL pointer dereference if inode doesn't need compression."
[CAUSE] @pages is firstly created by kcalloc() in compress_file_extent(): pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
Then passed to btrfs_compress_pages() to be utilized there:
ret = btrfs_compress_pages(... pages, &nr_pages, ...);
btrfs_compress_pages() will initialize each page as output, in zlib_compress_pages() we have:
pages[nr_pages] = out_page; nr_pages++;
Normally this is completely fine, but there is a special case which is in btrfs_compress_pages() itself:
switch (type) { default: return -E2BIG; }
In this case, we didn't modify @pages nor @out_pages, leaving them untouched, then when we cleanup pages, the we can hit NULL pointer dereference again:
if (pages) { for (i = 0; i < nr_pages; i++) { WARN_ON(pages[i]->mapping); put_page(pages[i]); } ... }
Since pages[i] are all initialized to zero, and btrfs_compress_pages() doesn't change them at all, accessing pages[i]->mapping would lead to NULL pointer dereference.
This is not possible for current kernel, as we check inode_need_compress() before doing pages allocation. But if we're going to remove that inode_need_compress() in compress_file_extent(), then it's going to be a problem.
[FIX] When btrfs_compress_pages() hits its default case, modify @out_pages to 0 to prevent such problem from happening.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=212331 CC: stable@vger.kernel.org # 5.10+ Reviewed-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Qu Wenruo wqu@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/compression.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
--- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -80,10 +80,15 @@ static int compression_compress_pages(in case BTRFS_COMPRESS_NONE: default: /* - * This can't happen, the type is validated several times - * before we get here. As a sane fallback, return what the - * callers will understand as 'no compression happened'. + * This can happen when compression races with remount setting + * it to 'no compress', while caller doesn't call + * inode_need_compress() to check if we really need to + * compress. + * + * Not a big deal, just need to inform caller that we + * haven't allocated any pages yet. */ + *out_pages = 0; return -E2BIG; } }
From: Maciej W. Rozycki macro@orcam.me.uk
commit 0ef3439cd80ba7770723edb0470d15815914bb62 upstream.
Fix a regression caused by making the 486SX separately selectable in Kconfig, for which the HIGHMEM64G setting has not been updated and therefore has become exposed as a user-selectable option for the M486SX configuration setting unlike with original M486 and all the other settings that choose non-PAE-enabled processors:
High Memory Support
- off (NOHIGHMEM)
2. 4GB (HIGHMEM4G) 3. 64GB (HIGHMEM64G) choice[1-3?]:
With the fix in place the setting is now correctly removed:
High Memory Support
- off (NOHIGHMEM)
2. 4GB (HIGHMEM4G) choice[1-2?]:
[ bp: Massage commit message. ]
Fixes: 87d6021b8143 ("x86/math-emu: Limit MATH_EMULATION to 486SX compatibles") Signed-off-by: Maciej W. Rozycki macro@orcam.me.uk Signed-off-by: Borislav Petkov bp@suse.de Cc: stable@vger.kernel.org # v5.5+ Link: https://lkml.kernel.org/r/alpine.DEB.2.21.2104141221340.44318@angie.orcam.me... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1414,7 +1414,7 @@ config HIGHMEM4G
config HIGHMEM64G bool "64GB" - depends on !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6 + depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6 select X86_PAE help Select this if you have a 32-bit processor and more than 4
From: Filipe Manana fdmanana@suse.com
commit 67addf29004c5be9fa0383c82a364bb59afc7f84 upstream.
When creating a subvolume we allocate an extent buffer for its root node after starting a transaction. We setup a root item for the subvolume that points to that extent buffer and then attempt to insert the root item into the root tree - however if that fails, due to ENOMEM for example, we do not free the extent buffer previously allocated and we do not abort the transaction (as at that point we did nothing that can not be undone).
This means that we effectively do not return the metadata extent back to the free space cache/tree and we leave a delayed reference for it which causes a metadata extent item to be added to the extent tree, in the next transaction commit, without having backreferences. When this happens 'btrfs check' reports the following:
$ btrfs check /dev/sdi Opening filesystem to check... Checking filesystem on /dev/sdi UUID: dce2cb9d-025f-4b05-a4bf-cee0ad3785eb [1/7] checking root items [2/7] checking extents ref mismatch on [30425088 16384] extent item 1, found 0 backref 30425088 root 256 not referenced back 0x564a91c23d70 incorrect global backref count on 30425088 found 1 wanted 0 backpointer mismatch on [30425088 16384] owner ref check failed [30425088 16384] ERROR: errors found in extent allocation tree or chunk allocation [3/7] checking free space cache [4/7] checking fs roots [5/7] checking only csums items (without verifying data) [6/7] checking root refs [7/7] checking quota groups skipped (not enabled on this FS) found 212992 bytes used, error(s) found total csum bytes: 0 total tree bytes: 131072 total fs tree bytes: 32768 total extent tree bytes: 16384 btree space waste bytes: 124669 file data blocks allocated: 65536 referenced 65536
So fix this by freeing the metadata extent if btrfs_insert_root() returns an error.
CC: stable@vger.kernel.org # 4.4+ Signed-off-by: Filipe Manana fdmanana@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/ioctl.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
--- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -678,8 +678,6 @@ static noinline int create_subvol(struct btrfs_set_root_otransid(root_item, trans->transid);
btrfs_tree_unlock(leaf); - free_extent_buffer(leaf); - leaf = NULL;
btrfs_set_root_dirid(root_item, new_dirid);
@@ -688,8 +686,22 @@ static noinline int create_subvol(struct key.type = BTRFS_ROOT_ITEM_KEY; ret = btrfs_insert_root(trans, fs_info->tree_root, &key, root_item); - if (ret) + if (ret) { + /* + * Since we don't abort the transaction in this case, free the + * tree block so that we don't leak space and leave the + * filesystem in an inconsistent state (an extent item in the + * extent tree without backreferences). Also no need to have + * the tree block locked since it is not in any tree at this + * point, so no other task can find it and use it. + */ + btrfs_free_tree_block(trans, root, leaf, 0, 1); + free_extent_buffer(leaf); goto fail; + } + + free_extent_buffer(leaf); + leaf = NULL;
key.offset = (u64)-1; new_root = btrfs_get_new_fs_root(fs_info, objectid, anon_dev);
From: Alexander Shishkin alexander.shishkin@linux.intel.com
commit 9f7f2a5e01ab4ee56b6d9c0572536fe5fd56e376 upstream.
This adds support for the Trace Hub in Rocket Lake CPUs.
Signed-off-by: Alexander Shishkin alexander.shishkin@linux.intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: stable stable@vger.kernel.org # v4.14+ Link: https://lore.kernel.org/r/20210414171251.14672-7-alexander.shishkin@linux.in... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -278,6 +278,11 @@ static const struct pci_device_id intel_ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f), .driver_data = (kernel_ulong_t)&intel_th_2x, }, + { + /* Rocket Lake CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4c19), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, { 0 }, };
From: Filipe Manana fdmanana@suse.com
commit 061dde8245356d8864d29e25207aa4daa0be4d3c upstream.
There is a race between a task aborting a transaction during a commit, a task doing an fsync and the transaction kthread, which leads to an use-after-free of the log root tree. When this happens, it results in a stack trace like the following:
BTRFS info (device dm-0): forced readonly BTRFS warning (device dm-0): Skipping commit of aborted transaction. BTRFS: error (device dm-0) in cleanup_transaction:1958: errno=-5 IO failure BTRFS warning (device dm-0): lost page write due to IO error on /dev/mapper/error-test (-5) BTRFS warning (device dm-0): Skipping commit of aborted transaction. BTRFS warning (device dm-0): direct IO failed ino 261 rw 0,0 sector 0xa4e8 len 4096 err no 10 BTRFS error (device dm-0): error writing primary super block to device 1 BTRFS warning (device dm-0): direct IO failed ino 261 rw 0,0 sector 0x12e000 len 4096 err no 10 BTRFS warning (device dm-0): direct IO failed ino 261 rw 0,0 sector 0x12e008 len 4096 err no 10 BTRFS warning (device dm-0): direct IO failed ino 261 rw 0,0 sector 0x12e010 len 4096 err no 10 BTRFS: error (device dm-0) in write_all_supers:4110: errno=-5 IO failure (1 errors while writing supers) BTRFS: error (device dm-0) in btrfs_sync_log:3308: errno=-5 IO failure general protection fault, probably for non-canonical address 0x6b6b6b6b6b6b6b68: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC PTI CPU: 2 PID: 2458471 Comm: fsstress Not tainted 5.12.0-rc5-btrfs-next-84 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 RIP: 0010:__mutex_lock+0x139/0xa40 Code: c0 74 19 (...) RSP: 0018:ffff9f18830d7b00 EFLAGS: 00010202 RAX: 6b6b6b6b6b6b6b68 RBX: 0000000000000001 RCX: 0000000000000002 RDX: ffffffffb9c54d13 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffff9f18830d7bc0 R08: 0000000000000000 R09: 0000000000000000 R10: ffff9f18830d7be0 R11: 0000000000000001 R12: ffff8c6cd199c040 R13: ffff8c6c95821358 R14: 00000000fffffffb R15: ffff8c6cbcf01358 FS: 00007fa9140c2b80(0000) GS:ffff8c6fac600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fa913d52000 CR3: 000000013d2b4003 CR4: 0000000000370ee0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: ? __btrfs_handle_fs_error+0xde/0x146 [btrfs] ? btrfs_sync_log+0x7c1/0xf20 [btrfs] ? btrfs_sync_log+0x7c1/0xf20 [btrfs] btrfs_sync_log+0x7c1/0xf20 [btrfs] btrfs_sync_file+0x40c/0x580 [btrfs] do_fsync+0x38/0x70 __x64_sys_fsync+0x10/0x20 do_syscall_64+0x33/0x80 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7fa9142a55c3 Code: 8b 15 09 (...) RSP: 002b:00007fff26278d48 EFLAGS: 00000246 ORIG_RAX: 000000000000004a RAX: ffffffffffffffda RBX: 0000563c83cb4560 RCX: 00007fa9142a55c3 RDX: 00007fff26278cb0 RSI: 00007fff26278cb0 RDI: 0000000000000005 RBP: 0000000000000005 R08: 0000000000000001 R09: 00007fff26278d5c R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000340 R13: 00007fff26278de0 R14: 00007fff26278d96 R15: 0000563c83ca57c0 Modules linked in: btrfs dm_zero dm_snapshot dm_thin_pool (...) ---[ end trace ee2f1b19327d791d ]---
The steps that lead to this crash are the following:
1) We are at transaction N;
2) We have two tasks with a transaction handle attached to transaction N. Task A and Task B. Task B is doing an fsync;
3) Task B is at btrfs_sync_log(), and has saved fs_info->log_root_tree into a local variable named 'log_root_tree' at the top of btrfs_sync_log(). Task B is about to call write_all_supers(), but before that...
4) Task A calls btrfs_commit_transaction(), and after it sets the transaction state to TRANS_STATE_COMMIT_START, an error happens before it waits for the transaction's 'num_writers' counter to reach a value of 1 (no one else attached to the transaction), so it jumps to the label "cleanup_transaction";
5) Task A then calls cleanup_transaction(), where it aborts the transaction, setting BTRFS_FS_STATE_TRANS_ABORTED on fs_info->fs_state, setting the ->aborted field of the transaction and the handle to an errno value and also setting BTRFS_FS_STATE_ERROR on fs_info->fs_state.
After that, at cleanup_transaction(), it deletes the transaction from the list of transactions (fs_info->trans_list), sets the transaction to the state TRANS_STATE_COMMIT_DOING and then waits for the number of writers to go down to 1, as it's currently 2 (1 for task A and 1 for task B);
6) The transaction kthread is running and sees that BTRFS_FS_STATE_ERROR is set in fs_info->fs_state, so it calls btrfs_cleanup_transaction().
There it sees the list fs_info->trans_list is empty, and then proceeds into calling btrfs_drop_all_logs(), which frees the log root tree with a call to btrfs_free_log_root_tree();
7) Task B calls write_all_supers() and, shortly after, under the label 'out_wake_log_root', it deferences the pointer stored in 'log_root_tree', which was already freed in the previous step by the transaction kthread. This results in a use-after-free leading to a crash.
Fix this by deleting the transaction from the list of transactions at cleanup_transaction() only after setting the transaction state to TRANS_STATE_COMMIT_DOING and waiting for all existing tasks that are attached to the transaction to release their transaction handles. This makes the transaction kthread wait for all the tasks attached to the transaction to be done with the transaction before dropping the log roots and doing other cleanups.
Fixes: ef67963dac255b ("btrfs: drop logs when we've aborted a transaction") CC: stable@vger.kernel.org # 5.10+ Reviewed-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/transaction.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
--- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1950,7 +1950,6 @@ static void cleanup_transaction(struct b */ BUG_ON(list_empty(&cur_trans->list));
- list_del_init(&cur_trans->list); if (cur_trans == fs_info->running_transaction) { cur_trans->state = TRANS_STATE_COMMIT_DOING; spin_unlock(&fs_info->trans_lock); @@ -1959,6 +1958,17 @@ static void cleanup_transaction(struct b
spin_lock(&fs_info->trans_lock); } + + /* + * Now that we know no one else is still using the transaction we can + * remove the transaction from the list of transactions. This avoids + * the transaction kthread from cleaning up the transaction while some + * other task is still using it, which could result in a use-after-free + * on things like log trees, as it forces the transaction kthread to + * wait for this transaction to be cleaned up by us. + */ + list_del_init(&cur_trans->list); + spin_unlock(&fs_info->trans_lock);
btrfs_cleanup_one_transaction(trans->transaction, fs_info);
From: Chen Jun chenjun102@huawei.com
commit 2d036dfa5f10df9782f5278fc591d79d283c1fad upstream.
The return value on success (>= 0) is overwritten by the return value of put_old_timex32(). That works correct in the fault case, but is wrong for the success case where put_old_timex32() returns 0.
Just check the return value of put_old_timex32() and return -EFAULT in case it is not zero.
[ tglx: Massage changelog ]
Fixes: 3a4d44b61625 ("ntp: Move adjtimex related compat syscalls to native counterparts") Signed-off-by: Chen Jun chenjun102@huawei.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Richard Cochran richardcochran@gmail.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210414030449.90692-1-chenjun102@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/time/posix-timers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -1191,8 +1191,8 @@ SYSCALL_DEFINE2(clock_adjtime32, clockid
err = do_clock_adjtime(which_clock, &ktx);
- if (err >= 0) - err = put_old_timex32(utp, &ktx); + if (err >= 0 && put_old_timex32(utp, &ktx)) + return -EFAULT;
return err; }
From: Phillip Potter phil@philpotter.co.uk
commit 19ab233989d0f7ab1de19a036e247afa4a0a1e9c upstream.
Use kzalloc() rather than kmalloc() for the dynamically allocated parts of the colormap in fb_alloc_cmap_gfp, to prevent a leak of random kernel data to userspace under certain circumstances.
Fixes a KMSAN-found infoleak bug reported by syzbot at: https://syzkaller.appspot.com/bug?id=741578659feabd108ad9e06696f0c1f2e69c4b6...
Reported-by: syzbot+47fa9c9c648b765305b9@syzkaller.appspotmail.com Cc: stable stable@vger.kernel.org Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Phillip Potter phil@philpotter.co.uk Link: https://lore.kernel.org/r/20210331220719.1499743-1-phil@philpotter.co.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/video/fbdev/core/fbcmap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/video/fbdev/core/fbcmap.c +++ b/drivers/video/fbdev/core/fbcmap.c @@ -101,17 +101,17 @@ int fb_alloc_cmap_gfp(struct fb_cmap *cm if (!len) return 0;
- cmap->red = kmalloc(size, flags); + cmap->red = kzalloc(size, flags); if (!cmap->red) goto fail; - cmap->green = kmalloc(size, flags); + cmap->green = kzalloc(size, flags); if (!cmap->green) goto fail; - cmap->blue = kmalloc(size, flags); + cmap->blue = kzalloc(size, flags); if (!cmap->blue) goto fail; if (transp) { - cmap->transp = kmalloc(size, flags); + cmap->transp = kzalloc(size, flags); if (!cmap->transp) goto fail; } else {
From: Dmitry Osipenko digetx@gmail.com
commit 32c8c34d8132b5fe8497c2538597445a0d65c29d upstream.
Trusted Foundation firmware doesn't implement the do_idle call and in this case suspending should fall back to the common suspend path. In order to fix this issue we will unconditionally set the NOFLUSH_L2 mode via firmware call, which is a NO-OP on Tegra30/124, and then proceed to the C7 idling, like it was done by the older Tegra114 cpuidle driver.
Fixes: 14e086baca50 ("cpuidle: tegra: Squash Tegra114 driver into the common driver") Cc: stable@vger.kernel.org # 5.7+ Reported-by: Anton Bambura jenneron@protonmail.com # TF701 T114 Tested-by: Anton Bambura jenneron@protonmail.com # TF701 T114 Tested-by: Matt Merhar mattmerhar@protonmail.com # Ouya T30 Tested-by: Peter Geis pgwipeout@gmail.com # Ouya T30 Signed-off-by: Dmitry Osipenko digetx@gmail.com Reviewed-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/20210302095405.28453-1-digetx@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/cpuidle/cpuidle-tegra.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/cpuidle/cpuidle-tegra.c +++ b/drivers/cpuidle/cpuidle-tegra.c @@ -135,13 +135,13 @@ static int tegra_cpuidle_c7_enter(void) { int err;
- if (tegra_cpuidle_using_firmware()) { - err = call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2); - if (err) - return err; + err = call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2); + if (err && err != -ENOSYS) + return err;
- return call_firmware_op(do_idle, 0); - } + err = call_firmware_op(do_idle, 0); + if (err != -ENOSYS) + return err;
return cpu_suspend(0, tegra30_pm_secondary_cpu_suspend); }
From: Tony Lindgren tony@atomide.com
[ Upstream commit 4700a00755fb5a4bb5109128297d6fd2d1272ee6 ]
We want to probe l4_wkup and l4_cfg interconnect devices first to avoid issues with missing resources. Otherwise we attempt to probe l4_per devices first causing pointless deferred probe and also annoyingh renumbering of the MMC devices for example.
Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/ti-sysc.c | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 16e389dce111..9afbe4992a1d 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -635,6 +635,51 @@ static int sysc_parse_and_check_child_range(struct sysc *ddata) return 0; }
+/* Interconnect instances to probe before l4_per instances */ +static struct resource early_bus_ranges[] = { + /* am3/4 l4_wkup */ + { .start = 0x44c00000, .end = 0x44c00000 + 0x300000, }, + /* omap4/5 and dra7 l4_cfg */ + { .start = 0x4a000000, .end = 0x4a000000 + 0x300000, }, + /* omap4 l4_wkup */ + { .start = 0x4a300000, .end = 0x4a300000 + 0x30000, }, + /* omap5 and dra7 l4_wkup without dra7 dcan segment */ + { .start = 0x4ae00000, .end = 0x4ae00000 + 0x30000, }, +}; + +static atomic_t sysc_defer = ATOMIC_INIT(10); + +/** + * sysc_defer_non_critical - defer non_critical interconnect probing + * @ddata: device driver data + * + * We want to probe l4_cfg and l4_wkup interconnect instances before any + * l4_per instances as l4_per instances depend on resources on l4_cfg and + * l4_wkup interconnects. + */ +static int sysc_defer_non_critical(struct sysc *ddata) +{ + struct resource *res; + int i; + + if (!atomic_read(&sysc_defer)) + return 0; + + for (i = 0; i < ARRAY_SIZE(early_bus_ranges); i++) { + res = &early_bus_ranges[i]; + if (ddata->module_pa >= res->start && + ddata->module_pa <= res->end) { + atomic_set(&sysc_defer, 0); + + return 0; + } + } + + atomic_dec_if_positive(&sysc_defer); + + return -EPROBE_DEFER; +} + static struct device_node *stdout_path;
static void sysc_init_stdout_path(struct sysc *ddata) @@ -859,6 +904,10 @@ static int sysc_map_and_check_registers(struct sysc *ddata) if (error) return error;
+ error = sysc_defer_non_critical(ddata); + if (error) + return error; + sysc_check_children(ddata);
error = sysc_parse_registers(ddata);
From: karthik alapati mail@karthek.com
[ Upstream commit 0c37baae130df39b19979bba88bde2ee70a33355 ]
fix sparse byte-order warnings by converting host byte-order type to __le16 byte-order types before assigning to hdr.length
Signed-off-by: karthik alapati mail@karthek.com Link: https://lore.kernel.org/r/0ae5c5c4c646506d8be871e7be5705542671a1d5.161392127... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wimax/i2400m/op-rfkill.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wimax/i2400m/op-rfkill.c b/drivers/net/wimax/i2400m/op-rfkill.c index 5c79f052cad2..34f81f16b5a0 100644 --- a/drivers/net/wimax/i2400m/op-rfkill.c +++ b/drivers/net/wimax/i2400m/op-rfkill.c @@ -86,7 +86,7 @@ int i2400m_op_rfkill_sw_toggle(struct wimax_dev *wimax_dev, if (cmd == NULL) goto error_alloc; cmd->hdr.type = cpu_to_le16(I2400M_MT_CMD_RF_CONTROL); - cmd->hdr.length = sizeof(cmd->sw_rf); + cmd->hdr.length = cpu_to_le16(sizeof(cmd->sw_rf)); cmd->hdr.version = cpu_to_le16(I2400M_L3L4_VERSION); cmd->sw_rf.hdr.type = cpu_to_le16(I2400M_TLV_RF_OPERATION); cmd->sw_rf.hdr.length = cpu_to_le16(sizeof(cmd->sw_rf.status));
From: David Bauer mail@david-bauer.net
[ Upstream commit 19e2132174583beb90c1bd3e9c842bc6d5c944d1 ]
spi-bitbang has to call the chipselect function on the ath79 SPI driver in order to communicate with the SPI slave device, as the ath79 SPI driver has three dedicated chipselect lines but can also be used with GPIOs for the CS lines.
Fixes commit 4a07b8bcd503 ("spi: bitbang: Make chipselect callback optional")
Signed-off-by: David Bauer mail@david-bauer.net Link: https://lore.kernel.org/r/20210303160837.165771-1-mail@david-bauer.net Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-ath79.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index eb9a243e9526..436327fb58de 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -158,6 +158,7 @@ static int ath79_spi_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); master->setup = spi_bitbang_setup; master->cleanup = spi_bitbang_cleanup; + master->flags = SPI_MASTER_GPIO_SS; if (pdata) { master->bus_num = pdata->bus_num; master->num_chipselect = pdata->num_chipselect;
From: David Bauer mail@david-bauer.net
[ Upstream commit ffb597b2bd3cd78b9bfb68f536743cd46dbb2cc4 ]
This removes the assignment of setup and cleanup functions for the ath79 target. Assigning the setup-method will lead to 'setup_transfer' not being assigned in spi_bitbang_init. Because of this, performing any TX/RX operation will lead to a kernel oops.
Also drop the redundant cleanup assignment, as it's also assigned in spi_bitbang_init.
Signed-off-by: David Bauer mail@david-bauer.net Link: https://lore.kernel.org/r/20210303160837.165771-2-mail@david-bauer.net Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-ath79.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 436327fb58de..98ace748cd98 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c @@ -156,8 +156,6 @@ static int ath79_spi_probe(struct platform_device *pdev)
master->use_gpio_descriptors = true; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); - master->setup = spi_bitbang_setup; - master->cleanup = spi_bitbang_cleanup; master->flags = SPI_MASTER_GPIO_SS; if (pdata) { master->bus_num = pdata->bus_num;
From: Bhaumik Bhatt bbhatt@codeaurora.org
[ Upstream commit 925089c1900f588615db5bf4e1d9064a5f2c18c7 ]
Currently, client devices are created in SBL or AMSS (mission mode) and only destroyed after power down or SYS ERROR. When moving between certain execution environments, such as from SBL to AMSS, no clean-up is required. This presents an issue where SBL-specific channels are left open and client drivers now run in an execution environment where they cannot operate. Fix this by expanding the mhi_destroy_device() to do an execution environment specific clean-up if one is requested. Close the gap and destroy devices in such scenarios that allow SBL client drivers to clean up once device enters mission mode.
Signed-off-by: Bhaumik Bhatt bbhatt@codeaurora.org Reviewed-by: Loic Poulain loic.poulain@linaro.org Reviewed-by: Hemant Kumar hemantk@codeaurora.org Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Link: https://lore.kernel.org/r/1614208985-20851-2-git-send-email-bbhatt@codeauror... Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/mhi/core/main.c | 29 +++++++++++++++++++++++++---- drivers/bus/mhi/core/pm.c | 3 +++ 2 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c index f46f772e2557..d86ce1a06b75 100644 --- a/drivers/bus/mhi/core/main.c +++ b/drivers/bus/mhi/core/main.c @@ -227,8 +227,10 @@ static bool is_valid_ring_ptr(struct mhi_ring *ring, dma_addr_t addr)
int mhi_destroy_device(struct device *dev, void *data) { + struct mhi_chan *ul_chan, *dl_chan; struct mhi_device *mhi_dev; struct mhi_controller *mhi_cntrl; + enum mhi_ee_type ee = MHI_EE_MAX;
if (dev->bus != &mhi_bus_type) return 0; @@ -240,6 +242,17 @@ int mhi_destroy_device(struct device *dev, void *data) if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) return 0;
+ ul_chan = mhi_dev->ul_chan; + dl_chan = mhi_dev->dl_chan; + + /* + * If execution environment is specified, remove only those devices that + * started in them based on ee_mask for the channels as we move on to a + * different execution environment + */ + if (data) + ee = *(enum mhi_ee_type *)data; + /* * For the suspend and resume case, this function will get called * without mhi_unregister_controller(). Hence, we need to drop the @@ -247,11 +260,19 @@ int mhi_destroy_device(struct device *dev, void *data) * be sure that there will be no instances of mhi_dev left after * this. */ - if (mhi_dev->ul_chan) - put_device(&mhi_dev->ul_chan->mhi_dev->dev); + if (ul_chan) { + if (ee != MHI_EE_MAX && !(ul_chan->ee_mask & BIT(ee))) + return 0;
- if (mhi_dev->dl_chan) - put_device(&mhi_dev->dl_chan->mhi_dev->dev); + put_device(&ul_chan->mhi_dev->dev); + } + + if (dl_chan) { + if (ee != MHI_EE_MAX && !(dl_chan->ee_mask & BIT(ee))) + return 0; + + put_device(&dl_chan->mhi_dev->dev); + }
dev_dbg(&mhi_cntrl->mhi_dev->dev, "destroy device for chan:%s\n", mhi_dev->name); diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c index ce2aafe33d53..aeb895c08460 100644 --- a/drivers/bus/mhi/core/pm.c +++ b/drivers/bus/mhi/core/pm.c @@ -376,6 +376,7 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) { struct mhi_event *mhi_event; struct device *dev = &mhi_cntrl->mhi_dev->dev; + enum mhi_ee_type current_ee = mhi_cntrl->ee; int i, ret;
dev_dbg(dev, "Processing Mission Mode transition\n"); @@ -390,6 +391,8 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl)
wake_up_all(&mhi_cntrl->state_event);
+ device_for_each_child(&mhi_cntrl->mhi_dev->dev, ¤t_ee, + mhi_destroy_device); mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_MISSION_MODE);
/* Force MHI to be in M0 state before continuing */
From: Ard Biesheuvel ardb@kernel.org
[ Upstream commit 83681f2bebb34dbb3f03fecd8f570308ab8b7c2c ]
Given that crypto_alloc_tfm() may return ERR pointers, and to avoid crashes on obscure error paths where such pointers are presented to crypto_destroy_tfm() (such as [0]), add an ERR_PTR check there before dereferencing the second argument as a struct crypto_tfm pointer.
[0] https://lore.kernel.org/linux-crypto/000000000000de949705bc59e0f6@google.com...
Reported-by: syzbot+12cf5fbfdeba210a89dd@syzkaller.appspotmail.com Reviewed-by: Eric Biggers ebiggers@google.com Signed-off-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/api.c | 2 +- include/crypto/acompress.h | 2 ++ include/crypto/aead.h | 2 ++ include/crypto/akcipher.h | 2 ++ include/crypto/hash.h | 4 ++++ include/crypto/kpp.h | 2 ++ include/crypto/rng.h | 2 ++ include/crypto/skcipher.h | 2 ++ 8 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/crypto/api.c b/crypto/api.c index ed08cbd5b9d3..c4eda56cff89 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -562,7 +562,7 @@ void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm) { struct crypto_alg *alg;
- if (unlikely(!mem)) + if (IS_ERR_OR_NULL(mem)) return;
alg = tfm->__crt_alg; diff --git a/include/crypto/acompress.h b/include/crypto/acompress.h index fcde59c65a81..cb3d6b1c655d 100644 --- a/include/crypto/acompress.h +++ b/include/crypto/acompress.h @@ -165,6 +165,8 @@ static inline struct crypto_acomp *crypto_acomp_reqtfm(struct acomp_req *req) * crypto_free_acomp() -- free ACOMPRESS tfm handle * * @tfm: ACOMPRESS tfm handle allocated with crypto_alloc_acomp() + * + * If @tfm is a NULL or error pointer, this function does nothing. */ static inline void crypto_free_acomp(struct crypto_acomp *tfm) { diff --git a/include/crypto/aead.h b/include/crypto/aead.h index c32a6f5664e9..fe956629f34c 100644 --- a/include/crypto/aead.h +++ b/include/crypto/aead.h @@ -185,6 +185,8 @@ static inline struct crypto_tfm *crypto_aead_tfm(struct crypto_aead *tfm) /** * crypto_free_aead() - zeroize and free aead handle * @tfm: cipher handle to be freed + * + * If @tfm is a NULL or error pointer, this function does nothing. */ static inline void crypto_free_aead(struct crypto_aead *tfm) { diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h index 1d3aa252caba..5764b46bd1ec 100644 --- a/include/crypto/akcipher.h +++ b/include/crypto/akcipher.h @@ -174,6 +174,8 @@ static inline struct crypto_akcipher *crypto_akcipher_reqtfm( * crypto_free_akcipher() - free AKCIPHER tfm handle * * @tfm: AKCIPHER tfm handle allocated with crypto_alloc_akcipher() + * + * If @tfm is a NULL or error pointer, this function does nothing. */ static inline void crypto_free_akcipher(struct crypto_akcipher *tfm) { diff --git a/include/crypto/hash.h b/include/crypto/hash.h index 13f8a6a54ca8..b2bc1e46e86a 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -281,6 +281,8 @@ static inline struct crypto_tfm *crypto_ahash_tfm(struct crypto_ahash *tfm) /** * crypto_free_ahash() - zeroize and free the ahash handle * @tfm: cipher handle to be freed + * + * If @tfm is a NULL or error pointer, this function does nothing. */ static inline void crypto_free_ahash(struct crypto_ahash *tfm) { @@ -724,6 +726,8 @@ static inline struct crypto_tfm *crypto_shash_tfm(struct crypto_shash *tfm) /** * crypto_free_shash() - zeroize and free the message digest handle * @tfm: cipher handle to be freed + * + * If @tfm is a NULL or error pointer, this function does nothing. */ static inline void crypto_free_shash(struct crypto_shash *tfm) { diff --git a/include/crypto/kpp.h b/include/crypto/kpp.h index 88b591215d5c..cccceadc164b 100644 --- a/include/crypto/kpp.h +++ b/include/crypto/kpp.h @@ -154,6 +154,8 @@ static inline void crypto_kpp_set_flags(struct crypto_kpp *tfm, u32 flags) * crypto_free_kpp() - free KPP tfm handle * * @tfm: KPP tfm handle allocated with crypto_alloc_kpp() + * + * If @tfm is a NULL or error pointer, this function does nothing. */ static inline void crypto_free_kpp(struct crypto_kpp *tfm) { diff --git a/include/crypto/rng.h b/include/crypto/rng.h index 8b4b844b4eef..17bb3673d3c1 100644 --- a/include/crypto/rng.h +++ b/include/crypto/rng.h @@ -111,6 +111,8 @@ static inline struct rng_alg *crypto_rng_alg(struct crypto_rng *tfm) /** * crypto_free_rng() - zeroize and free RNG handle * @tfm: cipher handle to be freed + * + * If @tfm is a NULL or error pointer, this function does nothing. */ static inline void crypto_free_rng(struct crypto_rng *tfm) { diff --git a/include/crypto/skcipher.h b/include/crypto/skcipher.h index 6a733b171a5d..ef0fc9ed4342 100644 --- a/include/crypto/skcipher.h +++ b/include/crypto/skcipher.h @@ -196,6 +196,8 @@ static inline struct crypto_tfm *crypto_skcipher_tfm( /** * crypto_free_skcipher() - zeroize and free cipher handle * @tfm: cipher handle to be freed + * + * If @tfm is a NULL or error pointer, this function does nothing. */ static inline void crypto_free_skcipher(struct crypto_skcipher *tfm) {
From: Hui Tang tanghui20@huawei.com
[ Upstream commit 792b32fad548281e1b7fe14df9063a96c54b32a2 ]
'dma_mapping_error' return a negative value if 'dma_addr' is equal to 'DMA_MAPPING_ERROR' not zero, so fix initialization of 'dma_addr'.
Signed-off-by: Hui Tang tanghui20@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_common/qat_algs.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c index d552dbcfe0a0..06abe1e2074e 100644 --- a/drivers/crypto/qat/qat_common/qat_algs.c +++ b/drivers/crypto/qat/qat_common/qat_algs.c @@ -670,7 +670,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, struct qat_alg_buf_list *bufl; struct qat_alg_buf_list *buflout = NULL; dma_addr_t blp; - dma_addr_t bloutp = 0; + dma_addr_t bloutp; struct scatterlist *sg; size_t sz_out, sz = struct_size(bufl, bufers, n + 1);
@@ -682,6 +682,9 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, if (unlikely(!bufl)) return -ENOMEM;
+ for_each_sg(sgl, sg, n, i) + bufl->bufers[i].addr = DMA_MAPPING_ERROR; + blp = dma_map_single(dev, bufl, sz, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(dev, blp))) goto err_in; @@ -715,10 +718,14 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, dev_to_node(&GET_DEV(inst->accel_dev))); if (unlikely(!buflout)) goto err_in; + + bufers = buflout->bufers; + for_each_sg(sglout, sg, n, i) + bufers[i].addr = DMA_MAPPING_ERROR; + bloutp = dma_map_single(dev, buflout, sz_out, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(dev, bloutp))) goto err_out; - bufers = buflout->bufers; for_each_sg(sglout, sg, n, i) { int y = sg_nctr;
From: Pawel Laszczak pawell@cadence.com
[ Upstream commit 26adde04acdff14a1f28d4a5dce46a8513a3038b ]
Patch adds extra checking for bInterval passed by configfs. The 5.6.4 chapter of USB Specification (rev. 2.0) say: "A high-bandwidth endpoint must specify a period of 1x125 µs (i.e., a bInterval value of 1)."
The issue was observed during testing UVC class on CV. I treat this change as improvement because we can control bInterval by configfs.
Reviewed-by: Peter Chen peter.chen@kernel.org Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Pawel Laszczak pawell@cadence.com Link: https://lore.kernel.org/r/20210308125338.4824-1-pawell@gli-login.cadence.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_uvc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 44b4352a2676..ed77a126a74f 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -633,7 +633,12 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
uvc_hs_streaming_ep.wMaxPacketSize = cpu_to_le16(max_packet_size | ((max_packet_mult - 1) << 11)); - uvc_hs_streaming_ep.bInterval = opts->streaming_interval; + + /* A high-bandwidth endpoint must specify a bInterval value of 1 */ + if (max_packet_mult > 1) + uvc_hs_streaming_ep.bInterval = 1; + else + uvc_hs_streaming_ep.bInterval = opts->streaming_interval;
uvc_ss_streaming_ep.wMaxPacketSize = cpu_to_le16(max_packet_size); uvc_ss_streaming_ep.bInterval = opts->streaming_interval;
From: Pawel Laszczak pawell@cadence.com
[ Upstream commit 6a154ec9ef6762c774cd2b50215c7a8f0f08a862 ]
According with USB Device Class Definition for Video Device the Processing Unit Descriptor bLength should be 12 (10 + bmControlSize), but it has 11.
Invalid length caused that Processing Unit Descriptor Test Video form CV tool failed. To fix this issue patch adds bmVideoStandards into uvc_processing_unit_descriptor structure.
The bmVideoStandards field was added in UVC 1.1 and it wasn't part of UVC 1.0a.
Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Pawel Laszczak pawell@cadence.com Reviewed-by: Peter Chen peter.chen@kernel.org Link: https://lore.kernel.org/r/20210315071748.29706-1-pawell@gli-login.cadence.co... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_uvc.c | 1 + drivers/usb/gadget/legacy/webcam.c | 1 + include/uapi/linux/usb/video.h | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index ed77a126a74f..f48a00e49794 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -822,6 +822,7 @@ static struct usb_function_instance *uvc_alloc_inst(void) pd->bmControls[0] = 1; pd->bmControls[1] = 0; pd->iProcessing = 0; + pd->bmVideoStandards = 0;
od = &opts->uvc_output_terminal; od->bLength = UVC_DT_OUTPUT_TERMINAL_SIZE; diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c index a9f8eb8e1c76..2c9eab2b863d 100644 --- a/drivers/usb/gadget/legacy/webcam.c +++ b/drivers/usb/gadget/legacy/webcam.c @@ -125,6 +125,7 @@ static const struct uvc_processing_unit_descriptor uvc_processing = { .bmControls[0] = 1, .bmControls[1] = 0, .iProcessing = 0, + .bmVideoStandards = 0, };
static const struct uvc_output_terminal_descriptor uvc_output_terminal = { diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h index d854cb19c42c..bfdae12cdacf 100644 --- a/include/uapi/linux/usb/video.h +++ b/include/uapi/linux/usb/video.h @@ -302,9 +302,10 @@ struct uvc_processing_unit_descriptor { __u8 bControlSize; __u8 bmControls[2]; __u8 iProcessing; + __u8 bmVideoStandards; } __attribute__((__packed__));
-#define UVC_DT_PROCESSING_UNIT_SIZE(n) (9+(n)) +#define UVC_DT_PROCESSING_UNIT_SIZE(n) (10+(n))
/* 3.7.2.6. Extension Unit Descriptor */ struct uvc_extension_unit_descriptor {
From: Joerg Roedel jroedel@suse.de
[ Upstream commit eab696d8e8b9c9d600be6fad8dd8dfdfaca6ca7c ]
A malicious hypervisor could disable the CPUID intercept for an SEV or SEV-ES guest and trick it into the no-SEV boot path, where it could potentially reveal secrets. This is not an issue for SEV-SNP guests, as the CPUID intercept can't be disabled for those.
Remove the Hypervisor CPUID bit check from the SEV detection code to protect against this kind of attack and add a Hypervisor bit equals zero check to the SME detection path to prevent non-encrypted guests from trying to enable SME.
This handles the following cases:
1) SEV(-ES) guest where CPUID intercept is disabled. The guest will still see leaf 0x8000001f and the SEV bit. It can retrieve the C-bit and boot normally.
2) Non-encrypted guests with intercepted CPUID will check the SEV_STATUS MSR and find it 0 and will try to enable SME. This will fail when the guest finds MSR_K8_SYSCFG to be zero, as it is emulated by KVM. But we can't rely on that, as there might be other hypervisors which return this MSR with bit 23 set. The Hypervisor bit check will prevent that the guest tries to enable SME in this case.
3) Non-encrypted guests on SEV capable hosts with CPUID intercept disabled (by a malicious hypervisor) will try to boot into the SME path. This will fail, but it is also not considered a problem because non-encrypted guests have no protection against the hypervisor anyway.
[ bp: s/non-SEV/non-encrypted/g ]
Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Borislav Petkov bp@suse.de Acked-by: Tom Lendacky thomas.lendacky@amd.com Link: https://lkml.kernel.org/r/20210312123824.306-3-joro@8bytes.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/boot/compressed/mem_encrypt.S | 6 ----- arch/x86/kernel/sev-es-shared.c | 6 +---- arch/x86/mm/mem_encrypt_identity.c | 35 ++++++++++++++------------ 3 files changed, 20 insertions(+), 27 deletions(-)
diff --git a/arch/x86/boot/compressed/mem_encrypt.S b/arch/x86/boot/compressed/mem_encrypt.S index aa561795efd1..a6dea4e8a082 100644 --- a/arch/x86/boot/compressed/mem_encrypt.S +++ b/arch/x86/boot/compressed/mem_encrypt.S @@ -23,12 +23,6 @@ SYM_FUNC_START(get_sev_encryption_bit) push %ecx push %edx
- /* Check if running under a hypervisor */ - movl $1, %eax - cpuid - bt $31, %ecx /* Check the hypervisor bit */ - jnc .Lno_sev - movl $0x80000000, %eax /* CPUID to check the highest leaf */ cpuid cmpl $0x8000001f, %eax /* See if 0x8000001f is available */ diff --git a/arch/x86/kernel/sev-es-shared.c b/arch/x86/kernel/sev-es-shared.c index cdc04d091242..387b71669818 100644 --- a/arch/x86/kernel/sev-es-shared.c +++ b/arch/x86/kernel/sev-es-shared.c @@ -186,7 +186,6 @@ void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code) * make it accessible to the hypervisor. * * In particular, check for: - * - Hypervisor CPUID bit * - Availability of CPUID leaf 0x8000001f * - SEV CPUID bit. * @@ -194,10 +193,7 @@ void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code) * can't be checked here. */
- if ((fn == 1 && !(regs->cx & BIT(31)))) - /* Hypervisor bit */ - goto fail; - else if (fn == 0x80000000 && (regs->ax < 0x8000001f)) + if (fn == 0x80000000 && (regs->ax < 0x8000001f)) /* SEV leaf check */ goto fail; else if ((fn == 0x8000001f && !(regs->ax & BIT(1)))) diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c index 6c5eb6f3f14f..a19374d26101 100644 --- a/arch/x86/mm/mem_encrypt_identity.c +++ b/arch/x86/mm/mem_encrypt_identity.c @@ -503,14 +503,10 @@ void __init sme_enable(struct boot_params *bp)
#define AMD_SME_BIT BIT(0) #define AMD_SEV_BIT BIT(1) - /* - * Set the feature mask (SME or SEV) based on whether we are - * running under a hypervisor. - */ - eax = 1; - ecx = 0; - native_cpuid(&eax, &ebx, &ecx, &edx); - feature_mask = (ecx & BIT(31)) ? AMD_SEV_BIT : AMD_SME_BIT; + + /* Check the SEV MSR whether SEV or SME is enabled */ + sev_status = __rdmsr(MSR_AMD64_SEV); + feature_mask = (sev_status & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT;
/* * Check for the SME/SEV feature: @@ -530,19 +526,26 @@ void __init sme_enable(struct boot_params *bp)
/* Check if memory encryption is enabled */ if (feature_mask == AMD_SME_BIT) { + /* + * No SME if Hypervisor bit is set. This check is here to + * prevent a guest from trying to enable SME. For running as a + * KVM guest the MSR_K8_SYSCFG will be sufficient, but there + * might be other hypervisors which emulate that MSR as non-zero + * or even pass it through to the guest. + * A malicious hypervisor can still trick a guest into this + * path, but there is no way to protect against that. + */ + eax = 1; + ecx = 0; + native_cpuid(&eax, &ebx, &ecx, &edx); + if (ecx & BIT(31)) + return; + /* For SME, check the SYSCFG MSR */ msr = __rdmsr(MSR_K8_SYSCFG); if (!(msr & MSR_K8_SYSCFG_MEM_ENCRYPT)) return; } else { - /* For SEV, check the SEV MSR */ - msr = __rdmsr(MSR_AMD64_SEV); - if (!(msr & MSR_AMD64_SEV_ENABLED)) - return; - - /* Save SEV_STATUS to avoid reading MSR again */ - sev_status = msr; - /* SEV state cannot be controlled by a command line option */ sme_me_mask = me_mask; sev_enabled = true;
From: Longfang Liu liulongfang@huawei.com
[ Upstream commit 4b7aef0230418345be1fb77abbb1592801869901 ]
When the log is output here, the device has not been initialized yet.
Signed-off-by: Longfang Liu liulongfang@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/hisilicon/sec2/sec_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c index bb493423668c..41f1fcacb280 100644 --- a/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -544,7 +544,7 @@ static int sec_skcipher_init(struct crypto_skcipher *tfm) crypto_skcipher_set_reqsize(tfm, sizeof(struct sec_req)); ctx->c_ctx.ivsize = crypto_skcipher_ivsize(tfm); if (ctx->c_ctx.ivsize > SEC_IV_SIZE) { - dev_err(SEC_CTX_DEV(ctx), "get error skcipher iv size!\n"); + pr_err("get error skcipher iv size!\n"); return -EINVAL; }
From: Vitaly Kuznetsov vkuznets@redhat.com
[ Upstream commit c93a5e20c3c2dabef8ea360a3d3f18c6f68233ab ]
When irq_matrix_free() is called for an unallocated vector the managed_allocated and total_allocated counters get out of sync with the real state of the matrix. Later, when the last interrupt is freed, these counters will underflow resulting in UINTMAX because the counters are unsigned.
While this is certainly a problem of the calling code, this can be catched in the allocator by checking the allocation bit for the to be freed vector which simplifies debugging.
An example of the problem described above: https://lore.kernel.org/lkml/20210318192819.636943062@linutronix.de/
Add the missing sanity check and emit a warning when it triggers.
Suggested-by: Thomas Gleixner tglx@linutronix.de Signed-off-by: Vitaly Kuznetsov vkuznets@redhat.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lore.kernel.org/r/20210319111823.1105248-1-vkuznets@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/irq/matrix.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c index 651a4ad6d711..8e586858bcf4 100644 --- a/kernel/irq/matrix.c +++ b/kernel/irq/matrix.c @@ -423,7 +423,9 @@ void irq_matrix_free(struct irq_matrix *m, unsigned int cpu, if (WARN_ON_ONCE(bit < m->alloc_start || bit >= m->alloc_end)) return;
- clear_bit(bit, cm->alloc_map); + if (WARN_ON_ONCE(!test_and_clear_bit(bit, cm->alloc_map))) + return; + cm->allocated--; if(managed) cm->managed_allocated--;
From: Ruslan Bilovol ruslan.bilovol@gmail.com
[ Upstream commit 3713d5ceb04d5ab6a5e2b86dfca49170053f3a5e ]
Currently user can configure UAC2 function with parameters that violate UAC2 spec or are not supported by UAC2 gadget implementation.
This can lead to incorrect behavior if such gadget is connected to the host - like enumeration failure or other issues depending on host's UAC2 driver implementation, bringing user to a long hours of debugging the issue.
Instead of silently accept these parameters, throw an error if they are not valid.
Signed-off-by: Ruslan Bilovol ruslan.bilovol@gmail.com Link: https://lore.kernel.org/r/1614599375-8803-4-git-send-email-ruslan.bilovol@gm... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_uac2.c | 39 ++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 6f03e944e0e3..dd960cea642f 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -14,6 +14,9 @@ #include "u_audio.h" #include "u_uac2.h"
+/* UAC2 spec: 4.1 Audio Channel Cluster Descriptor */ +#define UAC2_CHANNEL_MASK 0x07FFFFFF + /* * The driver implements a simple UAC_2 topology. * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture @@ -604,6 +607,36 @@ static void setup_descriptor(struct f_uac2_opts *opts) hs_audio_desc[i] = NULL; }
+static int afunc_validate_opts(struct g_audio *agdev, struct device *dev) +{ + struct f_uac2_opts *opts = g_audio_to_uac2_opts(agdev); + + if (!opts->p_chmask && !opts->c_chmask) { + dev_err(dev, "Error: no playback and capture channels\n"); + return -EINVAL; + } else if (opts->p_chmask & ~UAC2_CHANNEL_MASK) { + dev_err(dev, "Error: unsupported playback channels mask\n"); + return -EINVAL; + } else if (opts->c_chmask & ~UAC2_CHANNEL_MASK) { + dev_err(dev, "Error: unsupported capture channels mask\n"); + return -EINVAL; + } else if ((opts->p_ssize < 1) || (opts->p_ssize > 4)) { + dev_err(dev, "Error: incorrect playback sample size\n"); + return -EINVAL; + } else if ((opts->c_ssize < 1) || (opts->c_ssize > 4)) { + dev_err(dev, "Error: incorrect capture sample size\n"); + return -EINVAL; + } else if (!opts->p_srate) { + dev_err(dev, "Error: incorrect playback sampling rate\n"); + return -EINVAL; + } else if (!opts->c_srate) { + dev_err(dev, "Error: incorrect capture sampling rate\n"); + return -EINVAL; + } + + return 0; +} + static int afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) { @@ -612,11 +645,13 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) struct usb_composite_dev *cdev = cfg->cdev; struct usb_gadget *gadget = cdev->gadget; struct device *dev = &gadget->dev; - struct f_uac2_opts *uac2_opts; + struct f_uac2_opts *uac2_opts = g_audio_to_uac2_opts(agdev); struct usb_string *us; int ret;
- uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst); + ret = afunc_validate_opts(agdev, dev); + if (ret) + return ret;
us = usb_gstrings_attach(cdev, fn_strings, ARRAY_SIZE(strings_fn)); if (IS_ERR(us))
From: Ruslan Bilovol ruslan.bilovol@gmail.com
[ Upstream commit a59c68a6a3d1b18e2494f526eb19893a34fa6ec6 ]
Currently user can configure UAC1 function with parameters that violate UAC1 spec or are not supported by UAC1 gadget implementation.
This can lead to incorrect behavior if such gadget is connected to the host - like enumeration failure or other issues depending on host's UAC1 driver implementation, bringing user to a long hours of debugging the issue.
Instead of silently accept these parameters, throw an error if they are not valid.
Signed-off-by: Ruslan Bilovol ruslan.bilovol@gmail.com Link: https://lore.kernel.org/r/1614599375-8803-5-git-send-email-ruslan.bilovol@gm... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_uac1.c | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 560382e0a8f3..e65f474ad7b3 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -19,6 +19,9 @@ #include "u_audio.h" #include "u_uac1.h"
+/* UAC1 spec: 3.7.2.3 Audio Channel Cluster Format */ +#define UAC1_CHANNEL_MASK 0x0FFF + struct f_uac1 { struct g_audio g_audio; u8 ac_intf, as_in_intf, as_out_intf; @@ -30,6 +33,11 @@ static inline struct f_uac1 *func_to_uac1(struct usb_function *f) return container_of(f, struct f_uac1, g_audio.func); }
+static inline struct f_uac1_opts *g_audio_to_uac1_opts(struct g_audio *audio) +{ + return container_of(audio->func.fi, struct f_uac1_opts, func_inst); +} + /* * DESCRIPTORS ... most are static, but strings and full * configuration descriptors are built on demand. @@ -505,11 +513,42 @@ static void f_audio_disable(struct usb_function *f)
/*-------------------------------------------------------------------------*/
+static int f_audio_validate_opts(struct g_audio *audio, struct device *dev) +{ + struct f_uac1_opts *opts = g_audio_to_uac1_opts(audio); + + if (!opts->p_chmask && !opts->c_chmask) { + dev_err(dev, "Error: no playback and capture channels\n"); + return -EINVAL; + } else if (opts->p_chmask & ~UAC1_CHANNEL_MASK) { + dev_err(dev, "Error: unsupported playback channels mask\n"); + return -EINVAL; + } else if (opts->c_chmask & ~UAC1_CHANNEL_MASK) { + dev_err(dev, "Error: unsupported capture channels mask\n"); + return -EINVAL; + } else if ((opts->p_ssize < 1) || (opts->p_ssize > 4)) { + dev_err(dev, "Error: incorrect playback sample size\n"); + return -EINVAL; + } else if ((opts->c_ssize < 1) || (opts->c_ssize > 4)) { + dev_err(dev, "Error: incorrect capture sample size\n"); + return -EINVAL; + } else if (!opts->p_srate) { + dev_err(dev, "Error: incorrect playback sampling rate\n"); + return -EINVAL; + } else if (!opts->c_srate) { + dev_err(dev, "Error: incorrect capture sampling rate\n"); + return -EINVAL; + } + + return 0; +} + /* audio function driver setup/binding */ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; struct usb_gadget *gadget = cdev->gadget; + struct device *dev = &gadget->dev; struct f_uac1 *uac1 = func_to_uac1(f); struct g_audio *audio = func_to_g_audio(f); struct f_uac1_opts *audio_opts; @@ -519,6 +558,10 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) int rate; int status;
+ status = f_audio_validate_opts(audio, dev); + if (status) + return status; + audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst);
us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1));
From: Wesley Cheng wcheng@codeaurora.org
[ Upstream commit 71ca43f30df9c642970f9dc9b2d6f463f4967e7b ]
The current dwc3_gadget_reset_interrupt() will stop any active transfers, but only addresses blocking of EP queuing for while we are coming from a disconnected scenario, i.e. after receiving the disconnect event. If the host decides to issue a bus reset on the device, the connected parameter will still be set to true, allowing for EP queuing to continue while we are disabling the functions. To avoid this, set the connected flag to false until the stop active transfers is complete.
Signed-off-by: Wesley Cheng wcheng@codeaurora.org Link: https://lore.kernel.org/r/1616146285-19149-3-git-send-email-wcheng@codeauror... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/gadget.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 65ff41e3a18e..5b5520286eff 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3267,6 +3267,15 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) { u32 reg;
+ /* + * Ideally, dwc3_reset_gadget() would trigger the function + * drivers to stop any active transfers through ep disable. + * However, for functions which defer ep disable, such as mass + * storage, we will need to rely on the call to stop active + * transfers here, and avoid allowing of request queuing. + */ + dwc->connected = false; + /* * WORKAROUND: DWC3 revisions <1.88a have an issue which * would cause a missing Disconnect Event if there's a
From: Thinh Nguyen Thinh.Nguyen@synopsys.com
[ Upstream commit 64364bc912c01b33bba6c22e3ccb849bfca96398 ]
Some hosts incorrectly use sub-minor version for minor version (i.e. 0x02 instead of 0x20 for bcdUSB 0x320 and 0x01 for bcdUSB 0x310). Currently the xHCI driver works around this by just checking for minor revision > 0x01 for USB 3.1 everywhere. With the addition of USB 3.2, checking this gets a bit cumbersome. Since there is no USB release with bcdUSB 0x301 to 0x309, we can assume that sub-minor version 01 to 09 is incorrect. Let's try to fix this and use the minor revision that matches with the USB/xHCI spec to help with the version checking within the driver.
Acked-by: Mathias Nyman mathias.nyman@linux.intel.com Signed-off-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Link: https://lore.kernel.org/r/ed330e95a19dc367819c5b4d78bf7a541c35aa0a.161543277... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci-mem.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 138ba4528dd3..1ad0ac8c8209 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2143,6 +2143,15 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
if (major_revision == 0x03) { rhub = &xhci->usb3_rhub; + /* + * Some hosts incorrectly use sub-minor version for minor + * version (i.e. 0x02 instead of 0x20 for bcdUSB 0x320 and 0x01 + * for bcdUSB 0x310). Since there is no USB release with sub + * minor version 0x301 to 0x309, we can assume that they are + * incorrect and fix it here. + */ + if (minor_revision > 0x00 && minor_revision < 0x10) + minor_revision <<= 4; } else if (major_revision <= 0x02) { rhub = &xhci->usb2_rhub; } else {
From: Andre Przywara andre.przywara@arm.com
[ Upstream commit 4a423645bc2690376a7a94b4bb7b2f74bc6206ff ]
The mte selftest Makefile contains a check for GCC, to add the memtag -march flag to the compiler options. This check fails if the compiler is not explicitly specified, so reverts to the standard "cc", in which case --version doesn't mention the "gcc" string we match against: $ cc --version | head -n 1 cc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
This will not add the -march switch to the command line, so compilation fails: mte_helper.S: Assembler messages: mte_helper.S:25: Error: selected processor does not support `irg x0,x0,xzr' mte_helper.S:38: Error: selected processor does not support `gmi x1,x0,xzr' ...
Actually clang accepts the same -march option as well, so we can just drop this check and add this unconditionally to the command line, to avoid any future issues with this check altogether (gcc actually prints basename(argv[0]) when called with --version).
Signed-off-by: Andre Przywara andre.przywara@arm.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Reviewed-by: Mark Brown broone@kernel.org Link: https://lore.kernel.org/r/20210319165334.29213-2-andre.przywara@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/arm64/mte/Makefile | 2 -- 1 file changed, 2 deletions(-)
diff --git a/tools/testing/selftests/arm64/mte/Makefile b/tools/testing/selftests/arm64/mte/Makefile index 2480226dfe57..4084ef108d05 100644 --- a/tools/testing/selftests/arm64/mte/Makefile +++ b/tools/testing/selftests/arm64/mte/Makefile @@ -6,9 +6,7 @@ SRCS := $(filter-out mte_common_util.c,$(wildcard *.c)) PROGS := $(patsubst %.c,%,$(SRCS))
#Add mte compiler option -ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep gcc),) CFLAGS += -march=armv8.5-a+memtag -endif
#check if the compiler works well mte_cc_support := $(shell if ($(CC) $(CFLAGS) -E -x c /dev/null -o /dev/null 2>&1) then echo "1"; fi)
From: Dmitry Osipenko digetx@gmail.com
[ Upstream commit b27b9689e1f3278919c6183c565d837d0aef6fc1 ]
Rename avdd supply to vdda of the touchscreen node. The old supply name was incorrect.
Signed-off-by: Dmitry Osipenko digetx@gmail.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/tegra20-acer-a500-picasso.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts index a0b829738e8f..068aabcffb13 100644 --- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts +++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts @@ -448,7 +448,7 @@
reset-gpios = <&gpio TEGRA_GPIO(Q, 7) GPIO_ACTIVE_HIGH>;
- avdd-supply = <&vdd_3v3_sys>; + vdda-supply = <&vdd_3v3_sys>; vdd-supply = <&vdd_3v3_sys>; };
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
[ Upstream commit 4514d991d99211f225d83b7e640285f29f0755d0 ]
It should not be necessary to update the current_state field of struct pci_dev in pci_enable_device_flags() before calling do_pci_enable_device() for the device, because none of the code between that point and the pci_set_power_state() call in do_pci_enable_device() invoked later depends on it.
Moreover, doing that is actively harmful in some cases. For example, if the given PCI device depends on an ACPI power resource whose _STA method initially returns 0 ("off"), but the config space of the PCI device is accessible and the power state retrieved from the PCI_PM_CTRL register is D0, the current_state field in the struct pci_dev representing that device will get out of sync with the power.state of its ACPI companion object and that will lead to power management issues going forward.
To avoid such issues it is better to leave the current_state value as is until it is changed to PCI_D0 by do_pci_enable_device() as appropriate. However, the power state of the device is not changed to PCI_D0 if it is already enabled when pci_enable_device_flags() gets called for it, so update its current_state in that case, but use pci_update_current_state() covering platform PM too for that.
Link: https://lore.kernel.org/lkml/20210314000439.3138941-1-luzmaximilian@gmail.co... Reported-by: Maximilian Luz luzmaximilian@gmail.com Tested-by: Maximilian Luz luzmaximilian@gmail.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Reviewed-by: Mika Westerberg mika.westerberg@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pci.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 9e971fffeb6a..d5d9ea864fe6 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1874,20 +1874,10 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) int err; int i, bars = 0;
- /* - * Power state could be unknown at this point, either due to a fresh - * boot or a device removal call. So get the current power state - * so that things like MSI message writing will behave as expected - * (e.g. if the device really is in D0 at enable time). - */ - if (dev->pm_cap) { - u16 pmcsr; - pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); - dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); - } - - if (atomic_inc_return(&dev->enable_cnt) > 1) + if (atomic_inc_return(&dev->enable_cnt) > 1) { + pci_update_current_state(dev, dev->current_state); return 0; /* already enabled */ + }
bridge = pci_upstream_bridge(dev); if (bridge)
From: Andre Przywara andre.przywara@arm.com
[ Upstream commit 592432862cc4019075a7196d9961562c49507d6f ]
To check whether the CPU and kernel support the MTE features we want to test, we use an (emulated) CPU ID register read. However we only check against a very particular feature version (0b0010), even though the ARM ARM promises ID register features to be backwards compatible.
While this could be fixed by using ">=" instead of "==", we should actually use the explicit HWCAP2_MTE hardware capability, exposed by the kernel via the ELF auxiliary vectors.
That moves this responsibility to the kernel, and fixes running the tests on machines with FEAT_MTE3 capability.
Signed-off-by: Andre Przywara andre.przywara@arm.com Reviewed-by: Mark Brown broone@kernel.org Link: https://lore.kernel.org/r/20210319165334.29213-7-andre.przywara@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/arm64/mte/mte_common_util.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.c b/tools/testing/selftests/arm64/mte/mte_common_util.c index 39f8908988ea..70665ba88cbb 100644 --- a/tools/testing/selftests/arm64/mte/mte_common_util.c +++ b/tools/testing/selftests/arm64/mte/mte_common_util.c @@ -278,22 +278,13 @@ int mte_switch_mode(int mte_option, unsigned long incl_mask) return 0; }
-#define ID_AA64PFR1_MTE_SHIFT 8 -#define ID_AA64PFR1_MTE 2 - int mte_default_setup(void) { - unsigned long hwcaps = getauxval(AT_HWCAP); + unsigned long hwcaps2 = getauxval(AT_HWCAP2); unsigned long en = 0; int ret;
- if (!(hwcaps & HWCAP_CPUID)) { - ksft_print_msg("FAIL: CPUID registers unavailable\n"); - return KSFT_FAIL; - } - /* Read ID_AA64PFR1_EL1 register */ - asm volatile("mrs %0, id_aa64pfr1_el1" : "=r"(hwcaps) : : "memory"); - if (((hwcaps >> ID_AA64PFR1_MTE_SHIFT) & MT_TAG_MASK) != ID_AA64PFR1_MTE) { + if (!(hwcaps2 & HWCAP2_MTE)) { ksft_print_msg("FAIL: MTE features unavailable\n"); return KSFT_SKIP; }
From: Rafał Miłecki rafal@milecki.pl
[ Upstream commit 43986f38818278bb71a7fef6de689637bb734afe ]
This fixes warnings/errors like: arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dt.yaml: /: memory@0:reg:0: [0, 134217728, 2281701376, 402653184] is too long From schema: /lib/python3.6/site-packages/dtschema/schemas/reg.yaml
Signed-off-by: Rafał Miłecki rafal@milecki.pl Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts | 4 ++-- arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts | 4 ++-- arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 4 ++-- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 4 ++-- arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts | 4 ++-- arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 4 ++-- arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts | 4 ++-- arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 4 ++-- arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 4 ++-- arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 4 ++-- arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 4 ++-- arch/arm/boot/dts/bcm4709-linksys-ea9200.dts | 4 ++-- arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 4 ++-- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 4 ++-- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 4 ++-- arch/arm/boot/dts/bcm47094-linksys-panamera.dts | 4 ++-- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 4 ++-- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 4 ++-- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 4 ++-- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 4 ++-- arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 4 ++-- arch/arm/boot/dts/bcm47094-netgear-r8500.dts | 4 ++-- arch/arm/boot/dts/bcm47094-phicomm-k3.dts | 4 ++-- 23 files changed, 46 insertions(+), 46 deletions(-)
diff --git a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts index 6a96655d8626..8ed403767540 100644 --- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts +++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts @@ -21,8 +21,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts index 3b0029e61b4c..667b118ba4ee 100644 --- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts +++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts @@ -21,8 +21,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts index 90f57bad6b24..ff31ce45831a 100644 --- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts +++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts @@ -21,8 +21,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x18000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x18000000>; };
spi { diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts index fed75e6ab58c..61c7b137607e 100644 --- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts +++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts @@ -22,8 +22,8 @@
memory { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts index 79542e18915c..4c60eda296d9 100644 --- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts +++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts @@ -21,8 +21,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts index abd35a518046..7d46561fca3c 100644 --- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts +++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts @@ -21,8 +21,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts index c29950b43a95..0e273c598732 100644 --- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts +++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts @@ -21,8 +21,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts index 4dcec6865469..083ec4036bd7 100644 --- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts +++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts @@ -21,8 +21,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
spi { diff --git a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts index 0e349e39f608..8b1a05a0f1a1 100644 --- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts +++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts @@ -21,8 +21,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
spi { diff --git a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts index 8f1e565c3db4..6c6bb7b17d27 100644 --- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts +++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts @@ -21,8 +21,8 @@
memory { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts index ce888b1835d1..d29e7f80ea6a 100644 --- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts +++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts @@ -21,8 +21,8 @@
memory { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x18000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x18000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts index ed8619b54d69..38fbefdf2e4e 100644 --- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts +++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts @@ -18,8 +18,8 @@
memory { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
gpio-keys { diff --git a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts index 1f87993eae1d..7989a53597d4 100644 --- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts +++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts @@ -21,8 +21,8 @@
memory { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts index 6c6199a53d09..87b655be674c 100644 --- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts +++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts @@ -32,8 +32,8 @@
memory { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts index 911c65fbf251..e635a15041dd 100644 --- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts +++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts @@ -21,8 +21,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
nand: nand@18028000 { diff --git a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts index 0faae8950375..36d63beba8cd 100644 --- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts +++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts @@ -18,8 +18,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
gpio-keys { diff --git a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts index 50f7cd08cfbb..a6dc99955e19 100644 --- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts +++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts @@ -18,8 +18,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x18000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x18000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts index bcc420f85b56..ff98837bc0db 100644 --- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts +++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts @@ -18,8 +18,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x18000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x18000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts index 9ae815ddbb4b..2666195b6ffe 100644 --- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts +++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts @@ -18,8 +18,8 @@
memory { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x18000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x18000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts index a21b2d185596..9f798025748b 100644 --- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts +++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts @@ -18,8 +18,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts index 4d5c5aa7dc42..c8dfa4c58d2f 100644 --- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts +++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts @@ -18,8 +18,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x18000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x18000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts index f42a1703f4ab..42097a4c2659 100644 --- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts +++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts @@ -18,8 +18,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x18000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x18000000>; };
leds { diff --git a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts index ac3a4483dcb3..a2566ad4619c 100644 --- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts +++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts @@ -15,8 +15,8 @@
memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000 - 0x88000000 0x18000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x18000000>; };
gpio-keys {
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit aeceecd40d94ed3c00bfe1cfe59dd1bfac2fc6fe ]
The TVK1281618 R3 sensors are different from the R2 board, some incorrectness is fixed and some new sensors added, we also rename the nodes appropriately with accelerometer@ etc.
Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi | 73 +++++++++++++------ 1 file changed, 50 insertions(+), 23 deletions(-)
diff --git a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi index 9f285c7cf914..c0de1337bdaa 100644 --- a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi +++ b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi @@ -8,37 +8,43 @@ / { soc { i2c@80128000 { - /* Marked: - * 129 - * M35 - * L3GD20 - */ - l3gd20@6a { - /* Gyroscope */ - compatible = "st,l3gd20"; - status = "disabled"; + accelerometer@19 { + compatible = "st,lsm303dlhc-accel"; st,drdy-int-pin = <1>; - drive-open-drain; - reg = <0x6a>; // 0x6a or 0x6b + reg = <0x19>; vdd-supply = <&ab8500_ldo_aux1_reg>; vddio-supply = <&db8500_vsmps2_reg>; + interrupt-parent = <&gpio2>; + interrupts = <18 IRQ_TYPE_EDGE_RISING>, + <19 IRQ_TYPE_EDGE_RISING>; + pinctrl-names = "default"; + pinctrl-0 = <&accel_tvk_mode>; }; - /* - * Marked: - * 2122 - * C3H - * DQEEE - * LIS3DH? - */ - lis3dh@18 { - /* Accelerometer */ - compatible = "st,lis3dh-accel"; + magnetometer@1e { + compatible = "st,lsm303dlm-magn"; st,drdy-int-pin = <1>; - reg = <0x18>; + reg = <0x1e>; vdd-supply = <&ab8500_ldo_aux1_reg>; vddio-supply = <&db8500_vsmps2_reg>; + // This interrupt is not properly working with the driver + // interrupt-parent = <&gpio1>; + // interrupts = <0 IRQ_TYPE_EDGE_RISING>; pinctrl-names = "default"; - pinctrl-0 = <&accel_tvk_mode>; + pinctrl-0 = <&magn_tvk_mode>; + }; + gyroscope@68 { + /* Gyroscope */ + compatible = "st,l3g4200d-gyro"; + reg = <0x68>; + vdd-supply = <&ab8500_ldo_aux1_reg>; + vddio-supply = <&db8500_vsmps2_reg>; + }; + pressure@5c { + /* Barometer/pressure sensor */ + compatible = "st,lps001wp-press"; + reg = <0x5c>; + vdd-supply = <&ab8500_ldo_aux1_reg>; + vddio-supply = <&db8500_vsmps2_reg>; }; };
@@ -54,5 +60,26 @@ }; }; }; + + pinctrl { + accelerometer { + accel_tvk_mode: accel_tvk { + /* Accelerometer interrupt lines 1 & 2 */ + tvk_cfg { + pins = "GPIO82_C1", "GPIO83_D3"; + ste,config = <&gpio_in_pd>; + }; + }; + }; + magnetometer { + magn_tvk_mode: magn_tvk { + /* GPIO 32 used for DRDY, pull this down */ + tvk_cfg { + pins = "GPIO32_V2"; + ste,config = <&gpio_in_pd>; + }; + }; + }; + }; }; };
From: John Millikin john@john-millikin.com
[ Upstream commit 8abe7fc26ad8f28bfdf78adbed56acd1fa93f82d ]
When cross-compiling with Clang, the `$(CLANG_FLAGS)' variable contains additional flags needed to build C and assembly sources for the target platform. Normally this variable is automatically included in `$(KBUILD_CFLAGS)' via the top-level Makefile.
The x86 real-mode makefile builds `$(REALMODE_CFLAGS)' from a plain assignment and therefore drops the Clang flags. This causes Clang to not recognize x86-specific assembler directives:
arch/x86/realmode/rm/header.S:36:1: error: unknown directive .type real_mode_header STT_OBJECT ; .size real_mode_header, .-real_mode_header ^
Explicit propagation of `$(CLANG_FLAGS)' to `$(REALMODE_CFLAGS)', which is inherited by real-mode make rules, fixes cross-compilation with Clang for x86 targets.
Relevant flags:
* `--target' sets the target architecture when cross-compiling. This flag must be set for both compilation and assembly (`KBUILD_AFLAGS') to support architecture-specific assembler directives.
* `-no-integrated-as' tells clang to assemble with GNU Assembler instead of its built-in LLVM assembler. This flag is set by default unless `LLVM_IAS=1' is set, because the LLVM assembler can't yet parse certain GNU extensions.
Signed-off-by: John Millikin john@john-millikin.com Signed-off-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Borislav Petkov bp@suse.de Acked-by: Ard Biesheuvel ardb@kernel.org Tested-by: Sedat Dilek sedat.dilek@gmail.com Link: https://lkml.kernel.org/r/20210326000435.4785-2-nathan@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 9c86f2dc16b1..8ed757d06f77 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -40,6 +40,7 @@ REALMODE_CFLAGS += -ffreestanding REALMODE_CFLAGS += -fno-stack-protector REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member) REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4)) +REALMODE_CFLAGS += $(CLANG_FLAGS) export REALMODE_CFLAGS
# BITS is used as extension for files which are available in a 32 bit
From: Nathan Chancellor nathan@kernel.org
[ Upstream commit d5cbd80e302dfea59726c44c56ab7957f822409f ]
When cross compiling x86 on an ARM machine with clang, there are several errors along the lines of:
arch/x86/include/asm/string_64.h:27:10: error: invalid output constraint '=&c' in asm
This happens because the compressed boot Makefile reassigns KBUILD_CFLAGS and drops the clang flags that set the target architecture ('--target=') and the path to the GNU cross tools ('--prefix='), meaning that the host architecture is targeted.
These flags are available as $(CLANG_FLAGS) from the main Makefile so add them to the compressed boot folder's KBUILD_CFLAGS so that cross compiling works as expected.
Signed-off-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Borislav Petkov bp@suse.de Acked-by: Ard Biesheuvel ardb@kernel.org Link: https://lkml.kernel.org/r/20210326000435.4785-3-nathan@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/boot/compressed/Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 40b8fd375d52..6004047d25fd 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -46,6 +46,7 @@ KBUILD_CFLAGS += -D__DISABLE_EXPORTS # Disable relocation relaxation in case the link is not PIE. KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mrelax-relocations=no) KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h +KBUILD_CFLAGS += $(CLANG_FLAGS)
# sev-es.c indirectly inludes inat-table.h which is generated during # compilation and stored in $(objtree). Add the directory to the includes so
From: Nathan Chancellor nathan@kernel.org
[ Upstream commit 58d746c119dfa28e72fc35aacaf3d2a3ac625cd0 ]
When cross compiling x86 on an ARM machine with clang, there are several errors along the lines of:
arch/x86/include/asm/page_64.h:52:7: error: invalid output constraint '=D' in asm
This happens because the x86 flags in the EFI stub are not derived from KBUILD_CFLAGS like the other architectures are and the clang flags that set the target architecture ('--target=') and the path to the GNU cross tools ('--prefix=') are not present, meaning that the host architecture is targeted.
These flags are available as $(CLANG_FLAGS) from the main Makefile so add them to the cflags for x86 so that cross compiling works as expected.
Signed-off-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Borislav Petkov bp@suse.de Acked-by: Ard Biesheuvel ardb@kernel.org Link: https://lkml.kernel.org/r/20210326000435.4785-4-nathan@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/efi/libstub/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 8a94388e38b3..a2ae9c3b9579 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -13,7 +13,8 @@ cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \ -Wno-pointer-sign \ $(call cc-disable-warning, address-of-packed-member) \ $(call cc-disable-warning, gnu) \ - -fno-asynchronous-unwind-tables + -fno-asynchronous-unwind-tables \ + $(CLANG_FLAGS)
# arm64 uses the full KBUILD_CFLAGS so it's necessary to explicitly # disable the stackleak plugin
From: Dmitry Osipenko digetx@gmail.com
[ Upstream commit c45e66a6b9f40f2e95bc6d97fbf3daa1ebe88c6b ]
The SW-initiated power gate toggling is dropped by PMC if there is contention with a HW-initiated toggling, i.e. when one of CPU cores is gated by cpuidle driver. Software should retry the toggling after 10 microseconds on Tegra20/30 SoCs, hence add the retrying. On Tegra114+ the toggling method was changed in hardware, the TOGGLE_START bit indicates whether PMC is busy or could accept the command to toggle, hence handle that bit properly.
The problem pops up after enabling dynamic power gating of 3D hardware, where 3D power domain fails to turn on/off "randomly".
The programming sequence and quirks are documented in TRMs, but PMC driver obliviously re-used the Tegra20 logic for Tegra30+, which strikes back now. The 10 microseconds and other timeouts aren't documented in TRM, they are taken from downstream kernel.
Link: https://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git%3Ba=commit%3Bh=311dd1c31... Link: https://nv-tegra.nvidia.com/gitweb/?p=linux-3.10.git%3Ba=commit%3Bh=7f36693c... Tested-by: Peter Geis pgwipeout@gmail.com # Ouya T30 Tested-by: Nicolas Chauvet kwizart@gmail.com # PAZ00 T20 and TK1 T124 Tested-by: Matt Merhar mattmerhar@protonmail.com # Ouya T30 Signed-off-by: Dmitry Osipenko digetx@gmail.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/tegra/pmc.c | 70 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 5 deletions(-)
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index df9a5ca8c99c..0118bd986f90 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -317,6 +317,8 @@ struct tegra_pmc_soc { bool invert); int (*irq_set_wake)(struct irq_data *data, unsigned int on); int (*irq_set_type)(struct irq_data *data, unsigned int type); + int (*powergate_set)(struct tegra_pmc *pmc, unsigned int id, + bool new_state);
const char * const *reset_sources; unsigned int num_reset_sources; @@ -517,6 +519,63 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name) return -ENODEV; }
+static int tegra20_powergate_set(struct tegra_pmc *pmc, unsigned int id, + bool new_state) +{ + unsigned int retries = 100; + bool status; + int ret; + + /* + * As per TRM documentation, the toggle command will be dropped by PMC + * if there is contention with a HW-initiated toggling (i.e. CPU core + * power-gated), the command should be retried in that case. + */ + do { + tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE); + + /* wait for PMC to execute the command */ + ret = readx_poll_timeout(tegra_powergate_state, id, status, + status == new_state, 1, 10); + } while (ret == -ETIMEDOUT && retries--); + + return ret; +} + +static inline bool tegra_powergate_toggle_ready(struct tegra_pmc *pmc) +{ + return !(tegra_pmc_readl(pmc, PWRGATE_TOGGLE) & PWRGATE_TOGGLE_START); +} + +static int tegra114_powergate_set(struct tegra_pmc *pmc, unsigned int id, + bool new_state) +{ + bool status; + int err; + + /* wait while PMC power gating is contended */ + err = readx_poll_timeout(tegra_powergate_toggle_ready, pmc, status, + status == true, 1, 100); + if (err) + return err; + + tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE); + + /* wait for PMC to accept the command */ + err = readx_poll_timeout(tegra_powergate_toggle_ready, pmc, status, + status == true, 1, 100); + if (err) + return err; + + /* wait for PMC to execute the command */ + err = readx_poll_timeout(tegra_powergate_state, id, status, + status == new_state, 10, 100000); + if (err) + return err; + + return 0; +} + /** * tegra_powergate_set() - set the state of a partition * @pmc: power management controller @@ -526,7 +585,6 @@ static int tegra_powergate_lookup(struct tegra_pmc *pmc, const char *name) static int tegra_powergate_set(struct tegra_pmc *pmc, unsigned int id, bool new_state) { - bool status; int err;
if (id == TEGRA_POWERGATE_3D && pmc->soc->has_gpu_clamps) @@ -539,10 +597,7 @@ static int tegra_powergate_set(struct tegra_pmc *pmc, unsigned int id, return 0; }
- tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE); - - err = readx_poll_timeout(tegra_powergate_state, id, status, - status == new_state, 10, 100000); + err = pmc->soc->powergate_set(pmc, id, new_state);
mutex_unlock(&pmc->powergates_lock);
@@ -2699,6 +2754,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = { .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, + .powergate_set = tegra20_powergate_set, .reset_sources = NULL, .num_reset_sources = 0, .reset_levels = NULL, @@ -2757,6 +2813,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = { .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, + .powergate_set = tegra20_powergate_set, .reset_sources = tegra30_reset_sources, .num_reset_sources = ARRAY_SIZE(tegra30_reset_sources), .reset_levels = NULL, @@ -2811,6 +2868,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = { .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, + .powergate_set = tegra114_powergate_set, .reset_sources = tegra30_reset_sources, .num_reset_sources = ARRAY_SIZE(tegra30_reset_sources), .reset_levels = NULL, @@ -2925,6 +2983,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = { .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, + .powergate_set = tegra114_powergate_set, .reset_sources = tegra30_reset_sources, .num_reset_sources = ARRAY_SIZE(tegra30_reset_sources), .reset_levels = NULL, @@ -3048,6 +3107,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { .regs = &tegra20_pmc_regs, .init = tegra20_pmc_init, .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, + .powergate_set = tegra114_powergate_set, .irq_set_wake = tegra210_pmc_irq_set_wake, .irq_set_type = tegra210_pmc_irq_set_type, .reset_sources = tegra210_reset_sources,
From: Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm
[ Upstream commit a362b0cc94d476b097ba0ff466958c1d4e27e219 ]
Commit 99e71c029213 ("arm64: dts: imx8mq-librem5: Don't mark buck3 as always on") removed always-on marking from GPU regulator, which is great for power saving - however it introduces additional i2c0 traffic which can be deadly for devices from the Dogwood batch.
To workaround the i2c0 shutdown issue on Dogwood, this commit marks buck3 as always-on again - but only for Dogwood (r3).
Signed-off-by: Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm Signed-off-by: Martin Kepplinger martin.kepplinger@puri.sm Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts index 6704ea2c72a3..cc29223ca188 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts @@ -22,6 +22,10 @@ ti,termination-current = <144000>; /* uA */ };
+&buck3_reg { + regulator-always-on; +}; + &proximity { proximity-near-level = <25>; };
From: Jerome Forissier jerome@forissier.org
[ Upstream commit c650b8dc7a7910eb25af0aac1720f778b29e679d ]
When Secure World returns, it may have changed the size attribute of the memory references passed as [in/out] parameters. The GlobalPlatform TEE Internal Core API specification does not restrict the values that this size can take. In particular, Secure World may increase the value to be larger than the size of the input buffer to indicate that it needs more.
Therefore, the size check in optee_from_msg_param() is incorrect and needs to be removed. This fixes a number of failed test cases in the GlobalPlatform TEE Initial Configuratiom Test Suite v2_0_0_0-2017_06_09 when OP-TEE is compiled without dynamic shared memory support (CFG_CORE_DYN_SHM=n).
Reviewed-by: Sumit Garg sumit.garg@linaro.org Suggested-by: Jens Wiklander jens.wiklander@linaro.org Signed-off-by: Jerome Forissier jerome@forissier.org Signed-off-by: Jens Wiklander jens.wiklander@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tee/optee/core.c | 10 ---------- 1 file changed, 10 deletions(-)
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index cf4718c6d35d..63542c1cc291 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -79,16 +79,6 @@ int optee_from_msg_param(struct tee_param *params, size_t num_params, return rc; p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa; p->u.memref.shm = shm; - - /* Check that the memref is covered by the shm object */ - if (p->u.memref.size) { - size_t o = p->u.memref.shm_offs + - p->u.memref.size - 1; - - rc = tee_shm_get_pa(shm, o, NULL); - if (rc) - return rc; - } break; case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT: case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit 58ef9356260c291a4321e07ff507f31a1d8212af ]
We sometimes see COMMAND_IGNORED responses during the clock stop sequence. It turns out we already have information if devices are present on a link, so we should only prepare those when they are attached.
In addition, even when COMMAND_IGNORED are received, we should still proceed with the clock stop. The device will not be prepared but that's not a problem.
The only case where the clock stop will fail is if the Cadence IP reports an error (including a timeout), or if the devices throw a COMMAND_FAILED response.
BugLink: https://github.com/thesofproject/linux/issues/2621 Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Rander Wang rander.wang@intel.com Reviewed-by: Guennadi Liakhovetski guennadi.liakhovetski@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Link: https://lore.kernel.org/r/20210323013707.21455-1-yung-chuan.liao@linux.intel... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soundwire/cadence_master.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c index 580660599f46..c6d421a4b91b 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -1449,10 +1449,12 @@ int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake) }
/* Prepare slaves for clock stop */ - ret = sdw_bus_prep_clk_stop(&cdns->bus); - if (ret < 0) { - dev_err(cdns->dev, "prepare clock stop failed %d", ret); - return ret; + if (slave_present) { + ret = sdw_bus_prep_clk_stop(&cdns->bus); + if (ret < 0 && ret != -ENODATA) { + dev_err(cdns->dev, "prepare clock stop failed %d\n", ret); + return ret; + } }
/*
From: Robin Murphy robin.murphy@arm.com
[ Upstream commit 11fa1dc8020a2a9e0c59998920092d4df3fb7308 ]
By virtue of using platform_irq_get_optional() under the covers, platform_irq_count() needs the target interrupt controller to be available and may return -EPROBE_DEFER if it isn't. Let's use dev_err_probe() to avoid a spurious error log (and help debug any deferral issues) in that case.
Reported-by: Paul Menzel pmenzel@molgen.mpg.de Signed-off-by: Robin Murphy robin.murphy@arm.com Link: https://lore.kernel.org/r/073d5e0d3ed1f040592cb47ca6fe3759f40cc7d1.161677456... Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/perf/arm_pmu_platform.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/perf/arm_pmu_platform.c b/drivers/perf/arm_pmu_platform.c index 933bd8410fc2..bb6ae955083a 100644 --- a/drivers/perf/arm_pmu_platform.c +++ b/drivers/perf/arm_pmu_platform.c @@ -6,6 +6,7 @@ * Copyright (C) 2010 ARM Ltd., Will Deacon will.deacon@arm.com */ #define pr_fmt(fmt) "hw perfevents: " fmt +#define dev_fmt pr_fmt
#include <linux/bug.h> #include <linux/cpumask.h> @@ -100,10 +101,8 @@ static int pmu_parse_irqs(struct arm_pmu *pmu) struct pmu_hw_events __percpu *hw_events = pmu->hw_events;
num_irqs = platform_irq_count(pdev); - if (num_irqs < 0) { - pr_err("unable to count PMU IRQs\n"); - return num_irqs; - } + if (num_irqs < 0) + return dev_err_probe(&pdev->dev, num_irqs, "unable to count PMU IRQs\n");
/* * In this case we have no idea which CPUs are covered by the PMU.
From: Robin Murphy robin.murphy@arm.com
[ Upstream commit e338cb6bef254821a8c095018fd27254d74bfd6a ]
If we're aborting after failing to register the PMU device, we probably don't want to leak the IRQs that we've claimed.
Signed-off-by: Robin Murphy robin.murphy@arm.com Link: https://lore.kernel.org/r/53031a607fc8412a60024bfb3bb8cd7141f998f5.161677456... Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/perf/arm_pmu_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/perf/arm_pmu_platform.c b/drivers/perf/arm_pmu_platform.c index bb6ae955083a..ef9676418c9f 100644 --- a/drivers/perf/arm_pmu_platform.c +++ b/drivers/perf/arm_pmu_platform.c @@ -235,7 +235,7 @@ int arm_pmu_device_probe(struct platform_device *pdev,
ret = armpmu_register(pmu); if (ret) - goto out_free; + goto out_free_irqs;
return 0;
From: Eric Biggers ebiggers@google.com
[ Upstream commit a181e0fdb2164268274453b5b291589edbb9b22d ]
On big endian CPUs, the ChaCha20-based CRNG is using the wrong endianness for the ChaCha20 constants.
This doesn't matter cryptographically, but technically it means it's not ChaCha20 anymore. Fix it to always use the standard constants.
Cc: linux-crypto@vger.kernel.org Cc: Andy Lutomirski luto@kernel.org Cc: Jann Horn jannh@google.com Cc: Theodore Ts'o tytso@mit.edu Acked-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Eric Biggers ebiggers@google.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/random.c | 4 ++-- include/crypto/chacha.h | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c index f462b9d2f5a5..340ad21491e2 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -819,7 +819,7 @@ static bool __init crng_init_try_arch_early(struct crng_state *crng)
static void __maybe_unused crng_initialize_secondary(struct crng_state *crng) { - memcpy(&crng->state[0], "expand 32-byte k", 16); + chacha_init_consts(crng->state); _get_random_bytes(&crng->state[4], sizeof(__u32) * 12); crng_init_try_arch(crng); crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; @@ -827,7 +827,7 @@ static void __maybe_unused crng_initialize_secondary(struct crng_state *crng)
static void __init crng_initialize_primary(struct crng_state *crng) { - memcpy(&crng->state[0], "expand 32-byte k", 16); + chacha_init_consts(crng->state); _extract_entropy(&input_pool, &crng->state[4], sizeof(__u32) * 12, 0); if (crng_init_try_arch_early(crng) && trust_cpu) { invalidate_batched_entropy(); diff --git a/include/crypto/chacha.h b/include/crypto/chacha.h index 3a1c72fdb7cf..dabaee698718 100644 --- a/include/crypto/chacha.h +++ b/include/crypto/chacha.h @@ -47,13 +47,18 @@ static inline void hchacha_block(const u32 *state, u32 *out, int nrounds) hchacha_block_generic(state, out, nrounds); }
-void chacha_init_arch(u32 *state, const u32 *key, const u8 *iv); -static inline void chacha_init_generic(u32 *state, const u32 *key, const u8 *iv) +static inline void chacha_init_consts(u32 *state) { state[0] = 0x61707865; /* "expa" */ state[1] = 0x3320646e; /* "nd 3" */ state[2] = 0x79622d32; /* "2-by" */ state[3] = 0x6b206574; /* "te k" */ +} + +void chacha_init_arch(u32 *state, const u32 *key, const u8 *iv); +static inline void chacha_init_generic(u32 *state, const u32 *key, const u8 *iv) +{ + chacha_init_consts(state); state[4] = key[0]; state[5] = key[1]; state[6] = key[2];
From: Chunfeng Yun chunfeng.yun@mediatek.com
[ Upstream commit bee1f89aad2a51cd3339571bc8eadbb0dc88a683 ]
The xHCI driver support usb2 HW LPM by default, here add support XHCI_HW_LPM_DISABLE quirk, then we can disable usb2 lpm when need it.
Signed-off-by: Chunfeng Yun chunfeng.yun@mediatek.com Link: https://lore.kernel.org/r/1617181553-3503-4-git-send-email-chunfeng.yun@medi... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci-mtk.c | 3 +++ drivers/usb/host/xhci-mtk.h | 1 + 2 files changed, 4 insertions(+)
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 2f27dc0d9c6b..1c331577fca9 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -397,6 +397,8 @@ static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_SPURIOUS_SUCCESS; if (mtk->lpm_support) xhci->quirks |= XHCI_LPM_SUPPORT; + if (mtk->u2_lpm_disable) + xhci->quirks |= XHCI_HW_LPM_DISABLE;
/* * MTK xHCI 0.96: PSA is 1 by default even if doesn't support stream, @@ -469,6 +471,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) return ret;
mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable"); + mtk->u2_lpm_disable = of_property_read_bool(node, "usb2-lpm-disable"); /* optional property, ignore the error if it does not exist */ of_property_read_u32(node, "mediatek,u3p-dis-msk", &mtk->u3p_dis_msk); diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index cbb09dfea62e..080109012b9a 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -150,6 +150,7 @@ struct xhci_hcd_mtk { struct phy **phys; int num_phys; bool lpm_support; + bool u2_lpm_disable; /* usb remote wakeup */ bool uwk_en; struct regmap *uwk;
Hi!
[ Upstream commit bee1f89aad2a51cd3339571bc8eadbb0dc88a683 ]
The xHCI driver support usb2 HW LPM by default, here add support XHCI_HW_LPM_DISABLE quirk, then we can disable usb2 lpm when need it.
This is only needed with corresponding DTS, and I don't see such DTS entry in mainline or stable.
We may not want this in stable.
Best regards, Pavel
From: Russ Weight russell.h.weight@intel.com
[ Upstream commit a78a51a851ed3edc83264a67e2ba77a34f27965f ]
This patch adds the approved PCI Express Device IDs for the PF and VF for the card for D5005 PAC cards.
Signed-off-by: Russ Weight russell.h.weight@intel.com Signed-off-by: Matthew Gerlach matthew.gerlach@linux.intel.com Signed-off-by: Moritz Fischer mdf@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/fpga/dfl-pci.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/fpga/dfl-pci.c b/drivers/fpga/dfl-pci.c index a2203d03c9e2..bc108ee8e9eb 100644 --- a/drivers/fpga/dfl-pci.c +++ b/drivers/fpga/dfl-pci.c @@ -61,14 +61,16 @@ static void cci_pci_free_irq(struct pci_dev *pcidev) }
/* PCI Device ID */ -#define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD -#define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0 -#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4 -#define PCIE_DEVICE_ID_INTEL_PAC_N3000 0x0B30 +#define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD +#define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0 +#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4 +#define PCIE_DEVICE_ID_INTEL_PAC_N3000 0x0B30 +#define PCIE_DEVICE_ID_INTEL_PAC_D5005 0x0B2B /* VF Device */ -#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF -#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1 -#define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5 +#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF +#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1 +#define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5 +#define PCIE_DEVICE_ID_INTEL_PAC_D5005_VF 0x0B2C
static struct pci_device_id cci_pcie_id_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X),}, @@ -78,6 +80,8 @@ static struct pci_device_id cci_pcie_id_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X),}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X),}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_N3000),}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005),}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF),}, {0,} }; MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
From: Mathias Nyman mathias.nyman@linux.intel.com
[ Upstream commit 8a157d2ff104d2849c58226a1fd02365d7d60150 ]
return if rhub->ports is null after rhub->ports = kcalloc_node() Klockwork reported issue
Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20210406070208.3406266-2-mathias.nyman@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci-mem.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 1ad0ac8c8209..8ce043e6ed87 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2263,6 +2263,9 @@ static void xhci_create_rhub_port_array(struct xhci_hcd *xhci, return; rhub->ports = kcalloc_node(rhub->num_ports, sizeof(*rhub->ports), flags, dev_to_node(dev)); + if (!rhub->ports) + return; + for (i = 0; i < HCS_MAX_PORTS(xhci->hcs_params1); i++) { if (xhci->hw_ports[i].rhub != rhub || xhci->hw_ports[i].hcd_portnum == DUPLICATE_ENTRY)
From: Mathias Nyman mathias.nyman@linux.intel.com
[ Upstream commit 597899d2f7c5619c87185ee7953d004bd37fd0eb ]
Don't dereference ctrl_ctx before checking it's valid. Issue reported by Klockwork
Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20210406070208.3406266-3-mathias.nyman@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index c449de6164b1..384076e169f4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3227,6 +3227,14 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
/* config ep command clears toggle if add and drop ep flags are set */ ctrl_ctx = xhci_get_input_control_ctx(cfg_cmd->in_ctx); + if (!ctrl_ctx) { + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_free_command(xhci, cfg_cmd); + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", + __func__); + goto cleanup; + } + xhci_setup_input_ctx_for_config_ep(xhci, cfg_cmd->in_ctx, vdev->out_ctx, ctrl_ctx, ep_flag, ep_flag); xhci_endpoint_copy(xhci, cfg_cmd->in_ctx, vdev->out_ctx, ep_index);
From: Mathias Nyman mathias.nyman@linux.intel.com
[ Upstream commit 286fd02fd54b6acab65809549cf5fb3f2a886696 ]
The Max Interrupters supported by the controller is given in a 10bit wide bitfield, but the driver uses a fixed 128 size array to index these interrupters.
Klockwork reports a possible array out of bounds case which in theory is possible. In practice this hasn't been hit as a common number of Max Interrupters for new controllers is 8, not even close to 128.
This needs to be fixed anyway
Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20210406070208.3406266-4-mathias.nyman@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 384076e169f4..dbe5553872ff 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -228,6 +228,7 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci) struct device *dev = xhci_to_hcd(xhci)->self.sysdev; int err, i; u64 val; + u32 intrs;
/* * Some Renesas controllers get into a weird state if they are @@ -266,7 +267,10 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci) if (upper_32_bits(val)) xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring);
- for (i = 0; i < HCS_MAX_INTRS(xhci->hcs_params1); i++) { + intrs = min_t(u32, HCS_MAX_INTRS(xhci->hcs_params1), + ARRAY_SIZE(xhci->run_regs->ir_set)); + + for (i = 0; i < intrs; i++) { struct xhci_intr_reg __iomem *ir;
ir = &xhci->run_regs->ir_set[i];
From: Bhaumik Bhatt bbhatt@codeaurora.org
[ Upstream commit 4e44ae3d6d9c2c2a6d9356dd279c925532d5cd8c ]
If a channel was explicitly stopped but not reset and a driver remove is issued, clean up the channel context such that it is reflected on the device. This move is useful if a client driver module is unloaded or a device crash occurs with the host having placed the channel in a stopped state.
Signed-off-by: Bhaumik Bhatt bbhatt@codeaurora.org Reviewed-by: Hemant Kumar hemantk@codeaurora.org Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Link: https://lore.kernel.org/r/1617311778-1254-3-git-send-email-bbhatt@codeaurora... Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/mhi/core/init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c index 3422ea133deb..0d0386f67ffe 100644 --- a/drivers/bus/mhi/core/init.c +++ b/drivers/bus/mhi/core/init.c @@ -1280,7 +1280,8 @@ static int mhi_driver_remove(struct device *dev)
mutex_lock(&mhi_chan->mutex);
- if (ch_state[dir] == MHI_CH_STATE_ENABLED && + if ((ch_state[dir] == MHI_CH_STATE_ENABLED || + ch_state[dir] == MHI_CH_STATE_STOP) && !mhi_chan->offload_ch) mhi_deinit_chan_ctxt(mhi_cntrl, mhi_chan);
From: Ludovic Desroches ludovic.desroches@microchip.com
[ Upstream commit ca7a049ad1a72ec5f03d1330b53575237fcb727c ]
Having a button code and not a key code causes issues with libinput. udev won't set ID_INPUT_KEY. If it is forced, then it causes a bug within libinput.
Signed-off-by: Ludovic Desroches ludovic.desroches@microchip.com Signed-off-by: Nicolas Ferre nicolas.ferre@microchip.com Link: https://lore.kernel.org/r/20210402130227.21478-1-nicolas.ferre@microchip.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/at91-sam9x60ek.dts | 3 ++- arch/arm/boot/dts/at91-sama5d27_som1_ek.dts | 3 ++- arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts | 3 ++- arch/arm/boot/dts/at91-sama5d2_icp.dts | 3 ++- arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts | 3 ++- arch/arm/boot/dts/at91-sama5d2_xplained.dts | 3 ++- arch/arm/boot/dts/at91-sama5d3_xplained.dts | 3 ++- arch/arm/boot/dts/at91sam9260ek.dts | 3 ++- arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 3 ++- 9 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts index 775ceb3acb6c..edca66c232c1 100644 --- a/arch/arm/boot/dts/at91-sam9x60ek.dts +++ b/arch/arm/boot/dts/at91-sam9x60ek.dts @@ -8,6 +8,7 @@ */ /dts-v1/; #include "sam9x60.dtsi" +#include <dt-bindings/input/input.h>
/ { model = "Microchip SAM9X60-EK"; @@ -84,7 +85,7 @@ sw1 { label = "SW1"; gpios = <&pioD 18 GPIO_ACTIVE_LOW>; - linux,code=<0x104>; + linux,code=<KEY_PROG1>; wakeup-source; }; }; diff --git a/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts b/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts index 0e159f879c15..d3cd2443ba25 100644 --- a/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts +++ b/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts @@ -11,6 +11,7 @@ #include "at91-sama5d27_som1.dtsi" #include <dt-bindings/mfd/atmel-flexcom.h> #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h>
/ { model = "Atmel SAMA5D27 SOM1 EK"; @@ -467,7 +468,7 @@ pb4 { label = "USER"; gpios = <&pioA PIN_PA29 GPIO_ACTIVE_LOW>; - linux,code = <0x104>; + linux,code = <KEY_PROG1>; wakeup-source; }; }; diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts b/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts index 6b38fa3f5568..4883b84b4ede 100644 --- a/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts +++ b/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts @@ -8,6 +8,7 @@ */ /dts-v1/; #include "at91-sama5d27_wlsom1.dtsi" +#include <dt-bindings/input/input.h>
/ { model = "Microchip SAMA5D27 WLSOM1 EK"; @@ -35,7 +36,7 @@ sw4 { label = "USER BUTTON"; gpios = <&pioA PIN_PB2 GPIO_ACTIVE_LOW>; - linux,code = <0x104>; + linux,code = <KEY_PROG1>; wakeup-source; }; }; diff --git a/arch/arm/boot/dts/at91-sama5d2_icp.dts b/arch/arm/boot/dts/at91-sama5d2_icp.dts index 6783cf16ff81..19bb50f50c1f 100644 --- a/arch/arm/boot/dts/at91-sama5d2_icp.dts +++ b/arch/arm/boot/dts/at91-sama5d2_icp.dts @@ -12,6 +12,7 @@ #include "sama5d2.dtsi" #include "sama5d2-pinfunc.h" #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> #include <dt-bindings/mfd/atmel-flexcom.h>
/ { @@ -51,7 +52,7 @@ sw4 { label = "USER_PB1"; gpios = <&pioA PIN_PD0 GPIO_ACTIVE_LOW>; - linux,code = <0x104>; + linux,code = <KEY_PROG1>; wakeup-source; }; }; diff --git a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts index c894c7c788a9..1c6361ba1aca 100644 --- a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts +++ b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts @@ -11,6 +11,7 @@ #include "sama5d2-pinfunc.h" #include <dt-bindings/mfd/atmel-flexcom.h> #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> #include <dt-bindings/pinctrl/at91.h>
/ { @@ -403,7 +404,7 @@ bp1 { label = "PB_USER"; gpios = <&pioA PIN_PA10 GPIO_ACTIVE_LOW>; - linux,code = <0x104>; + linux,code = <KEY_PROG1>; wakeup-source; }; }; diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts index 058fae1b4a76..d767968ae217 100644 --- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts @@ -10,6 +10,7 @@ #include "sama5d2-pinfunc.h" #include <dt-bindings/mfd/atmel-flexcom.h> #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> #include <dt-bindings/regulator/active-semi,8945a-regulator.h>
/ { @@ -713,7 +714,7 @@ bp1 { label = "PB_USER"; gpios = <&pioA PIN_PB9 GPIO_ACTIVE_LOW>; - linux,code = <0x104>; + linux,code = <KEY_PROG1>; wakeup-source; }; }; diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts index 5179258f9247..9c55a921263b 100644 --- a/arch/arm/boot/dts/at91-sama5d3_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts @@ -7,6 +7,7 @@ */ /dts-v1/; #include "sama5d36.dtsi" +#include <dt-bindings/input/input.h>
/ { model = "SAMA5D3 Xplained"; @@ -354,7 +355,7 @@ bp3 { label = "PB_USER"; gpios = <&pioE 29 GPIO_ACTIVE_LOW>; - linux,code = <0x104>; + linux,code = <KEY_PROG1>; wakeup-source; }; }; diff --git a/arch/arm/boot/dts/at91sam9260ek.dts b/arch/arm/boot/dts/at91sam9260ek.dts index d3446e42b598..ce96345d28a3 100644 --- a/arch/arm/boot/dts/at91sam9260ek.dts +++ b/arch/arm/boot/dts/at91sam9260ek.dts @@ -7,6 +7,7 @@ */ /dts-v1/; #include "at91sam9260.dtsi" +#include <dt-bindings/input/input.h>
/ { model = "Atmel at91sam9260ek"; @@ -156,7 +157,7 @@ btn4 { label = "Button 4"; gpios = <&pioA 31 GPIO_ACTIVE_LOW>; - linux,code = <0x104>; + linux,code = <KEY_PROG1>; wakeup-source; }; }; diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index 6e6e672c0b86..87bb39060e8b 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -5,6 +5,7 @@ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com */ #include "at91sam9g20.dtsi" +#include <dt-bindings/input/input.h>
/ {
@@ -234,7 +235,7 @@ btn4 { label = "Button 4"; gpios = <&pioA 31 GPIO_ACTIVE_LOW>; - linux,code = <0x104>; + linux,code = <KEY_PROG1>; wakeup-source; }; };
From: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com
[ Upstream commit 2e70b710f36c80b6e78cf32a5c30b46dbb72213c ]
The current string size to print cpulist can accommodate upto 80 logical CPUs per package. But this limit is not enough. So increase the string size. Also prevent buffer overflow, if the string size reaches limit.
Signed-off-by: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/power/x86/intel-speed-select/isst-display.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index e105fece47b6..f32ce0362eb7 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -25,10 +25,14 @@ static void printcpulist(int str_len, char *str, int mask_size, index = snprintf(&str[curr_index], str_len - curr_index, ","); curr_index += index; + if (curr_index >= str_len) + break; } index = snprintf(&str[curr_index], str_len - curr_index, "%d", i); curr_index += index; + if (curr_index >= str_len) + break; first = 0; } } @@ -64,10 +68,14 @@ static void printcpumask(int str_len, char *str, int mask_size, index = snprintf(&str[curr_index], str_len - curr_index, "%08x", mask[i]); curr_index += index; + if (curr_index >= str_len) + break; if (i) { strncat(&str[curr_index], ",", str_len - curr_index); curr_index++; } + if (curr_index >= str_len) + break; }
free(mask); @@ -185,7 +193,7 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level, int disp_level) { char header[256]; - char value[256]; + char value[512];
snprintf(header, sizeof(header), "speed-select-base-freq-properties"); format_and_print(outf, disp_level, header, NULL); @@ -349,7 +357,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, struct isst_pkg_ctdp *pkg_dev) { char header[256]; - char value[256]; + char value[512]; static int level; int i;
From: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com
[ Upstream commit 5c782817a981981917ec3c647cf521022ee07143 ]
In some cases when firmware is busy or updating, some mailbox commands still timeout on some newer CPUs. To fix this issue, change how we process timeout.
With this change, replaced timeout from using simple count with real timeout in micro-seconds using ktime. When the command response takes more than average processing time, yield to other tasks. The worst case timeout is extended upto 1 milli-second.
Signed-off-by: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com Link: https://lore.kernel.org/r/20210330220840.3113959-1-srinivas.pandruvada@linux... Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../intel_speed_select_if/isst_if_mbox_pci.c | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c b/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c index 95f01e7a87d5..da958aa8468d 100644 --- a/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c +++ b/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c @@ -21,12 +21,16 @@ #define PUNIT_MAILBOX_BUSY_BIT 31
/* - * The average time to complete some commands is about 40us. The current - * count is enough to satisfy 40us. But when the firmware is very busy, this - * causes timeout occasionally. So increase to deal with some worst case - * scenarios. Most of the command still complete in few us. + * The average time to complete mailbox commands is less than 40us. Most of + * the commands complete in few micro seconds. But the same firmware handles + * requests from all power management features. + * We can create a scenario where we flood the firmware with requests then + * the mailbox response can be delayed for 100s of micro seconds. So define + * two timeouts. One for average case and one for long. + * If the firmware is taking more than average, just call cond_resched(). */ -#define OS_MAILBOX_RETRY_COUNT 100 +#define OS_MAILBOX_TIMEOUT_AVG_US 40 +#define OS_MAILBOX_TIMEOUT_MAX_US 1000
struct isst_if_device { struct mutex mutex; @@ -35,11 +39,13 @@ struct isst_if_device { static int isst_if_mbox_cmd(struct pci_dev *pdev, struct isst_if_mbox_cmd *mbox_cmd) { - u32 retries, data; + s64 tm_delta = 0; + ktime_t tm; + u32 data; int ret;
/* Poll for rb bit == 0 */ - retries = OS_MAILBOX_RETRY_COUNT; + tm = ktime_get(); do { ret = pci_read_config_dword(pdev, PUNIT_MAILBOX_INTERFACE, &data); @@ -48,11 +54,14 @@ static int isst_if_mbox_cmd(struct pci_dev *pdev,
if (data & BIT_ULL(PUNIT_MAILBOX_BUSY_BIT)) { ret = -EBUSY; + tm_delta = ktime_us_delta(ktime_get(), tm); + if (tm_delta > OS_MAILBOX_TIMEOUT_AVG_US) + cond_resched(); continue; } ret = 0; break; - } while (--retries); + } while (tm_delta < OS_MAILBOX_TIMEOUT_MAX_US);
if (ret) return ret; @@ -74,7 +83,8 @@ static int isst_if_mbox_cmd(struct pci_dev *pdev, return ret;
/* Poll for rb bit == 0 */ - retries = OS_MAILBOX_RETRY_COUNT; + tm_delta = 0; + tm = ktime_get(); do { ret = pci_read_config_dword(pdev, PUNIT_MAILBOX_INTERFACE, &data); @@ -83,6 +93,9 @@ static int isst_if_mbox_cmd(struct pci_dev *pdev,
if (data & BIT_ULL(PUNIT_MAILBOX_BUSY_BIT)) { ret = -EBUSY; + tm_delta = ktime_us_delta(ktime_get(), tm); + if (tm_delta > OS_MAILBOX_TIMEOUT_AVG_US) + cond_resched(); continue; }
@@ -96,7 +109,7 @@ static int isst_if_mbox_cmd(struct pci_dev *pdev, mbox_cmd->resp_data = data; ret = 0; break; - } while (--retries); + } while (tm_delta < OS_MAILBOX_TIMEOUT_MAX_US);
return ret; }
From: Wei Yongjun weiyongjun1@huawei.com
[ Upstream commit 9b844b087124c1538d05f40fda8a4fec75af55be ]
Call spi_master_get() holds the reference count to master device, thus we need an additional spi_master_put() call to reduce the reference count, otherwise we will leak a reference to master.
This commit fix it by removing the unnecessary spi_master_get().
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Wei Yongjun weiyongjun1@huawei.com Link: https://lore.kernel.org/r/20210409082955.2907950-1-weiyongjun1@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-dln2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-dln2.c b/drivers/spi/spi-dln2.c index 75b33d7d14b0..9a4d942fafcf 100644 --- a/drivers/spi/spi-dln2.c +++ b/drivers/spi/spi-dln2.c @@ -780,7 +780,7 @@ exit_free_master:
static int dln2_spi_remove(struct platform_device *pdev) { - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct spi_master *master = platform_get_drvdata(pdev); struct dln2_spi *dln2 = spi_master_get_devdata(master);
pm_runtime_disable(&pdev->dev);
From: Wei Yongjun weiyongjun1@huawei.com
[ Upstream commit a23faea76d4cf5f75decb574491e66f9ecd707e7 ]
Call spi_master_get() holds the reference count to master device, thus we need an additional spi_master_put() call to reduce the reference count, otherwise we will leak a reference to master.
This commit fix it by removing the unnecessary spi_master_get().
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Wei Yongjun weiyongjun1@huawei.com Link: https://lore.kernel.org/r/20210409082954.2906933-1-weiyongjun1@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-omap-100k.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c index 36a4922a134a..ccd817ee4917 100644 --- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c @@ -424,7 +424,7 @@ err:
static int omap1_spi100k_remove(struct platform_device *pdev) { - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct spi_master *master = platform_get_drvdata(pdev); struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
pm_runtime_disable(&pdev->dev); @@ -438,7 +438,7 @@ static int omap1_spi100k_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int omap1_spi100k_runtime_suspend(struct device *dev) { - struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); + struct spi_master *master = dev_get_drvdata(dev); struct omap1_spi100k *spi100k = spi_master_get_devdata(master);
clk_disable_unprepare(spi100k->ick); @@ -449,7 +449,7 @@ static int omap1_spi100k_runtime_suspend(struct device *dev)
static int omap1_spi100k_runtime_resume(struct device *dev) { - struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); + struct spi_master *master = dev_get_drvdata(dev); struct omap1_spi100k *spi100k = spi_master_get_devdata(master); int ret;
From: Wang Li wangli74@huawei.com
[ Upstream commit cec77e0a249892ceb10061bf17b63f9fb111d870 ]
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in reference leak here. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Wang Li wangli74@huawei.com Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Link: https://lore.kernel.org/r/20210409095458.29921-1-wangli74@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-qup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index 8dcb2e70735c..d39dec6d1c91 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -1263,7 +1263,7 @@ static int spi_qup_remove(struct platform_device *pdev) struct spi_qup *controller = spi_master_get_devdata(master); int ret;
- ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) return ret;
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit a932ee40c276767cd55fadec9e38829bf441db41 ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20210407092947.3271507-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/udc/tegra-xudc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c index 580bef8eb4cb..2319c9737c2b 100644 --- a/drivers/usb/gadget/udc/tegra-xudc.c +++ b/drivers/usb/gadget/udc/tegra-xudc.c @@ -3883,7 +3883,7 @@ static int tegra_xudc_remove(struct platform_device *pdev)
pm_runtime_get_sync(xudc->dev);
- cancel_delayed_work(&xudc->plc_reset_work); + cancel_delayed_work_sync(&xudc->plc_reset_work); cancel_work_sync(&xudc->usb_role_sw_work);
usb_del_gadget_udc(&xudc->gadget);
From: Bixuan Cui cuibixuan@huawei.com
[ Upstream commit 9535b99533904e9bc1607575aa8e9539a55435d7 ]
pm_runtime_get_sync will increment pm usage counter even it failed. thus a pairing decrement is needed. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Bixuan Cui cuibixuan@huawei.com Link: https://lore.kernel.org/r/20210408091836.55227-1-cuibixuan@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/musb/musb_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index fc0457db62e1..8f09a387b773 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2070,7 +2070,7 @@ static void musb_irq_work(struct work_struct *data) struct musb *musb = container_of(data, struct musb, irq_work.work); int error;
- error = pm_runtime_get_sync(musb->controller); + error = pm_runtime_resume_and_get(musb->controller); if (error < 0) { dev_err(musb->controller, "Could not enable: %i\n", error);
From: Bixuan Cui cuibixuan@huawei.com
[ Upstream commit 025f97d188006eeee4417bb475a6878d1e0eed3f ]
pm_runtime_get_sync will increment pm usage counter even it failed. thus a pairing decrement is needed. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Bixuan Cui cuibixuan@huawei.com Link: https://lore.kernel.org/r/20210408130831.56239-1-cuibixuan@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/core/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 17202b2ee063..22a86ae4f639 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3555,7 +3555,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) u16 portchange, portstatus;
if (!test_and_set_bit(port1, hub->child_usage_bits)) { - status = pm_runtime_get_sync(&port_dev->dev); + status = pm_runtime_resume_and_get(&port_dev->dev); if (status < 0) { dev_dbg(&udev->dev, "can't resume usb port, status %d\n", status);
From: Thinh Nguyen Thinh.Nguyen@synopsys.com
[ Upstream commit 475e8be53d0496f9bc6159f4abb3ff5f9b90e8de ]
If the device doesn't support LPM, make sure to disable the LPM capability and don't advertise to the host that it supports it.
Acked-by: Felipe Balbi balbi@kernel.org Signed-off-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Link: https://lore.kernel.org/r/9e68527ff932b1646f92a7593d4092a903754666.161836607... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/core.c | 2 ++ drivers/usb/dwc3/core.h | 4 +++- drivers/usb/dwc3/gadget.c | 9 ++++++++- 3 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 3101f0dcf6ae..1ffeb00b9391 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1297,6 +1297,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) "snps,usb3_lpm_capable"); dwc->usb2_lpm_disable = device_property_read_bool(dev, "snps,usb2-lpm-disable"); + dwc->usb2_gadget_lpm_disable = device_property_read_bool(dev, + "snps,usb2-gadget-lpm-disable"); device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd", &rx_thr_num_pkt_prd); device_property_read_u8(dev, "snps,rx-max-burst-prd", diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 1b241f937d8f..575a93b4f120 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1026,7 +1026,8 @@ struct dwc3_scratchpad_array { * @dis_start_transfer_quirk: set if start_transfer failure SW workaround is * not needed for DWC_usb31 version 1.70a-ea06 and below * @usb3_lpm_capable: set if hadrware supports Link Power Management - * @usb2_lpm_disable: set to disable usb2 lpm + * @usb2_lpm_disable: set to disable usb2 lpm for host + * @usb2_gadget_lpm_disable: set to disable usb2 lpm for gadget * @disable_scramble_quirk: set if we enable the disable scramble quirk * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk @@ -1227,6 +1228,7 @@ struct dwc3 { unsigned dis_start_transfer_quirk:1; unsigned usb3_lpm_capable:1; unsigned usb2_lpm_disable:1; + unsigned usb2_gadget_lpm_disable:1;
unsigned disable_scramble_quirk:1; unsigned u2exit_lfps_quirk:1; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 5b5520286eff..0ffd2a4e6309 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3398,6 +3398,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) /* Enable USB2 LPM Capability */
if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A) && + !dwc->usb2_gadget_lpm_disable && (speed != DWC3_DSTS_SUPERSPEED) && (speed != DWC3_DSTS_SUPERSPEED_PLUS)) { reg = dwc3_readl(dwc->regs, DWC3_DCFG); @@ -3424,6 +3425,12 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
dwc3_gadget_dctl_write_safe(dwc, reg); } else { + if (dwc->usb2_gadget_lpm_disable) { + reg = dwc3_readl(dwc->regs, DWC3_DCFG); + reg &= ~DWC3_DCFG_LPM_CAP; + dwc3_writel(dwc->regs, DWC3_DCFG, reg); + } + reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg &= ~DWC3_DCTL_HIRD_THRES_MASK; dwc3_gadget_dctl_write_safe(dwc, reg); @@ -3871,7 +3878,7 @@ int dwc3_gadget_init(struct dwc3 *dwc) dwc->gadget->speed = USB_SPEED_UNKNOWN; dwc->gadget->sg_supported = true; dwc->gadget->name = "dwc3-gadget"; - dwc->gadget->lpm_capable = true; + dwc->gadget->lpm_capable = !dwc->usb2_gadget_lpm_disable;
/* * FIXME We might be setting max_speed to <SUPER, however versions
From: Hillf Danton hdanton@sina.com
[ Upstream commit 0a360e8b65d62fe1a994f0a8da4f8d20877b2100 ]
Add the error path for registering tty devices and roll back in case of error in bid to avoid the UAF like the below one reported.
Plus syzbot reported general protection fault in cdev_del() on Sep 24, 2020 and both cases are down to the kobject_put() in tty_cdev_add().
------------[ cut here ]------------ refcount_t: underflow; use-after-free. WARNING: CPU: 1 PID: 8923 at lib/refcount.c:28 refcount_warn_saturate+0x1cf/0x210 -origin/lib/refcount.c:28 Modules linked in: CPU: 1 PID: 8923 Comm: executor Not tainted 5.12.0-rc5+ #8 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 RIP: 0010:refcount_warn_saturate+0x1cf/0x210 -origin/lib/refcount.c:28 Code: 4f ff ff ff e8 32 fa b5 fe 48 c7 c7 3d f8 f6 86 e8 d6 ab c6 fe c6 05 7c 34 67 04 01 48 c7 c7 68 f8 6d 86 31 c0 e8 81 2e 9d fe <0f> 0b e9 22 ff ff ff e8 05 fa b5 fe 48 c7 c7 3e f8 f6 86 e8 a9 ab RSP: 0018:ffffc90001633c60 EFLAGS: 00010246 RAX: 15d08b2e34b77800 RBX: 0000000000000003 RCX: ffff88804c056c80 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000003 R08: ffffffff813767aa R09: 0001ffffffffffff R10: 0001ffffffffffff R11: ffff88804c056c80 R12: ffff888040b7d000 R13: ffff88804c206938 R14: ffff88804c206900 R15: ffff888041b18488 FS: 00000000022c9940(0000) GS:ffff88807ec00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f9f9b122008 CR3: 0000000044b4b000 CR4: 0000000000750ee0 PKRU: 55555554 Call Trace: __refcount_sub_and_test -origin/./include/linux/refcount.h:283 [inline] __refcount_dec_and_test -origin/./include/linux/refcount.h:315 [inline] refcount_dec_and_test -origin/./include/linux/refcount.h:333 [inline] kref_put -origin/./include/linux/kref.h:64 [inline] kobject_put+0x17b/0x180 -origin/lib/kobject.c:753 cdev_del+0x4b/0x50 -origin/fs/char_dev.c:597 tty_unregister_device+0x99/0xd0 -origin/drivers/tty/tty_io.c:3343 gsmld_detach_gsm -origin/drivers/tty/n_gsm.c:2409 [inline] gsmld_close+0x6c/0x140 -origin/drivers/tty/n_gsm.c:2478 tty_ldisc_close -origin/drivers/tty/tty_ldisc.c:488 [inline] tty_ldisc_kill -origin/drivers/tty/tty_ldisc.c:636 [inline] tty_ldisc_release+0x1b6/0x400 -origin/drivers/tty/tty_ldisc.c:809 tty_release_struct+0x19/0xb0 -origin/drivers/tty/tty_io.c:1714 tty_release+0x9ad/0xa00 -origin/drivers/tty/tty_io.c:1885 __fput+0x260/0x4e0 -origin/fs/file_table.c:280 ____fput+0x11/0x20 -origin/fs/file_table.c:313 task_work_run+0x8e/0x110 -origin/kernel/task_work.c:140 tracehook_notify_resume -origin/./include/linux/tracehook.h:189 [inline] exit_to_user_mode_loop -origin/kernel/entry/common.c:174 [inline] exit_to_user_mode_prepare+0x16b/0x1a0 -origin/kernel/entry/common.c:208 __syscall_exit_to_user_mode_work -origin/kernel/entry/common.c:290 [inline] syscall_exit_to_user_mode+0x20/0x40 -origin/kernel/entry/common.c:301 do_syscall_64+0x45/0x80 -origin/arch/x86/entry/common.c:56 entry_SYSCALL_64_after_hwframe+0x44/0xae
Reported-by: syzbot+c49fe6089f295a05e6f8@syzkaller.appspotmail.com Reported-and-tested-by: Hao Sun sunhao.th@gmail.com Signed-off-by: Hillf Danton hdanton@sina.com Link: https://lore.kernel.org/r/20210412035758.1974-1-hdanton@sina.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index fea1eeac5b90..d76880ae68c8 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2382,8 +2382,18 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) /* Don't register device 0 - this is the control channel and not a usable tty interface */ base = mux_num_to_base(gsm); /* Base for this MUX */ - for (i = 1; i < NUM_DLCI; i++) - tty_register_device(gsm_tty_driver, base + i, NULL); + for (i = 1; i < NUM_DLCI; i++) { + struct device *dev; + + dev = tty_register_device(gsm_tty_driver, + base + i, NULL); + if (IS_ERR(dev)) { + for (i--; i >= 1; i--) + tty_unregister_device(gsm_tty_driver, + base + i); + return PTR_ERR(dev); + } + } } return ret; }
From: Pavel Machek pavel@ucw.cz
[ Upstream commit 18ffbc47d45a1489b664dd68fb3a7610a6e1dea3 ]
Consistently use "< ... +1" in for loops.
Fix of-by-one in for_each_set_bit().
Signed-off-by: Pavel Machek pavel@denx.de Signed-off-by: Alexander Shishkin alexander.shishkin@linux.intel.com Link: https://lore.kernel.org/lkml/20190724095841.GA6952@amd/ Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20210414171251.14672-6-alexander.shishkin@linux.in... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwtracing/intel_th/gth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c index f72803a02391..28509b02a0b5 100644 --- a/drivers/hwtracing/intel_th/gth.c +++ b/drivers/hwtracing/intel_th/gth.c @@ -543,7 +543,7 @@ static void intel_th_gth_disable(struct intel_th_device *thdev, output->active = false;
for_each_set_bit(master, gth->output[output->port].master, - TH_CONFIGURABLE_MASTERS) { + TH_CONFIGURABLE_MASTERS + 1) { gth_master_set(gth, master, -1); } spin_unlock(>h->gth_lock); @@ -697,7 +697,7 @@ static void intel_th_gth_unassign(struct intel_th_device *thdev, othdev->output.port = -1; othdev->output.active = false; gth->output[port].output = NULL; - for (master = 0; master <= TH_CONFIGURABLE_MASTERS; master++) + for (master = 0; master < TH_CONFIGURABLE_MASTERS + 1; master++) if (gth->master[master] == port) gth->master[master] = -1; spin_unlock(>h->gth_lock);
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit e1723d8b87b73ab363256e7ca3af3ddb75855680 ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20210407092716.3270248-1-yangyingliang@huawei.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/ti/phy-twl4030-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/ti/phy-twl4030-usb.c b/drivers/phy/ti/phy-twl4030-usb.c index 9887f908f540..812e5409d359 100644 --- a/drivers/phy/ti/phy-twl4030-usb.c +++ b/drivers/phy/ti/phy-twl4030-usb.c @@ -779,7 +779,7 @@ static int twl4030_usb_remove(struct platform_device *pdev)
usb_remove_phy(&twl->phy); pm_runtime_get_sync(twl->dev); - cancel_delayed_work(&twl->id_workaround_work); + cancel_delayed_work_sync(&twl->id_workaround_work); device_remove_file(twl->dev, &dev_attr_vbus);
/* set transceiver mode to power on defaults */
From: Shixin Liu liushixin2@huawei.com
[ Upstream commit 06cd7423cf451d68bfab289278d7890c9ae01a14 ]
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in reference leak here. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
Signed-off-by: Shixin Liu liushixin2@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 2 +- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c index ed2a69f82e1c..7c355bc2fb06 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c @@ -351,7 +351,7 @@ int sun8i_ss_cipher_init(struct crypto_tfm *tfm) op->enginectx.op.prepare_request = NULL; op->enginectx.op.unprepare_request = NULL;
- err = pm_runtime_get_sync(op->ss->dev); + err = pm_runtime_resume_and_get(op->ss->dev); if (err < 0) { dev_err(op->ss->dev, "pm error %d\n", err); goto error_pm; diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c index e0ddc684798d..80e89066dbd1 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c @@ -753,7 +753,7 @@ static int sun8i_ss_probe(struct platform_device *pdev) if (err) goto error_alg;
- err = pm_runtime_get_sync(ss->dev); + err = pm_runtime_resume_and_get(ss->dev); if (err < 0) goto error_alg;
From: Shixin Liu liushixin2@huawei.com
[ Upstream commit cc987ae9150c255352660d235ab27c834aa527be ]
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in reference leak here. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
Signed-off-by: Shixin Liu liushixin2@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c index 158422ff5695..00194d1d9ae6 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c @@ -932,7 +932,7 @@ static int sun8i_ce_probe(struct platform_device *pdev) if (err) goto error_alg;
- err = pm_runtime_get_sync(ce->dev); + err = pm_runtime_resume_and_get(ce->dev); if (err < 0) goto error_alg;
From: Shixin Liu liushixin2@huawei.com
[ Upstream commit 1cb3ad701970e68f18a9e5d090baf2b1b703d729 ]
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in reference leak here. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
Signed-off-by: Shixin Liu liushixin2@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/stm32/stm32-hash.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c index e3e25278a970..ff5362da118d 100644 --- a/drivers/crypto/stm32/stm32-hash.c +++ b/drivers/crypto/stm32/stm32-hash.c @@ -812,7 +812,7 @@ static void stm32_hash_finish_req(struct ahash_request *req, int err) static int stm32_hash_hw_init(struct stm32_hash_dev *hdev, struct stm32_hash_request_ctx *rctx) { - pm_runtime_get_sync(hdev->dev); + pm_runtime_resume_and_get(hdev->dev);
if (!(HASH_FLAGS_INIT & hdev->flags)) { stm32_hash_write(hdev, HASH_CR, HASH_CR_INIT); @@ -961,7 +961,7 @@ static int stm32_hash_export(struct ahash_request *req, void *out) u32 *preg; unsigned int i;
- pm_runtime_get_sync(hdev->dev); + pm_runtime_resume_and_get(hdev->dev);
while ((stm32_hash_read(hdev, HASH_SR) & HASH_SR_BUSY)) cpu_relax(); @@ -999,7 +999,7 @@ static int stm32_hash_import(struct ahash_request *req, const void *in)
preg = rctx->hw_context;
- pm_runtime_get_sync(hdev->dev); + pm_runtime_resume_and_get(hdev->dev);
stm32_hash_write(hdev, HASH_IMR, *preg++); stm32_hash_write(hdev, HASH_STR, *preg++); @@ -1565,7 +1565,7 @@ static int stm32_hash_remove(struct platform_device *pdev) if (!hdev) return -ENODEV;
- ret = pm_runtime_get_sync(hdev->dev); + ret = pm_runtime_resume_and_get(hdev->dev); if (ret < 0) return ret;
Hi!
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in reference leak here. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
I believe we need to enforce "patches need to be tested" rule at least against robots.
Code was correct in 3/4 instances, this introduces bugs. Yes, last one needs fixing.
Best regards, Pavel
+++ b/drivers/crypto/stm32/stm32-hash.c @@ -812,7 +812,7 @@ static void stm32_hash_finish_req(struct ahash_request *req, int err) static int stm32_hash_hw_init(struct stm32_hash_dev *hdev, struct stm32_hash_request_ctx *rctx) {
- pm_runtime_get_sync(hdev->dev);
- pm_runtime_resume_and_get(hdev->dev);
if (!(HASH_FLAGS_INIT & hdev->flags)) { stm32_hash_write(hdev, HASH_CR, HASH_CR_INIT); @@ -961,7 +961,7 @@ static int stm32_hash_export(struct ahash_request *req, void *out) u32 *preg; unsigned int i;
- pm_runtime_get_sync(hdev->dev);
- pm_runtime_resume_and_get(hdev->dev);
while ((stm32_hash_read(hdev, HASH_SR) & HASH_SR_BUSY)) cpu_relax(); @@ -999,7 +999,7 @@ static int stm32_hash_import(struct ahash_request *req, const void *in) preg = rctx->hw_context;
- pm_runtime_get_sync(hdev->dev);
- pm_runtime_resume_and_get(hdev->dev);
stm32_hash_write(hdev, HASH_IMR, *preg++); stm32_hash_write(hdev, HASH_STR, *preg++);
From: Shixin Liu liushixin2@huawei.com
[ Upstream commit 747bf30fd944f02f341b5f3bc7d97a13f2ae2fbe ]
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in reference leak here. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
Signed-off-by: Shixin Liu liushixin2@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/stm32/stm32-cryp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c index 2670c30332fa..7999b26a16ed 100644 --- a/drivers/crypto/stm32/stm32-cryp.c +++ b/drivers/crypto/stm32/stm32-cryp.c @@ -542,7 +542,7 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) int ret; u32 cfg, hw_mode;
- pm_runtime_get_sync(cryp->dev); + pm_runtime_resume_and_get(cryp->dev);
/* Disable interrupt */ stm32_cryp_write(cryp, CRYP_IMSCR, 0); @@ -2043,7 +2043,7 @@ static int stm32_cryp_remove(struct platform_device *pdev) if (!cryp) return -ENODEV;
- ret = pm_runtime_get_sync(cryp->dev); + ret = pm_runtime_resume_and_get(cryp->dev); if (ret < 0) return ret;
On Mon 2021-05-10 12:18:22, Greg Kroah-Hartman wrote:
From: Shixin Liu liushixin2@huawei.com
[ Upstream commit 747bf30fd944f02f341b5f3bc7d97a13f2ae2fbe ]
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in reference leak here. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
Yes, but that only works when code checks the return value.
+++ b/drivers/crypto/stm32/stm32-cryp.c @@ -542,7 +542,7 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) int ret; u32 cfg, hw_mode;
- pm_runtime_get_sync(cryp->dev);
- pm_runtime_resume_and_get(cryp->dev);
/* Disable interrupt */ stm32_cryp_write(cryp, CRYP_IMSCR, 0);
Again, this is wrong.
@@ -2043,7 +2043,7 @@ static int stm32_cryp_remove(struct platform_device *pdev) if (!cryp) return -ENODEV;
- ret = pm_runtime_get_sync(cryp->dev);
- ret = pm_runtime_resume_and_get(cryp->dev); if (ret < 0) return ret;
But this may be right.
Best regards, Pavel
On 2021/5/10 20:07, Pavel Machek wrote:
On Mon 2021-05-10 12:18:22, Greg Kroah-Hartman wrote:
From: Shixin Liu liushixin2@huawei.com
[ Upstream commit 747bf30fd944f02f341b5f3bc7d97a13f2ae2fbe ]
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in reference leak here. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
Yes, but that only works when code checks the return value.
Thank you for the correction. Yes, You are right that if we carry out runtime resume failed on the path where the return value is not checked, the pm usage counter will be put in later path.
But I have another question. Why don't we check the return values in these path? Does that mean these resumes will never fail?
+++ b/drivers/crypto/stm32/stm32-cryp.c @@ -542,7 +542,7 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) int ret; u32 cfg, hw_mode;
- pm_runtime_get_sync(cryp->dev);
- pm_runtime_resume_and_get(cryp->dev);
/* Disable interrupt */ stm32_cryp_write(cryp, CRYP_IMSCR, 0);
Again, this is wrong.
@@ -2043,7 +2043,7 @@ static int stm32_cryp_remove(struct platform_device *pdev) if (!cryp) return -ENODEV;
- ret = pm_runtime_get_sync(cryp->dev);
- ret = pm_runtime_resume_and_get(cryp->dev); if (ret < 0) return ret;
But this may be right.
Best regards, Pavel
From: Shixin Liu liushixin2@huawei.com
[ Upstream commit 13343badae093977295341d5a050f51ef128821c ]
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in reference leak here. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
Signed-off-by: Shixin Liu liushixin2@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/sa2ul.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c index eda93fab95fe..39d56ab12f27 100644 --- a/drivers/crypto/sa2ul.c +++ b/drivers/crypto/sa2ul.c @@ -2345,7 +2345,7 @@ static int sa_ul_probe(struct platform_device *pdev) dev_set_drvdata(sa_k3_dev, dev_data);
pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) { dev_err(&pdev->dev, "%s: failed to get sync: %d\n", __func__, ret);
From: Shixin Liu liushixin2@huawei.com
[ Upstream commit 1f34cc4a8da34fbb250efb928f9b8c6fe7ee0642 ]
pm_runtime_get_sync will increment pm usage counter even it failed. Forgetting to putting operation will result in reference leak here. Fix it by replacing it with pm_runtime_resume_and_get to keep usage counter balanced.
Signed-off-by: Shixin Liu liushixin2@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/omap-aes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 1b1e0ab0a831..0dd4c6b157de 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -103,7 +103,7 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd) dd->err = 0; }
- err = pm_runtime_get_sync(dd->dev); + err = pm_runtime_resume_and_get(dd->dev); if (err < 0) { dev_err(dd->dev, "failed to get sync: %d\n", err); return err; @@ -1133,7 +1133,7 @@ static int omap_aes_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(dev, DEFAULT_AUTOSUSPEND_DELAY);
pm_runtime_enable(dev); - err = pm_runtime_get_sync(dev); + err = pm_runtime_resume_and_get(dev); if (err < 0) { dev_err(dev, "%s: failed to get_sync(%d)\n", __func__, err); @@ -1302,7 +1302,7 @@ static int omap_aes_suspend(struct device *dev)
static int omap_aes_resume(struct device *dev) { - pm_runtime_get_sync(dev); + pm_runtime_resume_and_get(dev); return 0; } #endif
From: David E. Box david.e.box@linux.intel.com
[ Upstream commit c9f86d6ca6b5e23d30d16ade4b9fff5b922a610a ]
The DMI callbacks, used for quirks, currently access the PMC by getting the address a global pmc_dev struct. Instead, have the callbacks set a global quirk specific variable. In probe, after calling dmi_check_system(), pass pmc_dev to a function that will handle each quirk if its variable condition is met. This allows removing the global pmc_dev later.
Signed-off-by: David E. Box david.e.box@linux.intel.com Reviewed-by: Hans de Goede hdegoede@redhat.com Reviewed-by: Rajneesh Bhardwaj irenic.rajneesh@gmail.com Link: https://lore.kernel.org/r/20210417031252.3020837-2-david.e.box@linux.intel.c... Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/intel_pmc_core.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c index e06b36e87a33..ca32a4c80f62 100644 --- a/drivers/platform/x86/intel_pmc_core.c +++ b/drivers/platform/x86/intel_pmc_core.c @@ -1186,9 +1186,15 @@ static const struct pci_device_id pmc_pci_ids[] = { * the platform BIOS enforces 24Mhz crystal to shutdown * before PMC can assert SLP_S0#. */ +static bool xtal_ignore; static int quirk_xtal_ignore(const struct dmi_system_id *id) { - struct pmc_dev *pmcdev = &pmc; + xtal_ignore = true; + return 0; +} + +static void pmc_core_xtal_ignore(struct pmc_dev *pmcdev) +{ u32 value;
value = pmc_core_reg_read(pmcdev, pmcdev->map->pm_vric1_offset); @@ -1197,7 +1203,6 @@ static int quirk_xtal_ignore(const struct dmi_system_id *id) /* Low Voltage Mode Enable */ value &= ~SPT_PMC_VRIC1_SLPS0LVEN; pmc_core_reg_write(pmcdev, pmcdev->map->pm_vric1_offset, value); - return 0; }
static const struct dmi_system_id pmc_core_dmi_table[] = { @@ -1212,6 +1217,14 @@ static const struct dmi_system_id pmc_core_dmi_table[] = { {} };
+static void pmc_core_do_dmi_quirks(struct pmc_dev *pmcdev) +{ + dmi_check_system(pmc_core_dmi_table); + + if (xtal_ignore) + pmc_core_xtal_ignore(pmcdev); +} + static int pmc_core_probe(struct platform_device *pdev) { static bool device_initialized; @@ -1253,7 +1266,7 @@ static int pmc_core_probe(struct platform_device *pdev) mutex_init(&pmcdev->lock); platform_set_drvdata(pdev, pmcdev); pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(); - dmi_check_system(pmc_core_dmi_table); + pmc_core_do_dmi_quirks(pmcdev);
/* * On TGL, due to a hardware limitation, the GBE LTR blocks PC10 when
Hi!
From: David E. Box david.e.box@linux.intel.com
[ Upstream commit c9f86d6ca6b5e23d30d16ade4b9fff5b922a610a ]
The DMI callbacks, used for quirks, currently access the PMC by getting the address a global pmc_dev struct. Instead, have the callbacks set a global quirk specific variable. In probe, after calling dmi_check_system(), pass pmc_dev to a function that will handle each quirk if its variable condition is met. This allows removing the global pmc_dev later.
This does not fix a bug.. it is preparation for further cleanups that are not queued to 5.10 stable. So this should not be in 5.10 either.
Best regards, Pavel
On Mon, May 10, 2021 at 02:12:40PM +0200, Pavel Machek wrote:
Hi!
From: David E. Box david.e.box@linux.intel.com
[ Upstream commit c9f86d6ca6b5e23d30d16ade4b9fff5b922a610a ]
The DMI callbacks, used for quirks, currently access the PMC by getting the address a global pmc_dev struct. Instead, have the callbacks set a global quirk specific variable. In probe, after calling dmi_check_system(), pass pmc_dev to a function that will handle each quirk if its variable condition is met. This allows removing the global pmc_dev later.
This does not fix a bug.. it is preparation for further cleanups that are not queued to 5.10 stable. So this should not be in 5.10 either.
I'll leave this for now, it will be helpful for later.
thanks,
greg k-h
From: David Bauer mail@david-bauer.net
[ Upstream commit d347b4aaa1a042ea528e385d9070b74c77a14321 ]
When initially probing the SPI slave device, the call for disabling an SPI device without the SPI_CS_HIGH flag is not applied, as the condition for checking whether or not the state to be applied equals the one currently set evaluates to true.
This however might not necessarily be the case, as the chipselect might be active.
Add a force flag to spi_set_cs which allows to override this early exit condition. Set it to false everywhere except when called from spi_setup to sync up the initial CS state.
Fixes commit d40f0b6f2e21 ("spi: Avoid setting the chip select if we don't need to")
Signed-off-by: David Bauer mail@david-bauer.net Link: https://lore.kernel.org/r/20210416195956.121811-1-mail@david-bauer.net Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 4257a2d368f7..1eee8b3c1b38 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -787,7 +787,7 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
/*-------------------------------------------------------------------------*/
-static void spi_set_cs(struct spi_device *spi, bool enable) +static void spi_set_cs(struct spi_device *spi, bool enable, bool force) { bool enable1 = enable;
@@ -795,7 +795,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable) * Avoid calling into the driver (or doing delays) if the chip select * isn't actually changing from the last time this was called. */ - if ((spi->controller->last_cs_enable == enable) && + if (!force && (spi->controller->last_cs_enable == enable) && (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH))) return;
@@ -1243,7 +1243,7 @@ static int spi_transfer_one_message(struct spi_controller *ctlr, struct spi_statistics *statm = &ctlr->statistics; struct spi_statistics *stats = &msg->spi->statistics;
- spi_set_cs(msg->spi, true); + spi_set_cs(msg->spi, true, false);
SPI_STATISTICS_INCREMENT_FIELD(statm, messages); SPI_STATISTICS_INCREMENT_FIELD(stats, messages); @@ -1311,9 +1311,9 @@ fallback_pio: &msg->transfers)) { keep_cs = true; } else { - spi_set_cs(msg->spi, false); + spi_set_cs(msg->spi, false, false); _spi_transfer_cs_change_delay(msg, xfer); - spi_set_cs(msg->spi, true); + spi_set_cs(msg->spi, true, false); } }
@@ -1322,7 +1322,7 @@ fallback_pio:
out: if (ret != 0 || !keep_cs) - spi_set_cs(msg->spi, false); + spi_set_cs(msg->spi, false, false);
if (msg->status == -EINPROGRESS) msg->status = ret; @@ -3400,11 +3400,11 @@ int spi_setup(struct spi_device *spi) */ status = 0;
- spi_set_cs(spi, false); + spi_set_cs(spi, false, true); pm_runtime_mark_last_busy(spi->controller->dev.parent); pm_runtime_put_autosuspend(spi->controller->dev.parent); } else { - spi_set_cs(spi, false); + spi_set_cs(spi, false, true); }
mutex_unlock(&spi->controller->io_mutex);
From: Josef Bacik josef@toxicpanda.com
[ Upstream commit 84c50ba5214c2f3c1be4a931d521ec19f55dfdc8 ]
We do memory allocations here, read blocks from disk, all sorts of operations that could easily fail at any given point. Instead of panicing the box, simply return the error back up the chain, all callers at this point have proper error handling.
Signed-off-by: Josef Bacik josef@toxicpanda.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/relocation.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 6a44d8f5e12e..575604ebea44 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -733,10 +733,12 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans, struct extent_buffer *eb; struct btrfs_root_item *root_item; struct btrfs_key root_key; - int ret; + int ret = 0; + bool must_abort = false;
root_item = kmalloc(sizeof(*root_item), GFP_NOFS); - BUG_ON(!root_item); + if (!root_item) + return ERR_PTR(-ENOMEM);
root_key.objectid = BTRFS_TREE_RELOC_OBJECTID; root_key.type = BTRFS_ROOT_ITEM_KEY; @@ -748,7 +750,9 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans, /* called by btrfs_init_reloc_root */ ret = btrfs_copy_root(trans, root, root->commit_root, &eb, BTRFS_TREE_RELOC_OBJECTID); - BUG_ON(ret); + if (ret) + goto fail; + /* * Set the last_snapshot field to the generation of the commit * root - like this ctree.c:btrfs_block_can_be_shared() behaves @@ -769,9 +773,16 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans, */ ret = btrfs_copy_root(trans, root, root->node, &eb, BTRFS_TREE_RELOC_OBJECTID); - BUG_ON(ret); + if (ret) + goto fail; }
+ /* + * We have changed references at this point, we must abort the + * transaction if anything fails. + */ + must_abort = true; + memcpy(root_item, &root->root_item, sizeof(*root_item)); btrfs_set_root_bytenr(root_item, eb->start); btrfs_set_root_level(root_item, btrfs_header_level(eb)); @@ -789,14 +800,25 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
ret = btrfs_insert_root(trans, fs_info->tree_root, &root_key, root_item); - BUG_ON(ret); + if (ret) + goto fail; + kfree(root_item);
reloc_root = btrfs_read_tree_root(fs_info->tree_root, &root_key); - BUG_ON(IS_ERR(reloc_root)); + if (IS_ERR(reloc_root)) { + ret = PTR_ERR(reloc_root); + goto abort; + } set_bit(BTRFS_ROOT_SHAREABLE, &reloc_root->state); reloc_root->last_trans = trans->transid; return reloc_root; +fail: + kfree(root_item); +abort: + if (must_abort) + btrfs_abort_transaction(trans, ret); + return ERR_PTR(ret); }
/*
From: Josef Bacik josef@toxicpanda.com
[ Upstream commit 592fbcd50c99b8adf999a2a54f9245caff333139 ]
We call btrfs_update_root in btrfs_update_reloc_root, which can fail for all sorts of reasons, including IO errors. Instead of panicing the box lets return the error, now that all callers properly handle those errors.
Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Josef Bacik josef@toxicpanda.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/relocation.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 575604ebea44..b3368cfccabf 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -897,7 +897,7 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans, int ret;
if (!have_reloc_root(root)) - goto out; + return 0;
reloc_root = root->reloc_root; root_item = &reloc_root->root_item; @@ -930,10 +930,8 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
ret = btrfs_update_root(trans, fs_info->tree_root, &reloc_root->root_key, root_item); - BUG_ON(ret); btrfs_put_root(reloc_root); -out: - return 0; + return ret; }
/*
From: Josef Bacik josef@toxicpanda.com
[ Upstream commit 7a9213a93546e7eaef90e6e153af6b8fc7553f10 ]
A few BUG_ON()'s in replace_path are purely to keep us from making logical mistakes, so replace them with ASSERT()'s.
Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Josef Bacik josef@toxicpanda.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/relocation.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index b3368cfccabf..c21545c5b34b 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -1205,8 +1205,8 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc, int ret; int slot;
- BUG_ON(src->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID); - BUG_ON(dest->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID); + ASSERT(src->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID); + ASSERT(dest->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID);
last_snapshot = btrfs_root_last_snapshot(&src->root_item); again: @@ -1241,7 +1241,7 @@ again: struct btrfs_key first_key;
level = btrfs_header_level(parent); - BUG_ON(level < lowest_level); + ASSERT(level >= lowest_level);
ret = btrfs_bin_search(parent, &key, &slot); if (ret < 0)
From: Jared Baldridge jrb@expunge.us
[ Upstream commit 81ad7f9f78e4ff80e95be8282423f511b84f1166 ]
The OneGX1 Pro has a fairly unique combination of generic strings, but we additionally match on the BIOS date just to be safe.
Signed-off-by: Jared Baldridge jrb@expunge.us Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/41288ccb-1012-486b-81c1-a24c31... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index 58f5dc2f6dd5..f6bdec7fa925 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -84,6 +84,13 @@ static const struct drm_dmi_panel_orientation_data itworks_tw891 = { .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, };
+static const struct drm_dmi_panel_orientation_data onegx1_pro = { + .width = 1200, + .height = 1920, + .bios_dates = (const char * const []){ "12/17/2020", NULL }, + .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, +}; + static const struct drm_dmi_panel_orientation_data lcd720x1280_rightside_up = { .width = 720, .height = 1280, @@ -211,6 +218,13 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), }, .driver_data = (void *)&lcd1200x1920_rightside_up, + }, { /* OneGX1 Pro */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SYSTEM_PRODUCT_NAME"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Default string"), + }, + .driver_data = (void *)&onegx1_pro, }, { /* VIOS LTH17 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
From: Tong Zhang ztong0001@gmail.com
[ Upstream commit b91907a6241193465ca92e357adf16822242296d ]
if qxl_device_init() fail, drm device will not be registered, in this case, do not run qxl_drm_release()
[ 5.258534] ================================================================== [ 5.258931] BUG: KASAN: user-memory-access in qxl_destroy_monitors_object+0x42/0xa0 [qxl] [ 5.259388] Write of size 8 at addr 00000000000014dc by task modprobe/95 [ 5.259754] [ 5.259842] CPU: 0 PID: 95 Comm: modprobe Not tainted 5.11.0-rc6-00007-g88bb507a74ea #62 [ 5.260309] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-48-gd9c812dda54 [ 5.260917] Call Trace: [ 5.261056] dump_stack+0x7d/0xa3 [ 5.261245] kasan_report.cold+0x10c/0x10e [ 5.261475] ? qxl_destroy_monitors_object+0x42/0xa0 [qxl] [ 5.261789] check_memory_region+0x17c/0x1e0 [ 5.262029] qxl_destroy_monitors_object+0x42/0xa0 [qxl] [ 5.262332] qxl_modeset_fini+0x9/0x20 [qxl] [ 5.262595] qxl_drm_release+0x22/0x30 [qxl] [ 5.262841] drm_dev_release+0x32/0x50 [ 5.263047] release_nodes+0x39e/0x410 [ 5.263253] ? devres_release+0x40/0x40 [ 5.263462] really_probe+0x2ea/0x420 [ 5.263664] driver_probe_device+0x6d/0xd0 [ 5.263888] device_driver_attach+0x82/0x90 [ 5.264116] ? device_driver_attach+0x90/0x90 [ 5.264353] __driver_attach+0x60/0x100 [ 5.264563] ? device_driver_attach+0x90/0x90 [ 5.264801] bus_for_each_dev+0xe1/0x140 [ 5.265014] ? subsys_dev_iter_exit+0x10/0x10 [ 5.265251] ? klist_node_init+0x61/0x80 [ 5.265464] bus_add_driver+0x254/0x2a0 [ 5.265673] driver_register+0xd3/0x150 [ 5.265882] ? 0xffffffffc0048000 [ 5.266064] do_one_initcall+0x84/0x250 [ 5.266274] ? trace_event_raw_event_initcall_finish+0x150/0x150 [ 5.266596] ? unpoison_range+0xf/0x30 [ 5.266801] ? ____kasan_kmalloc.constprop.0+0x84/0xa0 [ 5.267082] ? unpoison_range+0xf/0x30 [ 5.267287] ? unpoison_range+0xf/0x30 [ 5.267491] do_init_module+0xf8/0x350 [ 5.267697] load_module+0x3fe6/0x4340 [ 5.267902] ? vm_unmap_ram+0x1d0/0x1d0 [ 5.268115] ? module_frob_arch_sections+0x20/0x20 [ 5.268375] ? __do_sys_finit_module+0x108/0x170 [ 5.268624] __do_sys_finit_module+0x108/0x170 [ 5.268865] ? __ia32_sys_init_module+0x40/0x40 [ 5.269111] ? file_open_root+0x200/0x200 [ 5.269330] ? do_sys_open+0x85/0xe0 [ 5.269527] ? filp_open+0x50/0x50 [ 5.269714] ? exit_to_user_mode_prepare+0xfc/0x130 [ 5.269978] do_syscall_64+0x33/0x40 [ 5.270176] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 5.270450] RIP: 0033:0x7fa3f685bcf7 [ 5.270646] Code: 48 89 57 30 48 8b 04 24 48 89 47 38 e9 1d a0 02 00 48 89 f8 48 89 f7 48 89 d1 [ 5.271634] RSP: 002b:00007ffca83048d8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 5.272037] RAX: ffffffffffffffda RBX: 0000000001e94a70 RCX: 00007fa3f685bcf7 [ 5.272416] RDX: 0000000000000000 RSI: 0000000001e939e0 RDI: 0000000000000003 [ 5.272794] RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000001 [ 5.273171] R10: 00007fa3f68bf300 R11: 0000000000000246 R12: 0000000001e939e0 [ 5.273550] R13: 0000000000000000 R14: 0000000001e93bd0 R15: 0000000000000001 [ 5.273928] ==================================================================
Signed-off-by: Tong Zhang ztong0001@gmail.com Link: http://patchwork.freedesktop.org/patch/msgid/20210203040727.868921-1-ztong00... Signed-off-by: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/qxl/qxl_drv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 6e7f16f4cec7..41cdf9d1e59d 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -144,6 +144,8 @@ static void qxl_drm_release(struct drm_device *dev) * reodering qxl_modeset_fini() + qxl_device_fini() calls is * non-trivial though. */ + if (!dev->registered) + return; qxl_modeset_fini(qdev); qxl_device_fini(qdev); }
From: Gerd Hoffmann kraxel@redhat.com
[ Upstream commit 4ca77c513537700d3fae69030879f781dde1904c ]
In case we have a shadow surface on shutdown release it so it doesn't leak.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com Acked-by: Thomas Zimmermann tzimmermann@suse.de Link: http://patchwork.freedesktop.org/patch/msgid/20210204145712.1531203-6-kraxel... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/qxl/qxl_display.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 862ef59d4d03..1f0802f5d84e 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -1224,6 +1224,10 @@ int qxl_modeset_init(struct qxl_device *qdev)
void qxl_modeset_fini(struct qxl_device *qdev) { + if (qdev->dumb_shadow_bo) { + drm_gem_object_put(&qdev->dumb_shadow_bo->tbo.base); + qdev->dumb_shadow_bo = NULL; + } qxl_destroy_monitors_object(qdev); drm_mode_config_cleanup(&qdev->ddev); }
From: Thomas Zimmermann tzimmermann@suse.de
[ Upstream commit ee4a92d690f30f3793df942939726bec0338e65b ]
Use AST_MAX_HWC_HEIGHT for setting offset_y in the cursor plane's atomic_check. The code used AST_MAX_HWC_WIDTH instead. This worked because both constants has the same value.
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Acked-by: Gerd Hoffmann kraxel@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20210209134632.12157-3-tzimmer... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/ast/ast_mode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 0a1e1cf57e19..a3c2f76668ab 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -688,7 +688,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, unsigned int offset_x, offset_y;
offset_x = AST_MAX_HWC_WIDTH - fb->width; - offset_y = AST_MAX_HWC_WIDTH - fb->height; + offset_y = AST_MAX_HWC_HEIGHT - fb->height;
if (state->fb != old_state->fb) { /* A new cursor image was installed. */
From: Martin Leung martin.leung@amd.com
[ Upstream commit efe213e5a57e0cd92fa4f328dc1963d330549982 ]
[Why] Hardware team remeasured, need to update timings to increase latency slightly and avoid intermittent underflows.
[How] sr exit latency update.
Signed-off-by: Martin Leung martin.leung@amd.com Reviewed-by: Alvin Lee Alvin.Lee2@amd.com Acked-by: Qingqing Zhuo Qingqing.Zhuo@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 2455d210ccf6..8465cae180da 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -180,7 +180,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_0_soc = { }, .min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */ .num_states = 1, - .sr_exit_time_us = 12, + .sr_exit_time_us = 15.5, .sr_enter_plus_exit_time_us = 20, .urgent_latency_us = 4.0, .urgent_latency_pixel_data_only_us = 4.0,
From: Tong Zhang ztong0001@gmail.com
[ Upstream commit dc739820ff90acccd013f6bb420222978a982791 ]
a connector is leaked upon module unload, it seems that we should do similar to sample driver as suggested in drm_drv.c.
Adding drm_atomic_helper_shutdown() in ast_pci_remove to prevent leaking.
[ 153.822134] WARNING: CPU: 0 PID: 173 at drivers/gpu/drm/drm_mode_config.c:504 drm_mode_config_cle0 [ 153.822698] Modules linked in: ast(-) drm_vram_helper drm_ttm_helper ttm [last unloaded: ttm] [ 153.823197] CPU: 0 PID: 173 Comm: modprobe Tainted: G W 5.11.0-03615-g55f62bc873474 [ 153.823708] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-48-gd9c812dda519-4 [ 153.824333] RIP: 0010:drm_mode_config_cleanup+0x418/0x470 [ 153.824637] Code: 0c 00 00 00 00 48 8b 84 24 a8 00 00 00 65 48 33 04 25 28 00 00 00 75 65 48 81 c0 [ 153.825668] RSP: 0018:ffff888103c9fb70 EFLAGS: 00010212 [ 153.825962] RAX: ffff888102b0d100 RBX: ffff888102b0c298 RCX: ffffffff818d8b2b [ 153.826356] RDX: dffffc0000000000 RSI: 000000007fffffff RDI: ffff888102b0c298 [ 153.826748] RBP: ffff888103c9fba0 R08: 0000000000000001 R09: ffffed1020561857 [ 153.827146] R10: ffff888102b0c2b7 R11: ffffed1020561856 R12: ffff888102b0c000 [ 153.827538] R13: ffff888102b0c2d8 R14: ffff888102b0c2d8 R15: 1ffff11020793f70 [ 153.827935] FS: 00007f24bff456a0(0000) GS:ffff88815b400000(0000) knlGS:0000000000000000 [ 153.828380] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 153.828697] CR2: 0000000001c39018 CR3: 0000000103c90000 CR4: 00000000000006f0 [ 153.829096] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 153.829486] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 153.829883] Call Trace: [ 153.830024] ? drmm_mode_config_init+0x930/0x930 [ 153.830281] ? cpumask_next+0x16/0x20 [ 153.830488] ? mnt_get_count+0x66/0x80 [ 153.830699] ? drm_mode_config_cleanup+0x470/0x470 [ 153.830972] drm_managed_release+0xed/0x1c0 [ 153.831208] drm_dev_release+0x3a/0x50 [ 153.831420] release_nodes+0x39e/0x410 [ 153.831631] ? devres_release+0x40/0x40 [ 153.831852] device_release_driver_internal+0x158/0x270 [ 153.832143] driver_detach+0x76/0xe0 [ 153.832344] bus_remove_driver+0x7e/0x100 [ 153.832568] pci_unregister_driver+0x28/0xf0 [ 153.832821] __x64_sys_delete_module+0x268/0x300 [ 153.833086] ? __ia32_sys_delete_module+0x300/0x300 [ 153.833357] ? call_rcu+0x372/0x4f0 [ 153.833553] ? fpregs_assert_state_consistent+0x4d/0x60 [ 153.833840] ? exit_to_user_mode_prepare+0x2f/0x130 [ 153.834118] do_syscall_64+0x33/0x40 [ 153.834317] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 153.834597] RIP: 0033:0x7f24bfec7cf7 [ 153.834797] Code: 48 89 57 30 48 8b 04 24 48 89 47 38 e9 1d a0 02 00 48 89 f8 48 89 f7 48 89 d6 41 [ 153.835812] RSP: 002b:00007fff72e6cb58 EFLAGS: 00000202 ORIG_RAX: 00000000000000b0 [ 153.836234] RAX: ffffffffffffffda RBX: 00007f24bff45690 RCX: 00007f24bfec7cf7 [ 153.836623] RDX: 00000000ffffffff RSI: 0000000000000080 RDI: 0000000001c2fb10 [ 153.837018] RBP: 0000000001c2fac0 R08: 2f2f2f2f2f2f2f2f R09: 0000000001c2fac0 [ 153.837408] R10: fefefefefefefeff R11: 0000000000000202 R12: 0000000001c2fac0 [ 153.837798] R13: 0000000001c2f9d0 R14: 0000000000000000 R15: 0000000000000001 [ 153.838194] ---[ end trace b92031513bbe596c ]--- [ 153.838441] [drm:drm_mode_config_cleanup] *ERROR* connector VGA-1 leaked!
Signed-off-by: Tong Zhang ztong0001@gmail.com Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/20210222023322.984885-1-ztong0... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/ast/ast_drv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index f0b4af1c390a..59d2466d40c6 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -30,6 +30,7 @@ #include <linux/module.h> #include <linux/pci.h>
+#include <drm/drm_atomic_helper.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_drv.h> #include <drm/drm_fb_helper.h> @@ -138,6 +139,7 @@ static void ast_pci_remove(struct pci_dev *pdev) struct drm_device *dev = pci_get_drvdata(pdev);
drm_dev_unregister(dev); + drm_atomic_helper_shutdown(dev); }
static int ast_drm_freeze(struct drm_device *dev)
From: Eryk Brol eryk.brol@amd.com
[ Upstream commit 349a19b2f1b01e713268c7de9944ad669ccdf369 ]
[why] This check for ASIC revision is no longer useful and causes lightup issues after a topology change in MST DSC scenario. In this case, DSC configs should be recalculated for the new topology. This check prevented that from happening on certain ASICs that do, in fact, support DSC.
[how] Change the ASIC revision to instead check if DSC is supported.
Signed-off-by: Eryk Brol eryk.brol@amd.com Acked-by: Bindu Ramamurthy bindu.r@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c07737c45677..830d302be045 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8659,7 +8659,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, }
#if defined(CONFIG_DRM_AMD_DC_DCN) - if (adev->asic_type >= CHIP_NAVI10) { + if (dc_resource_is_dsc_encoding_supported(dc)) { for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { if (drm_atomic_crtc_needs_modeset(new_crtc_state)) { ret = add_affected_mst_dsc_crtcs(state, crtc);
From: Aric Cyr aric.cyr@amd.com
[ Upstream commit 6ad98e8aeb0106f453bb154933e8355849244990 ]
[Why] There is a window of time where we optimize bandwidth due to no streams enabled will enable PSTATE changing but HUBPs are not disabled yet. This results in underflow counter increasing in some hotplug scenarios.
[How] Set the optimize-bandwidth flag for later processing once all the HUBPs are properly disabled.
Signed-off-by: Aric Cyr aric.cyr@amd.com Acked-by: Bindu Ramamurthy bindu.r@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index ffb21196bf59..921c4ca6e902 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2345,7 +2345,8 @@ static void commit_planes_do_stream_update(struct dc *dc, if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only) pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);
- dc->hwss.optimize_bandwidth(dc, dc->current_state); + dc->optimized_required = true; + } else { if (dc->optimize_seamless_boot_streams == 0) dc->hwss.prepare_bandwidth(dc, dc->current_state);
From: Xiaogang Chen xiaogang.chen@amd.com
[ Upstream commit b6f91fc183f758461b9462cc93e673adbbf95c2d ]
amdgpu DM handles INTERRUPT_LOW_IRQ_CONTEXT interrupt(hpd, hpd_rx) by using work queue and uses single work_struct. If new interrupt is recevied before the previous handler finished, new interrupts(same type) will be discarded and driver just sends "amdgpu_dm_irq_schedule_work FAILED" message out. If some important hpd, hpd_rx related interrupts are missed by driver the hot (un)plug devices may cause system hang or instability, such as issues with system resume from S3 sleep with mst device connected.
This patch dynamically allocates new amdgpu_dm_irq_handler_data for new interrupts if previous INTERRUPT_LOW_IRQ_CONTEXT interrupt work has not been handled. So the new interrupt works can be queued to the same workqueue_struct, instead of discard the new interrupts. All allocated amdgpu_dm_irq_handler_data are put into a single linked list and will be reused after.
Signed-off-by: Xiaogang Chen xiaogang.chen@amd.com Reviewed-by: Aurabindo Pillai aurabindo.pillai@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 14 +-- .../drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 115 ++++++++++++------ 2 files changed, 80 insertions(+), 49 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index a8a0e8cb1a11..1df7f1b18049 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -68,18 +68,6 @@ struct common_irq_params { enum dc_irq_source irq_src; };
-/** - * struct irq_list_head - Linked-list for low context IRQ handlers. - * - * @head: The list_head within &struct handler_data - * @work: A work_struct containing the deferred handler work - */ -struct irq_list_head { - struct list_head head; - /* In case this interrupt needs post-processing, 'work' will be queued*/ - struct work_struct work; -}; - /** * struct dm_compressor_info - Buffer info used by frame buffer compression * @cpu_addr: MMIO cpu addr @@ -270,7 +258,7 @@ struct amdgpu_display_manager { * Note that handlers are called in the same order as they were * registered (FIFO). */ - struct irq_list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER]; + struct list_head irq_handler_list_low_tab[DAL_IRQ_SOURCES_NUMBER];
/** * @irq_handler_list_high_tab: diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index 357778556b06..281b274e2b9b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c @@ -82,6 +82,7 @@ struct amdgpu_dm_irq_handler_data { struct amdgpu_display_manager *dm; /* DAL irq source which registered for this interrupt. */ enum dc_irq_source irq_source; + struct work_struct work; };
#define DM_IRQ_TABLE_LOCK(adev, flags) \ @@ -111,20 +112,10 @@ static void init_handler_common_data(struct amdgpu_dm_irq_handler_data *hcd, */ static void dm_irq_work_func(struct work_struct *work) { - struct irq_list_head *irq_list_head = - container_of(work, struct irq_list_head, work); - struct list_head *handler_list = &irq_list_head->head; - struct amdgpu_dm_irq_handler_data *handler_data; - - list_for_each_entry(handler_data, handler_list, list) { - DRM_DEBUG_KMS("DM_IRQ: work_func: for dal_src=%d\n", - handler_data->irq_source); + struct amdgpu_dm_irq_handler_data *handler_data = + container_of(work, struct amdgpu_dm_irq_handler_data, work);
- DRM_DEBUG_KMS("DM_IRQ: schedule_work: for dal_src=%d\n", - handler_data->irq_source); - - handler_data->handler(handler_data->handler_arg); - } + handler_data->handler(handler_data->handler_arg);
/* Call a DAL subcomponent which registered for interrupt notification * at INTERRUPT_LOW_IRQ_CONTEXT. @@ -156,7 +147,7 @@ static struct list_head *remove_irq_handler(struct amdgpu_device *adev, break; case INTERRUPT_LOW_IRQ_CONTEXT: default: - hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source].head; + hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source]; break; }
@@ -287,7 +278,8 @@ void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev, break; case INTERRUPT_LOW_IRQ_CONTEXT: default: - hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source].head; + hnd_list = &adev->dm.irq_handler_list_low_tab[irq_source]; + INIT_WORK(&handler_data->work, dm_irq_work_func); break; }
@@ -369,7 +361,7 @@ void amdgpu_dm_irq_unregister_interrupt(struct amdgpu_device *adev, int amdgpu_dm_irq_init(struct amdgpu_device *adev) { int src; - struct irq_list_head *lh; + struct list_head *lh;
DRM_DEBUG_KMS("DM_IRQ\n");
@@ -378,9 +370,7 @@ int amdgpu_dm_irq_init(struct amdgpu_device *adev) for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) { /* low context handler list init */ lh = &adev->dm.irq_handler_list_low_tab[src]; - INIT_LIST_HEAD(&lh->head); - INIT_WORK(&lh->work, dm_irq_work_func); - + INIT_LIST_HEAD(lh); /* high context handler init */ INIT_LIST_HEAD(&adev->dm.irq_handler_list_high_tab[src]); } @@ -397,8 +387,11 @@ int amdgpu_dm_irq_init(struct amdgpu_device *adev) void amdgpu_dm_irq_fini(struct amdgpu_device *adev) { int src; - struct irq_list_head *lh; + struct list_head *lh; + struct list_head *entry, *tmp; + struct amdgpu_dm_irq_handler_data *handler; unsigned long irq_table_flags; + DRM_DEBUG_KMS("DM_IRQ: releasing resources.\n"); for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) { DM_IRQ_TABLE_LOCK(adev, irq_table_flags); @@ -407,7 +400,16 @@ void amdgpu_dm_irq_fini(struct amdgpu_device *adev) * (because no code can schedule a new one). */ lh = &adev->dm.irq_handler_list_low_tab[src]; DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); - flush_work(&lh->work); + + if (!list_empty(lh)) { + list_for_each_safe(entry, tmp, lh) { + handler = list_entry( + entry, + struct amdgpu_dm_irq_handler_data, + list); + flush_work(&handler->work); + } + } } }
@@ -417,6 +419,8 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev) struct list_head *hnd_list_h; struct list_head *hnd_list_l; unsigned long irq_table_flags; + struct list_head *entry, *tmp; + struct amdgpu_dm_irq_handler_data *handler;
DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
@@ -427,14 +431,22 @@ int amdgpu_dm_irq_suspend(struct amdgpu_device *adev) * will be disabled from manage_dm_interrupts on disable CRTC. */ for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6RX; src++) { - hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; + hnd_list_l = &adev->dm.irq_handler_list_low_tab[src]; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) dc_interrupt_set(adev->dm.dc, src, false);
DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); - flush_work(&adev->dm.irq_handler_list_low_tab[src].work);
+ if (!list_empty(hnd_list_l)) { + list_for_each_safe (entry, tmp, hnd_list_l) { + handler = list_entry( + entry, + struct amdgpu_dm_irq_handler_data, + list); + flush_work(&handler->work); + } + } DM_IRQ_TABLE_LOCK(adev, irq_table_flags); }
@@ -454,7 +466,7 @@ int amdgpu_dm_irq_resume_early(struct amdgpu_device *adev)
/* re-enable short pulse interrupts HW interrupt */ for (src = DC_IRQ_SOURCE_HPD1RX; src <= DC_IRQ_SOURCE_HPD6RX; src++) { - hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; + hnd_list_l = &adev->dm.irq_handler_list_low_tab[src]; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) dc_interrupt_set(adev->dm.dc, src, true); @@ -480,7 +492,7 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev) * will be enabled from manage_dm_interrupts on enable CRTC. */ for (src = DC_IRQ_SOURCE_HPD1; src <= DC_IRQ_SOURCE_HPD6; src++) { - hnd_list_l = &adev->dm.irq_handler_list_low_tab[src].head; + hnd_list_l = &adev->dm.irq_handler_list_low_tab[src]; hnd_list_h = &adev->dm.irq_handler_list_high_tab[src]; if (!list_empty(hnd_list_l) || !list_empty(hnd_list_h)) dc_interrupt_set(adev->dm.dc, src, true); @@ -497,22 +509,53 @@ int amdgpu_dm_irq_resume_late(struct amdgpu_device *adev) static void amdgpu_dm_irq_schedule_work(struct amdgpu_device *adev, enum dc_irq_source irq_source) { - unsigned long irq_table_flags; - struct work_struct *work = NULL; + struct list_head *handler_list = &adev->dm.irq_handler_list_low_tab[irq_source]; + struct amdgpu_dm_irq_handler_data *handler_data; + bool work_queued = false;
- DM_IRQ_TABLE_LOCK(adev, irq_table_flags); + if (list_empty(handler_list)) + return;
- if (!list_empty(&adev->dm.irq_handler_list_low_tab[irq_source].head)) - work = &adev->dm.irq_handler_list_low_tab[irq_source].work; + list_for_each_entry (handler_data, handler_list, list) { + if (!queue_work(system_highpri_wq, &handler_data->work)) { + continue; + } else { + work_queued = true; + break; + } + }
- DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); + if (!work_queued) { + struct amdgpu_dm_irq_handler_data *handler_data_add; + /*get the amdgpu_dm_irq_handler_data of first item pointed by handler_list*/ + handler_data = container_of(handler_list->next, struct amdgpu_dm_irq_handler_data, list);
- if (work) { - if (!schedule_work(work)) - DRM_INFO("amdgpu_dm_irq_schedule_work FAILED src %d\n", - irq_source); - } + /*allocate a new amdgpu_dm_irq_handler_data*/ + handler_data_add = kzalloc(sizeof(*handler_data), GFP_KERNEL); + if (!handler_data_add) { + DRM_ERROR("DM_IRQ: failed to allocate irq handler!\n"); + return; + } + + /*copy new amdgpu_dm_irq_handler_data members from handler_data*/ + handler_data_add->handler = handler_data->handler; + handler_data_add->handler_arg = handler_data->handler_arg; + handler_data_add->dm = handler_data->dm; + handler_data_add->irq_source = irq_source;
+ list_add_tail(&handler_data_add->list, handler_list); + + INIT_WORK(&handler_data_add->work, dm_irq_work_func); + + if (queue_work(system_highpri_wq, &handler_data_add->work)) + DRM_DEBUG("Queued work for handling interrupt from " + "display for IRQ source %d\n", + irq_source); + else + DRM_ERROR("Failed to queue work for handling interrupt " + "from display for IRQ source %d\n", + irq_source); + } }
/*
From: Lee Jones lee.jones@linaro.org
[ Upstream commit 89adc10178fd6cb68c8ef1905d269070a4d3bd64 ]
Fixes the following W=1 kernel build warning(s):
In file included from drivers/gpu/drm/amd/amdgpu/../display/dc/dce112/dce112_resource.c:59: drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_11_2_sh_mask.h:10014:58: warning: initialized field overwritten [-Woverride-init] drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:214:16: note: in expansion of macro ‘AUX_SW_DATA__AUX_SW_AUTOINCREMENT_DISABLE__SHIFT’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:127:2: note: in expansion of macro ‘AUX_SF’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce112/dce112_resource.c:177:2: note: in expansion of macro ‘DCE_AUX_MASK_SH_LIST’ drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_11_2_sh_mask.h:10014:58: note: (near initialization for ‘aux_shift.AUX_SW_AUTOINCREMENT_DISABLE’) drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:214:16: note: in expansion of macro ‘AUX_SW_DATA__AUX_SW_AUTOINCREMENT_DISABLE__SHIFT’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:127:2: note: in expansion of macro ‘AUX_SF’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce112/dce112_resource.c:177:2: note: in expansion of macro ‘DCE_AUX_MASK_SH_LIST’ drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_11_2_sh_mask.h:10013:56: warning: initialized field overwritten [-Woverride-init] drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:214:16: note: in expansion of macro ‘AUX_SW_DATA__AUX_SW_AUTOINCREMENT_DISABLE_MASK’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:127:2: note: in expansion of macro ‘AUX_SF’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce112/dce112_resource.c:181:2: note: in expansion of macro ‘DCE_AUX_MASK_SH_LIST’ drivers/gpu/drm/amd/amdgpu/../include/asic_reg/dce/dce_11_2_sh_mask.h:10013:56: note: (near initialization for ‘aux_mask.AUX_SW_AUTOINCREMENT_DISABLE’) drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:214:16: note: in expansion of macro ‘AUX_SW_DATA__AUX_SW_AUTOINCREMENT_DISABLE_MASK’ drivers/gpu/drm/amd/amdgpu/../display/dc/dce/dce_aux.h:127:2: note: in expansion of macro ‘AUX_SF’
Cc: Harry Wentland harry.wentland@amd.com Cc: Leo Li sunpeng.li@amd.com Cc: Alex Deucher alexander.deucher@amd.com Cc: "Christian König" christian.koenig@amd.com Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: amd-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dce/dce_aux.h | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h index 382465862f29..f72f02e016ae 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h @@ -99,7 +99,6 @@ struct dce110_aux_registers { AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ - AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\
From: James Smart jsmart2021@gmail.com
[ Upstream commit 9302154c07bff4e7f7f43c506a1ac84540303d06 ]
The wqe_dbde field indicates whether a Data BDE is present in Words 0:2 and should therefore should be clear in the abts request wqe. By setting the bit we can be misleading fw into error cases.
Clear the wqe_dbde field.
Link: https://lore.kernel.org/r/20210301171821.3427-2-jsmart2021@gmail.com Co-developed-by: Dick Kennedy dick.kennedy@broadcom.com Signed-off-by: Dick Kennedy dick.kennedy@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_nvmet.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index d4ade7cdb93a..deab8931ab48 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -3300,7 +3300,6 @@ lpfc_nvmet_unsol_issue_abort(struct lpfc_hba *phba, bf_set(wqe_rcvoxid, &wqe_abts->xmit_sequence.wqe_com, xri);
/* Word 10 */ - bf_set(wqe_dbde, &wqe_abts->xmit_sequence.wqe_com, 1); bf_set(wqe_iod, &wqe_abts->xmit_sequence.wqe_com, LPFC_WQE_IOD_WRITE); bf_set(wqe_lenloc, &wqe_abts->xmit_sequence.wqe_com, LPFC_WQE_LENLOC_WORD12);
From: James Smart jsmart2021@gmail.com
[ Upstream commit bd4f5100424d17d4e560d6653902ef8e49b2fc1f ]
On a pt2pt setup, between 2 initiators, if one side issues a a LOGO, there is no relogin attempt. The FC specs are grey in this area on which port (higher wwn or not) is to re-login.
As there is no spec guidance, unconditionally re-PLOGI after the logout to ensure a login is re-established.
Link: https://lore.kernel.org/r/20210301171821.3427-8-jsmart2021@gmail.com Co-developed-by: Dick Kennedy dick.kennedy@broadcom.com Signed-off-by: Dick Kennedy dick.kennedy@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_nportdisc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 92d6e7b98770..17be94496110 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -903,9 +903,14 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, } } else if ((!(ndlp->nlp_type & NLP_FABRIC) && ((ndlp->nlp_type & NLP_FCP_TARGET) || - !(ndlp->nlp_type & NLP_FCP_INITIATOR))) || + (ndlp->nlp_type & NLP_NVME_TARGET) || + (vport->fc_flag & FC_PT2PT))) || (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { - /* Only try to re-login if this is NOT a Fabric Node */ + /* Only try to re-login if this is NOT a Fabric Node + * AND the remote NPORT is a FCP/NVME Target or we + * are in pt2pt mode. NLP_STE_ADISC_ISSUE is a special + * case for LOGO as a response to ADISC behavior. + */ mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000 * 1)); spin_lock_irq(shost->host_lock);
From: Emily Deng Emily.Deng@amd.com
[ Upstream commit bb0cd09be45ea457f25fdcbcb3d6cf2230f26c46 ]
When unloading driver after killing some applications, it will hit sdma flush tlb job timeout which is called by ttm_bo_delay_delete. So to avoid the job submit after fence driver fini, call ttm_bo_lock_delayed_workqueue before fence driver fini. And also put drm_sched_fini before waiting fence.
Signed-off-by: Emily Deng Emily.Deng@amd.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 76d10f1c579b..7f2689d4b86d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3551,6 +3551,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) { dev_info(adev->dev, "amdgpu: finishing device.\n"); flush_delayed_work(&adev->delayed_init_work); + ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); adev->shutdown = true;
kfree(adev->pci_state); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index fe2d495d08ab..d07c458c0bed 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -532,6 +532,8 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
if (!ring || !ring->fence_drv.initialized) continue; + if (!ring->no_scheduler) + drm_sched_fini(&ring->sched); r = amdgpu_fence_wait_empty(ring); if (r) { /* no need to trigger GPU reset as we are unloading */ @@ -540,8 +542,7 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev) if (ring->fence_drv.irq_src) amdgpu_irq_put(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); - if (!ring->no_scheduler) - drm_sched_fini(&ring->sched); + del_timer_sync(&ring->fence_drv.fallback_timer); for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j) dma_fence_put(ring->fence_drv.fences[j]);
From: Vincent Donnefort vincent.donnefort@arm.com
[ Upstream commit b89997aa88f0b07d8a6414c908af75062103b8c9 ]
Being called for each dequeue, util_est reduces the number of its updates by filtering out when the EWMA signal is different from the task util_avg by less than 1%. It is a problem for a sudden util_avg ramp-up. Due to the decay from a previous high util_avg, EWMA might now be close enough to the new util_avg. No update would then happen while it would leave ue.enqueued with an out-of-date value.
Taking into consideration the two util_est members, EWMA and enqueued for the filtering, ensures, for both, an up-to-date value.
This is for now an issue only for the trace probe that might return the stale value. Functional-wise, it isn't a problem, as the value is always accessed through max(enqueued, ewma).
This problem has been observed using LISA's UtilConvergence:test_means on the sd845c board.
No regression observed with Hackbench on sd845c and Perf-bench sched pipe on hikey/hikey960.
Signed-off-by: Vincent Donnefort vincent.donnefort@arm.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Signed-off-by: Ingo Molnar mingo@kernel.org Reviewed-by: Dietmar Eggemann dietmar.eggemann@arm.com Reviewed-by: Vincent Guittot vincent.guittot@linaro.org Link: https://lkml.kernel.org/r/20210225165820.1377125-1-vincent.donnefort@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/fair.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 348605306027..8f5bbc1469ed 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3948,6 +3948,8 @@ static inline void util_est_dequeue(struct cfs_rq *cfs_rq, trace_sched_util_est_cfs_tp(cfs_rq); }
+#define UTIL_EST_MARGIN (SCHED_CAPACITY_SCALE / 100) + /* * Check if a (signed) value is within a specified (unsigned) margin, * based on the observation that: @@ -3965,7 +3967,7 @@ static inline void util_est_update(struct cfs_rq *cfs_rq, struct task_struct *p, bool task_sleep) { - long last_ewma_diff; + long last_ewma_diff, last_enqueued_diff; struct util_est ue;
if (!sched_feat(UTIL_EST)) @@ -3986,6 +3988,8 @@ static inline void util_est_update(struct cfs_rq *cfs_rq, if (ue.enqueued & UTIL_AVG_UNCHANGED) return;
+ last_enqueued_diff = ue.enqueued; + /* * Reset EWMA on utilization increases, the moving average is used only * to smooth utilization decreases. @@ -3999,12 +4003,17 @@ static inline void util_est_update(struct cfs_rq *cfs_rq, }
/* - * Skip update of task's estimated utilization when its EWMA is + * Skip update of task's estimated utilization when its members are * already ~1% close to its last activation value. */ last_ewma_diff = ue.enqueued - ue.ewma; - if (within_margin(last_ewma_diff, (SCHED_CAPACITY_SCALE / 100))) + last_enqueued_diff -= ue.enqueued; + if (within_margin(last_ewma_diff, UTIL_EST_MARGIN)) { + if (!within_margin(last_enqueued_diff, UTIL_EST_MARGIN)) + goto done; + return; + }
/* * To avoid overestimation of actual task utilization, skip updates if
From: Uladzislau Rezki (Sony) urezki@gmail.com
[ Upstream commit ee6ddf58475cce8a3d3697614679cd8cb4a6f583 ]
Running an rcuscale stress-suite can lead to "Out of memory" of a system. This can happen under high memory pressure with a small amount of physical memory.
For example, a KVM test configuration with 64 CPUs and 512 megabytes can result in OOM when running rcuscale with below parameters:
../kvm.sh --torture rcuscale --allcpus --duration 10 --kconfig CONFIG_NR_CPUS=64 \ --bootargs "rcuscale.kfree_rcu_test=1 rcuscale.kfree_nthreads=16 rcuscale.holdoff=20 \ rcuscale.kfree_loops=10000 torture.disable_onoff_at_boot" --trust-make
<snip> [ 12.054448] kworker/1:1H invoked oom-killer: gfp_mask=0x2cc0(GFP_KERNEL|__GFP_NOWARN), order=0, oom_score_adj=0 [ 12.055303] CPU: 1 PID: 377 Comm: kworker/1:1H Not tainted 5.11.0-rc3+ #510 [ 12.055416] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.12.0-1 04/01/2014 [ 12.056485] Workqueue: events_highpri fill_page_cache_func [ 12.056485] Call Trace: [ 12.056485] dump_stack+0x57/0x6a [ 12.056485] dump_header+0x4c/0x30a [ 12.056485] ? del_timer_sync+0x20/0x30 [ 12.056485] out_of_memory.cold.47+0xa/0x7e [ 12.056485] __alloc_pages_slowpath.constprop.123+0x82f/0xc00 [ 12.056485] __alloc_pages_nodemask+0x289/0x2c0 [ 12.056485] __get_free_pages+0x8/0x30 [ 12.056485] fill_page_cache_func+0x39/0xb0 [ 12.056485] process_one_work+0x1ed/0x3b0 [ 12.056485] ? process_one_work+0x3b0/0x3b0 [ 12.060485] worker_thread+0x28/0x3c0 [ 12.060485] ? process_one_work+0x3b0/0x3b0 [ 12.060485] kthread+0x138/0x160 [ 12.060485] ? kthread_park+0x80/0x80 [ 12.060485] ret_from_fork+0x22/0x30 [ 12.062156] Mem-Info: [ 12.062350] active_anon:0 inactive_anon:0 isolated_anon:0 [ 12.062350] active_file:0 inactive_file:0 isolated_file:0 [ 12.062350] unevictable:0 dirty:0 writeback:0 [ 12.062350] slab_reclaimable:2797 slab_unreclaimable:80920 [ 12.062350] mapped:1 shmem:2 pagetables:8 bounce:0 [ 12.062350] free:10488 free_pcp:1227 free_cma:0 ... [ 12.101610] Out of memory and no killable processes... [ 12.102042] Kernel panic - not syncing: System is deadlocked on memory [ 12.102583] CPU: 1 PID: 377 Comm: kworker/1:1H Not tainted 5.11.0-rc3+ #510 [ 12.102600] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.12.0-1 04/01/2014 <snip>
Because kvfree_rcu() has a fallback path, memory allocation failure is not the end of the world. Furthermore, the added overhead of aggressive GFP settings must be balanced against the overhead of the fallback path, which is a cache miss for double-argument kvfree_rcu() and a call to synchronize_rcu() for single-argument kvfree_rcu(). The current choice of GFP_KERNEL|__GFP_NOWARN can result in longer latencies than a call to synchronize_rcu(), so less-tenacious GFP flags would be helpful.
Here is the tradeoff that must be balanced: a) Minimize use of the fallback path, b) Avoid pushing the system into OOM, c) Bound allocation latency to that of synchronize_rcu(), and d) Leave the emergency reserves to use cases lacking fallbacks.
This commit therefore changes GFP flags from GFP_KERNEL|__GFP_NOWARN to GFP_KERNEL|__GFP_NORETRY|__GFP_NOMEMALLOC|__GFP_NOWARN. This combination leaves the emergency reserves alone and can initiate reclaim, but will not invoke the OOM killer.
Signed-off-by: Uladzislau Rezki (Sony) urezki@gmail.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 5dc36c6e80fd..8a5cc76ecac9 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -3386,7 +3386,7 @@ static void fill_page_cache_func(struct work_struct *work)
for (i = 0; i < rcu_min_cached_objs; i++) { bnode = (struct kvfree_rcu_bulk_data *) - __get_free_page(GFP_KERNEL | __GFP_NOWARN); + __get_free_page(GFP_KERNEL | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
if (bnode) { raw_spin_lock_irqsave(&krcp->lock, flags);
From: Chaitanya Kulkarni chaitanya.kulkarni@wdc.com
[ Upstream commit fd48c056a32ed6e7754c7c475490f3bed54ed378 ]
This fixes a compilation warning in pscsi_complete_cmd():
drivers/target/target_core_pscsi.c: In function ‘pscsi_complete_cmd’: drivers/target/target_core_pscsi.c:624:5: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body] ; /* XXX: TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE */
Link: https://lore.kernel.org/r/20210228055645.22253-5-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie michael.christie@oracle.com Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Signed-off-by: Chaitanya Kulkarni chaitanya.kulkarni@wdc.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_pscsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 723a51a3f431..f10f0aa6cd37 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -620,8 +620,9 @@ static void pscsi_complete_cmd(struct se_cmd *cmd, u8 scsi_status, unsigned char *buf;
buf = transport_kmap_data_sg(cmd); - if (!buf) + if (!buf) { ; /* XXX: TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE */ + }
if (cdb[0] == MODE_SENSE_10) { if (!(buf[3] & 0x80))
From: Sean Young sean@mess.org
[ Upstream commit 28c7afb07ccfc0a939bb06ac1e7afe669901c65a ]
It's best if this condition is reported.
Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/rc/ite-cir.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index 0c6229592e13..e5c4a6941d26 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -276,8 +276,14 @@ static irqreturn_t ite_cir_isr(int irq, void *data) /* read the interrupt flags */ iflags = dev->params.get_irq_causes(dev);
+ /* Check for RX overflow */ + if (iflags & ITE_IRQ_RX_FIFO_OVERRUN) { + dev_warn(&dev->rdev->dev, "receive overflow\n"); + ir_raw_event_reset(dev->rdev); + } + /* check for the receive interrupt */ - if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) { + if (iflags & ITE_IRQ_RX_FIFO) { /* read the FIFO bytes */ rx_bytes = dev->params.get_rx_bytes(dev, rx_buf,
From: Julian Braha julianbraha@gmail.com
[ Upstream commit 24df8b74c8b2fb42c49ffe8585562da0c96446ff ]
When STA2X11_VIP is enabled, and GPIOLIB is disabled, Kbuild gives the following warning:
WARNING: unmet direct dependencies detected for VIDEO_ADV7180 Depends on [n]: MEDIA_SUPPORT [=y] && GPIOLIB [=n] && VIDEO_V4L2 [=y] && I2C [=y] Selected by [y]: - STA2X11_VIP [=y] && MEDIA_SUPPORT [=y] && MEDIA_PCI_SUPPORT [=y] && MEDIA_CAMERA_SUPPORT [=y] && PCI [=y] && VIDEO_V4L2 [=y] && VIRT_TO_BUS [=y] && I2C [=y] && (STA2X11 [=n] || COMPILE_TEST [=y]) && MEDIA_SUBDRV_AUTOSELECT [=y]
This is because STA2X11_VIP selects VIDEO_ADV7180 without selecting or depending on GPIOLIB, despite VIDEO_ADV7180 depending on GPIOLIB.
Signed-off-by: Julian Braha julianbraha@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/sta2x11/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/media/pci/sta2x11/Kconfig b/drivers/media/pci/sta2x11/Kconfig index 4dd98f94a91e..27bb78513631 100644 --- a/drivers/media/pci/sta2x11/Kconfig +++ b/drivers/media/pci/sta2x11/Kconfig @@ -3,6 +3,7 @@ config STA2X11_VIP tristate "STA2X11 VIP Video For Linux" depends on PCI && VIDEO_V4L2 && VIRT_TO_BUS && I2C depends on STA2X11 || COMPILE_TEST + select GPIOLIB if MEDIA_SUBDRV_AUTOSELECT select VIDEO_ADV7180 if MEDIA_SUBDRV_AUTOSELECT select VIDEOBUF2_DMA_CONTIG select MEDIA_CONTROLLER
From: Laurent Pinchart laurent.pinchart@ideasonboard.com
[ Upstream commit cc271b6754691af74d710b761eaf027e3743e243 ]
The correct return code to report an invalid pipeline configuration is -EPIPE. Return it instead of -EINVAL from __capture_legacy_try_fmt() when the capture format doesn't match the media bus format of the connected subdev.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Reviewed-by: Rui Miguel Silva rmfrfs@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/imx/imx-media-capture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c index c1931eb2540e..b2f2cb3d6a60 100644 --- a/drivers/staging/media/imx/imx-media-capture.c +++ b/drivers/staging/media/imx/imx-media-capture.c @@ -557,7 +557,7 @@ static int capture_validate_fmt(struct capture_priv *priv) priv->vdev.fmt.fmt.pix.height != f.fmt.pix.height || priv->vdev.cc->cs != cc->cs || priv->vdev.compose.width != compose.width || - priv->vdev.compose.height != compose.height) ? -EINVAL : 0; + priv->vdev.compose.height != compose.height) ? -EPIPE : 0; }
static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
From: Mauro Carvalho Chehab mchehab+huawei@kernel.org
[ Upstream commit 1f6c45ac5fd70ab59136ab5babc7def269f3f509 ]
In practice, IA_CSS_PIPE_ID_NUM should never be used when calling atomisp_q_video_buffers_to_css(), as the driver should discover the right pipe before calling it.
Yet, if some pipe parsing issue happens, it could end using it.
So, add a WARN_ON() to prevent such case.
Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/atomisp/pci/atomisp_fops.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c index 453bb6913550..f1e6b2597853 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c @@ -221,6 +221,9 @@ int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd, unsigned long irqflags; int err = 0;
+ if (WARN_ON(css_pipe_id >= IA_CSS_PIPE_ID_NUM)) + return -EINVAL; + while (pipe->buffers_in_css < ATOMISP_CSS_Q_DEPTH) { struct videobuf_buffer *vb;
From: Matthias Schiffer matthias.schiffer@ew.tq-group.com
[ Upstream commit c4d57c22ac65bd503716062a06fad55a01569cac ]
On all newer bq27xxx ICs, the AveragePower register contains a signed value; in addition to handling the raw value as unsigned, the driver code also didn't convert it to µW as expected.
At least for the BQ28Z610, the reference manual incorrectly states that the value is in units of 1mW and not 10mW. I have no way of knowing whether the manuals of other supported ICs contain the same error, or if there are models that actually use 1mW. At least, the new code shouldn't be *less* correct than the old version for any device.
power_avg is removed from the cache structure, se we don't have to extend it to store both a signed value and an error code. Always getting an up-to-date value may be desirable anyways, as it avoids inconsistent current and power readings when switching between charging and discharging.
Signed-off-by: Matthias Schiffer matthias.schiffer@ew.tq-group.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/bq27xxx_battery.c | 51 ++++++++++++++------------ include/linux/power/bq27xxx_battery.h | 1 - 2 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c index 315e0909e6a4..72a2bcf3ab32 100644 --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -1631,27 +1631,6 @@ static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg) return tval * 60; }
-/* - * Read an average power register. - * Return < 0 if something fails. - */ -static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di) -{ - int tval; - - tval = bq27xxx_read(di, BQ27XXX_REG_AP, false); - if (tval < 0) { - dev_err(di->dev, "error reading average power register %02x: %d\n", - BQ27XXX_REG_AP, tval); - return tval; - } - - if (di->opts & BQ27XXX_O_ZERO) - return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS; - else - return tval; -} - /* * Returns true if a battery over temperature condition is detected */ @@ -1739,8 +1718,6 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di) } if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR) cache.cycle_count = bq27xxx_battery_read_cyct(di); - if (di->regs[BQ27XXX_REG_AP] != INVALID_REG_ADDR) - cache.power_avg = bq27xxx_battery_read_pwr_avg(di);
/* We only have to read charge design full once */ if (di->charge_design_full <= 0) @@ -1803,6 +1780,32 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di, return 0; }
+/* + * Get the average power in µW + * Return < 0 if something fails. + */ +static int bq27xxx_battery_pwr_avg(struct bq27xxx_device_info *di, + union power_supply_propval *val) +{ + int power; + + power = bq27xxx_read(di, BQ27XXX_REG_AP, false); + if (power < 0) { + dev_err(di->dev, + "error reading average power register %02x: %d\n", + BQ27XXX_REG_AP, power); + return power; + } + + if (di->opts & BQ27XXX_O_ZERO) + val->intval = (power * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS; + else + /* Other gauges return a signed value in units of 10mW */ + val->intval = (int)((s16)power) * 10000; + + return 0; +} + static int bq27xxx_battery_status(struct bq27xxx_device_info *di, union power_supply_propval *val) { @@ -1987,7 +1990,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy, ret = bq27xxx_simple_value(di->cache.energy, val); break; case POWER_SUPPLY_PROP_POWER_AVG: - ret = bq27xxx_simple_value(di->cache.power_avg, val); + ret = bq27xxx_battery_pwr_avg(di, val); break; case POWER_SUPPLY_PROP_HEALTH: ret = bq27xxx_simple_value(di->cache.health, val); diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h index 111a40d0d3d5..8d5f4f40fb41 100644 --- a/include/linux/power/bq27xxx_battery.h +++ b/include/linux/power/bq27xxx_battery.h @@ -53,7 +53,6 @@ struct bq27xxx_reg_cache { int capacity; int energy; int flags; - int power_avg; int health; };
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit c309a3e8793f7e01c4a4ec7960658380572cb576 ]
When the jack is partially inserted and then removed again it may be removed while the hpdet code is running. In this case the following may happen:
1. The "JACKDET rise" or ""JACKDET fall" IRQ triggers 2. arizona_jackdet runs and takes info->lock 3. The "HPDET" IRQ triggers 4. arizona_hpdet_irq runs, blocks on info->lock 5. arizona_jackdet calls arizona_stop_mic() and clears info->hpdet_done 6. arizona_jackdet releases info->lock 7. arizona_hpdet_irq now can continue running and: 7.1 Calls arizona_start_mic() (if a mic was detected) 7.2 sets info->hpdet_done
Step 7 is undesirable / a bug: 7.1 causes the device to stay in a high power-state (with MICVDD enabled) 7.2 causes hpdet to not run on the next jack insertion, which in turn causes the EXTCON_JACK_HEADPHONE state to never get set
This fixes both issues by skipping these 2 steps when arizona_hpdet_irq runs after the jack has been unplugged.
Signed-off-by: Hans de Goede hdegoede@redhat.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Acked-by: Charles Keepax ckeepax@opensource.cirrus.com Tested-by: Charles Keepax ckeepax@opensource.cirrus.com Acked-by: Chanwoo Choi cw00.choi@samsung.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/extcon/extcon-arizona.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index aae82db542a5..f7ef247de46a 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -601,7 +601,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) struct arizona *arizona = info->arizona; int id_gpio = arizona->pdata.hpdet_id_gpio; unsigned int report = EXTCON_JACK_HEADPHONE; - int ret, reading; + int ret, reading, state; bool mic = false;
mutex_lock(&info->lock); @@ -614,12 +614,11 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) }
/* If the cable was removed while measuring ignore the result */ - ret = extcon_get_state(info->edev, EXTCON_MECHANICAL); - if (ret < 0) { - dev_err(arizona->dev, "Failed to check cable state: %d\n", - ret); + state = extcon_get_state(info->edev, EXTCON_MECHANICAL); + if (state < 0) { + dev_err(arizona->dev, "Failed to check cable state: %d\n", state); goto out; - } else if (!ret) { + } else if (!state) { dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n"); goto done; } @@ -667,7 +666,7 @@ done: gpio_set_value_cansleep(id_gpio, 0);
/* If we have a mic then reenable MICDET */ - if (mic || info->mic) + if (state && (mic || info->mic)) arizona_start_mic(info);
if (info->hpdet_active) { @@ -675,7 +674,9 @@ done: info->hpdet_active = false; }
- info->hpdet_done = true; + /* Do not set hp_det done when the cable has been unplugged */ + if (state) + info->hpdet_done = true;
out: mutex_unlock(&info->lock);
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit e5b499f6fb17bc95a813e85d0796522280203806 ]
We must free/disable all interrupts and cancel all pending works before doing further cleanup.
Before this commit arizona_extcon_remove() was doing several register writes to shut things down before disabling the IRQs and it was cancelling only 1 of the 3 different works used.
Move all the register-writes shutting things down to after the disabling of the IRQs and add the 2 missing cancel_delayed_work_sync() calls.
This fixes various possible races on driver unbind. One of which would always trigger on devices using the mic-clamp feature for jack detection. The ARIZONA_MICD_CLAMP_MODE_MASK update was done before disabling the IRQs, causing: 1. arizona_jackdet() to run 2. detect a jack being inserted (clamp disabled means jack inserted) 3. call arizona_start_mic() which: 3.1 Enables the MICVDD regulator 3.2 takes a pm_runtime_reference
And this was all happening after the ARIZONA_MICD_ENA bit clearing, which would undo 3.1 and 3.2 because the ARIZONA_MICD_CLAMP_MODE_MASK update was being done after the ARIZONA_MICD_ENA bit clearing.
So this means that arizona_extcon_remove() would exit with 1. MICVDD enabled and 2. The pm_runtime_reference being unbalanced.
MICVDD still being enabled caused the following oops when the regulator is released by the devm framework:
[ 2850.745757] ------------[ cut here ]------------ [ 2850.745827] WARNING: CPU: 2 PID: 2098 at drivers/regulator/core.c:2123 _regulator_put.part.0+0x19f/0x1b0 [ 2850.745835] Modules linked in: extcon_arizona ... ... [ 2850.746909] Call Trace: [ 2850.746932] regulator_put+0x2d/0x40 [ 2850.746946] release_nodes+0x22a/0x260 [ 2850.746984] __device_release_driver+0x190/0x240 [ 2850.747002] driver_detach+0xd4/0x120 ... [ 2850.747337] ---[ end trace f455dfd7abd9781f ]---
Note this oops is just one of various theoretically possible races caused by the wrong ordering inside arizona_extcon_remove(), this fixes the ordering fixing all possible races, including the reported oops.
Signed-off-by: Hans de Goede hdegoede@redhat.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Acked-by: Charles Keepax ckeepax@opensource.cirrus.com Tested-by: Charles Keepax ckeepax@opensource.cirrus.com Acked-by: Chanwoo Choi cw00.choi@samsung.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/extcon/extcon-arizona.c | 40 +++++++++++++++++---------------- 1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index f7ef247de46a..76aacbac5869 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -1760,25 +1760,6 @@ static int arizona_extcon_remove(struct platform_device *pdev) bool change; int ret;
- ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, - ARIZONA_MICD_ENA, 0, - &change); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to disable micd on remove: %d\n", - ret); - } else if (change) { - regulator_disable(info->micvdd); - pm_runtime_put(info->dev); - } - - gpiod_put(info->micd_pol_gpio); - - pm_runtime_disable(&pdev->dev); - - regmap_update_bits(arizona->regmap, - ARIZONA_MICD_CLAMP_CONTROL, - ARIZONA_MICD_CLAMP_MODE_MASK, 0); - if (info->micd_clamp) { jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE; jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL; @@ -1794,10 +1775,31 @@ static int arizona_extcon_remove(struct platform_device *pdev) arizona_free_irq(arizona, jack_irq_rise, info); arizona_free_irq(arizona, jack_irq_fall, info); cancel_delayed_work_sync(&info->hpdet_work); + cancel_delayed_work_sync(&info->micd_detect_work); + cancel_delayed_work_sync(&info->micd_timeout_work); + + ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, + ARIZONA_MICD_ENA, 0, + &change); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to disable micd on remove: %d\n", + ret); + } else if (change) { + regulator_disable(info->micvdd); + pm_runtime_put(info->dev); + } + + regmap_update_bits(arizona->regmap, + ARIZONA_MICD_CLAMP_CONTROL, + ARIZONA_MICD_CLAMP_MODE_MASK, 0); regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, ARIZONA_JD1_ENA, 0); arizona_clk32k_disable(arizona);
+ gpiod_put(info->micd_pol_gpio); + + pm_runtime_disable(&pdev->dev); + return 0; }
From: Daniel Niv danielniv3@gmail.com
[ Upstream commit c759b2970c561e3b56aa030deb13db104262adfe ]
Add a fix for the memory leak bugs that can occur when the saa7164_encoder_register() function fails. The function allocates memory without explicitly freeing it when errors occur. Add a better error handling that deallocate the unused buffers before the function exits during a fail.
Signed-off-by: Daniel Niv danielniv3@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/saa7164/saa7164-encoder.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c index 11e1eb6a6809..1d1d32e043f1 100644 --- a/drivers/media/pci/saa7164/saa7164-encoder.c +++ b/drivers/media/pci/saa7164/saa7164-encoder.c @@ -1008,7 +1008,7 @@ int saa7164_encoder_register(struct saa7164_port *port) printk(KERN_ERR "%s() failed (errno = %d), NO PCI configuration\n", __func__, result); result = -ENOMEM; - goto failed; + goto fail_pci; }
/* Establish encoder defaults here */ @@ -1062,7 +1062,7 @@ int saa7164_encoder_register(struct saa7164_port *port) 100000, ENCODER_DEF_BITRATE); if (hdl->error) { result = hdl->error; - goto failed; + goto fail_hdl; }
port->std = V4L2_STD_NTSC_M; @@ -1080,7 +1080,7 @@ int saa7164_encoder_register(struct saa7164_port *port) printk(KERN_INFO "%s: can't allocate mpeg device\n", dev->name); result = -ENOMEM; - goto failed; + goto fail_hdl; }
port->v4l_device->ctrl_handler = hdl; @@ -1091,10 +1091,7 @@ int saa7164_encoder_register(struct saa7164_port *port) if (result < 0) { printk(KERN_INFO "%s: can't register mpeg device\n", dev->name); - /* TODO: We're going to leak here if we don't dealloc - The buffers above. The unreg function can't deal wit it. - */ - goto failed; + goto fail_reg; }
printk(KERN_INFO "%s: registered device video%d [mpeg]\n", @@ -1116,9 +1113,14 @@ int saa7164_encoder_register(struct saa7164_port *port)
saa7164_api_set_encoder(port); saa7164_api_get_encoder(port); + return 0;
- result = 0; -failed: +fail_reg: + video_device_release(port->v4l_device); + port->v4l_device = NULL; +fail_hdl: + v4l2_ctrl_handler_free(hdl); +fail_pci: return result; }
From: Hans Verkuil hverkuil-cisco@xs4all.nl
[ Upstream commit eaaea4681984c79d2b2b160387b297477f0c1aab ]
act_len can be uninitialized if usb_bulk_msg() returns an error. Set it to 0 to avoid a KMSAN error.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Reported-by: syzbot+a4e309017a5f3a24c7b3@syzkaller.appspotmail.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/gspca/sq905.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c index 97799cfb832e..949111070971 100644 --- a/drivers/media/usb/gspca/sq905.c +++ b/drivers/media/usb/gspca/sq905.c @@ -158,7 +158,7 @@ static int sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock) { int ret; - int act_len; + int act_len = 0;
gspca_dev->usb_buf[0] = '\0'; if (need_lock)
From: dongjian dongjian@yulong.com
[ Upstream commit 2469b836fa835c67648acad17d62bc805236a6ea ]
Fixes coccicheck error:
drivers/power/supply/pm2301_charger.c:1089:7-27: ERROR: drivers/power/supply/lp8788-charger.c:502:8-28: ERROR: drivers/power/supply/tps65217_charger.c:239:8-33: ERROR: drivers/power/supply/tps65090-charger.c:303:8-33: ERROR:
Threaded IRQ with no primary handler requested without IRQF_ONESHOT
Signed-off-by: dongjian dongjian@yulong.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/lp8788-charger.c | 2 +- drivers/power/supply/pm2301_charger.c | 2 +- drivers/power/supply/tps65090-charger.c | 2 +- drivers/power/supply/tps65217_charger.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/power/supply/lp8788-charger.c b/drivers/power/supply/lp8788-charger.c index e7931ffb7151..397e5a03b7d9 100644 --- a/drivers/power/supply/lp8788-charger.c +++ b/drivers/power/supply/lp8788-charger.c @@ -501,7 +501,7 @@ static int lp8788_set_irqs(struct platform_device *pdev,
ret = request_threaded_irq(virq, NULL, lp8788_charger_irq_thread, - 0, name, pchg); + IRQF_ONESHOT, name, pchg); if (ret) break; } diff --git a/drivers/power/supply/pm2301_charger.c b/drivers/power/supply/pm2301_charger.c index 2df6a2459d1f..34f168f62178 100644 --- a/drivers/power/supply/pm2301_charger.c +++ b/drivers/power/supply/pm2301_charger.c @@ -1090,7 +1090,7 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, ret = request_threaded_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), NULL, pm2xxx_charger_irq[0].isr, - pm2->pdata->irq_type, + pm2->pdata->irq_type | IRQF_ONESHOT, pm2xxx_charger_irq[0].name, pm2);
if (ret != 0) { diff --git a/drivers/power/supply/tps65090-charger.c b/drivers/power/supply/tps65090-charger.c index 6b0098e5a88b..0990b2fa6cd8 100644 --- a/drivers/power/supply/tps65090-charger.c +++ b/drivers/power/supply/tps65090-charger.c @@ -301,7 +301,7 @@ static int tps65090_charger_probe(struct platform_device *pdev)
if (irq != -ENXIO) { ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, - tps65090_charger_isr, 0, "tps65090-charger", cdata); + tps65090_charger_isr, IRQF_ONESHOT, "tps65090-charger", cdata); if (ret) { dev_err(cdata->dev, "Unable to register irq %d err %d\n", irq, diff --git a/drivers/power/supply/tps65217_charger.c b/drivers/power/supply/tps65217_charger.c index 814c2b81fdfe..ba33d1617e0b 100644 --- a/drivers/power/supply/tps65217_charger.c +++ b/drivers/power/supply/tps65217_charger.c @@ -238,7 +238,7 @@ static int tps65217_charger_probe(struct platform_device *pdev) for (i = 0; i < NUM_CHARGER_IRQS; i++) { ret = devm_request_threaded_irq(&pdev->dev, irq[i], NULL, tps65217_charger_irq, - 0, "tps65217-charger", + IRQF_ONESHOT, "tps65217-charger", charger); if (ret) { dev_err(charger->dev,
From: Obeida Shamoun oshmoun100@googlemail.com
[ Upstream commit cdfd4c689e2a52c313b35ddfc1852ff274f91acb ]
WLED3_SINK_REG_SYNC is, as the name implies, a sink register offset. Therefore, use the sink address as base instead of the ctrl address.
This fixes the sync toggle on wled4, which can be observed by the fact that adjusting brightness now works.
It has no effect on wled3 because sink and ctrl base addresses are the same. This allows adjusting the brightness without having to disable then reenable the module.
Signed-off-by: Obeida Shamoun oshmoun100@googlemail.com Signed-off-by: Konrad Dybcio konrad.dybcio@somainline.org Signed-off-by: Marijn Suijten marijn.suijten@somainline.org Reviewed-by: Daniel Thompson daniel.thompson@linaro.org Acked-by: Kiran Gunda kgunda@codeaurora.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/backlight/qcom-wled.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c index 3bc7800eb0a9..83a187fdaa1d 100644 --- a/drivers/video/backlight/qcom-wled.c +++ b/drivers/video/backlight/qcom-wled.c @@ -336,13 +336,13 @@ static int wled3_sync_toggle(struct wled *wled) unsigned int mask = GENMASK(wled->max_string_count - 1, 0);
rc = regmap_update_bits(wled->regmap, - wled->ctrl_addr + WLED3_SINK_REG_SYNC, + wled->sink_addr + WLED3_SINK_REG_SYNC, mask, mask); if (rc < 0) return rc;
rc = regmap_update_bits(wled->regmap, - wled->ctrl_addr + WLED3_SINK_REG_SYNC, + wled->sink_addr + WLED3_SINK_REG_SYNC, mask, WLED3_SINK_REG_SYNC_CLEAR);
return rc;
From: Kiran Gunda kgunda@codeaurora.org
[ Upstream commit 4d6e9cdff7fbb6bef3e5559596fab3eeffaf95ca ]
Currently, for WLED5, the FSC (Full scale current) setting is not updated properly due to driver toggling the wrong register after an FSC update.
On WLED5 we should only toggle the MOD_SYNC bit after a brightness update. For an FSC update we need to toggle the SYNC bits instead.
Fix it by adopting the common wled3_sync_toggle() for WLED5 and introducing new code to the brightness update path to compensate.
Signed-off-by: Kiran Gunda kgunda@codeaurora.org Reviewed-by: Daniel Thompson daniel.thompson@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/backlight/qcom-wled.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c index 83a187fdaa1d..cd11c5776438 100644 --- a/drivers/video/backlight/qcom-wled.c +++ b/drivers/video/backlight/qcom-wled.c @@ -348,7 +348,7 @@ static int wled3_sync_toggle(struct wled *wled) return rc; }
-static int wled5_sync_toggle(struct wled *wled) +static int wled5_mod_sync_toggle(struct wled *wled) { int rc; u8 val; @@ -445,10 +445,23 @@ static int wled_update_status(struct backlight_device *bl) goto unlock_mutex; }
- rc = wled->wled_sync_toggle(wled); - if (rc < 0) { - dev_err(wled->dev, "wled sync failed rc:%d\n", rc); - goto unlock_mutex; + if (wled->version < 5) { + rc = wled->wled_sync_toggle(wled); + if (rc < 0) { + dev_err(wled->dev, "wled sync failed rc:%d\n", rc); + goto unlock_mutex; + } + } else { + /* + * For WLED5 toggling the MOD_SYNC_BIT updates the + * brightness + */ + rc = wled5_mod_sync_toggle(wled); + if (rc < 0) { + dev_err(wled->dev, "wled mod sync failed rc:%d\n", + rc); + goto unlock_mutex; + } } }
@@ -1459,7 +1472,7 @@ static int wled_configure(struct wled *wled) size = ARRAY_SIZE(wled5_opts); *cfg = wled5_config_defaults; wled->wled_set_brightness = wled5_set_brightness; - wled->wled_sync_toggle = wled5_sync_toggle; + wled->wled_sync_toggle = wled3_sync_toggle; wled->wled_cabc_config = wled5_cabc_config; wled->wled_ovp_delay = wled5_ovp_delay; wled->wled_auto_detection_required =
From: Jonathan Kim jonathan.kim@amd.com
[ Upstream commit 4ac5617c4b7d0f0a8f879997f8ceaa14636d7554 ]
The psp supplies the link type in the upper 2 bits of the psp xgmi node information num_hops field. With a new link type, Aldebaran has these bits set to a non-zero value (1 = xGMI3) so the KFD topology will report the incorrect IO link weights without proper masking. The actual number of hops is located in the 3 least significant bits of this field so mask if off accordingly before passing it to the KFD.
Signed-off-by: Jonathan Kim jonathan.kim@amd.com Reviewed-by: Amber Lin amber.lin@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index 1162913c8bf4..0526dec1d736 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -465,15 +465,22 @@ int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_dev }
+/* + * NOTE psp_xgmi_node_info.num_hops layout is as follows: + * num_hops[7:6] = link type (0 = xGMI2, 1 = xGMI3, 2/3 = reserved) + * num_hops[5:3] = reserved + * num_hops[2:0] = number of hops + */ int amdgpu_xgmi_get_hops_count(struct amdgpu_device *adev, struct amdgpu_device *peer_adev) { struct psp_xgmi_topology_info *top = &adev->psp.xgmi_context.top_info; + uint8_t num_hops_mask = 0x7; int i;
for (i = 0 ; i < top->num_nodes; ++i) if (top->nodes[i].node_id == peer_adev->gmc.xgmi.node_id) - return top->nodes[i].num_hops; + return top->nodes[i].num_hops & num_hops_mask; return -EINVAL; }
From: Anson Jacob Anson.Jacob@amd.com
[ Upstream commit 50e2fc36e72d4ad672032ebf646cecb48656efe0 ]
If get_num_sdma_queues or get_num_xgmi_sdma_queues is 0, we end up doing a shift operation where the number of bits shifted equals number of bits in the operand. This behaviour is undefined.
Set num_sdma_queues or num_xgmi_sdma_queues to ULLONG_MAX, if the count is >= number of bits in the operand.
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1472
Reported-by: Lyude Paul lyude@redhat.com Signed-off-by: Anson Jacob Anson.Jacob@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Tested-by: Lyude Paul lyude@redhat.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/amd/amdkfd/kfd_device_queue_manager.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 8e5cfb1f8a51..6ea8a4b6efde 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1128,6 +1128,9 @@ static int set_sched_resources(struct device_queue_manager *dqm)
static int initialize_cpsch(struct device_queue_manager *dqm) { + uint64_t num_sdma_queues; + uint64_t num_xgmi_sdma_queues; + pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm));
mutex_init(&dqm->lock_hidden); @@ -1136,8 +1139,18 @@ static int initialize_cpsch(struct device_queue_manager *dqm) dqm->active_cp_queue_count = 0; dqm->gws_queue_count = 0; dqm->active_runlist = false; - dqm->sdma_bitmap = ~0ULL >> (64 - get_num_sdma_queues(dqm)); - dqm->xgmi_sdma_bitmap = ~0ULL >> (64 - get_num_xgmi_sdma_queues(dqm)); + + num_sdma_queues = get_num_sdma_queues(dqm); + if (num_sdma_queues >= BITS_PER_TYPE(dqm->sdma_bitmap)) + dqm->sdma_bitmap = ULLONG_MAX; + else + dqm->sdma_bitmap = (BIT_ULL(num_sdma_queues) - 1); + + num_xgmi_sdma_queues = get_num_xgmi_sdma_queues(dqm); + if (num_xgmi_sdma_queues >= BITS_PER_TYPE(dqm->xgmi_sdma_bitmap)) + dqm->xgmi_sdma_bitmap = ULLONG_MAX; + else + dqm->xgmi_sdma_bitmap = (BIT_ULL(num_xgmi_sdma_queues) - 1);
INIT_WORK(&dqm->hw_exception_work, kfd_process_hw_exception);
From: shaoyunl shaoyun.liu@amd.com
[ Upstream commit c8941550aa66b2a90f4b32c45d59e8571e33336e ]
This recent change introduce SDMA interrupt info printing with irq->process function. These functions do not require a set function to enable/disable the irq
Signed-off-by: shaoyunl shaoyun.liu@amd.com Reviewed-by: Hawking Zhang Hawking.Zhang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 300ac73b4738..2f70fdd6104f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -499,7 +499,7 @@ void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev) for (j = 0; j < AMDGPU_MAX_IRQ_SRC_ID; ++j) { struct amdgpu_irq_src *src = adev->irq.client[i].sources[j];
- if (!src) + if (!src || !src->funcs || !src->funcs->set) continue; for (k = 0; k < src->num_types; k++) amdgpu_irq_update(adev, src, k);
From: Kenneth Feng kenneth.feng@amd.com
[ Upstream commit 0979d43259e13846d86ba17e451e17fec185d240 ]
Workload number mapped to the correct one. This issue is only on vega10.
Signed-off-by: Kenneth Feng kenneth.feng@amd.com Reviewed-by: Kevin Wang kevin1.wang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c index ed4eafc744d3..132c269c7c89 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -5159,7 +5159,7 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui
out: smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask, - 1 << power_profile_mode, + (!power_profile_mode) ? 0 : 1 << (power_profile_mode - 1), NULL); hwmgr->power_profile_mode = power_profile_mode;
From: Anson Jacob Anson.Jacob@amd.com
[ Upstream commit 6a30a92997eee49554f72b462dce90abe54a496f ]
[Why] dc_cursor_position do not initialise position.translate_by_source when crtc or plane->state->fb is NULL. UBSAN caught this error in dce110_set_cursor_position, as the value was garbage.
[How] Initialise dc_cursor_position structure elements to 0 in handle_cursor_update before calling get_cursor_position.
Tested-by: Daniel Wheeler daniel.wheeler@amd.com Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1471 Reported-by: Lyude Paul lyude@redhat.com Signed-off-by: Anson Jacob Anson.Jacob@amd.com Reviewed-by: Aurabindo Jayamohanan Pillai Aurabindo.Pillai@amd.com Acked-by: Solomon Chiu solomon.chiu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 830d302be045..12a4f0675fb0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6800,10 +6800,6 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc, int x, y; int xorigin = 0, yorigin = 0;
- position->enable = false; - position->x = 0; - position->y = 0; - if (!crtc || !plane->state->fb) return 0;
@@ -6850,7 +6846,7 @@ static void handle_cursor_update(struct drm_plane *plane, struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL; struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); uint64_t address = afb ? afb->address : 0; - struct dc_cursor_position position; + struct dc_cursor_position position = {0}; struct dc_cursor_attributes attributes; int ret;
From: Aric Cyr aric.cyr@amd.com
[ Upstream commit 4710430a779e6077d81218ac768787545bff8c49 ]
[Why] When unplugging a display, the underflow counter can be seen to increase because PSTATE switch is allowed even when some planes are not blanked.
[How] Check that all planes are not active instead of all streams before allowing PSTATE change.
Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Aric Cyr aric.cyr@amd.com Acked-by: Solomon Chiu solomon.chiu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c index 95d883482227..cab47bb21172 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c @@ -240,6 +240,7 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base, bool force_reset = false; bool update_uclk = false; bool p_state_change_support; + int total_plane_count;
if (dc->work_arounds.skip_clock_update || !clk_mgr->smu_present) return; @@ -280,7 +281,8 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base, clk_mgr_base->clks.socclk_khz = new_clocks->socclk_khz;
clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support; - p_state_change_support = new_clocks->p_state_change_support || (display_count == 0); + total_plane_count = clk_mgr_helper_get_active_plane_cnt(dc, context); + p_state_change_support = new_clocks->p_state_change_support || (total_plane_count == 0); if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) { clk_mgr_base->clks.p_state_change_support = p_state_change_support;
From: Dmytro Laktyushkin Dmytro.Laktyushkin@amd.com
[ Upstream commit 8ee0fea4baf90e43efe2275de208a7809f9985bc ]
Incorrect variable used, missing initialization during validation.
Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Dmytro Laktyushkin Dmytro.Laktyushkin@amd.com Reviewed-by: Eric Bernstein Eric.Bernstein@amd.com Acked-by: Solomon Chiu solomon.chiu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c | 1 + drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c | 1 + 2 files changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c index 45f028986a8d..b3f0476899d3 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c @@ -3437,6 +3437,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l mode_lib->vba.DCCEnabledInAnyPlane = true; } } + mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly; for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { locals->FabricAndDRAMBandwidthPerState[i] = dml_min( mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c index 80170f9721ce..1bcda7eba4a6 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c @@ -3510,6 +3510,7 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode mode_lib->vba.DCCEnabledInAnyPlane = true; } } + mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly; for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { locals->FabricAndDRAMBandwidthPerState[i] = dml_min( mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit a2b2cc660822cae08c351c7f6b452bfd1330a4f7 ]
This patch fixes the following Coverity warning:
CID 361199 (#1 of 1): Unchecked return value (CHECKED_RETURN) 3. check_return: Calling qla24xx_get_isp_stats without checking return value (as is done elsewhere 4 out of 5 times).
Link: https://lore.kernel.org/r/20210320232359.941-7-bvanassche@acm.org Cc: Quinn Tran qutran@marvell.com Cc: Mike Christie michael.christie@oracle.com Cc: Himanshu Madhani himanshu.madhani@oracle.com Cc: Daniel Wagner dwagner@suse.de Cc: Lee Duncan lduncan@suse.com Reviewed-by: Daniel Wagner dwagner@suse.de Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_attr.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index ab45ac1e5a72..6a2c4a6fcded 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -2855,6 +2855,8 @@ qla2x00_reset_host_stats(struct Scsi_Host *shost) vha->qla_stats.jiffies_at_last_reset = get_jiffies_64();
if (IS_FWI2_CAPABLE(ha)) { + int rval; + stats = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stats), &stats_dma, GFP_KERNEL); if (!stats) { @@ -2864,7 +2866,11 @@ qla2x00_reset_host_stats(struct Scsi_Host *shost) }
/* reset firmware statistics */ - qla24xx_get_isp_stats(base_vha, stats, stats_dma, BIT_0); + rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, BIT_0); + if (rval != QLA_SUCCESS) + ql_log(ql_log_warn, vha, 0x70de, + "Resetting ISP statistics failed: rval = %d\n", + rval);
dma_free_coherent(&ha->pdev->dev, sizeof(*stats), stats, stats_dma);
From: Dmitry Vyukov dvyukov@google.com
[ Upstream commit b4142fc4d52d051d4d8df1fb6c569e5b445d369e ]
vkms_vblank_simulate() uses WARN_ON for timing-dependent condition (timer overrun). This is a mis-use of WARN_ON, WARN_ON must be used to denote kernel bugs. Use pr_warn() instead.
Signed-off-by: Dmitry Vyukov dvyukov@google.com Reported-by: syzbot+4fc21a003c8332eb0bdd@syzkaller.appspotmail.com Cc: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Cc: Melissa Wen melissa.srw@gmail.com Cc: Haneen Mohammed hamohammed.sa@gmail.com Cc: Daniel Vetter daniel@ffwll.ch Cc: David Airlie airlied@linux.ie Cc: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Acked-by: Melissa Wen melissa.srw@gmail.com Signed-off-by: Melissa Wen melissa.srw@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20210320132840.1315853-1-dvyuk... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vkms/vkms_crtc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 09c012d54d58..1ae5cd47d954 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -18,7 +18,8 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer, output->period_ns); - WARN_ON(ret_overrun != 1); + if (ret_overrun != 1) + pr_warn("%s: vblank timer overrun\n", __func__);
spin_lock(&output->lock); ret = drm_crtc_handle_vblank(crtc);
From: Quinn Tran qutran@marvell.com
[ Upstream commit 2ce35c0821afc2acd5ee1c3f60d149f8b2520ce8 ]
On bsg command completion, bsg_job_done() was called while qla driver continued to access the bsg_job buffer. bsg_job_done() would free up resources that ended up being reused by other task while the driver continued to access the buffers. As a result, driver was reading garbage data.
localhost kernel: BUG: KASAN: use-after-free in sg_next+0x64/0x80 localhost kernel: Read of size 8 at addr ffff8883228a3330 by task swapper/26/0 localhost kernel: localhost kernel: CPU: 26 PID: 0 Comm: swapper/26 Kdump: loaded Tainted: G OE --------- - - 4.18.0-193.el8.x86_64+debug #1 localhost kernel: Hardware name: HP ProLiant DL360 Gen9/ProLiant DL360 Gen9, BIOS P89 08/12/2016 localhost kernel: Call Trace: localhost kernel: <IRQ> localhost kernel: dump_stack+0x9a/0xf0 localhost kernel: print_address_description.cold.3+0x9/0x23b localhost kernel: kasan_report.cold.4+0x65/0x95 localhost kernel: debug_dma_unmap_sg.part.12+0x10d/0x2d0 localhost kernel: qla2x00_bsg_sp_free+0xaf6/0x1010 [qla2xxx]
Link: https://lore.kernel.org/r/20210329085229.4367-6-njavali@marvell.com Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Saurav Kashyap skashyap@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_bsg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 23b604832a54..7fa085969a63 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -24,10 +24,11 @@ void qla2x00_bsg_job_done(srb_t *sp, int res) struct bsg_job *bsg_job = sp->u.bsg_job; struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+ sp->free(sp); + bsg_reply->result = res; bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); - sp->free(sp); }
void qla2x00_bsg_sp_free(srb_t *sp)
From: Peng Fan peng.fan@nxp.com
[ Upstream commit f410ee0aa2df050a9505f5c261953e9b18e21206 ]
When imx_data->pinctrl is not a valid pointer, pinctrl_lookup_state will trigger kernel panic.
When we boot Dual OS on Jailhouse hypervisor, we let the 1st Linux to configure pinmux ready for the 2nd OS, so the 2nd OS not have pinctrl settings.
Similar to this commit b62eee9f804e ("mmc: sdhci-esdhc-imx: no fail when no pinctrl available").
Reviewed-by: Bough Chen haobo.chen@nxp.com Reviewed-by: Alice Guo alice.guo@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com Link: https://lore.kernel.org/r/1614222604-27066-6-git-send-email-peng.fan@oss.nxp... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-esdhc-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 5d9b3106d2f7..d28809e47962 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -1504,7 +1504,7 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
mmc_of_parse_voltage(np, &host->ocr_mask);
- if (esdhc_is_usdhc(imx_data)) { + if (esdhc_is_usdhc(imx_data) && !IS_ERR(imx_data->pinctrl)) { imx_data->pins_100mhz = pinctrl_lookup_state(imx_data->pinctrl, ESDHC_PINCTRL_STATE_100MHZ); imx_data->pins_200mhz = pinctrl_lookup_state(imx_data->pinctrl,
From: Adrian Hunter adrian.hunter@intel.com
[ Upstream commit ee629112be8b4eff71d4d3d108a28bc7dc877e13 ]
Add PCI IDs for Intel LKF eMMC and SD card host controllers.
Signed-off-by: Adrian Hunter adrian.hunter@intel.com Link: https://lore.kernel.org/r/20210322055356.24923-1-adrian.hunter@intel.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-pci-core.c | 2 ++ drivers/mmc/host/sdhci-pci.h | 2 ++ 2 files changed, 4 insertions(+)
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 936e4db9060f..bf04a08eeba1 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -1930,6 +1930,8 @@ static const struct pci_device_id pci_ids[] = { SDHCI_PCI_DEVICE(INTEL, CMLH_SD, intel_byt_sd), SDHCI_PCI_DEVICE(INTEL, JSL_EMMC, intel_glk_emmc), SDHCI_PCI_DEVICE(INTEL, JSL_SD, intel_byt_sd), + SDHCI_PCI_DEVICE(INTEL, LKF_EMMC, intel_glk_emmc), + SDHCI_PCI_DEVICE(INTEL, LKF_SD, intel_byt_sd), SDHCI_PCI_DEVICE(O2, 8120, o2), SDHCI_PCI_DEVICE(O2, 8220, o2), SDHCI_PCI_DEVICE(O2, 8221, o2), diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index d0ed232af0eb..8f90c4163bb5 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h @@ -57,6 +57,8 @@ #define PCI_DEVICE_ID_INTEL_CMLH_SD 0x06f5 #define PCI_DEVICE_ID_INTEL_JSL_EMMC 0x4dc4 #define PCI_DEVICE_ID_INTEL_JSL_SD 0x4df8 +#define PCI_DEVICE_ID_INTEL_LKF_EMMC 0x98c4 +#define PCI_DEVICE_ID_INTEL_LKF_SD 0x98f8
#define PCI_DEVICE_ID_SYSKONNECT_8000 0x8000 #define PCI_DEVICE_ID_VIA_95D0 0x95d0
From: Al Cooper alcooperx@gmail.com
[ Upstream commit f0bdf98fab058efe7bf49732f70a0f26d1143154 ]
Remove the CQHCI_QUIRK_SHORT_TXFR_DESC_SZ quirk because the latest chips have this fixed and earlier chips have other CQE problems that prevent the feature from being enabled.
Signed-off-by: Al Cooper alcooperx@gmail.com Acked-by: Florian Fainelli f.fainelli@gmail.com Link: https://lore.kernel.org/r/20210325192834.42955-1-alcooperx@gmail.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-brcmstb.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c index f9780c65ebe9..f24623aac2db 100644 --- a/drivers/mmc/host/sdhci-brcmstb.c +++ b/drivers/mmc/host/sdhci-brcmstb.c @@ -199,7 +199,6 @@ static int sdhci_brcmstb_add_host(struct sdhci_host *host, if (dma64) { dev_dbg(mmc_dev(host->mmc), "Using 64 bit DMA\n"); cq_host->caps |= CQHCI_TASK_DESC_SZ_128; - cq_host->quirks |= CQHCI_QUIRK_SHORT_TXFR_DESC_SZ; }
ret = cqhci_init(cq_host, host->mmc, dma64);
From: Xingui Yang yangxingui@huawei.com
[ Upstream commit 234e6d2c18f5b080cde874483c4c361f3ae7cffe ]
On Hisilicon Kunpeng920, ESP is set to 1 by default for all ports of SATA controller. In some scenarios, some ports are not external SATA ports, and it cause disks connected to these ports to be identified as removable disks. So disable the SXS capability on the software side to prevent users from mistakenly considering non-removable disks as removable disks and performing related operations.
Signed-off-by: Xingui Yang yangxingui@huawei.com Signed-off-by: Luo Jiaxing luojiaxing@huawei.com Reviewed-by: John Garry john.garry@huawei.com Link: https://lore.kernel.org/r/1615544676-61926-1-git-send-email-luojiaxing@huawe... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ata/ahci.c | 5 +++++ drivers/ata/ahci.h | 1 + drivers/ata/libahci.c | 5 +++++ 3 files changed, 11 insertions(+)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 00ba8e5a1ccc..33192a8f687d 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1772,6 +1772,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;
#ifdef CONFIG_ARM64 + if (pdev->vendor == PCI_VENDOR_ID_HUAWEI && + pdev->device == 0xa235 && + pdev->revision < 0x30) + hpriv->flags |= AHCI_HFLAG_NO_SXS; + if (pdev->vendor == 0x177d && pdev->device == 0xa01c) hpriv->irq_handler = ahci_thunderx_irq_handler; #endif diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 98b8baa47dc5..d1f284f0c83d 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -242,6 +242,7 @@ enum { suspend/resume */ AHCI_HFLAG_IGN_NOTSUPP_POWER_ON = (1 << 27), /* ignore -EOPNOTSUPP from phy_power_on() */ + AHCI_HFLAG_NO_SXS = (1 << 28), /* SXS not supported */
/* ap->flags bits */
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index ea5bf5f4cbed..fec2e9754aed 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -493,6 +493,11 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) cap |= HOST_CAP_ALPM; }
+ if ((cap & HOST_CAP_SXS) && (hpriv->flags & AHCI_HFLAG_NO_SXS)) { + dev_info(dev, "controller does not support SXS, disabling CAP_SXS\n"); + cap &= ~HOST_CAP_SXS; + } + if (hpriv->force_port_map && port_map != hpriv->force_port_map) { dev_info(dev, "forcing port_map 0x%x -> 0x%x\n", port_map, hpriv->force_port_map);
From: Carsten Haitzler carsten.haitzler@arm.com
[ Upstream commit be3e477effba636ad25dcd244db264c6cd5c1f36 ]
KASAN found this problem. find_first_bit() expects to look at a pointer pointing to a long, but we look at a u32 - this is going to be an issue with endianness but, KSAN already flags this as out-of-bounds stack reads. This fixes it by just importing inot a local long.
Signed-off-by: Carsten Haitzler carsten.haitzler@arm.com Acked-by: Liviu Dudau liviu.dudau@arm.com Signed-off-by: Liviu Dudau liviu.dudau@arm.com Link: https://patchwork.freedesktop.org/patch/msgid/20201218150812.68195-1-carsten... Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/arm/display/include/malidp_utils.h | 3 --- .../drm/arm/display/komeda/komeda_pipeline.c | 16 +++++++++++----- .../display/komeda/komeda_pipeline_state.c | 19 +++++++++++-------- 3 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/arm/display/include/malidp_utils.h b/drivers/gpu/drm/arm/display/include/malidp_utils.h index 3bc383d5bf73..49a1d7f3539c 100644 --- a/drivers/gpu/drm/arm/display/include/malidp_utils.h +++ b/drivers/gpu/drm/arm/display/include/malidp_utils.h @@ -13,9 +13,6 @@ #define has_bit(nr, mask) (BIT(nr) & (mask)) #define has_bits(bits, mask) (((bits) & (mask)) == (bits))
-#define dp_for_each_set_bit(bit, mask) \ - for_each_set_bit((bit), ((unsigned long *)&(mask)), sizeof(mask) * 8) - #define dp_wait_cond(__cond, __tries, __min_range, __max_range) \ ({ \ int num_tries = __tries; \ diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c index 452e505a1fd3..79a6339840bb 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c @@ -46,8 +46,9 @@ void komeda_pipeline_destroy(struct komeda_dev *mdev, { struct komeda_component *c; int i; + unsigned long avail_comps = pipe->avail_comps;
- dp_for_each_set_bit(i, pipe->avail_comps) { + for_each_set_bit(i, &avail_comps, 32) { c = komeda_pipeline_get_component(pipe, i); komeda_component_destroy(mdev, c); } @@ -246,6 +247,7 @@ static void komeda_pipeline_dump(struct komeda_pipeline *pipe) { struct komeda_component *c; int id; + unsigned long avail_comps = pipe->avail_comps;
DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n", pipe->id, pipe->n_layers, pipe->n_scalers, @@ -257,7 +259,7 @@ static void komeda_pipeline_dump(struct komeda_pipeline *pipe) pipe->of_output_links[1] ? pipe->of_output_links[1]->full_name : "none");
- dp_for_each_set_bit(id, pipe->avail_comps) { + for_each_set_bit(id, &avail_comps, 32) { c = komeda_pipeline_get_component(pipe, id);
komeda_component_dump(c); @@ -269,8 +271,9 @@ static void komeda_component_verify_inputs(struct komeda_component *c) struct komeda_pipeline *pipe = c->pipeline; struct komeda_component *input; int id; + unsigned long supported_inputs = c->supported_inputs;
- dp_for_each_set_bit(id, c->supported_inputs) { + for_each_set_bit(id, &supported_inputs, 32) { input = komeda_pipeline_get_component(pipe, id); if (!input) { c->supported_inputs &= ~(BIT(id)); @@ -301,8 +304,9 @@ static void komeda_pipeline_assemble(struct komeda_pipeline *pipe) struct komeda_component *c; struct komeda_layer *layer; int i, id; + unsigned long avail_comps = pipe->avail_comps;
- dp_for_each_set_bit(id, pipe->avail_comps) { + for_each_set_bit(id, &avail_comps, 32) { c = komeda_pipeline_get_component(pipe, id); komeda_component_verify_inputs(c); } @@ -354,13 +358,15 @@ void komeda_pipeline_dump_register(struct komeda_pipeline *pipe, { struct komeda_component *c; u32 id; + unsigned long avail_comps;
seq_printf(sf, "\n======== Pipeline-%d ==========\n", pipe->id);
if (pipe->funcs && pipe->funcs->dump_register) pipe->funcs->dump_register(pipe, sf);
- dp_for_each_set_bit(id, pipe->avail_comps) { + avail_comps = pipe->avail_comps; + for_each_set_bit(id, &avail_comps, 32) { c = komeda_pipeline_get_component(pipe, id);
seq_printf(sf, "\n------%s------\n", c->name); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c index 8f32ae7c25d0..c3cdf283ecef 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -1231,14 +1231,15 @@ komeda_pipeline_unbound_components(struct komeda_pipeline *pipe, struct komeda_pipeline_state *old = priv_to_pipe_st(pipe->obj.state); struct komeda_component_state *c_st; struct komeda_component *c; - u32 disabling_comps, id; + u32 id; + unsigned long disabling_comps;
WARN_ON(!old);
disabling_comps = (~new->active_comps) & old->active_comps;
/* unbound all disabling component */ - dp_for_each_set_bit(id, disabling_comps) { + for_each_set_bit(id, &disabling_comps, 32) { c = komeda_pipeline_get_component(pipe, id); c_st = komeda_component_get_state_and_set_user(c, drm_st, NULL, new->crtc); @@ -1286,7 +1287,8 @@ bool komeda_pipeline_disable(struct komeda_pipeline *pipe, struct komeda_pipeline_state *old; struct komeda_component *c; struct komeda_component_state *c_st; - u32 id, disabling_comps = 0; + u32 id; + unsigned long disabling_comps;
old = komeda_pipeline_get_old_state(pipe, old_state);
@@ -1296,10 +1298,10 @@ bool komeda_pipeline_disable(struct komeda_pipeline *pipe, disabling_comps = old->active_comps & pipe->standalone_disabled_comps;
- DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, disabling_comps: 0x%x.\n", + DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, disabling_comps: 0x%lx.\n", pipe->id, old->active_comps, disabling_comps);
- dp_for_each_set_bit(id, disabling_comps) { + for_each_set_bit(id, &disabling_comps, 32) { c = komeda_pipeline_get_component(pipe, id); c_st = priv_to_comp_st(c->obj.state);
@@ -1330,16 +1332,17 @@ void komeda_pipeline_update(struct komeda_pipeline *pipe, struct komeda_pipeline_state *new = priv_to_pipe_st(pipe->obj.state); struct komeda_pipeline_state *old; struct komeda_component *c; - u32 id, changed_comps = 0; + u32 id; + unsigned long changed_comps;
old = komeda_pipeline_get_old_state(pipe, old_state);
changed_comps = new->active_comps | old->active_comps;
- DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%x.\n", + DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%lx.\n", pipe->id, new->active_comps, changed_comps);
- dp_for_each_set_bit(id, changed_comps) { + for_each_set_bit(id, &changed_comps, 32) { c = komeda_pipeline_get_component(pipe, id);
if (new->active_comps & BIT(c->id))
From: Hou Pu houpu.main@gmail.com
[ Upstream commit 79695dcd9ad4463a82def7f42960e6d7baa76f0b ]
Return NVME_SC_INVALID_FIELD from discovery controller like normal controller when executing identify or get log page command.
Signed-off-by: Hou Pu houpu.main@gmail.com Reviewed-by: Chaitanya Kulkarni chaitanya.kulkarni@wdc.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/target/discovery.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c index f40c05c33c3a..5b8ee824b100 100644 --- a/drivers/nvme/target/discovery.c +++ b/drivers/nvme/target/discovery.c @@ -177,12 +177,14 @@ static void nvmet_execute_disc_get_log_page(struct nvmet_req *req) if (req->cmd->get_log_page.lid != NVME_LOG_DISC) { req->error_loc = offsetof(struct nvme_get_log_page_command, lid); - status = NVME_SC_INVALID_OPCODE | NVME_SC_DNR; + status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; goto out; }
/* Spec requires dword aligned offsets */ if (offset & 0x3) { + req->error_loc = + offsetof(struct nvme_get_log_page_command, lpo); status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; goto out; } @@ -249,7 +251,7 @@ static void nvmet_execute_disc_identify(struct nvmet_req *req)
if (req->cmd->identify.cns != NVME_ID_CNS_CTRL) { req->error_loc = offsetof(struct nvme_identify, cns); - status = NVME_SC_INVALID_OPCODE | NVME_SC_DNR; + status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; goto out; }
From: Fenghua Yu fenghua.yu@intel.com
[ Upstream commit a9d26a302dea29eb84f491b1340a57e56c631a71 ]
David reported a buffer overflow error in the check_results() function of the cmt unit test and he suggested enabling _FORTIFY_SOURCE gcc compiler option to automatically detect any such errors.
Feature Test Macros man page describes_FORTIFY_SOURCE as below
"Defining this macro causes some lightweight checks to be performed to detect some buffer overflow errors when employing various string and memory manipulation functions (for example, memcpy, memset, stpcpy, strcpy, strncpy, strcat, strncat, sprintf, snprintf, vsprintf, vsnprintf, gets, and wide character variants thereof). For some functions, argument consistency is checked; for example, a check is made that open has been supplied with a mode argument when the specified flags include O_CREAT. Not all problems are detected, just some common cases.
If _FORTIFY_SOURCE is set to 1, with compiler optimization level 1 (gcc -O1) and above, checks that shouldn't change the behavior of conforming programs are performed.
With _FORTIFY_SOURCE set to 2, some more checking is added, but some conforming programs might fail.
Some of the checks can be performed at compile time (via macros logic implemented in header files), and result in compiler warnings; other checks take place at run time, and result in a run-time error if the check fails.
Use of this macro requires compiler support, available with gcc since version 4.0."
Fix the buffer overflow error in the check_results() function of the cmt unit test and enable _FORTIFY_SOURCE gcc check to catch any future buffer overflow errors.
Reported-by: David Binderman dcb314@hotmail.com Suggested-by: David Binderman dcb314@hotmail.com Tested-by: Babu Moger babu.moger@amd.com Signed-off-by: Fenghua Yu fenghua.yu@intel.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/resctrl/Makefile | 2 +- tools/testing/selftests/resctrl/cqm_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/resctrl/Makefile b/tools/testing/selftests/resctrl/Makefile index d585cc1948cc..6bcee2ec91a9 100644 --- a/tools/testing/selftests/resctrl/Makefile +++ b/tools/testing/selftests/resctrl/Makefile @@ -1,5 +1,5 @@ CC = $(CROSS_COMPILE)gcc -CFLAGS = -g -Wall +CFLAGS = -g -Wall -O2 -D_FORTIFY_SOURCE=2 SRCS=$(wildcard *.c) OBJS=$(SRCS:.c=.o)
diff --git a/tools/testing/selftests/resctrl/cqm_test.c b/tools/testing/selftests/resctrl/cqm_test.c index c8756152bd61..5e7308ac63be 100644 --- a/tools/testing/selftests/resctrl/cqm_test.c +++ b/tools/testing/selftests/resctrl/cqm_test.c @@ -86,7 +86,7 @@ static int check_results(struct resctrl_val_param *param, int no_of_bits) return errno; }
- while (fgets(temp, 1024, fp)) { + while (fgets(temp, sizeof(temp), fp)) { char *token = strtok(temp, ":\t"); int fields = 0;
From: Fenghua Yu fenghua.yu@intel.com
[ Upstream commit 8236c51d85a64643588505a6791e022cc8d84864 ]
Reinette reported following compilation issue on Fedora 32, gcc version 10.1.1
/usr/bin/ld: cqm_test.o:<src_dir>/cqm_test.c:22: multiple definition of `cache_size'; cat_test.o:<src_dir>/cat_test.c:23: first defined here
The same issue is reported for long_mask, cbm_mask, count_of_bits etc variables as well. Compiler isn't happy because these variables are defined globally in two .c files namely cqm_test.c and cat_test.c and the compiler during compilation finds that the variable is already defined (multiple definition error).
Taking a closer look at the usage of these variables reveals that these variables are used only locally in functions such as cqm_resctrl_val() (defined in cqm_test.c) and cat_perf_miss_val() (defined in cat_test.c). These variables are not shared between those functions. So, there is no need for these variables to be global. Hence, fix this issue by making them static variables.
Reported-by: Reinette Chatre reinette.chatre@intel.com Tested-by: Babu Moger babu.moger@amd.com Signed-off-by: Fenghua Yu fenghua.yu@intel.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/resctrl/cat_test.c | 10 +++++----- tools/testing/selftests/resctrl/cqm_test.c | 10 +++++----- tools/testing/selftests/resctrl/resctrl.h | 2 +- tools/testing/selftests/resctrl/resctrlfs.c | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c index 5da43767b973..bdeeb5772592 100644 --- a/tools/testing/selftests/resctrl/cat_test.c +++ b/tools/testing/selftests/resctrl/cat_test.c @@ -17,10 +17,10 @@ #define MAX_DIFF_PERCENT 4 #define MAX_DIFF 1000000
-int count_of_bits; -char cbm_mask[256]; -unsigned long long_mask; -unsigned long cache_size; +static int count_of_bits; +static char cbm_mask[256]; +static unsigned long long_mask; +static unsigned long cache_size;
/* * Change schemata. Write schemata to specified @@ -136,7 +136,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) return -1;
/* Get default cbm mask for L3/L2 cache */ - ret = get_cbm_mask(cache_type); + ret = get_cbm_mask(cache_type, cbm_mask); if (ret) return ret;
diff --git a/tools/testing/selftests/resctrl/cqm_test.c b/tools/testing/selftests/resctrl/cqm_test.c index 5e7308ac63be..de33d1c0466e 100644 --- a/tools/testing/selftests/resctrl/cqm_test.c +++ b/tools/testing/selftests/resctrl/cqm_test.c @@ -16,10 +16,10 @@ #define MAX_DIFF 2000000 #define MAX_DIFF_PERCENT 15
-int count_of_bits; -char cbm_mask[256]; -unsigned long long_mask; -unsigned long cache_size; +static int count_of_bits; +static char cbm_mask[256]; +static unsigned long long_mask; +static unsigned long cache_size;
static int cqm_setup(int num, ...) { @@ -125,7 +125,7 @@ int cqm_resctrl_val(int cpu_no, int n, char **benchmark_cmd) if (!validate_resctrl_feature_request("cqm")) return -1;
- ret = get_cbm_mask("L3"); + ret = get_cbm_mask("L3", cbm_mask); if (ret) return ret;
diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h index 39bf59c6b9c5..959c71e39bdc 100644 --- a/tools/testing/selftests/resctrl/resctrl.h +++ b/tools/testing/selftests/resctrl/resctrl.h @@ -92,7 +92,7 @@ void tests_cleanup(void); void mbm_test_cleanup(void); int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd); void mba_test_cleanup(void); -int get_cbm_mask(char *cache_type); +int get_cbm_mask(char *cache_type, char *cbm_mask); int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size); void ctrlc_handler(int signum, siginfo_t *info, void *ptr); int cat_val(struct resctrl_val_param *param); diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/selftests/resctrl/resctrlfs.c index 19c0ec4045a4..2a16100c9c3f 100644 --- a/tools/testing/selftests/resctrl/resctrlfs.c +++ b/tools/testing/selftests/resctrl/resctrlfs.c @@ -49,8 +49,6 @@ static int find_resctrl_mount(char *buffer) return -ENOENT; }
-char cbm_mask[256]; - /* * remount_resctrlfs - Remount resctrl FS at /sys/fs/resctrl * @mum_resctrlfs: Should the resctrl FS be remounted? @@ -205,16 +203,18 @@ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size) /* * get_cbm_mask - Get cbm mask for given cache * @cache_type: Cache level L2/L3 - * - * Mask is stored in cbm_mask which is global variable. + * @cbm_mask: cbm_mask returned as a string * * Return: = 0 on success, < 0 on failure. */ -int get_cbm_mask(char *cache_type) +int get_cbm_mask(char *cache_type, char *cbm_mask) { char cbm_mask_path[1024]; FILE *fp;
+ if (!cbm_mask) + return -1; + sprintf(cbm_mask_path, "%s/%s/cbm_mask", CBM_MASK_PATH, cache_type);
fp = fopen(cbm_mask_path, "r");
From: Fenghua Yu fenghua.yu@intel.com
[ Upstream commit 896016d2ad051811ff9c9c087393adc063322fbc ]
Reinette reported following compilation issue on Fedora 32, gcc version 10.1.1
/usr/bin/ld: resctrl_tests.o:<src_dir>/resctrl.h:65: multiple definition of `bm_pid'; cache.o:<src_dir>/resctrl.h:65: first defined here
Other variables are ppid, tests_run, llc_occup_path, is_amd. Compiler isn't happy because these variables are defined globally in two .c files but are not declared as extern.
To fix issues for the global variables, declare them as extern.
Chang Log: - Split this patch from v4's patch 1 (Shuah).
Reported-by: Reinette Chatre reinette.chatre@intel.com Tested-by: Babu Moger babu.moger@amd.com Signed-off-by: Fenghua Yu fenghua.yu@intel.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/resctrl/resctrl.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h index 959c71e39bdc..12b77182cb44 100644 --- a/tools/testing/selftests/resctrl/resctrl.h +++ b/tools/testing/selftests/resctrl/resctrl.h @@ -62,11 +62,11 @@ struct resctrl_val_param { int (*setup)(int num, ...); };
-pid_t bm_pid, ppid; -int tests_run; +extern pid_t bm_pid, ppid; +extern int tests_run;
-char llc_occup_path[1024]; -bool is_amd; +extern char llc_occup_path[1024]; +extern bool is_amd;
bool check_resctrlfs_support(void); int filter_dmesg(void);
From: Fenghua Yu fenghua.yu@intel.com
[ Upstream commit 2428673638ea28fa93d2a38b1c3e8d70122b00ee ]
Checking resctrl features call strcmp() to compare feature strings (e.g. "mba", "cat" etc). The checkings are error prone and don't have good coding style. Define the constant strings in macros and call strncmp() to solve the potential issues.
Suggested-by: Shuah Khan skhan@linuxfoundation.org Tested-by: Babu Moger babu.moger@amd.com Signed-off-by: Fenghua Yu fenghua.yu@intel.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/resctrl/cache.c | 8 +++---- tools/testing/selftests/resctrl/cat_test.c | 2 +- tools/testing/selftests/resctrl/cqm_test.c | 2 +- tools/testing/selftests/resctrl/fill_buf.c | 4 ++-- tools/testing/selftests/resctrl/mba_test.c | 2 +- tools/testing/selftests/resctrl/mbm_test.c | 2 +- tools/testing/selftests/resctrl/resctrl.h | 5 +++++ .../testing/selftests/resctrl/resctrl_tests.c | 12 +++++----- tools/testing/selftests/resctrl/resctrl_val.c | 22 +++++++++---------- tools/testing/selftests/resctrl/resctrlfs.c | 17 +++++++------- 10 files changed, 41 insertions(+), 35 deletions(-)
diff --git a/tools/testing/selftests/resctrl/cache.c b/tools/testing/selftests/resctrl/cache.c index 38dbf4962e33..5922cc1b0386 100644 --- a/tools/testing/selftests/resctrl/cache.c +++ b/tools/testing/selftests/resctrl/cache.c @@ -182,7 +182,7 @@ int measure_cache_vals(struct resctrl_val_param *param, int bm_pid) /* * Measure cache miss from perf. */ - if (!strcmp(param->resctrl_val, "cat")) { + if (!strncmp(param->resctrl_val, CAT_STR, sizeof(CAT_STR))) { ret = get_llc_perf(&llc_perf_miss); if (ret < 0) return ret; @@ -192,7 +192,7 @@ int measure_cache_vals(struct resctrl_val_param *param, int bm_pid) /* * Measure llc occupancy from resctrl. */ - if (!strcmp(param->resctrl_val, "cqm")) { + if (!strncmp(param->resctrl_val, CQM_STR, sizeof(CQM_STR))) { ret = get_llc_occu_resctrl(&llc_occu_resc); if (ret < 0) return ret; @@ -234,7 +234,7 @@ int cat_val(struct resctrl_val_param *param) if (ret) return ret;
- if ((strcmp(resctrl_val, "cat") == 0)) { + if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) { ret = initialize_llc_perf(); if (ret) return ret; @@ -242,7 +242,7 @@ int cat_val(struct resctrl_val_param *param)
/* Test runs until the callback setup() tells the test to stop. */ while (1) { - if (strcmp(resctrl_val, "cat") == 0) { + if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) { ret = param->setup(1, param); if (ret) { ret = 0; diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c index bdeeb5772592..20823725daca 100644 --- a/tools/testing/selftests/resctrl/cat_test.c +++ b/tools/testing/selftests/resctrl/cat_test.c @@ -164,7 +164,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) return -1;
struct resctrl_val_param param = { - .resctrl_val = "cat", + .resctrl_val = CAT_STR, .cpu_no = cpu_no, .mum_resctrlfs = 0, .setup = cat_setup, diff --git a/tools/testing/selftests/resctrl/cqm_test.c b/tools/testing/selftests/resctrl/cqm_test.c index de33d1c0466e..271752e9ef5b 100644 --- a/tools/testing/selftests/resctrl/cqm_test.c +++ b/tools/testing/selftests/resctrl/cqm_test.c @@ -145,7 +145,7 @@ int cqm_resctrl_val(int cpu_no, int n, char **benchmark_cmd) }
struct resctrl_val_param param = { - .resctrl_val = "cqm", + .resctrl_val = CQM_STR, .ctrlgrp = "c1", .mongrp = "m1", .cpu_no = cpu_no, diff --git a/tools/testing/selftests/resctrl/fill_buf.c b/tools/testing/selftests/resctrl/fill_buf.c index 79c611c99a3d..51e5cf22632f 100644 --- a/tools/testing/selftests/resctrl/fill_buf.c +++ b/tools/testing/selftests/resctrl/fill_buf.c @@ -115,7 +115,7 @@ static int fill_cache_read(unsigned char *start_ptr, unsigned char *end_ptr,
while (1) { ret = fill_one_span_read(start_ptr, end_ptr); - if (!strcmp(resctrl_val, "cat")) + if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) break; }
@@ -134,7 +134,7 @@ static int fill_cache_write(unsigned char *start_ptr, unsigned char *end_ptr, { while (1) { fill_one_span_write(start_ptr, end_ptr); - if (!strcmp(resctrl_val, "cat")) + if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) break; }
diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c index 7bf8eaa6204b..6449fbd96096 100644 --- a/tools/testing/selftests/resctrl/mba_test.c +++ b/tools/testing/selftests/resctrl/mba_test.c @@ -141,7 +141,7 @@ void mba_test_cleanup(void) int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd) { struct resctrl_val_param param = { - .resctrl_val = "mba", + .resctrl_val = MBA_STR, .ctrlgrp = "c1", .mongrp = "m1", .cpu_no = cpu_no, diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c index 4700f7453f81..ec6cfe01c9c2 100644 --- a/tools/testing/selftests/resctrl/mbm_test.c +++ b/tools/testing/selftests/resctrl/mbm_test.c @@ -114,7 +114,7 @@ void mbm_test_cleanup(void) int mbm_bw_change(int span, int cpu_no, char *bw_report, char **benchmark_cmd) { struct resctrl_val_param param = { - .resctrl_val = "mbm", + .resctrl_val = MBM_STR, .ctrlgrp = "c1", .mongrp = "m1", .span = span, diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h index 12b77182cb44..36da6136af96 100644 --- a/tools/testing/selftests/resctrl/resctrl.h +++ b/tools/testing/selftests/resctrl/resctrl.h @@ -62,6 +62,11 @@ struct resctrl_val_param { int (*setup)(int num, ...); };
+#define MBM_STR "mbm" +#define MBA_STR "mba" +#define CQM_STR "cqm" +#define CAT_STR "cat" + extern pid_t bm_pid, ppid; extern int tests_run;
diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c index 425cc85ac883..4b109a59f72d 100644 --- a/tools/testing/selftests/resctrl/resctrl_tests.c +++ b/tools/testing/selftests/resctrl/resctrl_tests.c @@ -85,13 +85,13 @@ int main(int argc, char **argv) cqm_test = false; cat_test = false; while (token) { - if (!strcmp(token, "mbm")) { + if (!strncmp(token, MBM_STR, sizeof(MBM_STR))) { mbm_test = true; - } else if (!strcmp(token, "mba")) { + } else if (!strncmp(token, MBA_STR, sizeof(MBA_STR))) { mba_test = true; - } else if (!strcmp(token, "cqm")) { + } else if (!strncmp(token, CQM_STR, sizeof(CQM_STR))) { cqm_test = true; - } else if (!strcmp(token, "cat")) { + } else if (!strncmp(token, CAT_STR, sizeof(CAT_STR))) { cat_test = true; } else { printf("invalid argument\n"); @@ -161,7 +161,7 @@ int main(int argc, char **argv) if (!is_amd && mbm_test) { printf("# Starting MBM BW change ...\n"); if (!has_ben) - sprintf(benchmark_cmd[5], "%s", "mba"); + sprintf(benchmark_cmd[5], "%s", MBA_STR); res = mbm_bw_change(span, cpu_no, bw_report, benchmark_cmd); printf("%sok MBM: bw change\n", res ? "not " : ""); mbm_test_cleanup(); @@ -181,7 +181,7 @@ int main(int argc, char **argv) if (cqm_test) { printf("# Starting CQM test ...\n"); if (!has_ben) - sprintf(benchmark_cmd[5], "%s", "cqm"); + sprintf(benchmark_cmd[5], "%s", CQM_STR); res = cqm_resctrl_val(cpu_no, no_of_bits, benchmark_cmd); printf("%sok CQM: test\n", res ? "not " : ""); cqm_test_cleanup(); diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c index 520fea3606d1..aed71fd0713b 100644 --- a/tools/testing/selftests/resctrl/resctrl_val.c +++ b/tools/testing/selftests/resctrl/resctrl_val.c @@ -397,10 +397,10 @@ static void initialize_mem_bw_resctrl(const char *ctrlgrp, const char *mongrp, return; }
- if (strcmp(resctrl_val, "mbm") == 0) + if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) set_mbm_path(ctrlgrp, mongrp, resource_id);
- if ((strcmp(resctrl_val, "mba") == 0)) { + if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) { if (ctrlgrp) sprintf(mbm_total_path, CON_MBM_LOCAL_BYTES_PATH, RESCTRL_PATH, ctrlgrp, resource_id); @@ -524,7 +524,7 @@ static void initialize_llc_occu_resctrl(const char *ctrlgrp, const char *mongrp, return; }
- if (strcmp(resctrl_val, "cqm") == 0) + if (!strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR))) set_cqm_path(ctrlgrp, mongrp, resource_id); }
@@ -579,8 +579,8 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param) if (strcmp(param->filename, "") == 0) sprintf(param->filename, "stdio");
- if ((strcmp(resctrl_val, "mba")) == 0 || - (strcmp(resctrl_val, "mbm")) == 0) { + if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) || + !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) { ret = validate_bw_report_request(param->bw_report); if (ret) return ret; @@ -674,15 +674,15 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param) if (ret) goto out;
- if ((strcmp(resctrl_val, "mbm") == 0) || - (strcmp(resctrl_val, "mba") == 0)) { + if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) || + !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) { ret = initialize_mem_bw_imc(); if (ret) goto out;
initialize_mem_bw_resctrl(param->ctrlgrp, param->mongrp, param->cpu_no, resctrl_val); - } else if (strcmp(resctrl_val, "cqm") == 0) + } else if (!strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR))) initialize_llc_occu_resctrl(param->ctrlgrp, param->mongrp, param->cpu_no, resctrl_val);
@@ -710,8 +710,8 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
/* Test runs until the callback setup() tells the test to stop. */ while (1) { - if ((strcmp(resctrl_val, "mbm") == 0) || - (strcmp(resctrl_val, "mba") == 0)) { + if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) || + !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) { ret = param->setup(1, param); if (ret) { ret = 0; @@ -721,7 +721,7 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param) ret = measure_vals(param, &bw_resc_start); if (ret) break; - } else if (strcmp(resctrl_val, "cqm") == 0) { + } else if (!strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR))) { ret = param->setup(1, param); if (ret) { ret = 0; diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/selftests/resctrl/resctrlfs.c index 2a16100c9c3f..4174e48e06d1 100644 --- a/tools/testing/selftests/resctrl/resctrlfs.c +++ b/tools/testing/selftests/resctrl/resctrlfs.c @@ -334,7 +334,7 @@ void run_benchmark(int signum, siginfo_t *info, void *ucontext) operation = atoi(benchmark_cmd[4]); sprintf(resctrl_val, "%s", benchmark_cmd[5]);
- if (strcmp(resctrl_val, "cqm") != 0) + if (strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR))) buffer_span = span * MB; else buffer_span = span; @@ -459,8 +459,8 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp, goto out;
/* Create mon grp and write pid into it for "mbm" and "cqm" test */ - if ((strcmp(resctrl_val, "cqm") == 0) || - (strcmp(resctrl_val, "mbm") == 0)) { + if (!strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR)) || + !strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) { if (strlen(mongrp)) { sprintf(monitorgroup_p, "%s/mon_groups", controlgroup); sprintf(monitorgroup, "%s/%s", monitorgroup_p, mongrp); @@ -505,9 +505,9 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val) int resource_id, ret = 0; FILE *fp;
- if ((strcmp(resctrl_val, "mba") != 0) && - (strcmp(resctrl_val, "cat") != 0) && - (strcmp(resctrl_val, "cqm") != 0)) + if (strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR)) && + strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) && + strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR))) return -ENOENT;
if (!schemata) { @@ -528,9 +528,10 @@ int write_schemata(char *ctrlgrp, char *schemata, int cpu_no, char *resctrl_val) else sprintf(controlgroup, "%s/schemata", RESCTRL_PATH);
- if (!strcmp(resctrl_val, "cat") || !strcmp(resctrl_val, "cqm")) + if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)) || + !strncmp(resctrl_val, CQM_STR, sizeof(CQM_STR))) sprintf(schema, "%s%d%c%s", "L3:", resource_id, '=', schemata); - if (strcmp(resctrl_val, "mba") == 0) + if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) sprintf(schema, "%s%d%c%s", "MB:", resource_id, '=', schemata);
fp = fopen(controlgroup, "w");
From: Fenghua Yu fenghua.yu@intel.com
[ Upstream commit d7af3d0d515cbdf63b6c3398a3c15ecb1bc2bd38 ]
resctrl test suite accepts command line arguments (like -b, -t, -n and -p) as documented in the help. But passing -n and -p throws an invalid option error. This happens because -n and -p are missing in the list of characters that getopt() recognizes as valid arguments. Hence, they are treated as invalid options.
Fix this by adding them to the list of characters that getopt() recognizes as valid arguments. Please note that the main() function already has the logic to deal with the values passed as part of these arguments and hence no changes are needed there.
Tested-by: Babu Moger babu.moger@amd.com Signed-off-by: Fenghua Yu fenghua.yu@intel.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/resctrl/resctrl_tests.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c index 4b109a59f72d..ac2269610aa9 100644 --- a/tools/testing/selftests/resctrl/resctrl_tests.c +++ b/tools/testing/selftests/resctrl/resctrl_tests.c @@ -73,7 +73,7 @@ int main(int argc, char **argv) } }
- while ((c = getopt(argc_new, argv, "ht:b:")) != -1) { + while ((c = getopt(argc_new, argv, "ht:b:n:p:")) != -1) { char *token;
switch (c) {
From: Fenghua Yu fenghua.yu@intel.com
[ Upstream commit ee0415681eb661efa1eb2db7acc263f2c7df1e23 ]
Resctrl test suite before running any unit test (like cmt, cat, mbm and mba) should first check if the feature is enabled (by kernel and not just supported by H/W) on the platform or not. validate_resctrl_feature_request() is supposed to do that. This function intends to grep for relevant flags in /proc/cpuinfo but there are several issues here
1. validate_resctrl_feature_request() calls fgrep() to get flags from /proc/cpuinfo. But, fgrep() can only return a string with maximum of 255 characters and hence the complete cpu flags are never returned. 2. The substring search logic is also busted. If strstr() finds requested resctrl feature in the cpu flags, it returns pointer to the first occurrence. But, the logic negates the return value of strstr() and hence validate_resctrl_feature_request() returns false if the feature is present in the cpu flags and returns true if the feature is not present. 3. validate_resctrl_feature_request() checks if a resctrl feature is reported in /proc/cpuinfo flags or not. Having a cpu flag means that the H/W supports the feature, but it doesn't mean that the kernel enabled it. A user could selectively enable only a subset of resctrl features using kernel command line arguments. Hence, /proc/cpuinfo isn't a reliable source to check if a feature is enabled or not.
The 3rd issue being the major one and fixing it requires changing the way validate_resctrl_feature_request() works. Since, /proc/cpuinfo isn't the right place to check if a resctrl feature is enabled or not, a more appropriate place is /sys/fs/resctrl/info directory. Change validate_resctrl_feature_request() such that,
1. For cat, check if /sys/fs/resctrl/info/L3 directory is present or not 2. For mba, check if /sys/fs/resctrl/info/MB directory is present or not 3. For cmt, check if /sys/fs/resctrl/info/L3_MON directory is present and check if /sys/fs/resctrl/info/L3_MON/mon_features has llc_occupancy 4. For mbm, check if /sys/fs/resctrl/info/L3_MON directory is present and check if /sys/fs/resctrl/info/L3_MON/mon_features has mbm_<total/local>_bytes
Please note that only L3_CAT, L3_CMT, MBA and MBM are supported. CDP and L2 variants can be added later.
Reported-by: Reinette Chatre reinette.chatre@intel.com Tested-by: Babu Moger babu.moger@amd.com Signed-off-by: Fenghua Yu fenghua.yu@intel.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/resctrl/resctrl.h | 6 ++- tools/testing/selftests/resctrl/resctrlfs.c | 52 ++++++++++++++++----- 2 files changed, 46 insertions(+), 12 deletions(-)
diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h index 36da6136af96..9dcc96e1ad3d 100644 --- a/tools/testing/selftests/resctrl/resctrl.h +++ b/tools/testing/selftests/resctrl/resctrl.h @@ -28,6 +28,10 @@ #define RESCTRL_PATH "/sys/fs/resctrl" #define PHYS_ID_PATH "/sys/devices/system/cpu/cpu" #define CBM_MASK_PATH "/sys/fs/resctrl/info" +#define L3_PATH "/sys/fs/resctrl/info/L3" +#define MB_PATH "/sys/fs/resctrl/info/MB" +#define L3_MON_PATH "/sys/fs/resctrl/info/L3_MON" +#define L3_MON_FEATURES_PATH "/sys/fs/resctrl/info/L3_MON/mon_features"
#define PARENT_EXIT(err_msg) \ do { \ @@ -79,7 +83,7 @@ int remount_resctrlfs(bool mum_resctrlfs); int get_resource_id(int cpu_no, int *resource_id); int umount_resctrlfs(void); int validate_bw_report_request(char *bw_report); -bool validate_resctrl_feature_request(char *resctrl_val); +bool validate_resctrl_feature_request(const char *resctrl_val); char *fgrep(FILE *inf, const char *str); int taskset_benchmark(pid_t bm_pid, int cpu_no); void run_benchmark(int signum, siginfo_t *info, void *ucontext); diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/selftests/resctrl/resctrlfs.c index 4174e48e06d1..b57170f53861 100644 --- a/tools/testing/selftests/resctrl/resctrlfs.c +++ b/tools/testing/selftests/resctrl/resctrlfs.c @@ -616,26 +616,56 @@ char *fgrep(FILE *inf, const char *str) * validate_resctrl_feature_request - Check if requested feature is valid. * @resctrl_val: Requested feature * - * Return: 0 on success, non-zero on failure + * Return: True if the feature is supported, else false */ -bool validate_resctrl_feature_request(char *resctrl_val) +bool validate_resctrl_feature_request(const char *resctrl_val) { - FILE *inf = fopen("/proc/cpuinfo", "r"); + struct stat statbuf; bool found = false; char *res; + FILE *inf;
- if (!inf) + if (!resctrl_val) return false;
- res = fgrep(inf, "flags"); - - if (res) { - char *s = strchr(res, ':'); + if (remount_resctrlfs(false)) + return false;
- found = s && !strstr(s, resctrl_val); - free(res); + if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR))) { + if (!stat(L3_PATH, &statbuf)) + return true; + } else if (!strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) { + if (!stat(MB_PATH, &statbuf)) + return true; + } else if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) || + !strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) { + if (!stat(L3_MON_PATH, &statbuf)) { + inf = fopen(L3_MON_FEATURES_PATH, "r"); + if (!inf) + return false; + + if (!strncmp(resctrl_val, CMT_STR, sizeof(CMT_STR))) { + res = fgrep(inf, "llc_occupancy"); + if (res) { + found = true; + free(res); + } + } + + if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR))) { + res = fgrep(inf, "mbm_total_bytes"); + if (res) { + free(res); + res = fgrep(inf, "mbm_local_bytes"); + if (res) { + found = true; + free(res); + } + } + } + fclose(inf); + } } - fclose(inf);
return found; }
From: Fenghua Yu fenghua.yu@intel.com
[ Upstream commit d81343b5eedf84be71a4313e8fd073d0c510afcf ]
iMC (Integrated Memory Controller) counters are usually at "/sys/bus/event_source/devices/" and are named as "uncore_imc_<n>". num_of_imcs() function tries to count number of such iMC counters so that it could appropriately initialize required number of perf_attr structures that could be used to read these iMC counters.
num_of_imcs() function assumes that all the directories under this path that start with "uncore_imc" are iMC counters. But, on some systems there could be directories named as "uncore_imc_free_running" which aren't iMC counters. Trying to read from such directories will result in "not found file" errors and MBM/MBA tests will fail.
Hence, fix the logic in num_of_imcs() such that it looks at the first character after "uncore_imc_" to check if it's a numerical digit or not. If it's a digit then the directory represents an iMC counter, else, skip the directory.
Reported-by: Reinette Chatre reinette.chatre@intel.com Tested-by: Babu Moger babu.moger@amd.com Signed-off-by: Fenghua Yu fenghua.yu@intel.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/resctrl/resctrl_val.c | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c index aed71fd0713b..5478c23c62ba 100644 --- a/tools/testing/selftests/resctrl/resctrl_val.c +++ b/tools/testing/selftests/resctrl/resctrl_val.c @@ -221,8 +221,8 @@ static int read_from_imc_dir(char *imc_dir, int count) */ static int num_of_imcs(void) { + char imc_dir[512], *temp; unsigned int count = 0; - char imc_dir[512]; struct dirent *ep; int ret; DIR *dp; @@ -230,7 +230,25 @@ static int num_of_imcs(void) dp = opendir(DYN_PMU_PATH); if (dp) { while ((ep = readdir(dp))) { - if (strstr(ep->d_name, UNCORE_IMC)) { + temp = strstr(ep->d_name, UNCORE_IMC); + if (!temp) + continue; + + /* + * imc counters are named as "uncore_imc_<n>", hence + * increment the pointer to point to <n>. Note that + * sizeof(UNCORE_IMC) would count for null character as + * well and hence the last underscore character in + * uncore_imc'_' need not be counted. + */ + temp = temp + sizeof(UNCORE_IMC); + + /* + * Some directories under "DYN_PMU_PATH" could have + * names like "uncore_imc_free_running", hence, check if + * first character is a numerical digit or not. + */ + if (temp[0] >= '0' && temp[0] <= '9') { sprintf(imc_dir, "%s/%s/", DYN_PMU_PATH, ep->d_name); ret = read_from_imc_dir(imc_dir, count);
From: Fenghua Yu fenghua.yu@intel.com
[ Upstream commit 1205b688c92558a04d8dd4cbc2b213e0fceba5db ]
Dan reported following static checker warnings
tools/testing/selftests/resctrl/resctrl_val.c:545 measure_vals() warn: 'bw_imc' unsigned <= 0
tools/testing/selftests/resctrl/resctrl_val.c:549 measure_vals() warn: 'bw_resc_end' unsigned <= 0
These warnings are reported because 1. measure_vals() declares 'bw_imc' and 'bw_resc_end' as unsigned long variables 2. Return value of get_mem_bw_imc() and get_mem_bw_resctrl() are assigned to 'bw_imc' and 'bw_resc_end' respectively 3. The returned values are checked for <= 0 to see if the calls failed
Checking for < 0 for an unsigned value doesn't make any sense.
Fix this issue by changing the implementation of get_mem_bw_imc() and get_mem_bw_resctrl() such that they now accept reference to a variable and set the variable appropriately upon success and return 0, else return < 0 on error.
Reported-by: Dan Carpenter dan.carpenter@oracle.com Tested-by: Babu Moger babu.moger@amd.com Signed-off-by: Fenghua Yu fenghua.yu@intel.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/resctrl/resctrl_val.c | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-)
diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c index 5478c23c62ba..8df557894059 100644 --- a/tools/testing/selftests/resctrl/resctrl_val.c +++ b/tools/testing/selftests/resctrl/resctrl_val.c @@ -300,9 +300,9 @@ static int initialize_mem_bw_imc(void) * Memory B/W utilized by a process on a socket can be calculated using * iMC counters. Perf events are used to read these counters. * - * Return: >= 0 on success. < 0 on failure. + * Return: = 0 on success. < 0 on failure. */ -static float get_mem_bw_imc(int cpu_no, char *bw_report) +static int get_mem_bw_imc(int cpu_no, char *bw_report, float *bw_imc) { float reads, writes, of_mul_read, of_mul_write; int imc, j, ret; @@ -373,13 +373,18 @@ static float get_mem_bw_imc(int cpu_no, char *bw_report) close(imc_counters_config[imc][WRITE].fd); }
- if (strcmp(bw_report, "reads") == 0) - return reads; + if (strcmp(bw_report, "reads") == 0) { + *bw_imc = reads; + return 0; + }
- if (strcmp(bw_report, "writes") == 0) - return writes; + if (strcmp(bw_report, "writes") == 0) { + *bw_imc = writes; + return 0; + }
- return (reads + writes); + *bw_imc = reads + writes; + return 0; }
void set_mbm_path(const char *ctrlgrp, const char *mongrp, int resource_id) @@ -438,9 +443,8 @@ static void initialize_mem_bw_resctrl(const char *ctrlgrp, const char *mongrp, * 1. If con_mon grp is given, then read from it * 2. If con_mon grp is not given, then read from root con_mon grp */ -static unsigned long get_mem_bw_resctrl(void) +static int get_mem_bw_resctrl(unsigned long *mbm_total) { - unsigned long mbm_total = 0; FILE *fp;
fp = fopen(mbm_total_path, "r"); @@ -449,7 +453,7 @@ static unsigned long get_mem_bw_resctrl(void)
return -1; } - if (fscanf(fp, "%lu", &mbm_total) <= 0) { + if (fscanf(fp, "%lu", mbm_total) <= 0) { perror("Could not get mbm local bytes"); fclose(fp);
@@ -457,7 +461,7 @@ static unsigned long get_mem_bw_resctrl(void) } fclose(fp);
- return mbm_total; + return 0; }
pid_t bm_pid, ppid; @@ -549,7 +553,8 @@ static void initialize_llc_occu_resctrl(const char *ctrlgrp, const char *mongrp, static int measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start) { - unsigned long bw_imc, bw_resc, bw_resc_end; + unsigned long bw_resc, bw_resc_end; + float bw_imc; int ret;
/* @@ -559,13 +564,13 @@ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start) * Compare the two values to validate resctrl value. * It takes 1sec to measure the data. */ - bw_imc = get_mem_bw_imc(param->cpu_no, param->bw_report); - if (bw_imc <= 0) - return bw_imc; + ret = get_mem_bw_imc(param->cpu_no, param->bw_report, &bw_imc); + if (ret < 0) + return ret;
- bw_resc_end = get_mem_bw_resctrl(); - if (bw_resc_end <= 0) - return bw_resc_end; + ret = get_mem_bw_resctrl(&bw_resc_end); + if (ret < 0) + return ret;
bw_resc = (bw_resc_end - *bw_resc_start) / MB; ret = print_results_bw(param->filename, bm_pid, bw_imc, bw_resc);
From: Carl Philipp Klemm philipp@uvos.xyz
[ Upstream commit 751faedf06e895a17e985a88ef5b6364ffd797ed ]
Adds 80000 us sleep when the usb cable is plugged in to hopefully avoid bouncing contacts.
Upon pluging in the usb cable vbus will bounce for some time, causing cpcap to dissconnect charging due to detecting an undervoltage condition. This is a scope of vbus on xt894 while quickly inserting the usb cable with firm force, probed at the far side of the usb socket and vbus loaded with approx 1k: http://uvos.xyz/maserati/usbplug.jpg.
As can clearly be seen, vbus is all over the place for the first 15 ms or so with a small blip at ~40 ms this causes the cpcap to trip up and disable charging again.
The delay helps cpcap_usb_detect avoid the worst of this. It is, however, still not ideal as strong vibrations can cause the issue to reapear any time during charging. I have however not been able to cause the device to stop charging due to this in practice as it is hard to vibrate the device such that the vbus pins start bouncing again but cpcap_usb_detect is not called again due to a detected disconnect/reconnect event.
Signed-off-by: Carl Philipp Klemm philipp@uvos.xyz Tested-by: Tony Lindgren tony@atomide.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/cpcap-charger.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c index 22fff01425d6..891e1eb8e39d 100644 --- a/drivers/power/supply/cpcap-charger.c +++ b/drivers/power/supply/cpcap-charger.c @@ -633,6 +633,9 @@ static void cpcap_usb_detect(struct work_struct *work) return; }
+ /* Delay for 80ms to avoid vbus bouncing when usb cable is plugged in */ + usleep_range(80000, 120000); + /* Throttle chrgcurr2 interrupt for charger done and retry */ switch (ddata->state) { case CPCAP_CHARGER_CHARGING:
From: Don Brace don.brace@microchip.com
[ Upstream commit c6d3ee209b9e863c6251f72101511340451ca324 ]
Correct SCSI midlayer sending more requests than exposed host queue depth causing firmware ASSERT and lockup issues by enabling host-wide tags.
Note: This also results in better performance.
Link: https://lore.kernel.org/r/161549369787.25025.8975999483518581619.stgit@brunh... Suggested-by: Ming Lei ming.lei@redhat.com Suggested-by: John Garry john.garry@huawei.com Reviewed-by: Scott Benesh scott.benesh@microchip.com Reviewed-by: Scott Teel scott.teel@microchip.com Reviewed-by: Mike McGowen mike.mcgowen@microchip.com Reviewed-by: Kevin Barnett kevin.barnett@microchip.com Signed-off-by: Don Brace don.brace@microchip.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/smartpqi/smartpqi_init.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 9d0229656681..9300a677510d 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -6601,6 +6601,7 @@ static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info) shost->irq = pci_irq_vector(ctrl_info->pci_dev, 0); shost->unique_id = shost->irq; shost->nr_hw_queues = ctrl_info->num_queue_groups; + shost->host_tagset = 1; shost->hostdata[0] = (unsigned long)ctrl_info;
rc = scsi_add_host(shost, &ctrl_info->pci_dev->dev);
From: Murthy Bhat Murthy.Bhat@microchip.com
[ Upstream commit b622a601a13ae5974c5b0aeecb990c224b8db0d9 ]
While failing queued I/Os in TMF path, there was a request leak and hence stale entries in request pool with ref count being non-zero. In shutdown path we have a BUG_ON to catch stuck I/O either in firmware or in the driver. The stale requests caused a system crash. The I/O request pool leakage also lead to a significant performance drop.
Link: https://lore.kernel.org/r/161549370379.25025.12793264112620796062.stgit@brun... Reviewed-by: Scott Teel scott.teel@microchip.com Reviewed-by: Scott Benesh scott.benesh@microchip.com Reviewed-by: Kevin Barnett kevin.barnett@microchip.com Signed-off-by: Murthy Bhat Murthy.Bhat@microchip.com Signed-off-by: Don Brace don.brace@microchip.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/smartpqi/smartpqi_init.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 9300a677510d..afd004fdce76 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -5491,6 +5491,8 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info,
list_del(&io_request->request_list_entry); set_host_byte(scmd, DID_RESET); + pqi_free_io_request(io_request); + scsi_dma_unmap(scmd); pqi_scsi_done(scmd); }
@@ -5527,6 +5529,8 @@ static void pqi_fail_io_queued_for_all_devices(struct pqi_ctrl_info *ctrl_info)
list_del(&io_request->request_list_entry); set_host_byte(scmd, DID_RESET); + pqi_free_io_request(io_request); + scsi_dma_unmap(scmd); pqi_scsi_done(scmd); }
From: Kevin Barnett kevin.barnett@microchip.com
[ Upstream commit 75fbeacca3ad30835e903002dba98dd909b4dfff ]
Add support for newer hardware.
Link: https://lore.kernel.org/r/161549386882.25025.2594251735886014958.stgit@brunh... Reviewed-by: Scott Benesh scott.benesh@microchip.com Reviewed-by: Scott Teel scott.teel@microchip.com Acked-by: Martin Wilck mwilck@suse.com Signed-off-by: Kevin Barnett kevin.barnett@microchip.com Signed-off-by: Don Brace don.brace@microchip.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/smartpqi/smartpqi_init.c | 156 ++++++++++++++++++++++++++ 1 file changed, 156 insertions(+)
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index afd004fdce76..5083e5d2b467 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -8226,6 +8226,10 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x152d, 0x8a37) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x193d, 0x8460) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x193d, 0x1104) @@ -8298,6 +8302,22 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x1bd4, 0x004f) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0051) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0052) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0053) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0054) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x19e5, 0xd227) @@ -8458,6 +8478,122 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_ADAPTEC2, 0x1380) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1400) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1402) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1410) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1411) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1412) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1420) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1430) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1440) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1441) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1450) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1452) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1460) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1461) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1462) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1470) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1471) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1472) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1480) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1490) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1491) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14a0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14a1) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14b0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14b1) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14c0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14c1) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14d0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14e0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14f0) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_ADVANTECH, 0x8312) @@ -8522,6 +8658,10 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_HP, 0x1001) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_HP, 0x1002) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_HP, 0x1100) @@ -8530,6 +8670,22 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_HP, 0x1101) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x0294) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x02db) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x02dc) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x032e) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x1d8d, 0x0800)
From: Ewan D. Milne emilne@redhat.com
[ Upstream commit bc3f2b42b70eb1b8576e753e7d0e117bbb674496 ]
Some arrays return ILLEGAL_REQUEST with ASC 00h if they don't support the RTPG extended header so remove the check for INVALID FIELD IN CDB.
Link: https://lore.kernel.org/r/20210331201154.20348-1-emilne@redhat.com Reviewed-by: Hannes Reinecke hare@suse.de Signed-off-by: Ewan D. Milne emilne@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/device_handler/scsi_dh_alua.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 308bda2e9c00..df5a3bbeba5e 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -565,10 +565,11 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) * even though it shouldn't according to T10. * The retry without rtpg_ext_hdr_req set * handles this. + * Note: some arrays return a sense key of ILLEGAL_REQUEST + * with ASC 00h if they don't support the extended header. */ if (!(pg->flags & ALUA_RTPG_EXT_HDR_UNSUPP) && - sense_hdr.sense_key == ILLEGAL_REQUEST && - sense_hdr.asc == 0x24 && sense_hdr.ascq == 0) { + sense_hdr.sense_key == ILLEGAL_REQUEST) { pg->flags |= ALUA_RTPG_EXT_HDR_UNSUPP; goto retry; }
From: Muhammad Usama Anjum musamaanjum@gmail.com
[ Upstream commit 0ae10a7dc8992ee682ff0b1752ff7c83d472eef1 ]
If some error occurs, URB buffers should also be freed. If they aren't freed with the dvb here, the em28xx_dvb_fini call doesn't frees the URB buffers as dvb is set to NULL. The function in which error occurs should do all the cleanup for the allocations it had done.
Tested the patch with the reproducer provided by syzbot. This patch fixes the memleak.
Reported-by: syzbot+889397c820fa56adf25d@syzkaller.appspotmail.com Signed-off-by: Muhammad Usama Anjum musamaanjum@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/em28xx/em28xx-dvb.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index fb9cbfa81a84..3cd9e9556fa9 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -1984,6 +1984,7 @@ ret: return result;
out_free: + em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE); kfree(dvb); dev->dvb = NULL; goto ret;
From: Hans Verkuil hverkuil-cisco@xs4all.nl
[ Upstream commit 443ec4bbc6116f6f492a7a1282bfd8422c862158 ]
The EDID had a few mistakes as reported by edid-decode:
Block 1, CTA-861 Extension Block: Video Data Block: For improved preferred timing interoperability, set 'Native detailed modes' to 1. Video Capability Data Block: S_PT is equal to S_IT and S_CE, so should be set to 0 instead.
Fixed those.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/test-drivers/vivid/vivid-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c index aa8d350fd682..1e356dc65d31 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.c +++ b/drivers/media/test-drivers/vivid/vivid-core.c @@ -205,13 +205,13 @@ static const u8 vivid_hdmi_edid[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7b,
- 0x02, 0x03, 0x3f, 0xf0, 0x51, 0x61, 0x60, 0x5f, + 0x02, 0x03, 0x3f, 0xf1, 0x51, 0x61, 0x60, 0x5f, 0x5e, 0x5d, 0x10, 0x1f, 0x04, 0x13, 0x22, 0x21, 0x20, 0x05, 0x14, 0x02, 0x11, 0x01, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00, 0x60, 0x01, 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4, - 0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xea, 0xe3, + 0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xca, 0xe3, 0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0x4d, 0xd0, 0x00, 0xa0, 0xf0, 0x70, 0x3e, 0x80, 0x30, 0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, @@ -220,7 +220,7 @@ static const u8 vivid_hdmi_edid[256] = { 0x00, 0x00, 0x1a, 0x1a, 0x1d, 0x00, 0x80, 0x51, 0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, };
static int vidioc_querycap(struct file *file, void *priv,
From: Abhinav Kumar abhinavk@codeaurora.org
[ Upstream commit 7d649cfe0314aad2ba18042885ab9de2f13ad809 ]
Fix an incorrect NULL check reported by kbot in the MSM DP driver
smatch warnings: drivers/gpu/drm/msm/dp/dp_hpd.c:37 dp_hpd_connect() error: we previously assumed 'hpd_priv->dp_cb' could be null (see line 37)
Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Abhinav Kumar abhinavk@codeaurora.org Reviewed-by: Stephen Boyd swboyd@chromium.org Link: https://lore.kernel.org/r/1614971839-2686-2-git-send-email-abhinavk@codeauro... Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dp/dp_hpd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_hpd.c b/drivers/gpu/drm/msm/dp/dp_hpd.c index 5b8fe32022b5..e1c90fa47411 100644 --- a/drivers/gpu/drm/msm/dp/dp_hpd.c +++ b/drivers/gpu/drm/msm/dp/dp_hpd.c @@ -34,8 +34,8 @@ int dp_hpd_connect(struct dp_usbpd *dp_usbpd, bool hpd)
dp_usbpd->hpd_high = hpd;
- if (!hpd_priv->dp_cb && !hpd_priv->dp_cb->configure - && !hpd_priv->dp_cb->disconnect) { + if (!hpd_priv->dp_cb || !hpd_priv->dp_cb->configure + || !hpd_priv->dp_cb->disconnect) { pr_err("hpd dp_cb not initialized\n"); return -EINVAL; }
From: Colin Ian King colin.king@canonical.com
[ Upstream commit 657d4d1934f75a2d978c3cf2086495eaa542e7a9 ]
There is an error return path that is not kfree'ing socfpga_clk leading to a memory leak. Fix this by adding in the missing kfree call.
Addresses-Coverity: ("Resource leak") Signed-off-by: Colin Ian King colin.king@canonical.com Link: https://lore.kernel.org/r/20210406170115.430990-1-colin.king@canonical.com Acked-by: Dinh Nguyen dinguyen@kernel.org Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/socfpga/clk-gate-a10.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c index cd5df9103614..d62778884208 100644 --- a/drivers/clk/socfpga/clk-gate-a10.c +++ b/drivers/clk/socfpga/clk-gate-a10.c @@ -146,6 +146,7 @@ static void __init __socfpga_gate_init(struct device_node *node, if (IS_ERR(socfpga_clk->sys_mgr_base_addr)) { pr_err("%s: failed to find altr,sys-mgr regmap!\n", __func__); + kfree(socfpga_clk); return; } }
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit b6cfa007b3b229771d9588970adb4ab3e0487f49 ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/generic-adc-battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/power/supply/generic-adc-battery.c b/drivers/power/supply/generic-adc-battery.c index caa829738ef7..58f09314741a 100644 --- a/drivers/power/supply/generic-adc-battery.c +++ b/drivers/power/supply/generic-adc-battery.c @@ -382,7 +382,7 @@ static int gab_remove(struct platform_device *pdev) }
kfree(adc_bat->psy_desc.properties); - cancel_delayed_work(&adc_bat->bat_work); + cancel_delayed_work_sync(&adc_bat->bat_work); return 0; }
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 68ae256945d2abe9036a7b68af4cc65aff79d5b7 ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/s3c_adc_battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/power/supply/s3c_adc_battery.c b/drivers/power/supply/s3c_adc_battery.c index 60b7f41ab063..ff46bcf5db01 100644 --- a/drivers/power/supply/s3c_adc_battery.c +++ b/drivers/power/supply/s3c_adc_battery.c @@ -394,7 +394,7 @@ static int s3c_adc_bat_remove(struct platform_device *pdev) gpio_free(pdata->gpio_charge_finished); }
- cancel_delayed_work(&bat_work); + cancel_delayed_work_sync(&bat_work);
if (pdata->exit) pdata->exit();
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 6107a4fdf8554a7aa9488bdc835bb010062fa8a9 ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/tc358743.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 831b5b54fd78..1b309bb743c7 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -2193,7 +2193,7 @@ static int tc358743_remove(struct i2c_client *client) del_timer_sync(&state->timer); flush_work(&state->work_i2c_poll); } - cancel_delayed_work(&state->delayed_work_enable_hotplug); + cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); cec_unregister_adapter(state->cec_adap); v4l2_async_unregister_subdev(sd); v4l2_device_unregister_subdev(sd);
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit fa56f5f1fe31c2050675fa63b84963ebd504a5b3 ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/adv7604.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 09004d928d11..d1f58795794f 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -3616,7 +3616,7 @@ static int adv76xx_remove(struct i2c_client *client) io_write(sd, 0x6e, 0); io_write(sd, 0x73, 0);
- cancel_delayed_work(&state->delayed_work_enable_hotplug); + cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); v4l2_async_unregister_subdev(sd); media_entity_cleanup(&sd->entity); adv76xx_unregister_clients(to_state(sd));
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 2c9541720c66899adf6f3600984cf3ef151295ad ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/adv7511-v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c index a3161d709015..ab7883cff8b2 100644 --- a/drivers/media/i2c/adv7511-v4l2.c +++ b/drivers/media/i2c/adv7511-v4l2.c @@ -1964,7 +1964,7 @@ static int adv7511_remove(struct i2c_client *client)
adv7511_set_isr(sd, false); adv7511_init_setup(sd); - cancel_delayed_work(&state->edid_handler); + cancel_delayed_work_sync(&state->edid_handler); i2c_unregister_device(state->i2c_edid); i2c_unregister_device(state->i2c_cec); i2c_unregister_device(state->i2c_pktmem);
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 7f820ab5d4eebfe2d970d32a76ae496a6c286f0f ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/tda1997x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index a09bf0a39d05..89bb7e6dc7a4 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -2804,7 +2804,7 @@ static int tda1997x_remove(struct i2c_client *client) media_entity_cleanup(&sd->entity); v4l2_ctrl_handler_free(&state->hdl); regulator_bulk_disable(TDA1997X_NUM_SUPPLIES, state->supplies); - cancel_delayed_work(&state->delayed_work_enable_hpd); + cancel_delayed_work_sync(&state->delayed_work_enable_hpd); mutex_destroy(&state->page_lock); mutex_destroy(&state->lock);
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 4a15275b6a18597079f18241c87511406575179a ]
This driver's remove path calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free.
Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/adv7842.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 0855f648416d..f7d2b6cd3008 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -3586,7 +3586,7 @@ static int adv7842_remove(struct i2c_client *client) struct adv7842_state *state = to_state(sd);
adv7842_irq_enable(sd, false); - cancel_delayed_work(&state->delayed_work_enable_hotplug); + cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); v4l2_device_unregister_subdev(sd); media_entity_cleanup(&sd->entity); adv7842_unregister_clients(sd);
From: Dinghao Liu dinghao.liu@zju.edu.cn
[ Upstream commit 69306a947b3ae21e0d1cbfc9508f00fec86c7297 ]
pm_runtime_get_sync() will increase the runtime PM counter even it returns an error. Thus a pairing decrement is needed to prevent refcount leak. Fix this by replacing this API with pm_runtime_resume_and_get(), which will not change the runtime PM counter on error.
Signed-off-by: Dinghao Liu dinghao.liu@zju.edu.cn Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/sti/bdisp/bdisp-debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/sti/bdisp/bdisp-debug.c b/drivers/media/platform/sti/bdisp/bdisp-debug.c index 2b270093009c..a27f638df11c 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-debug.c +++ b/drivers/media/platform/sti/bdisp/bdisp-debug.c @@ -480,7 +480,7 @@ static int regs_show(struct seq_file *s, void *data) int ret; unsigned int i;
- ret = pm_runtime_get_sync(bdisp->dev); + ret = pm_runtime_resume_and_get(bdisp->dev); if (ret < 0) { seq_puts(s, "Cannot wake up IP\n"); return 0;
From: Dinghao Liu dinghao.liu@zju.edu.cn
[ Upstream commit f1995d5e43cf897f63b4d7a7f84a252d891ae820 ]
pm_runtime_get_sync() will increase the runtime PM counter even it returns an error. Thus a pairing decrement is needed to prevent refcount leak. Fix this by replacing this API with pm_runtime_resume_and_get(), which will not change the runtime PM counter on error.
Signed-off-by: Dinghao Liu dinghao.liu@zju.edu.cn Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/sunxi/sun8i-di/sun8i-di.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c index ba5d07886607..2c159483c56b 100644 --- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c +++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c @@ -589,7 +589,7 @@ static int deinterlace_start_streaming(struct vb2_queue *vq, unsigned int count) int ret;
if (V4L2_TYPE_IS_OUTPUT(vq->type)) { - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) { dev_err(dev, "Failed to enable module\n");
From: Pavel Skripkin paskripkin@gmail.com
[ Upstream commit b7cd0da982e3043f2eec7235ac5530cb18d6af1d ]
syzbot reported memory leak in dvb-usb. The problem was in invalid error handling in dvb_usb_adapter_init().
for (n = 0; n < d->props.num_adapters; n++) { .... if ((ret = dvb_usb_adapter_stream_init(adap)) || (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) || (ret = dvb_usb_adapter_frontend_init(adap))) { return ret; } ... d->num_adapters_initialized++; ... }
In case of error in dvb_usb_adapter_dvb_init() or dvb_usb_adapter_dvb_init() d->num_adapters_initialized won't be incremented, but dvb_usb_adapter_exit() relies on it:
for (n = 0; n < d->num_adapters_initialized; n++)
So, allocated objects won't be freed.
Signed-off-by: Pavel Skripkin paskripkin@gmail.com Reported-by: syzbot+3c2be7424cea3b932b0e@syzkaller.appspotmail.com Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/dvb-usb/dvb-usb-init.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c index c1a7634e27b4..adc8b287326b 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c @@ -79,11 +79,17 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) } }
- if ((ret = dvb_usb_adapter_stream_init(adap)) || - (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) || - (ret = dvb_usb_adapter_frontend_init(adap))) { + ret = dvb_usb_adapter_stream_init(adap); + if (ret) return ret; - } + + ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs); + if (ret) + goto dvb_init_err; + + ret = dvb_usb_adapter_frontend_init(adap); + if (ret) + goto frontend_init_err;
/* use exclusive FE lock if there is multiple shared FEs */ if (adap->fe_adap[1].fe) @@ -103,6 +109,12 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) }
return 0; + +frontend_init_err: + dvb_usb_adapter_dvb_exit(adap); +dvb_init_err: + dvb_usb_adapter_stream_exit(adap); + return ret; }
static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
From: Hans Verkuil hverkuil-cisco@xs4all.nl
[ Upstream commit 4f4e6644cd876c844cdb3bea2dd7051787d5ae25 ]
For two of the supported sensors the stv06xx driver allocates memory which is stored in sd->sensor_priv. This memory is freed on a disconnect, but if the probe() fails, then it isn't freed and so this leaks memory.
Add a new probe_error() op that drivers can use to free any allocated memory in case there was a probe failure.
Thanks to Pavel Skripkin paskripkin@gmail.com for discovering the cause of the memory leak.
Reported-and-tested-by: syzbot+e7f4c64a4248a0340c37@syzkaller.appspotmail.com
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/gspca/gspca.c | 2 ++ drivers/media/usb/gspca/gspca.h | 1 + drivers/media/usb/gspca/stv06xx/stv06xx.c | 9 +++++++++ 3 files changed, 12 insertions(+)
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index 158c8e28ed2c..47d8f28bfdfc 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c @@ -1576,6 +1576,8 @@ out: #endif v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler); v4l2_device_unregister(&gspca_dev->v4l2_dev); + if (sd_desc->probe_error) + sd_desc->probe_error(gspca_dev); kfree(gspca_dev->usb_buf); kfree(gspca_dev); return ret; diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h index b0ced2e14006..a6554d5e9e1a 100644 --- a/drivers/media/usb/gspca/gspca.h +++ b/drivers/media/usb/gspca/gspca.h @@ -105,6 +105,7 @@ struct sd_desc { cam_cf_op config; /* called on probe */ cam_op init; /* called on probe and resume */ cam_op init_controls; /* called on probe */ + cam_v_op probe_error; /* called if probe failed, do cleanup here */ cam_op start; /* called on stream on after URBs creation */ cam_pkt_op pkt_scan; /* optional operations */ diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c index 95673fc0a99c..d9bc2aacc885 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c @@ -529,12 +529,21 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, static int stv06xx_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id);
+static void stv06xx_probe_error(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *)gspca_dev; + + kfree(sd->sensor_priv); + sd->sensor_priv = NULL; +} + /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, .config = stv06xx_config, .init = stv06xx_init, .init_controls = stv06xx_init_controls, + .probe_error = stv06xx_probe_error, .start = stv06xx_start, .stopN = stv06xx_stopN, .pkt_scan = stv06xx_pkt_scan,
From: Lingutla Chandrasekhar clingutla@codeaurora.org
[ Upstream commit 9bcb959d05eeb564dfc9cac13a59843a4fb2edf2 ]
During load balance, LBF_SOME_PINNED will be set if any candidate task cannot be detached due to CPU affinity constraints. This can result in setting env->sd->parent->sgc->group_imbalance, which can lead to a group being classified as group_imbalanced (rather than any of the other, lower group_type) when balancing at a higher level.
In workloads involving a single task per CPU, LBF_SOME_PINNED can often be set due to per-CPU kthreads being the only other runnable tasks on any given rq. This results in changing the group classification during load-balance at higher levels when in reality there is nothing that can be done for this affinity constraint: per-CPU kthreads, as the name implies, don't get to move around (modulo hotplug shenanigans).
It's not as clear for userspace tasks - a task could be in an N-CPU cpuset with N-1 offline CPUs, making it an "accidental" per-CPU task rather than an intended one. KTHREAD_IS_PER_CPU gives us an indisputable signal which we can leverage here to not set LBF_SOME_PINNED.
Note that the aforementioned classification to group_imbalance (when nothing can be done) is especially problematic on big.LITTLE systems, which have a topology the likes of:
DIE [ ] MC [ ][ ] 0 1 2 3 L L B B
arch_scale_cpu_capacity(L) < arch_scale_cpu_capacity(B)
Here, setting LBF_SOME_PINNED due to a per-CPU kthread when balancing at MC level on CPUs [0-1] will subsequently prevent CPUs [2-3] from classifying the [0-1] group as group_misfit_task when balancing at DIE level. Thus, if CPUs [0-1] are running CPU-bound (misfit) tasks, ill-timed per-CPU kthreads can significantly delay the upgmigration of said misfit tasks. Systems relying on ASYM_PACKING are likely to face similar issues.
Signed-off-by: Lingutla Chandrasekhar clingutla@codeaurora.org [Use kthread_is_per_cpu() rather than p->nr_cpus_allowed] [Reword changelog] Signed-off-by: Valentin Schneider valentin.schneider@arm.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Dietmar Eggemann dietmar.eggemann@arm.com Reviewed-by: Vincent Guittot vincent.guittot@linaro.org Link: https://lkml.kernel.org/r/20210407220628.3798191-2-valentin.schneider@arm.co... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/fair.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 8f5bbc1469ed..481f4cc0958f 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7552,6 +7552,10 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) if (throttled_lb_pair(task_group(p), env->src_cpu, env->dst_cpu)) return 0;
+ /* Disregard pcpu kthreads; they are where they need to be. */ + if ((p->flags & PF_KTHREAD) && kthread_is_per_cpu(p)) + return 0; + if (!cpumask_test_cpu(env->dst_cpu, p->cpus_ptr)) { int cpu;
From: Marijn Suijten marijn.suijten@somainline.org
[ Upstream commit 2ad52bdb220de5ab348098e3482b01235d15a842 ]
Leaving this at a close-to-maximum register value 0xFFF0 means it takes very long for the MDSS to generate a software vsync interrupt when the hardware TE interrupt doesn't arrive. Configuring this to double the vtotal (like some downstream kernels) leads to a frame to take at most twice before the vsync signal, until hardware TE comes up.
In this case the hardware interrupt responsible for providing this signal - "disp-te" gpio - is not hooked up to the mdp5 vsync/pp logic at all. This solves severe panel update issues observed on at least the Xperia Loire and Tone series, until said gpio is properly hooked up to an irq.
Suggested-by: AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org Signed-off-by: Marijn Suijten marijn.suijten@somainline.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org Link: https://lore.kernel.org/r/20210406214726.131534-2-marijn.suijten@somainline.... Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c index ff2c1d583c79..f6df4d3b1406 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c @@ -49,9 +49,17 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder, | MDP5_PP_SYNC_CONFIG_VSYNC_IN_EN; cfg |= MDP5_PP_SYNC_CONFIG_VSYNC_COUNT(vclks_line);
+ /* + * Tearcheck emits a blanking signal every vclks_line * vtotal * 2 ticks on + * the vsync_clk equating to roughly half the desired panel refresh rate. + * This is only necessary as stability fallback if interrupts from the + * panel arrive too late or not at all, but is currently used by default + * because these panel interrupts are not wired up yet. + */ mdp5_write(mdp5_kms, REG_MDP5_PP_SYNC_CONFIG_VSYNC(pp_id), cfg); mdp5_write(mdp5_kms, - REG_MDP5_PP_SYNC_CONFIG_HEIGHT(pp_id), 0xfff0); + REG_MDP5_PP_SYNC_CONFIG_HEIGHT(pp_id), (2 * mode->vtotal)); + mdp5_write(mdp5_kms, REG_MDP5_PP_VSYNC_INIT_VAL(pp_id), mode->vdisplay); mdp5_write(mdp5_kms, REG_MDP5_PP_RD_PTR_IRQ(pp_id), mode->vdisplay + 1);
From: Marijn Suijten marijn.suijten@somainline.org
[ Upstream commit 377569f82ea8228c421cef4da33e056a900b58ca ]
Neither vtotal nor drm_mode_vrefresh contain a value that is premultiplied by 100 making the x100 variable name incorrect and resulting in vclks_line to become 100 times larger than it is supposed to be. The hardware counts 100 clockticks too many before tearcheck, leading to severe panel issues on at least the Sony Xperia lineup.
This is likely an artifact from the original MDSS DSI panel driver where the calculation [1] corrected for a premultiplied reference framerate by 100 [2]. It does not appear that the above values were ever premultiplied in the history of the DRM MDP5 driver.
With this change applied the value written to the SYNC_CONFIG_VSYNC register is now identical to downstream kernels.
[1]: https://source.codeaurora.org/quic/la/kernel/msm-3.18/tree/drivers/video/msm... [2]: https://source.codeaurora.org/quic/la/kernel/msm-3.18/tree/drivers/video/msm...
Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org Signed-off-by: Marijn Suijten marijn.suijten@somainline.org Link: https://lore.kernel.org/r/20210406214726.131534-3-marijn.suijten@somainline.... Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c index f6df4d3b1406..0392d4dfe270 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c @@ -20,7 +20,7 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder, { struct mdp5_kms *mdp5_kms = get_kms(encoder); struct device *dev = encoder->dev->dev; - u32 total_lines_x100, vclks_line, cfg; + u32 total_lines, vclks_line, cfg; long vsync_clk_speed; struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc); int pp_id = mixer->pp; @@ -30,8 +30,8 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder, return -EINVAL; }
- total_lines_x100 = mode->vtotal * drm_mode_vrefresh(mode); - if (!total_lines_x100) { + total_lines = mode->vtotal * drm_mode_vrefresh(mode); + if (!total_lines) { DRM_DEV_ERROR(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n", __func__, mode->vtotal, drm_mode_vrefresh(mode)); return -EINVAL; @@ -43,7 +43,7 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder, vsync_clk_speed); return -EINVAL; } - vclks_line = vsync_clk_speed * 100 / total_lines_x100; + vclks_line = vsync_clk_speed / total_lines;
cfg = MDP5_PP_SYNC_CONFIG_VSYNC_COUNTER_EN | MDP5_PP_SYNC_CONFIG_VSYNC_IN_EN;
From: Daniel Gomez daniel@qtec.com
[ Upstream commit 0f6f9dd490d524930081a6ef1d60171ce39220b9 ]
If userptr pages have been pinned but not bounded, they remain uncleared.
Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Daniel Gomez daniel@qtec.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index a0248d78190f..06a662ea33dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1254,13 +1254,13 @@ static void amdgpu_ttm_backend_unbind(struct ttm_bo_device *bdev, struct amdgpu_ttm_tt *gtt = (void *)ttm; int r;
- if (!gtt->bound) - return; - /* if the pages have userptr pinning then clear that first */ if (gtt->userptr) amdgpu_ttm_tt_unpin_userptr(bdev, ttm);
+ if (!gtt->bound) + return; + if (gtt->offset == AMDGPU_BO_INVALID_OFFSET) return;
From: Daniel Gomez daniel@qtec.com
[ Upstream commit 5aeaa43e0ef1006320c077cbc49f4a8229ca3460 ]
If userptr pages have been pinned but not bounded, they remain uncleared.
Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Daniel Gomez daniel@qtec.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/radeon/radeon_ttm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 36150b7f31a9..a65cb349fac2 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -566,13 +566,14 @@ static void radeon_ttm_backend_unbind(struct ttm_bo_device *bdev, struct ttm_tt struct radeon_ttm_tt *gtt = (void *)ttm; struct radeon_device *rdev = radeon_get_rdev(bdev);
+ if (gtt->userptr) + radeon_ttm_tt_unpin_userptr(bdev, ttm); + if (!gtt->bound) return;
radeon_gart_unbind(rdev, gtt->offset, ttm->num_pages);
- if (gtt->userptr) - radeon_ttm_tt_unpin_userptr(bdev, ttm); gtt->bound = false; }
From: Fangzhi Zuo Jerry.Zuo@amd.com
[ Upstream commit c006a1c00de29e8cdcde1d0254ac23433ed3fee9 ]
1. Catch invalid link_rate and link_count settings 2. Call dc interface to overwrite preferred link settings, and wait until next stream update to apply the new settings.
Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Fangzhi Zuo Jerry.Zuo@amd.com Reviewed-by: Nicholas Kazlauskas Nicholas.Kazlauskas@amd.com Acked-by: Solomon Chiu solomon.chiu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 8cd646eef096..e02a55fc1382 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -150,7 +150,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size, * * --- to get dp configuration * - * cat link_settings + * cat /sys/kernel/debug/dri/0/DP-x/link_settings * * It will list current, verified, reported, preferred dp configuration. * current -- for current video mode @@ -163,7 +163,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size, * echo <lane_count> <link_rate> > link_settings * * for example, to force to 2 lane, 2.7GHz, - * echo 4 0xa > link_settings + * echo 4 0xa > /sys/kernel/debug/dri/0/DP-x/link_settings * * spread_spectrum could not be changed dynamically. * @@ -171,7 +171,7 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size, * done. please check link settings after force operation to see if HW get * programming. * - * cat link_settings + * cat /sys/kernel/debug/dri/0/DP-x/link_settings * * check current and preferred settings. * @@ -255,7 +255,7 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, int max_param_num = 2; uint8_t param_nums = 0; long param[2]; - bool valid_input = false; + bool valid_input = true;
if (size == 0) return -EINVAL; @@ -282,9 +282,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, case LANE_COUNT_ONE: case LANE_COUNT_TWO: case LANE_COUNT_FOUR: - valid_input = true; break; default: + valid_input = false; break; }
@@ -294,9 +294,9 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, case LINK_RATE_RBR2: case LINK_RATE_HIGH2: case LINK_RATE_HIGH3: - valid_input = true; break; default: + valid_input = false; break; }
@@ -310,10 +310,11 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, * spread spectrum will not be changed */ prefer_link_settings.link_spread = link->cur_link_settings.link_spread; + prefer_link_settings.use_link_rate_set = false; prefer_link_settings.lane_count = param[0]; prefer_link_settings.link_rate = param[1];
- dc_link_set_preferred_link_settings(dc, &prefer_link_settings, link); + dc_link_set_preferred_training_settings(dc, &prefer_link_settings, NULL, link, true);
kfree(wr_buf); return size;
From: Anson Jacob Anson.Jacob@amd.com
[ Upstream commit 54718747a6e1037317a8b3610c3be40621b2b75e ]
[Why] On NAVI14 CONFIG_UBSAN reported shift-out-of-bounds at display_rq_dlg_calc_20v2.c:304:38
rq_param->misc.rq_c.blk256_height is 0 when chroma(*_c) is invalid. dml_log2 returns -1023 for log2(0), although log2(0) is undefined.
Which ended up as: rq_param->dlg.rq_c.swath_height = 1 << -1023
[How] Fix applied on all dml versions. 1. Ensure dml_log2 is only called if the argument is greater than 0. 2. Subtract req128_l/req128_c from log2_swath_height_l/log2_swath_height_c only when it is greater than 0.
Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Anson Jacob Anson.Jacob@amd.com Reviewed-by: Dmytro Laktyushkin Dmytro.Laktyushkin@amd.com Reviewed-by: Jun Lei Jun.Lei@amd.com Acked-by: Solomon Chiu solomon.chiu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../dc/dml/dcn20/display_rq_dlg_calc_20.c | 28 +++++++++++++++---- .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c | 28 +++++++++++++++---- .../dc/dml/dcn21/display_rq_dlg_calc_21.c | 28 +++++++++++++++---- .../dc/dml/dcn30/display_rq_dlg_calc_30.c | 28 +++++++++++++++---- .../display/dc/dml/dml1_display_rq_dlg_calc.c | 28 +++++++++++++++---- 5 files changed, 115 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c index 72423dc425dc..799bae229e67 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c @@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c index 9c78446c3a9d..6a6d5970d1d5 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c @@ -293,13 +293,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c index edd41d358291..dc1c81a6e377 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c @@ -277,13 +277,31 @@ static void handle_det_buf_split( if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c index 416bf6fb67bd..58c312f80a07 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c @@ -237,13 +237,31 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c index 4c3e9cc30167..414da64f5734 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c @@ -344,13 +344,31 @@ static void handle_det_buf_split( if (surf_linear) { log2_swath_height_l = 0; log2_swath_height_c = 0; - } else if (!surf_vert) { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_height) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_height) - req128_c; } else { - log2_swath_height_l = dml_log2(rq_param->misc.rq_l.blk256_width) - req128_l; - log2_swath_height_c = dml_log2(rq_param->misc.rq_c.blk256_width) - req128_c; + unsigned int swath_height_l; + unsigned int swath_height_c; + + if (!surf_vert) { + swath_height_l = rq_param->misc.rq_l.blk256_height; + swath_height_c = rq_param->misc.rq_c.blk256_height; + } else { + swath_height_l = rq_param->misc.rq_l.blk256_width; + swath_height_c = rq_param->misc.rq_c.blk256_width; + } + + if (swath_height_l > 0) + log2_swath_height_l = dml_log2(swath_height_l); + + if (req128_l && log2_swath_height_l > 0) + log2_swath_height_l -= 1; + + if (swath_height_c > 0) + log2_swath_height_c = dml_log2(swath_height_c); + + if (req128_c && log2_swath_height_c > 0) + log2_swath_height_c -= 1; } + rq_param->dlg.rq_l.swath_height = 1 << log2_swath_height_l; rq_param->dlg.rq_c.swath_height = 1 << log2_swath_height_c;
From: Qu Huang jinsdb@126.com
[ Upstream commit d73610211eec8aa027850982b1a48980aa1bc96e ]
Here is the system crash log: [ 1272.884438] BUG: unable to handle kernel NULL pointer dereference at (null) [ 1272.884444] IP: [< (null)>] (null) [ 1272.884447] PGD 825b09067 PUD 8267c8067 PMD 0 [ 1272.884452] Oops: 0010 [#1] SMP [ 1272.884509] CPU: 13 PID: 3485 Comm: cat Kdump: loaded Tainted: G [ 1272.884515] task: ffff9a38dbd4d140 ti: ffff9a37cd3b8000 task.ti: ffff9a37cd3b8000 [ 1272.884517] RIP: 0010:[<0000000000000000>] [< (null)>] (null) [ 1272.884520] RSP: 0018:ffff9a37cd3bbe68 EFLAGS: 00010203 [ 1272.884522] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000014d5f [ 1272.884524] RDX: fffffffffffffff4 RSI: 0000000000000001 RDI: ffff9a38aca4d200 [ 1272.884526] RBP: ffff9a37cd3bbed0 R08: ffff9a38dcd5f1a0 R09: ffff9a31ffc07300 [ 1272.884527] R10: ffff9a31ffc07300 R11: ffffffffaddd5e9d R12: ffff9a38b4e0fb00 [ 1272.884529] R13: 0000000000000001 R14: ffff9a37cd3bbf18 R15: ffff9a38aca4d200 [ 1272.884532] FS: 00007feccaa67740(0000) GS:ffff9a38dcd40000(0000) knlGS:0000000000000000 [ 1272.884534] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1272.884536] CR2: 0000000000000000 CR3: 00000008267c0000 CR4: 00000000003407e0 [ 1272.884537] Call Trace: [ 1272.884544] [<ffffffffade68940>] ? seq_read+0x130/0x440 [ 1272.884548] [<ffffffffade40f8f>] vfs_read+0x9f/0x170 [ 1272.884552] [<ffffffffade41e4f>] SyS_read+0x7f/0xf0 [ 1272.884557] [<ffffffffae374ddb>] system_call_fastpath+0x22/0x27 [ 1272.884558] Code: Bad RIP value. [ 1272.884562] RIP [< (null)>] (null) [ 1272.884564] RSP <ffff9a37cd3bbe68> [ 1272.884566] CR2: 0000000000000000
Signed-off-by: Qu Huang jinsdb@126.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c index 511712c2e382..673d5e34f213 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c @@ -33,6 +33,11 @@ static int kfd_debugfs_open(struct inode *inode, struct file *file)
return single_open(file, show, NULL); } +static int kfd_debugfs_hang_hws_read(struct seq_file *m, void *data) +{ + seq_printf(m, "echo gpu_id > hang_hws\n"); + return 0; +}
static ssize_t kfd_debugfs_hang_hws_write(struct file *file, const char __user *user_buf, size_t size, loff_t *ppos) @@ -94,7 +99,7 @@ void kfd_debugfs_init(void) debugfs_create_file("rls", S_IFREG | 0444, debugfs_root, kfd_debugfs_rls_by_device, &kfd_debugfs_fops); debugfs_create_file("hang_hws", S_IFREG | 0200, debugfs_root, - NULL, &kfd_debugfs_hang_hws_fops); + kfd_debugfs_hang_hws_read, &kfd_debugfs_hang_hws_fops); }
void kfd_debugfs_fini(void)
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 7d98d416c2cc1c1f7d9508e887de4630e521d797 ]
clang points out that the %hu format string does not match the type of the variables here:
drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c:263:7: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat] version_major, version_minor); ^~~~~~~~~~~~~ include/drm/drm_print.h:498:19: note: expanded from macro 'DRM_ERROR' __drm_err(fmt, ##__VA_ARGS__) ~~~ ^~~~~~~~~~~
Change it to a regular %u, the same way a previous patch did for another instance of the same warning.
Reviewed-by: Christian König christian.koenig@amd.com Reviewed-by: Tom Rix trix@redhat.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index f8bebf18ee36..665ead139c30 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -259,7 +259,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) if ((adev->asic_type == CHIP_POLARIS10 || adev->asic_type == CHIP_POLARIS11) && (adev->uvd.fw_version < FW_1_66_16)) - DRM_ERROR("POLARIS10/11 UVD firmware version %hu.%hu is too old.\n", + DRM_ERROR("POLARIS10/11 UVD firmware version %u.%u is too old.\n", version_major, version_minor); } else { unsigned int enc_major, enc_minor, dec_minor;
From: Werner Sembach wse@tuxedocomputers.com
[ Upstream commit 68eb3ae3c63708f823aeeb63bb15197c727bd9bf ]
When encoder validation of a display mode fails, retry with less bandwidth heavy YCbCr420 color mode, if available. This enables some HDMI 1.4 setups to support 4k60Hz output, which previously failed silently.
On some setups, while the monitor and the gpu support display modes with pixel clocks of up to 600MHz, the link encoder might not. This prevents YCbCr444 and RGB encoding for 4k60Hz, but YCbCr420 encoding might still be possible. However, which color mode is used is decided before the link encoder capabilities are checked. This patch fixes the problem by retrying to find a display mode with YCbCr420 enforced and using it, if it is valid.
Reviewed-by: Harry Wentland harry.wentland@amd.com Signed-off-by: Werner Sembach wse@tuxedocomputers.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 12a4f0675fb0..d18341b7daac 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5328,6 +5328,15 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
} while (stream == NULL && requested_bpc >= 6);
+ if (dc_result == DC_FAIL_ENC_VALIDATE && !aconnector->force_yuv420_output) { + DRM_DEBUG_KMS("Retry forcing YCbCr420 encoding\n"); + + aconnector->force_yuv420_output = true; + stream = create_validate_stream_for_sink(aconnector, drm_mode, + dm_state, old_stream); + aconnector->force_yuv420_output = false; + } + return stream; }
From: Guchun Chen guchun.chen@amd.com
[ Upstream commit 3c3dc654333f6389803cdcaf03912e94173ae510 ]
ttm->sg needs to be checked before accessing its child member.
Call Trace: amdgpu_ttm_backend_destroy+0x12/0x70 [amdgpu] ttm_bo_cleanup_memtype_use+0x3a/0x60 [ttm] ttm_bo_release+0x17d/0x300 [ttm] amdgpu_bo_unref+0x1a/0x30 [amdgpu] amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu+0x78b/0x8b0 [amdgpu] kfd_ioctl_alloc_memory_of_gpu+0x118/0x220 [amdgpu] kfd_ioctl+0x222/0x400 [amdgpu] ? kfd_dev_is_large_bar+0x90/0x90 [amdgpu] __x64_sys_ioctl+0x8e/0xd0 ? __context_tracking_exit+0x52/0x90 do_syscall_64+0x33/0x80 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7f97f264d317 Code: b3 66 90 48 8b 05 71 4b 2d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 41 4b 2d 00 f7 d8 64 89 01 48 RSP: 002b:00007ffdb402c338 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f97f3cc63a0 RCX: 00007f97f264d317 RDX: 00007ffdb402c380 RSI: 00000000c0284b16 RDI: 0000000000000003 RBP: 00007ffdb402c380 R08: 00007ffdb402c428 R09: 00000000c4000004 R10: 00000000c4000004 R11: 0000000000000246 R12: 00000000c0284b16 R13: 0000000000000003 R14: 00007f97f3cc63a0 R15: 00007f8836200000
Signed-off-by: Guchun Chen guchun.chen@amd.com Acked-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 06a662ea33dd..ab7755a3885a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1034,7 +1034,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_bo_device *bdev, DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
/* double check that we don't free the table twice */ - if (!ttm->sg->sgl) + if (!ttm->sg || !ttm->sg->sgl) return;
/* unmap the pages mapped to the device */
From: James Smart jsmart2021@gmail.com
[ Upstream commit fffd18ec6579c2d9c72b212169259062fe747888 ]
Fix a crash caused by a double put on the node when the driver completed an ACC for an unsolicted abort on the same node. The second put was executed by lpfc_nlp_not_used() and is wrong because the completion routine executes the nlp_put when the iocbq was released. Additionally, the driver is issuing a LOGO then immediately calls lpfc_nlp_set_state to put the node into NPR. This call does nothing.
Remove the lpfc_nlp_not_used call and additional set_state in the completion routine. Remove the lpfc_nlp_set_state post issue_logo. Isn't necessary.
Link: https://lore.kernel.org/r/20210412013127.2387-3-jsmart2021@gmail.com Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_nportdisc.c | 2 -- drivers/scsi/lpfc/lpfc_sli.c | 1 - 2 files changed, 3 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 17be94496110..6afcb1426e35 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1984,8 +1984,6 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
lpfc_issue_els_logo(vport, ndlp, 0); - ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; - lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); return ndlp->nlp_state; }
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index f103340820c6..5841d2523549 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -17836,7 +17836,6 @@ lpfc_sli4_seq_abort_rsp_cmpl(struct lpfc_hba *phba, if (cmd_iocbq) { ndlp = (struct lpfc_nodelist *)cmd_iocbq->context1; lpfc_nlp_put(ndlp); - lpfc_nlp_not_used(ndlp); lpfc_sli_release_iocbq(phba, cmd_iocbq); }
From: James Smart jsmart2021@gmail.com
[ Upstream commit 304ee43238fed517faa123e034b593905b8679f8 ]
In SLI-4, when performing a mailbox command with MBX_POLL, the driver uses the BMBX register to send the command rather than the MQ. A flag is set indicating the BMBX register is active and saves the mailbox job struct (mboxq) in the mbox_active element of the adapter. The routine then waits for completion or timeout. The mailbox job struct is not freed by the routine. In cases of timeout, the adapter will be reset. The lpfc_sli_mbox_sys_flush() routine will clean up the mbox in preparation for the reset. It clears the BMBX active flag and marks the job structure as MBX_NOT_FINISHED. But, it never frees the mboxq job structure. Expectation in both normal completion and timeout cases is that the issuer of the mbx command will free the structure. Unfortunately, not all calling paths are freeing the memory in cases of error.
All calling paths were looked at and updated, if missing, to free the mboxq memory regardless of completion status.
Link: https://lore.kernel.org/r/20210412013127.2387-7-jsmart2021@gmail.com Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_attr.c | 75 +++++++++++++++++++++-------------- drivers/scsi/lpfc/lpfc_init.c | 9 ++--- drivers/scsi/lpfc/lpfc_sli.c | 42 ++++++++++---------- 3 files changed, 70 insertions(+), 56 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index e94eac194676..bdea2867516c 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1690,8 +1690,7 @@ lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out) lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, "0071 Set trunk mode failed with status: %d", rc); - if (rc != MBX_TIMEOUT) - mempool_free(mbox, phba->mbox_mem_pool); + mempool_free(mbox, phba->mbox_mem_pool);
return 0; } @@ -6780,15 +6779,19 @@ lpfc_get_stats(struct Scsi_Host *shost) pmboxq->ctx_buf = NULL; pmboxq->vport = vport;
- if (vport->fc_flag & FC_OFFLINE_MODE) + if (vport->fc_flag & FC_OFFLINE_MODE) { rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else - rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc != MBX_TIMEOUT) + if (rc != MBX_SUCCESS) { mempool_free(pmboxq, phba->mbox_mem_pool); - return NULL; + return NULL; + } + } else { + rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); + if (rc != MBX_SUCCESS) { + if (rc != MBX_TIMEOUT) + mempool_free(pmboxq, phba->mbox_mem_pool); + return NULL; + } }
memset(hs, 0, sizeof (struct fc_host_statistics)); @@ -6812,15 +6815,19 @@ lpfc_get_stats(struct Scsi_Host *shost) pmboxq->ctx_buf = NULL; pmboxq->vport = vport;
- if (vport->fc_flag & FC_OFFLINE_MODE) + if (vport->fc_flag & FC_OFFLINE_MODE) { rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else - rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc != MBX_TIMEOUT) + if (rc != MBX_SUCCESS) { mempool_free(pmboxq, phba->mbox_mem_pool); - return NULL; + return NULL; + } + } else { + rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); + if (rc != MBX_SUCCESS) { + if (rc != MBX_TIMEOUT) + mempool_free(pmboxq, phba->mbox_mem_pool); + return NULL; + } }
hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt; @@ -6893,15 +6900,19 @@ lpfc_reset_stats(struct Scsi_Host *shost) pmboxq->vport = vport;
if ((vport->fc_flag & FC_OFFLINE_MODE) || - (!(psli->sli_flag & LPFC_SLI_ACTIVE))) + (!(psli->sli_flag & LPFC_SLI_ACTIVE))) { rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else - rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc != MBX_TIMEOUT) + if (rc != MBX_SUCCESS) { mempool_free(pmboxq, phba->mbox_mem_pool); - return; + return; + } + } else { + rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); + if (rc != MBX_SUCCESS) { + if (rc != MBX_TIMEOUT) + mempool_free(pmboxq, phba->mbox_mem_pool); + return; + } }
memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); @@ -6911,15 +6922,19 @@ lpfc_reset_stats(struct Scsi_Host *shost) pmboxq->vport = vport;
if ((vport->fc_flag & FC_OFFLINE_MODE) || - (!(psli->sli_flag & LPFC_SLI_ACTIVE))) + (!(psli->sli_flag & LPFC_SLI_ACTIVE))) { rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else + if (rc != MBX_SUCCESS) { + mempool_free(pmboxq, phba->mbox_mem_pool); + return; + } + } else { rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc != MBX_TIMEOUT) - mempool_free( pmboxq, phba->mbox_mem_pool); - return; + if (rc != MBX_SUCCESS) { + if (rc != MBX_TIMEOUT) + mempool_free(pmboxq, phba->mbox_mem_pool); + return; + } }
lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 40fe889033d4..b17a75216964 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -9636,8 +9636,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) "3250 QUERY_FW_CFG mailbox failed with status " "x%x add_status x%x, mbx status x%x\n", shdr_status, shdr_add_status, rc); - if (rc != MBX_TIMEOUT) - mempool_free(mboxq, phba->mbox_mem_pool); + mempool_free(mboxq, phba->mbox_mem_pool); rc = -ENXIO; goto out_error; } @@ -9653,8 +9652,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) "ulp1_mode:x%x\n", phba->sli4_hba.fw_func_mode, phba->sli4_hba.ulp0_mode, phba->sli4_hba.ulp1_mode);
- if (rc != MBX_TIMEOUT) - mempool_free(mboxq, phba->mbox_mem_pool); + mempool_free(mboxq, phba->mbox_mem_pool);
/* * Set up HBA Event Queues (EQs) @@ -10252,8 +10250,7 @@ lpfc_pci_function_reset(struct lpfc_hba *phba) shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) - mempool_free(mboxq, phba->mbox_mem_pool); + mempool_free(mboxq, phba->mbox_mem_pool); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "0495 SLI_FUNCTION_RESET mailbox " diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 5841d2523549..3e5c0718555a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -5546,12 +5546,10 @@ lpfc_sli4_get_ctl_attr(struct lpfc_hba *phba) phba->sli4_hba.lnk_info.lnk_no, phba->BIOSVersion); out_free_mboxq: - if (rc != MBX_TIMEOUT) { - if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) - lpfc_sli4_mbox_cmd_free(phba, mboxq); - else - mempool_free(mboxq, phba->mbox_mem_pool); - } + if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) + lpfc_sli4_mbox_cmd_free(phba, mboxq); + else + mempool_free(mboxq, phba->mbox_mem_pool); return rc; }
@@ -5652,12 +5650,10 @@ retrieve_ppname: }
out_free_mboxq: - if (rc != MBX_TIMEOUT) { - if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) - lpfc_sli4_mbox_cmd_free(phba, mboxq); - else - mempool_free(mboxq, phba->mbox_mem_pool); - } + if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) + lpfc_sli4_mbox_cmd_free(phba, mboxq); + else + mempool_free(mboxq, phba->mbox_mem_pool); return rc; }
@@ -16844,8 +16840,7 @@ lpfc_rq_destroy(struct lpfc_hba *phba, struct lpfc_queue *hrq, "2509 RQ_DESTROY mailbox failed with " "status x%x add_status x%x, mbx status x%x\n", shdr_status, shdr_add_status, rc); - if (rc != MBX_TIMEOUT) - mempool_free(mbox, hrq->phba->mbox_mem_pool); + mempool_free(mbox, hrq->phba->mbox_mem_pool); return -ENXIO; } bf_set(lpfc_mbx_rq_destroy_q_id, &mbox->u.mqe.un.rq_destroy.u.request, @@ -16942,7 +16937,9 @@ lpfc_sli4_post_sgl(struct lpfc_hba *phba, shdr = (union lpfc_sli4_cfg_shdr *) &post_sgl_pages->header.cfg_shdr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) + if (!phba->sli4_hba.intr_enable) + mempool_free(mbox, phba->mbox_mem_pool); + else if (rc != MBX_TIMEOUT) mempool_free(mbox, phba->mbox_mem_pool); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, @@ -17139,7 +17136,9 @@ lpfc_sli4_post_sgl_list(struct lpfc_hba *phba, shdr = (union lpfc_sli4_cfg_shdr *) &sgl->cfg_shdr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) + if (!phba->sli4_hba.intr_enable) + lpfc_sli4_mbox_cmd_free(phba, mbox); + else if (rc != MBX_TIMEOUT) lpfc_sli4_mbox_cmd_free(phba, mbox); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, @@ -17252,7 +17251,9 @@ lpfc_sli4_post_io_sgl_block(struct lpfc_hba *phba, struct list_head *nblist, shdr = (union lpfc_sli4_cfg_shdr *)&sgl->cfg_shdr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) + if (!phba->sli4_hba.intr_enable) + lpfc_sli4_mbox_cmd_free(phba, mbox); + else if (rc != MBX_TIMEOUT) lpfc_sli4_mbox_cmd_free(phba, mbox); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, @@ -18607,8 +18608,7 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page) shdr = (union lpfc_sli4_cfg_shdr *) &hdr_tmpl->header.cfg_shdr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) - mempool_free(mboxq, phba->mbox_mem_pool); + mempool_free(mboxq, phba->mbox_mem_pool); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "2514 POST_RPI_HDR mailbox failed with " @@ -19852,7 +19852,9 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list, break; } } - if (rc != MBX_TIMEOUT) + if (!phba->sli4_hba.intr_enable) + mempool_free(mbox, phba->mbox_mem_pool); + else if (rc != MBX_TIMEOUT) mempool_free(mbox, phba->mbox_mem_pool); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
From: James Smart jsmart2021@gmail.com
[ Upstream commit b62232ba8caccaf1954e197058104a6478fac1af ]
SLI-4 does not contain a PORT_CAPABILITIES mailbox command (only SLI-3 does, and SLI-3 doesn't use it), yet there are SLI-4 code paths that have code to issue the command. The command will always fail.
Remove the code for the mailbox command and leave only the resulting "failure path" logic.
Link: https://lore.kernel.org/r/20210412013127.2387-12-jsmart2021@gmail.com Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_crtn.h | 3 - drivers/scsi/lpfc/lpfc_hw4.h | 174 +--------------------------------- drivers/scsi/lpfc/lpfc_init.c | 103 +------------------- drivers/scsi/lpfc/lpfc_mbox.c | 36 ------- 4 files changed, 3 insertions(+), 313 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 782f6f76f18a..26f4a345bd14 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -55,9 +55,6 @@ void lpfc_register_new_vport(struct lpfc_hba *, struct lpfc_vport *, void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *); void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *); -void lpfc_supported_pages(struct lpfcMboxq *); -void lpfc_pc_sli4_params(struct lpfcMboxq *); -int lpfc_pc_sli4_params_get(struct lpfc_hba *, LPFC_MBOXQ_t *); int lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *, struct lpfcMboxq *, uint16_t, uint16_t, bool); int lpfc_get_sli4_parameters(struct lpfc_hba *, LPFC_MBOXQ_t *); diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 12e4e76233e6..47e832b7f2c2 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -124,6 +124,7 @@ struct lpfc_sli_intf { /* Define SLI4 Alignment requirements. */ #define LPFC_ALIGN_16_BYTE 16 #define LPFC_ALIGN_64_BYTE 64 +#define SLI4_PAGE_SIZE 4096
/* Define SLI4 specific definitions. */ #define LPFC_MQ_CQE_BYTE_OFFSET 256 @@ -2976,62 +2977,6 @@ struct lpfc_mbx_request_features { #define lpfc_mbx_rq_ftr_rsp_mrqp_WORD word3 };
-struct lpfc_mbx_supp_pages { - uint32_t word1; -#define qs_SHIFT 0 -#define qs_MASK 0x00000001 -#define qs_WORD word1 -#define wr_SHIFT 1 -#define wr_MASK 0x00000001 -#define wr_WORD word1 -#define pf_SHIFT 8 -#define pf_MASK 0x000000ff -#define pf_WORD word1 -#define cpn_SHIFT 16 -#define cpn_MASK 0x000000ff -#define cpn_WORD word1 - uint32_t word2; -#define list_offset_SHIFT 0 -#define list_offset_MASK 0x000000ff -#define list_offset_WORD word2 -#define next_offset_SHIFT 8 -#define next_offset_MASK 0x000000ff -#define next_offset_WORD word2 -#define elem_cnt_SHIFT 16 -#define elem_cnt_MASK 0x000000ff -#define elem_cnt_WORD word2 - uint32_t word3; -#define pn_0_SHIFT 24 -#define pn_0_MASK 0x000000ff -#define pn_0_WORD word3 -#define pn_1_SHIFT 16 -#define pn_1_MASK 0x000000ff -#define pn_1_WORD word3 -#define pn_2_SHIFT 8 -#define pn_2_MASK 0x000000ff -#define pn_2_WORD word3 -#define pn_3_SHIFT 0 -#define pn_3_MASK 0x000000ff -#define pn_3_WORD word3 - uint32_t word4; -#define pn_4_SHIFT 24 -#define pn_4_MASK 0x000000ff -#define pn_4_WORD word4 -#define pn_5_SHIFT 16 -#define pn_5_MASK 0x000000ff -#define pn_5_WORD word4 -#define pn_6_SHIFT 8 -#define pn_6_MASK 0x000000ff -#define pn_6_WORD word4 -#define pn_7_SHIFT 0 -#define pn_7_MASK 0x000000ff -#define pn_7_WORD word4 - uint32_t rsvd[27]; -#define LPFC_SUPP_PAGES 0 -#define LPFC_BLOCK_GUARD_PROFILES 1 -#define LPFC_SLI4_PARAMETERS 2 -}; - struct lpfc_mbx_memory_dump_type3 { uint32_t word1; #define lpfc_mbx_memory_dump_type3_type_SHIFT 0 @@ -3248,121 +3193,6 @@ struct user_eeprom { uint8_t reserved191[57]; };
-struct lpfc_mbx_pc_sli4_params { - uint32_t word1; -#define qs_SHIFT 0 -#define qs_MASK 0x00000001 -#define qs_WORD word1 -#define wr_SHIFT 1 -#define wr_MASK 0x00000001 -#define wr_WORD word1 -#define pf_SHIFT 8 -#define pf_MASK 0x000000ff -#define pf_WORD word1 -#define cpn_SHIFT 16 -#define cpn_MASK 0x000000ff -#define cpn_WORD word1 - uint32_t word2; -#define if_type_SHIFT 0 -#define if_type_MASK 0x00000007 -#define if_type_WORD word2 -#define sli_rev_SHIFT 4 -#define sli_rev_MASK 0x0000000f -#define sli_rev_WORD word2 -#define sli_family_SHIFT 8 -#define sli_family_MASK 0x000000ff -#define sli_family_WORD word2 -#define featurelevel_1_SHIFT 16 -#define featurelevel_1_MASK 0x000000ff -#define featurelevel_1_WORD word2 -#define featurelevel_2_SHIFT 24 -#define featurelevel_2_MASK 0x0000001f -#define featurelevel_2_WORD word2 - uint32_t word3; -#define fcoe_SHIFT 0 -#define fcoe_MASK 0x00000001 -#define fcoe_WORD word3 -#define fc_SHIFT 1 -#define fc_MASK 0x00000001 -#define fc_WORD word3 -#define nic_SHIFT 2 -#define nic_MASK 0x00000001 -#define nic_WORD word3 -#define iscsi_SHIFT 3 -#define iscsi_MASK 0x00000001 -#define iscsi_WORD word3 -#define rdma_SHIFT 4 -#define rdma_MASK 0x00000001 -#define rdma_WORD word3 - uint32_t sge_supp_len; -#define SLI4_PAGE_SIZE 4096 - uint32_t word5; -#define if_page_sz_SHIFT 0 -#define if_page_sz_MASK 0x0000ffff -#define if_page_sz_WORD word5 -#define loopbk_scope_SHIFT 24 -#define loopbk_scope_MASK 0x0000000f -#define loopbk_scope_WORD word5 -#define rq_db_window_SHIFT 28 -#define rq_db_window_MASK 0x0000000f -#define rq_db_window_WORD word5 - uint32_t word6; -#define eq_pages_SHIFT 0 -#define eq_pages_MASK 0x0000000f -#define eq_pages_WORD word6 -#define eqe_size_SHIFT 8 -#define eqe_size_MASK 0x000000ff -#define eqe_size_WORD word6 - uint32_t word7; -#define cq_pages_SHIFT 0 -#define cq_pages_MASK 0x0000000f -#define cq_pages_WORD word7 -#define cqe_size_SHIFT 8 -#define cqe_size_MASK 0x000000ff -#define cqe_size_WORD word7 - uint32_t word8; -#define mq_pages_SHIFT 0 -#define mq_pages_MASK 0x0000000f -#define mq_pages_WORD word8 -#define mqe_size_SHIFT 8 -#define mqe_size_MASK 0x000000ff -#define mqe_size_WORD word8 -#define mq_elem_cnt_SHIFT 16 -#define mq_elem_cnt_MASK 0x000000ff -#define mq_elem_cnt_WORD word8 - uint32_t word9; -#define wq_pages_SHIFT 0 -#define wq_pages_MASK 0x0000ffff -#define wq_pages_WORD word9 -#define wqe_size_SHIFT 8 -#define wqe_size_MASK 0x000000ff -#define wqe_size_WORD word9 - uint32_t word10; -#define rq_pages_SHIFT 0 -#define rq_pages_MASK 0x0000ffff -#define rq_pages_WORD word10 -#define rqe_size_SHIFT 8 -#define rqe_size_MASK 0x000000ff -#define rqe_size_WORD word10 - uint32_t word11; -#define hdr_pages_SHIFT 0 -#define hdr_pages_MASK 0x0000000f -#define hdr_pages_WORD word11 -#define hdr_size_SHIFT 8 -#define hdr_size_MASK 0x0000000f -#define hdr_size_WORD word11 -#define hdr_pp_align_SHIFT 16 -#define hdr_pp_align_MASK 0x0000ffff -#define hdr_pp_align_WORD word11 - uint32_t word12; -#define sgl_pages_SHIFT 0 -#define sgl_pages_MASK 0x0000000f -#define sgl_pages_WORD word12 -#define sgl_pp_align_SHIFT 16 -#define sgl_pp_align_MASK 0x0000ffff -#define sgl_pp_align_WORD word12 - uint32_t rsvd_13_63[51]; -}; #define SLI4_PAGE_ALIGN(addr) (((addr)+((SLI4_PAGE_SIZE)-1)) \ &(~((SLI4_PAGE_SIZE)-1)))
@@ -3988,8 +3818,6 @@ struct lpfc_mqe { struct lpfc_mbx_post_hdr_tmpl hdr_tmpl; struct lpfc_mbx_query_fw_config query_fw_cfg; struct lpfc_mbx_set_beacon_config beacon_config; - struct lpfc_mbx_supp_pages supp_pages; - struct lpfc_mbx_pc_sli4_params sli4_params; struct lpfc_mbx_get_sli4_parameters get_sli4_parameters; struct lpfc_mbx_set_link_diag_state link_diag_state; struct lpfc_mbx_set_link_diag_loopback link_diag_loopback; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index b17a75216964..2dde5ddc687d 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -6548,8 +6548,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) LPFC_MBOXQ_t *mboxq; MAILBOX_t *mb; int rc, i, max_buf_size; - uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0}; - struct lpfc_mqe *mqe; int longs; int extra; uint64_t wwn; @@ -6783,32 +6781,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
lpfc_nvme_mod_param_dep(phba);
- /* Get the Supported Pages if PORT_CAPABILITIES is supported by port. */ - lpfc_supported_pages(mboxq); - rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); - if (!rc) { - mqe = &mboxq->u.mqe; - memcpy(&pn_page[0], ((uint8_t *)&mqe->un.supp_pages.word3), - LPFC_MAX_SUPPORTED_PAGES); - for (i = 0; i < LPFC_MAX_SUPPORTED_PAGES; i++) { - switch (pn_page[i]) { - case LPFC_SLI4_PARAMETERS: - phba->sli4_hba.pc_sli4_params.supported = 1; - break; - default: - break; - } - } - /* Read the port's SLI4 Parameters capabilities if supported. */ - if (phba->sli4_hba.pc_sli4_params.supported) - rc = lpfc_pc_sli4_params_get(phba, mboxq); - if (rc) { - mempool_free(mboxq, phba->mbox_mem_pool); - rc = -EIO; - goto out_free_bsmbx; - } - } - /* * Get sli4 parameters that override parameters from Port capabilities. * If this call fails, it isn't critical unless the SLI4 parameters come @@ -12046,78 +12018,6 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba) phba->pport->work_port_events = 0; }
- /** - * lpfc_pc_sli4_params_get - Get the SLI4_PARAMS port capabilities. - * @phba: Pointer to HBA context object. - * @mboxq: Pointer to the mailboxq memory for the mailbox command response. - * - * This function is called in the SLI4 code path to read the port's - * sli4 capabilities. - * - * This function may be be called from any context that can block-wait - * for the completion. The expectation is that this routine is called - * typically from probe_one or from the online routine. - **/ -int -lpfc_pc_sli4_params_get(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) -{ - int rc; - struct lpfc_mqe *mqe; - struct lpfc_pc_sli4_params *sli4_params; - uint32_t mbox_tmo; - - rc = 0; - mqe = &mboxq->u.mqe; - - /* Read the port's SLI4 Parameters port capabilities */ - lpfc_pc_sli4_params(mboxq); - if (!phba->sli4_hba.intr_enable) - rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); - else { - mbox_tmo = lpfc_mbox_tmo_val(phba, mboxq); - rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); - } - - if (unlikely(rc)) - return 1; - - sli4_params = &phba->sli4_hba.pc_sli4_params; - sli4_params->if_type = bf_get(if_type, &mqe->un.sli4_params); - sli4_params->sli_rev = bf_get(sli_rev, &mqe->un.sli4_params); - sli4_params->sli_family = bf_get(sli_family, &mqe->un.sli4_params); - sli4_params->featurelevel_1 = bf_get(featurelevel_1, - &mqe->un.sli4_params); - sli4_params->featurelevel_2 = bf_get(featurelevel_2, - &mqe->un.sli4_params); - sli4_params->proto_types = mqe->un.sli4_params.word3; - sli4_params->sge_supp_len = mqe->un.sli4_params.sge_supp_len; - sli4_params->if_page_sz = bf_get(if_page_sz, &mqe->un.sli4_params); - sli4_params->rq_db_window = bf_get(rq_db_window, &mqe->un.sli4_params); - sli4_params->loopbk_scope = bf_get(loopbk_scope, &mqe->un.sli4_params); - sli4_params->eq_pages_max = bf_get(eq_pages, &mqe->un.sli4_params); - sli4_params->eqe_size = bf_get(eqe_size, &mqe->un.sli4_params); - sli4_params->cq_pages_max = bf_get(cq_pages, &mqe->un.sli4_params); - sli4_params->cqe_size = bf_get(cqe_size, &mqe->un.sli4_params); - sli4_params->mq_pages_max = bf_get(mq_pages, &mqe->un.sli4_params); - sli4_params->mqe_size = bf_get(mqe_size, &mqe->un.sli4_params); - sli4_params->mq_elem_cnt = bf_get(mq_elem_cnt, &mqe->un.sli4_params); - sli4_params->wq_pages_max = bf_get(wq_pages, &mqe->un.sli4_params); - sli4_params->wqe_size = bf_get(wqe_size, &mqe->un.sli4_params); - sli4_params->rq_pages_max = bf_get(rq_pages, &mqe->un.sli4_params); - sli4_params->rqe_size = bf_get(rqe_size, &mqe->un.sli4_params); - sli4_params->hdr_pages_max = bf_get(hdr_pages, &mqe->un.sli4_params); - sli4_params->hdr_size = bf_get(hdr_size, &mqe->un.sli4_params); - sli4_params->hdr_pp_align = bf_get(hdr_pp_align, &mqe->un.sli4_params); - sli4_params->sgl_pages_max = bf_get(sgl_pages, &mqe->un.sli4_params); - sli4_params->sgl_pp_align = bf_get(sgl_pp_align, &mqe->un.sli4_params); - - /* Make sure that sge_supp_len can be handled by the driver */ - if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE) - sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE; - - return rc; -} - /** * lpfc_get_sli4_parameters - Get the SLI4 Config PARAMETERS. * @phba: Pointer to HBA context object. @@ -12176,7 +12076,8 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) else phba->sli3_options &= ~LPFC_SLI4_PHWQ_ENABLED; sli4_params->sge_supp_len = mbx_sli4_parameters->sge_supp_len; - sli4_params->loopbk_scope = bf_get(loopbk_scope, mbx_sli4_parameters); + sli4_params->loopbk_scope = bf_get(cfg_loopbk_scope, + mbx_sli4_parameters); sli4_params->oas_supported = bf_get(cfg_oas, mbx_sli4_parameters); sli4_params->cqv = bf_get(cfg_cqv, mbx_sli4_parameters); sli4_params->mqv = bf_get(cfg_mqv, mbx_sli4_parameters); diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 3414ffcb26fe..8764fdfc41d4 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -2624,39 +2624,3 @@ lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp) resume_rpi->event_tag = ndlp->phba->fc_eventTag; }
-/** - * lpfc_supported_pages - Initialize the PORT_CAPABILITIES supported pages - * mailbox command. - * @mbox: pointer to lpfc mbox command to initialize. - * - * The PORT_CAPABILITIES supported pages mailbox command is issued to - * retrieve the particular feature pages supported by the port. - **/ -void -lpfc_supported_pages(struct lpfcMboxq *mbox) -{ - struct lpfc_mbx_supp_pages *supp_pages; - - memset(mbox, 0, sizeof(*mbox)); - supp_pages = &mbox->u.mqe.un.supp_pages; - bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES); - bf_set(cpn, supp_pages, LPFC_SUPP_PAGES); -} - -/** - * lpfc_pc_sli4_params - Initialize the PORT_CAPABILITIES SLI4 Params mbox cmd. - * @mbox: pointer to lpfc mbox command to initialize. - * - * The PORT_CAPABILITIES SLI4 parameters mailbox command is issued to - * retrieve the particular SLI4 features supported by the port. - **/ -void -lpfc_pc_sli4_params(struct lpfcMboxq *mbox) -{ - struct lpfc_mbx_pc_sli4_params *sli4_params; - - memset(mbox, 0, sizeof(*mbox)); - sli4_params = &mbox->u.mqe.un.sli4_params; - bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES); - bf_set(cpn, sli4_params, LPFC_SLI4_PARAMETERS); -}
From: Xu Yilun yilun.xu@intel.com
[ Upstream commit d9b326b2c3673f939941806146aee38e5c635fd0 ]
This patch fixes the max register address of MAX 10 BMC. The range 0x20000000 ~ 0x200000fc are for control registers of the QSPI flash controller, which are not accessible to host.
Signed-off-by: Xu Yilun yilun.xu@intel.com Reviewed-by: Tom Rix trix@redhat.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/mfd/intel-m10-bmc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/mfd/intel-m10-bmc.h b/include/linux/mfd/intel-m10-bmc.h index c8ef2f1654a4..06da62c25234 100644 --- a/include/linux/mfd/intel-m10-bmc.h +++ b/include/linux/mfd/intel-m10-bmc.h @@ -11,7 +11,7 @@
#define M10BMC_LEGACY_SYS_BASE 0x300400 #define M10BMC_SYS_BASE 0x300800 -#define M10BMC_MEM_END 0x200000fc +#define M10BMC_MEM_END 0x1fffffff
/* Register offset of system registers */ #define NIOS2_FW_VERSION 0x0
From: Hubert Streidl hubert.streidl@de.bosch.com
[ Upstream commit 586478bfc9f7e16504d6f64cf18bcbdf6fd0cbc9 ]
By default the PMIC DA9063 2-wire interface is SMBus compliant. This means the PMIC will automatically reset the interface when the clock signal ceases for more than the SMBus timeout of 35 ms.
If the I2C driver / device is not capable of creating atomic I2C transactions, a context change can cause a ceasing of the clock signal. This can happen if for example a real-time thread is scheduled. Then the DA9063 in SMBus mode will reset the 2-wire interface. Subsequently a write message could end up in the wrong register. This could cause unpredictable system behavior.
The DA9063 PMIC also supports an I2C compliant mode for the 2-wire interface. This mode does not reset the interface when the clock signal ceases. Thus the problem depicted above does not occur.
This patch tests for the bus functionality "I2C_FUNC_I2C". It can reasonably be assumed that the bus cannot obey SMBus timings if this functionality is set. SMBus commands most probably are emulated in this case which is prone to the latency issue described above.
This patch enables the I2C bus mode if I2C_FUNC_I2C is set or otherwise keeps the default SMBus mode.
Signed-off-by: Hubert Streidl hubert.streidl@de.bosch.com Signed-off-by: Mark Jonas mark.jonas@de.bosch.com Reviewed-by: Wolfram Sang wsa+renesas@sang-engineering.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/da9063-i2c.c | 10 ++++++++++ include/linux/mfd/da9063/registers.h | 3 +++ 2 files changed, 13 insertions(+)
diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c index b8217ad303ce..3419814d016b 100644 --- a/drivers/mfd/da9063-i2c.c +++ b/drivers/mfd/da9063-i2c.c @@ -442,6 +442,16 @@ static int da9063_i2c_probe(struct i2c_client *i2c, return ret; }
+ /* If SMBus is not available and only I2C is possible, enter I2C mode */ + if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) { + ret = regmap_clear_bits(da9063->regmap, DA9063_REG_CONFIG_J, + DA9063_TWOWIRE_TO); + if (ret < 0) { + dev_err(da9063->dev, "Failed to set Two-Wire Bus Mode.\n"); + return -EIO; + } + } + return da9063_device_init(da9063, i2c->irq); }
diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h index 1dbabf1b3cb8..6e0f66a2e727 100644 --- a/include/linux/mfd/da9063/registers.h +++ b/include/linux/mfd/da9063/registers.h @@ -1037,6 +1037,9 @@ #define DA9063_NONKEY_PIN_AUTODOWN 0x02 #define DA9063_NONKEY_PIN_AUTOFLPRT 0x03
+/* DA9063_REG_CONFIG_J (addr=0x10F) */ +#define DA9063_TWOWIRE_TO 0x40 + /* DA9063_REG_MON_REG_5 (addr=0x116) */ #define DA9063_MON_A8_IDX_MASK 0x07 #define DA9063_MON_A8_IDX_NONE 0x00
From: Dinghao Liu dinghao.liu@zju.edu.cn
[ Upstream commit fe6df2b48043bbe1e852b2320501d3b169363c35 ]
pm_runtime_get_sync() will increase the rumtime PM counter even it returns an error. Thus a pairing decrement is needed to prevent refcount leak. Fix this by replacing this API with pm_runtime_resume_and_get(), which will not change the runtime PM counter on error.
Signed-off-by: Dinghao Liu dinghao.liu@zju.edu.cn Acked-by: Charles Keepax ckeepax@opensource.cirrus.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/arizona-irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index 077d9ab112b7..d919ae9691e2 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c @@ -100,7 +100,7 @@ static irqreturn_t arizona_irq_thread(int irq, void *data) unsigned int val; int ret;
- ret = pm_runtime_get_sync(arizona->dev); + ret = pm_runtime_resume_and_get(arizona->dev); if (ret < 0) { dev_err(arizona->dev, "Failed to resume device: %d\n", ret); return IRQ_NONE;
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit 90d6697810f06aceea9de71ad836a8c7669789cd ]
Since the 'mfs' member has been declared as 'u32' in include/scsi/libfc.h, use the %u format specifier instead of %hu. This patch fixes the following clang compiler warning:
warning: format specifies type 'unsigned short' but the argument has type 'u32' (aka 'unsigned int') [-Wformat] "lport->mfs:%hu\n", mfs, lport->mfs); ~~~ ^~~~~~~~~~ %u
Link: https://lore.kernel.org/r/20210415220826.29438-8-bvanassche@acm.org Cc: Hannes Reinecke hare@suse.de Signed-off-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/libfc/fc_lport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 6557fda85c5c..abb14b206be0 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -1731,7 +1731,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) { FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, " - "lport->mfs:%hu\n", mfs, lport->mfs); + "lport->mfs:%u\n", mfs, lport->mfs); fc_lport_error(lport, fp); goto out; }
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit ef54c1a476aef7eef26fe13ea10dc090952c00f8 ]
Make perf_event_exit_event() more robust, such that we can use it from other contexts. Specifically the up and coming remove_on_exec.
For this to work we need to address a few issues. Remove_on_exec will not destroy the entire context, so we cannot rely on TASK_TOMBSTONE to disable event_function_call() and we thus have to use perf_remove_from_context().
When using perf_remove_from_context(), there's two races to consider. The first is against close(), where we can have concurrent tear-down of the event. The second is against child_list iteration, which should not find a half baked event.
To address this, teach perf_remove_from_context() to special case !ctx->is_active and about DETACH_CHILD.
[ elver@google.com: fix racing parent/child exit in sync_child_event(). ] Signed-off-by: Marco Elver elver@google.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20210408103605.1676875-2-elver@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/perf_event.h | 1 + kernel/events/core.c | 142 +++++++++++++++++++++---------------- 2 files changed, 80 insertions(+), 63 deletions(-)
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 22ce0604b448..072ac6c1ef2b 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -607,6 +607,7 @@ struct swevent_hlist { #define PERF_ATTACH_TASK_DATA 0x08 #define PERF_ATTACH_ITRACE 0x10 #define PERF_ATTACH_SCHED_CB 0x20 +#define PERF_ATTACH_CHILD 0x40
struct perf_cgroup; struct perf_buffer; diff --git a/kernel/events/core.c b/kernel/events/core.c index 8e1b8126c0e4..45fa7167cee2 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -2209,6 +2209,26 @@ out: perf_event__header_size(leader); }
+static void sync_child_event(struct perf_event *child_event); + +static void perf_child_detach(struct perf_event *event) +{ + struct perf_event *parent_event = event->parent; + + if (!(event->attach_state & PERF_ATTACH_CHILD)) + return; + + event->attach_state &= ~PERF_ATTACH_CHILD; + + if (WARN_ON_ONCE(!parent_event)) + return; + + lockdep_assert_held(&parent_event->child_mutex); + + sync_child_event(event); + list_del_init(&event->child_list); +} + static bool is_orphaned_event(struct perf_event *event) { return event->state == PERF_EVENT_STATE_DEAD; @@ -2316,6 +2336,7 @@ group_sched_out(struct perf_event *group_event, }
#define DETACH_GROUP 0x01UL +#define DETACH_CHILD 0x02UL
/* * Cross CPU call to remove a performance event @@ -2339,6 +2360,8 @@ __perf_remove_from_context(struct perf_event *event, event_sched_out(event, cpuctx, ctx); if (flags & DETACH_GROUP) perf_group_detach(event); + if (flags & DETACH_CHILD) + perf_child_detach(event); list_del_event(event, ctx);
if (!ctx->nr_events && ctx->is_active) { @@ -2367,25 +2390,21 @@ static void perf_remove_from_context(struct perf_event *event, unsigned long fla
lockdep_assert_held(&ctx->mutex);
- event_function_call(event, __perf_remove_from_context, (void *)flags); - /* - * The above event_function_call() can NO-OP when it hits - * TASK_TOMBSTONE. In that case we must already have been detached - * from the context (by perf_event_exit_event()) but the grouping - * might still be in-tact. + * Because of perf_event_exit_task(), perf_remove_from_context() ought + * to work in the face of TASK_TOMBSTONE, unlike every other + * event_function_call() user. */ - WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT); - if ((flags & DETACH_GROUP) && - (event->attach_state & PERF_ATTACH_GROUP)) { - /* - * Since in that case we cannot possibly be scheduled, simply - * detach now. - */ - raw_spin_lock_irq(&ctx->lock); - perf_group_detach(event); + raw_spin_lock_irq(&ctx->lock); + if (!ctx->is_active) { + __perf_remove_from_context(event, __get_cpu_context(ctx), + ctx, (void *)flags); raw_spin_unlock_irq(&ctx->lock); + return; } + raw_spin_unlock_irq(&ctx->lock); + + event_function_call(event, __perf_remove_from_context, (void *)flags); }
/* @@ -12249,14 +12268,17 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu) } EXPORT_SYMBOL_GPL(perf_pmu_migrate_context);
-static void sync_child_event(struct perf_event *child_event, - struct task_struct *child) +static void sync_child_event(struct perf_event *child_event) { struct perf_event *parent_event = child_event->parent; u64 child_val;
- if (child_event->attr.inherit_stat) - perf_event_read_event(child_event, child); + if (child_event->attr.inherit_stat) { + struct task_struct *task = child_event->ctx->task; + + if (task && task != TASK_TOMBSTONE) + perf_event_read_event(child_event, task); + }
child_val = perf_event_count(child_event);
@@ -12271,60 +12293,53 @@ static void sync_child_event(struct perf_event *child_event, }
static void -perf_event_exit_event(struct perf_event *child_event, - struct perf_event_context *child_ctx, - struct task_struct *child) +perf_event_exit_event(struct perf_event *event, struct perf_event_context *ctx) { - struct perf_event *parent_event = child_event->parent; + struct perf_event *parent_event = event->parent; + unsigned long detach_flags = 0;
- /* - * Do not destroy the 'original' grouping; because of the context - * switch optimization the original events could've ended up in a - * random child task. - * - * If we were to destroy the original group, all group related - * operations would cease to function properly after this random - * child dies. - * - * Do destroy all inherited groups, we don't care about those - * and being thorough is better. - */ - raw_spin_lock_irq(&child_ctx->lock); - WARN_ON_ONCE(child_ctx->is_active); + if (parent_event) { + /* + * Do not destroy the 'original' grouping; because of the + * context switch optimization the original events could've + * ended up in a random child task. + * + * If we were to destroy the original group, all group related + * operations would cease to function properly after this + * random child dies. + * + * Do destroy all inherited groups, we don't care about those + * and being thorough is better. + */ + detach_flags = DETACH_GROUP | DETACH_CHILD; + mutex_lock(&parent_event->child_mutex); + }
- if (parent_event) - perf_group_detach(child_event); - list_del_event(child_event, child_ctx); - perf_event_set_state(child_event, PERF_EVENT_STATE_EXIT); /* is_event_hup() */ - raw_spin_unlock_irq(&child_ctx->lock); + perf_remove_from_context(event, detach_flags); + + raw_spin_lock_irq(&ctx->lock); + if (event->state > PERF_EVENT_STATE_EXIT) + perf_event_set_state(event, PERF_EVENT_STATE_EXIT); + raw_spin_unlock_irq(&ctx->lock);
/* - * Parent events are governed by their filedesc, retain them. + * Child events can be freed. */ - if (!parent_event) { - perf_event_wakeup(child_event); + if (parent_event) { + mutex_unlock(&parent_event->child_mutex); + /* + * Kick perf_poll() for is_event_hup(); + */ + perf_event_wakeup(parent_event); + free_event(event); + put_event(parent_event); return; } - /* - * Child events can be cleaned up. - */ - - sync_child_event(child_event, child);
/* - * Remove this event from the parent's list - */ - WARN_ON_ONCE(parent_event->ctx->parent_ctx); - mutex_lock(&parent_event->child_mutex); - list_del_init(&child_event->child_list); - mutex_unlock(&parent_event->child_mutex); - - /* - * Kick perf_poll() for is_event_hup(). + * Parent events are governed by their filedesc, retain them. */ - perf_event_wakeup(parent_event); - free_event(child_event); - put_event(parent_event); + perf_event_wakeup(event); }
static void perf_event_exit_task_context(struct task_struct *child, int ctxn) @@ -12381,7 +12396,7 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn) perf_event_task(child, child_ctx, 0);
list_for_each_entry_safe(child_event, next, &child_ctx->event_list, event_entry) - perf_event_exit_event(child_event, child_ctx, child); + perf_event_exit_event(child_event, child_ctx);
mutex_unlock(&child_ctx->mutex);
@@ -12641,6 +12656,7 @@ inherit_event(struct perf_event *parent_event, */ raw_spin_lock_irqsave(&child_ctx->lock, flags); add_event_to_ctx(child_event, child_ctx); + child_event->attach_state |= PERF_ATTACH_CHILD; raw_spin_unlock_irqrestore(&child_ctx->lock, flags);
/*
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 0c2de3f054a59f15e01804b75a04355c48de628c ]
The current sched_slice() seems to have issues; there's two possible things that could be improved:
- the 'nr_running' used for __sched_period() is daft when cgroups are considered. Using the RQ wide h_nr_running seems like a much more consistent number.
- (esp) cgroups can slice it real fine, which makes for easy over-scheduling, ensure min_gran is what the name says.
Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Tested-by: Valentin Schneider valentin.schneider@arm.com Link: https://lkml.kernel.org/r/20210412102001.611897312@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/fair.c | 12 +++++++++++- kernel/sched/features.h | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 481f4cc0958f..a0239649c741 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -700,7 +700,13 @@ static u64 __sched_period(unsigned long nr_running) */ static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se) { - u64 slice = __sched_period(cfs_rq->nr_running + !se->on_rq); + unsigned int nr_running = cfs_rq->nr_running; + u64 slice; + + if (sched_feat(ALT_PERIOD)) + nr_running = rq_of(cfs_rq)->cfs.h_nr_running; + + slice = __sched_period(nr_running + !se->on_rq);
for_each_sched_entity(se) { struct load_weight *load; @@ -717,6 +723,10 @@ static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se) } slice = __calc_delta(slice, se->load.weight, load); } + + if (sched_feat(BASE_SLICE)) + slice = max(slice, (u64)sysctl_sched_min_granularity); + return slice; }
diff --git a/kernel/sched/features.h b/kernel/sched/features.h index 68d369cba9e4..f1bf5e12d889 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h @@ -90,3 +90,6 @@ SCHED_FEAT(WA_BIAS, true) */ SCHED_FEAT(UTIL_EST, true) SCHED_FEAT(UTIL_EST_FASTUP, true) + +SCHED_FEAT(ALT_PERIOD, true) +SCHED_FEAT(BASE_SLICE, true)
From: Gioh Kim gi-oh.kim@cloud.ionos.com
[ Upstream commit 12b06533104e802df73c1fbe159437c19933d6c0 ]
When unloading the rnbd-clt module, it does not free a memory including the filename of the symbolic link to /sys/block/rnbdX.
It is found by kmemleak as below.
unreferenced object 0xffff9f1a83d3c740 (size 16): comm "bash", pid 736, jiffies 4295179665 (age 9841.310s) hex dump (first 16 bytes): 21 64 65 76 21 6e 75 6c 6c 62 30 40 62 6c 61 00 !dev!nullb0@bla. backtrace: [<0000000039f0c55e>] 0xffffffffc0456c24 [<000000001aab9513>] kernfs_fop_write+0xcf/0x1c0 [<00000000db5aa4b3>] vfs_write+0xdb/0x1d0 [<000000007a2e2207>] ksys_write+0x65/0xe0 [<00000000055e280a>] do_syscall_64+0x50/0x1b0 [<00000000c2b51831>] entry_SYSCALL_64_after_hwframe+0x49/0xbe
Signed-off-by: Gioh Kim gi-oh.kim@ionos.com Signed-off-by: Jack Wang jinpu.wang@ionos.com Link: https://lore.kernel.org/r/20210419073722.15351-13-gi-oh.kim@ionos.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/rnbd/rnbd-clt-sysfs.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/block/rnbd/rnbd-clt-sysfs.c b/drivers/block/rnbd/rnbd-clt-sysfs.c index d9dd138ca9c6..5613cd45866b 100644 --- a/drivers/block/rnbd/rnbd-clt-sysfs.c +++ b/drivers/block/rnbd/rnbd-clt-sysfs.c @@ -433,10 +433,14 @@ void rnbd_clt_remove_dev_symlink(struct rnbd_clt_dev *dev) * i.e. rnbd_clt_unmap_dev_store() leading to a sysfs warning because * of sysfs link already was removed already. */ - if (dev->blk_symlink_name && try_module_get(THIS_MODULE)) { - sysfs_remove_link(rnbd_devs_kobj, dev->blk_symlink_name); + if (dev->blk_symlink_name) { + if (try_module_get(THIS_MODULE)) { + sysfs_remove_link(rnbd_devs_kobj, dev->blk_symlink_name); + module_put(THIS_MODULE); + } + /* It should be freed always. */ kfree(dev->blk_symlink_name); - module_put(THIS_MODULE); + dev->blk_symlink_name = NULL; } }
From: Harald Freudenberger freude@linux.ibm.com
[ Upstream commit 28096067686c5a5cbd4c35b079749bd805df5010 ]
A review of the code showed, that this function which is exposed within the whole kernel should do a parameter check for the amount of bytes requested. If this requested bytes is too high an unsigned int overflow could happen causing this function to try to memcpy a really big memory chunk.
This is not a security issue as there are only two invocations of this function from arch/s390/include/asm/archrandom.h and both are not exposed to userland.
Reported-by: Sven Schnelle svens@linux.ibm.com Signed-off-by: Harald Freudenberger freude@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/crypto/arch_random.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/s390/crypto/arch_random.c b/arch/s390/crypto/arch_random.c index dd95cdbd22ce..4cbb4b6d85a8 100644 --- a/arch/s390/crypto/arch_random.c +++ b/arch/s390/crypto/arch_random.c @@ -53,6 +53,10 @@ static DECLARE_DELAYED_WORK(arch_rng_work, arch_rng_refill_buffer);
bool s390_arch_random_generate(u8 *buf, unsigned int nbytes) { + /* max hunk is ARCH_RNG_BUF_SIZE */ + if (nbytes > ARCH_RNG_BUF_SIZE) + return false; + /* lock rng buffer */ if (!spin_trylock(&arch_rng_lock)) return false;
From: Charan Teja Reddy charante@codeaurora.org
[ Upstream commit 9d10a13d1e4c349b76f1c675a874a7f981d6d3b4 ]
psi_group_cpu->tasks, represented by the unsigned int, stores the number of tasks that could be stalled on a psi resource(io/mem/cpu). Decrementing these counters at zero leads to wrapping which further leads to the psi_group_cpu->state_mask is being set with the respective pressure state. This could result into the unnecessary time sampling for the pressure state thus cause the spurious psi events. This can further lead to wrong actions being taken at the user land based on these psi events.
Though psi_bug is set under these conditions but that just for debug purpose. Fix it by decrementing the ->tasks count only when it is non-zero.
Signed-off-by: Charan Teja Reddy charante@codeaurora.org Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Johannes Weiner hannes@cmpxchg.org Link: https://lkml.kernel.org/r/1618585336-37219-1-git-send-email-charante@codeaur... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/psi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c index 967732c0766c..651218ded981 100644 --- a/kernel/sched/psi.c +++ b/kernel/sched/psi.c @@ -711,14 +711,15 @@ static void psi_group_change(struct psi_group *group, int cpu, for (t = 0, m = clear; m; m &= ~(1 << t), t++) { if (!(m & (1 << t))) continue; - if (groupc->tasks[t] == 0 && !psi_bug) { + if (groupc->tasks[t]) { + groupc->tasks[t]--; + } else if (!psi_bug) { printk_deferred(KERN_ERR "psi: task underflow! cpu=%d t=%d tasks=[%u %u %u %u] clear=%x set=%x\n", cpu, t, groupc->tasks[0], groupc->tasks[1], groupc->tasks[2], groupc->tasks[3], clear, set); psi_bug = 1; } - groupc->tasks[t]--; }
for (t = 0; set; set &= ~(1 << t), t++)
From: Guangqing Zhu zhuguangqing83@gmail.com
[ Upstream commit d0a43c12ee9f57ddb284272187bd18726c2c2c98 ]
Fix invalid usage of a list_for_each_entry in cpcap_battery_irq_thread(). Empty list or fully traversed list points to list head, which is not NULL (and before the first element containing real data).
Signed-off-by: Guangqing Zhu zhuguangqing83@gmail.com Reviewed-by: Tony Lindgren tony@atomide.com Reviewed-by: Carl Philipp Klemm philipp@uvos.xyz Tested-by: Carl Philipp Klemm philipp@uvos.xyz Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/cpcap-battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c index cebc5c8fda1b..793d4ca52f8a 100644 --- a/drivers/power/supply/cpcap-battery.c +++ b/drivers/power/supply/cpcap-battery.c @@ -626,7 +626,7 @@ static irqreturn_t cpcap_battery_irq_thread(int irq, void *data) break; }
- if (!d) + if (list_entry_is_head(d, &ddata->irq_list, node)) return IRQ_NONE;
latest = cpcap_battery_latest(ddata);
From: Lv Yunlong lyl2019@mail.ustc.edu.cn
commit 1c98f574403dbcf2eb832d5535a10d967333ef2d upstream.
Our code analyzer reported a uaf.
In snd_emu8000_create_mixer, the callee snd_ctl_add(..,emu->controls[i]) calls snd_ctl_add_replace(.., kcontrol,..). Inside snd_ctl_add_replace(), if error happens, kcontrol will be freed by snd_ctl_free_one(kcontrol). Then emu->controls[i] points to a freed memory, and the execution comes to __error branch of snd_emu8000_create_mixer. The freed emu->controls[i] is used in snd_ctl_remove(card, emu->controls[i]).
My patch set emu->controls[i] to NULL if snd_ctl_add() failed to avoid the uaf.
Signed-off-by: Lv Yunlong lyl2019@mail.ustc.edu.cn Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210426131129.4796-1-lyl2019@mail.ustc.edu.cn Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/isa/sb/emu8000.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c @@ -1029,8 +1029,10 @@ snd_emu8000_create_mixer(struct snd_card
memset(emu->controls, 0, sizeof(emu->controls)); for (i = 0; i < EMU8000_NUM_CONTROLS; i++) { - if ((err = snd_ctl_add(card, emu->controls[i] = snd_ctl_new1(mixer_defs[i], emu))) < 0) + if ((err = snd_ctl_add(card, emu->controls[i] = snd_ctl_new1(mixer_defs[i], emu))) < 0) { + emu->controls[i] = NULL; goto __error; + } } return 0;
From: Takashi Iwai tiwai@suse.de
commit 2e6a731296be9d356fdccee9fb6ae345dad96438 upstream.
Just re-order the cx5066_fixups[] entries for HP devices for avoiding the oversight of the duplicated or unapplied item in future. No functional changes.
Also Cc-to-stable for the further patch applications.
Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210428112704.23967-14-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_conexant.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
--- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -930,18 +930,18 @@ static const struct snd_pci_quirk cxt506 SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK), - SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK), - SND_PCI_QUIRK(0x103c, 0x83b2, "HP EliteBook 840 G5", CXT_FIXUP_HP_DOCK), - SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), - SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK), - SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO), - SND_PCI_QUIRK(0x103c, 0x836e, "HP ProBook 455 G5", CXT_FIXUP_MUTE_LED_GPIO), - SND_PCI_QUIRK(0x103c, 0x837f, "HP ProBook 470 G5", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x836e, "HP ProBook 455 G5", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x837f, "HP ProBook 470 G5", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x83b2, "HP EliteBook 840 G5", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x8402, "HP ProBook 645 G4", CXT_FIXUP_MUTE_LED_GPIO), SND_PCI_QUIRK(0x103c, 0x8427, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x844f, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
From: Lv Yunlong lyl2019@mail.ustc.edu.cn
commit 4fb44dd2c1dda18606348acdfdb97e8759dde9df upstream.
In snd_sb_qsound_build, snd_ctl_add(..,p->qsound_switch...) and snd_ctl_add(..,p->qsound_space..) are called. But the second arguments of snd_ctl_add() could be freed via snd_ctl_add_replace() ->snd_ctl_free_one(). After the error code is returned, snd_sb_qsound_destroy(p) is called in __error branch.
But in snd_sb_qsound_destroy(), the freed p->qsound_switch and p->qsound_space are still used by snd_ctl_remove().
My patch set p->qsound_switch and p->qsound_space to NULL if snd_ctl_add() failed to avoid the uaf bugs. But these codes need to further be improved with the code style.
Signed-off-by: Lv Yunlong lyl2019@mail.ustc.edu.cn Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210426145541.8070-1-lyl2019@mail.ustc.edu.cn Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/isa/sb/sb16_csp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c @@ -1045,10 +1045,14 @@ static int snd_sb_qsound_build(struct sn
spin_lock_init(&p->q_lock);
- if ((err = snd_ctl_add(card, p->qsound_switch = snd_ctl_new1(&snd_sb_qsound_switch, p))) < 0) + if ((err = snd_ctl_add(card, p->qsound_switch = snd_ctl_new1(&snd_sb_qsound_switch, p))) < 0) { + p->qsound_switch = NULL; goto __error; - if ((err = snd_ctl_add(card, p->qsound_space = snd_ctl_new1(&snd_sb_qsound_space, p))) < 0) + } + if ((err = snd_ctl_add(card, p->qsound_space = snd_ctl_new1(&snd_sb_qsound_space, p))) < 0) { + p->qsound_space = NULL; goto __error; + }
return 0;
From: Takashi Iwai tiwai@suse.de
commit d2e8f641257d0d3af6e45d6ac2d6f9d56b8ea964 upstream.
In the current code, we have some assumption that the audio clock selector has been set up implicitly and don't want to touch it unless it's really needed for the fallback autoclock setup. This works for most devices but some seem having a problem. Partially this was covered for the devices with a single connector at the initialization phase (commit 086b957cc17f "ALSA: usb-audio: Skip the clock selector inquiry for single connections"), but also there are cases where the wrong clock set up is kept silently. The latter seems to be the cause of the noises on Behringer devices.
In this patch, we explicitly set up the audio clock selector whenever the appropriate node is found.
Reported-by: Geraldo Nascimento geraldogabriel@gmail.com BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199327 Link: https://lore.kernel.org/r/CAEsQvcvF7LnO8PxyyCxuRCx=7jNeSCvFAd-+dE0g_rd1rOxxd... Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210413084152.32325-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/usb/clock.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
--- a/sound/usb/clock.c +++ b/sound/usb/clock.c @@ -296,7 +296,7 @@ static int __uac_clock_find_source(struc
selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id); if (selector) { - int ret, i, cur; + int ret, i, cur, err;
/* the entity ID we are looking for is a selector. * find out what it currently selects */ @@ -318,13 +318,17 @@ static int __uac_clock_find_source(struc ret = __uac_clock_find_source(chip, fmt, selector->baCSourceID[ret - 1], visited, validate); + if (ret > 0) { + err = uac_clock_selector_set_val(chip, entity_id, cur); + if (err < 0) + return err; + } + if (!validate || ret > 0 || !chip->autoclock) return ret;
/* The current clock source is invalid, try others. */ for (i = 1; i <= selector->bNrInPins; i++) { - int err; - if (i == cur) continue;
@@ -390,7 +394,7 @@ static int __uac3_clock_find_source(stru
selector = snd_usb_find_clock_selector_v3(chip->ctrl_intf, entity_id); if (selector) { - int ret, i, cur; + int ret, i, cur, err;
/* the entity ID we are looking for is a selector. * find out what it currently selects */ @@ -412,6 +416,12 @@ static int __uac3_clock_find_source(stru ret = __uac3_clock_find_source(chip, fmt, selector->baCSourceID[ret - 1], visited, validate); + if (ret > 0) { + err = uac_clock_selector_set_val(chip, entity_id, cur); + if (err < 0) + return err; + } + if (!validate || ret > 0 || !chip->autoclock) return ret;
From: Timo Gurr timo.gurr@gmail.com
commit ab2165e2e6ed17345ffa8ee88ca764e8788ebcd7 upstream.
The decibel volume range contains a negative maximum value resulting in pipewire complaining about the device and effectivly having no sound output. The wrong values also resulted in the headset sounding muted already at a mixer level of about ~25%.
PipeWire BugLink: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1049
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=212897 Signed-off-by: Timo Gurr timo.gurr@gmail.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210503110822.10222-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/usb/mixer_maps.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
--- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -337,6 +337,13 @@ static const struct usbmix_name_map bose { 0 } /* terminator */ };
+/* Sennheiser Communications Headset [PC 8], the dB value is reported as -6 negative maximum */ +static const struct usbmix_dB_map sennheiser_pc8_dB = {-9500, 0}; +static const struct usbmix_name_map sennheiser_pc8_map[] = { + { 9, NULL, .dB = &sennheiser_pc8_dB }, + { 0 } /* terminator */ +}; + /* * Dell usb dock with ALC4020 codec had a firmware problem where it got * screwed up when zero volume is passed; just skip it as a workaround @@ -593,6 +600,11 @@ static const struct usbmix_ctl_map usbmi .id = USB_ID(0x17aa, 0x1046), .map = lenovo_p620_rear_map, }, + { + /* Sennheiser Communications Headset [PC 8] */ + .id = USB_ID(0x1395, 0x0025), + .map = sennheiser_pc8_map, + }, { 0 } /* terminator */ };
From: Jonas Witschel diabonas@archlinux.org
commit 75b62ab65d2715ce6ff0794033d61ab9dc4a2dfc upstream.
The HP ProBook 445 G7 (17T32ES) uses ALC236. Like ALC236_FIXUP_HP_GPIO_LED, COEF index 0x34 bit 5 is used to control the playback mute LED, but the microphone mute LED is controlled using pin VREF instead of a COEF index.
AlsaInfo: https://alsa-project.org/db/?f=0d3f4d1af39cc359f9fea9b550727ee87e5cf45a Signed-off-by: Jonas Witschel diabonas@archlinux.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210416105852.52588-1-diabonas@archlinux.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4438,6 +4438,25 @@ static void alc236_fixup_hp_mute_led(str alc236_fixup_hp_coef_micmute_led(codec, fix, action); }
+static void alc236_fixup_hp_micmute_led_vref(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + spec->cap_mute_led_nid = 0x1a; + snd_hda_gen_add_micmute_led_cdev(codec, vref_micmute_led_set); + codec->power_filter = led_power_filter; + } +} + +static void alc236_fixup_hp_mute_led_micmute_vref(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + alc236_fixup_hp_mute_led_coefbit(codec, fix, action); + alc236_fixup_hp_micmute_led_vref(codec, fix, action); +} + #if IS_REACHABLE(CONFIG_INPUT) static void gpio2_mic_hotkey_event(struct hda_codec *codec, struct hda_jack_callback *event) @@ -6400,6 +6419,7 @@ enum { ALC285_FIXUP_HP_MUTE_LED, ALC236_FIXUP_HP_GPIO_LED, ALC236_FIXUP_HP_MUTE_LED, + ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF, ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, ALC295_FIXUP_ASUS_MIC_NO_PRESENCE, ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS, @@ -7646,6 +7666,10 @@ static const struct hda_fixup alc269_fix .type = HDA_FIXUP_FUNC, .v.func = alc236_fixup_hp_mute_led, }, + [ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc236_fixup_hp_mute_led_micmute_vref, + }, [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = { .type = HDA_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { @@ -8063,6 +8087,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8730, "HP ProBook 445 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
From: Luke D Jones luke@ljones.dev
commit 76fae6185f5456865ff1bcb647709d44fd987eb6 upstream.
The GA503 has almost exactly the same default setup as the GA401 model with the same issues. The GA401 quirks solve all the issues so we will use the full quirk chain.
Signed-off-by: Luke D Jones luke@ljones.dev Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210419030411.28304-1-luke@ljones.dev Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8138,6 +8138,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), + SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS), SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
From: Phil Calvin phil@philcalvin.com
commit d1ee66c5d3c5a0498dd5e3f2af5b8c219a98bba5 upstream.
Fix two bugs with the Intel HDA Realtek ALC233 sound codec present in Intel NUC NUC8i7BEH and probably a few other similar NUC models.
These codecs advertise a 4-level microphone input boost amplifier on pin 0x19, but the highest two boost settings do not work correctly, and produce only low analog noise that does not seem to contain any discernible signal. There is an existing fixup for this exact problem but for a different PCI subsystem ID, so we re-use that logic.
Changing the boost level also triggers a DC spike in the input signal that bleeds off over about a second and overwhelms any input during that time. Thankfully, the existing fixup has the side effect of making the boost control show up in userspace as a mute/unmute switch, and this keeps (e.g.) PulseAudio from fiddling with it during normal input volume adjustments.
Finally, the NUC hardware has built-in inverted stereo mics. This patch also enables the usual fixup for this so the two channels cancel noise instead of the actual signal.
[ Re-ordered the quirk entry point by tiwai ]
Signed-off-by: Phil Calvin phil@philcalvin.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/80dc5663-7734-e7e5-25ef-15b5df24511a@philcalvin.co... Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6435,6 +6435,8 @@ enum { ALC269_FIXUP_LEMOTE_A1802, ALC269_FIXUP_LEMOTE_A190X, ALC256_FIXUP_INTEL_NUC8_RUGGED, + ALC233_FIXUP_INTEL_NUC8_DMIC, + ALC233_FIXUP_INTEL_NUC8_BOOST, ALC256_FIXUP_INTEL_NUC10, ALC255_FIXUP_XIAOMI_HEADSET_MIC, ALC274_FIXUP_HP_MIC, @@ -7156,6 +7158,16 @@ static const struct hda_fixup alc269_fix .type = HDA_FIXUP_FUNC, .v.func = alc233_fixup_lenovo_line2_mic_hotkey, }, + [ALC233_FIXUP_INTEL_NUC8_DMIC] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_inv_dmic, + .chained = true, + .chain_id = ALC233_FIXUP_INTEL_NUC8_BOOST, + }, + [ALC233_FIXUP_INTEL_NUC8_BOOST] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_limit_int_mic_boost + }, [ALC255_FIXUP_DELL_SPK_NOISE] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_disable_aamix, @@ -8305,6 +8317,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE), SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802), SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X), + SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC), SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED), SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10),
From: Kailang Yang kailang@realtek.com
commit 1c9d9dfd2d254211cb37b1513b1da3e6835b8f00 upstream.
Boot with plugged headset, the Headset Mic will be gone.
Signed-off-by: Kailang Yang kailang@realtek.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/207eecfc3189466a820720bc0c409ea9@realtek.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8087,6 +8087,8 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC), SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x8077, "HP", ALC256_FIXUP_HP_HEADSET_MIC), + SND_PCI_QUIRK(0x103c, 0x8158, "HP", ALC256_FIXUP_HP_HEADSET_MIC), SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
From: Sami Loone sami@loone.fi
commit 9bbb94e57df135ef61bef075d9c99b8d9e89e246 upstream.
Remove a duplicate vendor+subvendor pin fixup entry as one is masking the other and making it unreachable. Consider the more specific newcomer as a second chance instead.
The generic entry is made less strict to also match for laptops with slightly different 0x12 pin configuration. Tested on Lenovo Yoga 6 (AMD) where 0x12 is 0x40000000.
Fixes: 607184cb1635 ("ALSA: hda/realtek - Add supported for more Lenovo ALC285 Headset Button") Signed-off-by: Sami Loone sami@loone.fi Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/YIXS+GT/dGI/LtK6@yoga Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8774,12 +8774,7 @@ static const struct snd_hda_pin_quirk al {0x12, 0x90a60130}, {0x19, 0x03a11020}, {0x21, 0x0321101f}), - SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, - {0x14, 0x90170110}, - {0x19, 0x04a11040}, - {0x21, 0x04211020}), SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE, - {0x12, 0x90a60130}, {0x14, 0x90170110}, {0x19, 0x04a11040}, {0x21, 0x04211020}), @@ -8950,6 +8945,10 @@ static const struct snd_hda_pin_quirk al SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, {0x19, 0x40000000}, {0x1a, 0x40000000}), + SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, + {0x14, 0x90170110}, + {0x19, 0x04a11040}, + {0x21, 0x04211020}), {} };
From: Eckhart Mohr e.mohr@tuxedocomputers.com
commit 970e3012c04c96351c413f193a9c909e6d871ce2 upstream.
This applies a SND_PCI_QUIRK(...) to the Clevo PCx0Dx barebones. This fix enables audio output over the headset jack and ensures that a microphone connected via the headset combo jack is correctly recognized when pluged in.
[ Rearranged the list entries in a sorted order -- tiwai ]
Signed-off-by: Eckhart Mohr e.mohr@tuxedocomputers.com Co-developed-by: Werner Sembach wse@tuxedocomputers.com Signed-off-by: Werner Sembach wse@tuxedocomputers.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210427153025.451118-1-wse@tuxedocomputers.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2552,8 +2552,10 @@ static const struct snd_pci_quirk alc882 SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x65e1, "Clevo PB51[ED][DF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), + SND_PCI_QUIRK(0x1558, 0x65e5, "Clevo PC50D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), + SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
From: Bas Nieuwenhuizen bas@basnieuwenhuizen.nl
commit 301b1d3a9104f4f3a8ab4171cf88d0f55d632b41 upstream.
It was reported that on Zen+ system turbostat started exiting, which was tracked down to the MSR_PKG_ENERGY_STAT read failing because offset_to_idx wasn't returning a non-negative index.
This patch combined the modification from Bingsong Si and Bas Nieuwenhuizen and addd the MSR to the index system as alternative for MSR_PKG_ENERGY_STATUS.
Fixes: 9972d5d84d76 ("tools/power turbostat: Enable accumulate RAPL display") Reported-by: youling257 youling257@gmail.com Tested-by: youling257 youling257@gmail.com Tested-by: Kurt Garloff kurt@garloff.de Tested-by: Bingsong Si owen.si@ucloud.cn Tested-by: Artem S. Tashkinov aros@gmx.com Co-developed-by: Bingsong Si owen.si@ucloud.cn Co-developed-by: Terry Bowman terry.bowman@amd.com Signed-off-by: Bas Nieuwenhuizen bas@basnieuwenhuizen.nl Reviewed-by: Chen Yu yu.c.chen@intel.com Signed-off-by: Len Brown len.brown@intel.com Cc: Salvatore Bonaccorso carnil@debian.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/power/x86/turbostat/turbostat.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -297,7 +297,10 @@ int idx_to_offset(int idx)
switch (idx) { case IDX_PKG_ENERGY: - offset = MSR_PKG_ENERGY_STATUS; + if (do_rapl & RAPL_AMD_F17H) + offset = MSR_PKG_ENERGY_STAT; + else + offset = MSR_PKG_ENERGY_STATUS; break; case IDX_DRAM_ENERGY: offset = MSR_DRAM_ENERGY_STATUS; @@ -326,6 +329,7 @@ int offset_to_idx(int offset)
switch (offset) { case MSR_PKG_ENERGY_STATUS: + case MSR_PKG_ENERGY_STAT: idx = IDX_PKG_ENERGY; break; case MSR_DRAM_ENERGY_STATUS: @@ -353,7 +357,7 @@ int idx_valid(int idx) { switch (idx) { case IDX_PKG_ENERGY: - return do_rapl & RAPL_PKG; + return do_rapl & (RAPL_PKG | RAPL_AMD_F17H); case IDX_DRAM_ENERGY: return do_rapl & RAPL_DRAM; case IDX_PP0_ENERGY:
From: Filipe Manana fdmanana@suse.com
[ Upstream commit f9690f426b2134cc3e74bfc5d9dfd6a4b2ca5281 ]
Commit dbcc7d57bffc0c ("btrfs: fix race when cloning extent buffer during rewind of an old root"), fixed a race when we need to rewind the extent buffer of an old root. It was caused by picking a new mod log operation for the extent buffer while getting a cloned extent buffer with an outdated number of items (off by -1), because we cloned the extent buffer without locking it first.
However there is still another similar race, but in the opposite direction. The cloned extent buffer has a number of items that does not match the number of tree mod log operations that are going to be replayed. This is because right after we got the last (most recent) tree mod log operation to replay and before locking and cloning the extent buffer, another task adds a new pointer to the extent buffer, which results in adding a new tree mod log operation and incrementing the number of items in the extent buffer. So after cloning we have mismatch between the number of items in the extent buffer and the number of mod log operations we are going to apply to it. This results in hitting a BUG_ON() that produces the following stack trace:
------------[ cut here ]------------ kernel BUG at fs/btrfs/tree-mod-log.c:675! invalid opcode: 0000 [#1] SMP KASAN PTI CPU: 3 PID: 4811 Comm: crawl_1215 Tainted: G W 5.12.0-7d1efdf501f8-misc-next+ #99 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 RIP: 0010:tree_mod_log_rewind+0x3b1/0x3c0 Code: 05 48 8d 74 10 (...) RSP: 0018:ffffc90001027090 EFLAGS: 00010293 RAX: 0000000000000000 RBX: ffff8880a8514600 RCX: ffffffffaa9e59b6 RDX: 0000000000000007 RSI: dffffc0000000000 RDI: ffff8880a851462c RBP: ffffc900010270e0 R08: 00000000000000c0 R09: ffffed1004333417 R10: ffff88802199a0b7 R11: ffffed1004333416 R12: 000000000000000e R13: ffff888135af8748 R14: ffff88818766ff00 R15: ffff8880a851462c FS: 00007f29acf62700(0000) GS:ffff8881f2200000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f0e6013f718 CR3: 000000010d42e003 CR4: 0000000000170ee0 Call Trace: btrfs_get_old_root+0x16a/0x5c0 ? lock_downgrade+0x400/0x400 btrfs_search_old_slot+0x192/0x520 ? btrfs_search_slot+0x1090/0x1090 ? free_extent_buffer.part.61+0xd7/0x140 ? free_extent_buffer+0x13/0x20 resolve_indirect_refs+0x3e9/0xfc0 ? lock_downgrade+0x400/0x400 ? __kasan_check_read+0x11/0x20 ? add_prelim_ref.part.11+0x150/0x150 ? lock_downgrade+0x400/0x400 ? __kasan_check_read+0x11/0x20 ? lock_acquired+0xbb/0x620 ? __kasan_check_write+0x14/0x20 ? do_raw_spin_unlock+0xa8/0x140 ? rb_insert_color+0x340/0x360 ? prelim_ref_insert+0x12d/0x430 find_parent_nodes+0x5c3/0x1830 ? stack_trace_save+0x87/0xb0 ? resolve_indirect_refs+0xfc0/0xfc0 ? fs_reclaim_acquire+0x67/0xf0 ? __kasan_check_read+0x11/0x20 ? lockdep_hardirqs_on_prepare+0x210/0x210 ? fs_reclaim_acquire+0x67/0xf0 ? __kasan_check_read+0x11/0x20 ? ___might_sleep+0x10f/0x1e0 ? __kasan_kmalloc+0x9d/0xd0 ? trace_hardirqs_on+0x55/0x120 btrfs_find_all_roots_safe+0x142/0x1e0 ? find_parent_nodes+0x1830/0x1830 ? trace_hardirqs_on+0x55/0x120 ? ulist_free+0x1f/0x30 ? btrfs_inode_flags_to_xflags+0x50/0x50 iterate_extent_inodes+0x20e/0x580 ? tree_backref_for_extent+0x230/0x230 ? release_extent_buffer+0x225/0x280 ? read_extent_buffer+0xdd/0x110 ? lock_downgrade+0x400/0x400 ? __kasan_check_read+0x11/0x20 ? lock_acquired+0xbb/0x620 ? __kasan_check_write+0x14/0x20 ? do_raw_spin_unlock+0xa8/0x140 ? _raw_spin_unlock+0x22/0x30 ? release_extent_buffer+0x225/0x280 iterate_inodes_from_logical+0x129/0x170 ? iterate_inodes_from_logical+0x129/0x170 ? btrfs_inode_flags_to_xflags+0x50/0x50 ? iterate_extent_inodes+0x580/0x580 ? __vmalloc_node+0x92/0xb0 ? init_data_container+0x34/0xb0 ? init_data_container+0x34/0xb0 ? kvmalloc_node+0x60/0x80 btrfs_ioctl_logical_to_ino+0x158/0x230 btrfs_ioctl+0x2038/0x4360 ? __kasan_check_write+0x14/0x20 ? mmput+0x3b/0x220 ? btrfs_ioctl_get_supported_features+0x30/0x30 ? __kasan_check_read+0x11/0x20 ? __kasan_check_read+0x11/0x20 ? lock_release+0xc8/0x650 ? __might_fault+0x64/0xd0 ? __kasan_check_read+0x11/0x20 ? lock_downgrade+0x400/0x400 ? lockdep_hardirqs_on_prepare+0x210/0x210 ? lockdep_hardirqs_on_prepare+0x13/0x210 ? _raw_spin_unlock_irqrestore+0x51/0x63 ? __kasan_check_read+0x11/0x20 ? do_vfs_ioctl+0xfc/0x9d0 ? ioctl_file_clone+0xe0/0xe0 ? lock_downgrade+0x400/0x400 ? lockdep_hardirqs_on_prepare+0x210/0x210 ? __kasan_check_read+0x11/0x20 ? lock_release+0xc8/0x650 ? __task_pid_nr_ns+0xd3/0x250 ? __kasan_check_read+0x11/0x20 ? __fget_files+0x160/0x230 ? __fget_light+0xf2/0x110 __x64_sys_ioctl+0xc3/0x100 do_syscall_64+0x37/0x80 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f29ae85b427 Code: 00 00 90 48 8b (...) RSP: 002b:00007f29acf5fcf8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f29acf5ff40 RCX: 00007f29ae85b427 RDX: 00007f29acf5ff48 RSI: 00000000c038943b RDI: 0000000000000003 RBP: 0000000001000000 R08: 0000000000000000 R09: 00007f29acf60120 R10: 00005640d5fc7b00 R11: 0000000000000246 R12: 0000000000000003 R13: 00007f29acf5ff48 R14: 00007f29acf5ff40 R15: 00007f29acf5fef8 Modules linked in: ---[ end trace 85e5fce078dfbe04 ]---
(gdb) l *(tree_mod_log_rewind+0x3b1) 0xffffffff819e5b21 is in tree_mod_log_rewind (fs/btrfs/tree-mod-log.c:675). 670 * the modification. As we're going backwards, we do the 671 * opposite of each operation here. 672 */ 673 switch (tm->op) { 674 case BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING: 675 BUG_ON(tm->slot < n); 676 fallthrough; 677 case BTRFS_MOD_LOG_KEY_REMOVE_WHILE_MOVING: 678 case BTRFS_MOD_LOG_KEY_REMOVE: 679 btrfs_set_node_key(eb, &tm->key, tm->slot); (gdb) quit
The following steps explain in more detail how it happens:
1) We have one tree mod log user (through fiemap or the logical ino ioctl), with a sequence number of 1, so we have fs_info->tree_mod_seq == 1. This is task A;
2) Another task is at ctree.c:balance_level() and we have eb X currently as the root of the tree, and we promote its single child, eb Y, as the new root.
Then, at ctree.c:balance_level(), we call:
ret = btrfs_tree_mod_log_insert_root(root->node, child, true);
3) At btrfs_tree_mod_log_insert_root() we create a tree mod log operation of type BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING, with a ->logical field pointing to ebX->start. We only have one item in eb X, so we create only one tree mod log operation, and store in the "tm_list" array;
4) Then, still at btrfs_tree_mod_log_insert_root(), we create a tree mod log element of operation type BTRFS_MOD_LOG_ROOT_REPLACE, ->logical set to ebY->start, ->old_root.logical set to ebX->start, ->old_root.level set to the level of eb X and ->generation set to the generation of eb X;
5) Then btrfs_tree_mod_log_insert_root() calls tree_mod_log_free_eb() with "tm_list" as argument. After that, tree_mod_log_free_eb() calls tree_mod_log_insert(). This inserts the mod log operation of type BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING from step 3 into the rbtree with a sequence number of 2 (and fs_info->tree_mod_seq set to 2);
6) Then, after inserting the "tm_list" single element into the tree mod log rbtree, the BTRFS_MOD_LOG_ROOT_REPLACE element is inserted, which gets the sequence number 3 (and fs_info->tree_mod_seq set to 3);
7) Back to ctree.c:balance_level(), we free eb X by calling btrfs_free_tree_block() on it. Because eb X was created in the current transaction, has no other references and writeback did not happen for it, we add it back to the free space cache/tree;
8) Later some other task B allocates the metadata extent from eb X, since it is marked as free space in the space cache/tree, and uses it as a node for some other btree;
9) The tree mod log user task calls btrfs_search_old_slot(), which calls btrfs_get_old_root(), and finally that calls tree_mod_log_oldest_root() with time_seq == 1 and eb_root == eb Y;
10) The first iteration of the while loop finds the tree mod log element with sequence number 3, for the logical address of eb Y and of type BTRFS_MOD_LOG_ROOT_REPLACE;
11) Because the operation type is BTRFS_MOD_LOG_ROOT_REPLACE, we don't break out of the loop, and set root_logical to point to tm->old_root.logical, which corresponds to the logical address of eb X;
12) On the next iteration of the while loop, the call to tree_mod_log_search_oldest() returns the smallest tree mod log element for the logical address of eb X, which has a sequence number of 2, an operation type of BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING and corresponds to the old slot 0 of eb X (eb X had only 1 item in it before being freed at step 7);
13) We then break out of the while loop and return the tree mod log operation of type BTRFS_MOD_LOG_ROOT_REPLACE (eb Y), and not the one for slot 0 of eb X, to btrfs_get_old_root();
14) At btrfs_get_old_root(), we process the BTRFS_MOD_LOG_ROOT_REPLACE operation and set "logical" to the logical address of eb X, which was the old root. We then call tree_mod_log_search() passing it the logical address of eb X and time_seq == 1;
15) But before calling tree_mod_log_search(), task B locks eb X, adds a key to eb X, which results in adding a tree mod log operation of type BTRFS_MOD_LOG_KEY_ADD, with a sequence number of 4, to the tree mod log, and increments the number of items in eb X from 0 to 1. Now fs_info->tree_mod_seq has a value of 4;
16) Task A then calls tree_mod_log_search(), which returns the most recent tree mod log operation for eb X, which is the one just added by task B at the previous step, with a sequence number of 4, a type of BTRFS_MOD_LOG_KEY_ADD and for slot 0;
17) Before task A locks and clones eb X, task A adds another key to eb X, which results in adding a new BTRFS_MOD_LOG_KEY_ADD mod log operation, with a sequence number of 5, for slot 1 of eb X, increments the number of items in eb X from 1 to 2, and unlocks eb X. Now fs_info->tree_mod_seq has a value of 5;
18) Task A then locks eb X and clones it. The clone has a value of 2 for the number of items and the pointer "tm" points to the tree mod log operation with sequence number 4, not the most recent one with a sequence number of 5, so there is mismatch between the number of mod log operations that are going to be applied to the cloned version of eb X and the number of items in the clone;
19) Task A then calls tree_mod_log_rewind() with the clone of eb X, the tree mod log operation with sequence number 4 and a type of BTRFS_MOD_LOG_KEY_ADD, and time_seq == 1;
20) At tree_mod_log_rewind(), we set the local variable "n" with a value of 2, which is the number of items in the clone of eb X.
Then in the first iteration of the while loop, we process the mod log operation with sequence number 4, which is targeted at slot 0 and has a type of BTRFS_MOD_LOG_KEY_ADD. This results in decrementing "n" from 2 to 1.
Then we pick the next tree mod log operation for eb X, which is the tree mod log operation with a sequence number of 2, a type of BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING and for slot 0, it is the one added in step 5 to the tree mod log tree.
We go back to the top of the loop to process this mod log operation, and because its slot is 0 and "n" has a value of 1, we hit the BUG_ON:
(...) switch (tm->op) { case BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING: BUG_ON(tm->slot < n); fallthrough; (...)
Fix this by checking for a more recent tree mod log operation after locking and cloning the extent buffer of the old root node, and use it as the first operation to apply to the cloned extent buffer when rewinding it.
Stable backport notes: due to moved code and renames, in =< 5.11 the change should be applied to ctree.c:get_old_root.
Reported-by: Zygo Blaxell ce3g8jdj@umail.furryterror.org Link: https://lore.kernel.org/linux-btrfs/20210404040732.GZ32440@hungrycats.org/ Fixes: 834328a8493079 ("Btrfs: tree mod log's old roots could still be part of the tree") CC: stable@vger.kernel.org # 4.4+ Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/ctree.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 9faf15bd5a54..519cf145f9bd 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1367,10 +1367,30 @@ get_old_root(struct btrfs_root *root, u64 time_seq) "failed to read tree block %llu from get_old_root", logical); } else { + struct tree_mod_elem *tm2; + btrfs_tree_read_lock(old); eb = btrfs_clone_extent_buffer(old); + /* + * After the lookup for the most recent tree mod operation + * above and before we locked and cloned the extent buffer + * 'old', a new tree mod log operation may have been added. + * So lookup for a more recent one to make sure the number + * of mod log operations we replay is consistent with the + * number of items we have in the cloned extent buffer, + * otherwise we can hit a BUG_ON when rewinding the extent + * buffer. + */ + tm2 = tree_mod_log_search(fs_info, logical, time_seq); btrfs_tree_read_unlock(old); free_extent_buffer(old); + ASSERT(tm2); + ASSERT(tm2 == tm || tm2->seq > tm->seq); + if (!tm2 || tm2->seq < tm->seq) { + free_extent_buffer(eb); + return NULL; + } + tm = tm2; } } else if (old_root) { eb_root_owner = btrfs_header_owner(eb_root);
From: Bill Wendling morbo@google.com
[ Upstream commit 388708028e6937f3fc5fc19aeeb847f8970f489c ]
The arm64 assembler in binutils 2.32 and above generates a program property note in a note section, .note.gnu.property, to encode used x86 ISAs and features. But the kernel linker script only contains a single NOTE segment:
PHDRS { text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ note PT_NOTE FLAGS(4); /* PF_R */ }
The NOTE segment generated by the vDSO linker script is aligned to 4 bytes. But the .note.gnu.property section must be aligned to 8 bytes on arm64.
$ readelf -n vdso64.so
Displaying notes found in: .note Owner Data size Description Linux 0x00000004 Unknown note type: (0x00000000) description data: 06 00 00 00 readelf: Warning: note with invalid namesz and/or descsz found at offset 0x20 readelf: Warning: type: 0x78, namesize: 0x00000100, descsize: 0x756e694c, alignment: 8
Since the note.gnu.property section in the vDSO is not checked by the dynamic linker, discard the .note.gnu.property sections in the vDSO.
Similar to commit 4caffe6a28d31 ("x86/vdso: Discard .note.gnu.property sections in vDSO"), but for arm64.
Signed-off-by: Bill Wendling morbo@google.com Reviewed-by: Kees Cook keescook@chromium.org Acked-by: Ard Biesheuvel ardb@kernel.org Link: https://lore.kernel.org/r/20210423205159.830854-1-morbo@google.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kernel/vdso/vdso.lds.S | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S index d808ad31e01f..b840ab1b705c 100644 --- a/arch/arm64/kernel/vdso/vdso.lds.S +++ b/arch/arm64/kernel/vdso/vdso.lds.S @@ -31,6 +31,13 @@ SECTIONS .gnu.version_d : { *(.gnu.version_d) } .gnu.version_r : { *(.gnu.version_r) }
+ /* + * Discard .note.gnu.property sections which are unused and have + * different alignment requirement from vDSO note sections. + */ + /DISCARD/ : { + *(.note.GNU-stack .note.gnu.property) + } .note : { *(.note.*) } :text :note
. = ALIGN(16); @@ -51,7 +58,6 @@ SECTIONS PROVIDE(end = .);
/DISCARD/ : { - *(.note.GNU-stack) *(.data .data.* .gnu.linkonce.d.* .sdata*) *(.bss .sbss .dynbss .dynsbss) }
From: Nathan Chancellor nathan@kernel.org
commit 885480b084696331bea61a4f7eba10652999a9c1 upstream.
Currently, -Wunused-but-set-variable is only supported by GCC so it is disabled unconditionally in a GCC only block (it is enabled with W=1). clang currently has its implementation for this warning in review so preemptively move this statement out of the GCC only block and wrap it with cc-disable-warning so that both compilers function the same.
Cc: stable@vger.kernel.org Link: https://reviews.llvm.org/D100581 Signed-off-by: Nathan Chancellor nathan@kernel.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Tested-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/Makefile +++ b/Makefile @@ -775,16 +775,16 @@ KBUILD_CFLAGS += -Wno-gnu KBUILD_CFLAGS += -mno-global-merge else
-# These warnings generated too much noise in a regular build. -# Use make W=1 to enable them (see scripts/Makefile.extrawarn) -KBUILD_CFLAGS += -Wno-unused-but-set-variable - # Warn about unmarked fall-throughs in switch statement. # Disabled for clang while comment to attribute conversion happens and # https://github.com/ClangBuiltLinux/linux/issues/636 is discussed. KBUILD_CFLAGS += $(call cc-option,-Wimplicit-fallthrough,) endif
+# These warnings generated too much noise in a regular build. +# Use make W=1 to enable them (see scripts/Makefile.extrawarn) +KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) + KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable) ifdef CONFIG_FRAME_POINTER KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
From: Theodore Ts'o tytso@mit.edu
commit 5afa7e8b70d65819245fece61a65fd753b4aae33 upstream.
statx(2) notes that any attribute that is not indicated as supported by stx_attributes_mask has no usable value. Commits 801e523796004 ("fs: move generic stat response attr handling to vfs_getattr_nosec") and 712b2698e4c02 ("fs/stat: Define DAX statx attribute") sets STATX_ATTR_AUTOMOUNT and STATX_ATTR_DAX, respectively, without setting stx_attributes_mask, which can cause xfstests generic/532 to fail.
Fix this in the same way as commit 1b9598c8fb99 ("xfs: fix reporting supported extra file attributes for statx()")
Fixes: 801e523796004 ("fs: move generic stat response attr handling to vfs_getattr_nosec") Fixes: 712b2698e4c02 ("fs/stat: Define DAX statx attribute") Cc: stable@kernel.org Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/stat.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/fs/stat.c +++ b/fs/stat.c @@ -77,12 +77,20 @@ int vfs_getattr_nosec(const struct path /* SB_NOATIME means filesystem supplies dummy atime value */ if (inode->i_sb->s_flags & SB_NOATIME) stat->result_mask &= ~STATX_ATIME; + + /* + * Note: If you add another clause to set an attribute flag, please + * update attributes_mask below. + */ if (IS_AUTOMOUNT(inode)) stat->attributes |= STATX_ATTR_AUTOMOUNT;
if (IS_DAX(inode)) stat->attributes |= STATX_ATTR_DAX;
+ stat->attributes_mask |= (STATX_ATTR_AUTOMOUNT | + STATX_ATTR_DAX); + if (inode->i_op->getattr) return inode->i_op->getattr(path, stat, request_mask, query_flags);
From: Luis Henriques lhenriques@suse.de
commit c79c5e0178922a9e092ec8fed026750f39dcaef4 upstream.
When accidentally passing twice the same tag to qemu, kmemleak ended up reporting a memory leak in virtiofs. Also, looking at the log I saw the following error (that's when I realised the duplicated tag):
virtiofs: probe of virtio5 failed with error -17
Here's the kmemleak log for reference:
unreferenced object 0xffff888103d47800 (size 1024): comm "systemd-udevd", pid 118, jiffies 4294893780 (age 18.340s) hex dump (first 32 bytes): 00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N.......... ff ff ff ff ff ff ff ff 80 90 02 a0 ff ff ff ff ................ backtrace: [<000000000ebb87c1>] virtio_fs_probe+0x171/0x7ae [virtiofs] [<00000000f8aca419>] virtio_dev_probe+0x15f/0x210 [<000000004d6baf3c>] really_probe+0xea/0x430 [<00000000a6ceeac8>] device_driver_attach+0xa8/0xb0 [<00000000196f47a7>] __driver_attach+0x98/0x140 [<000000000b20601d>] bus_for_each_dev+0x7b/0xc0 [<00000000399c7b7f>] bus_add_driver+0x11b/0x1f0 [<0000000032b09ba7>] driver_register+0x8f/0xe0 [<00000000cdd55998>] 0xffffffffa002c013 [<000000000ea196a2>] do_one_initcall+0x64/0x2e0 [<0000000008f727ce>] do_init_module+0x5c/0x260 [<000000003cdedab6>] __do_sys_finit_module+0xb5/0x120 [<00000000ad2f48c6>] do_syscall_64+0x33/0x40 [<00000000809526b5>] entry_SYSCALL_64_after_hwframe+0x44/0xae
Cc: stable@vger.kernel.org Signed-off-by: Luis Henriques lhenriques@suse.de Fixes: a62a8ef9d97d ("virtio-fs: add virtiofs filesystem") Reviewed-by: Stefan Hajnoczi stefanha@redhat.com Reviewed-by: Vivek Goyal vgoyal@redhat.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/fuse/virtio_fs.c | 1 + 1 file changed, 1 insertion(+)
--- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -896,6 +896,7 @@ static int virtio_fs_probe(struct virtio out_vqs: vdev->config->reset(vdev); virtio_fs_cleanup_vqs(vdev, fs); + kfree(fs->vqs);
out: vdev->priv = NULL;
From: Marco Elver elver@google.com
commit e36299efe7d749976fbdaaf756dee6ef32543c2c upstream.
Commit 56348560d495 ("debugfs: do not attempt to create a new file before the filesystem is initalized") forbids creating new debugfs files until debugfs is fully initialized. This means that KCSAN's debugfs file creation, which happened at the end of __init(), no longer works. And was apparently never supposed to work!
However, there is no reason to create KCSAN's debugfs file so early. This commit therefore moves its creation to a late_initcall() callback.
Cc: "Rafael J. Wysocki" rafael@kernel.org Cc: stable stable@vger.kernel.org Fixes: 56348560d495 ("debugfs: do not attempt to create a new file before the filesystem is initalized") Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Marco Elver elver@google.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/kcsan/core.c | 2 -- kernel/kcsan/debugfs.c | 4 +++- kernel/kcsan/kcsan.h | 5 ----- 3 files changed, 3 insertions(+), 8 deletions(-)
--- a/kernel/kcsan/core.c +++ b/kernel/kcsan/core.c @@ -639,8 +639,6 @@ void __init kcsan_init(void)
BUG_ON(!in_task());
- kcsan_debugfs_init(); - for_each_possible_cpu(cpu) per_cpu(kcsan_rand_state, cpu) = (u32)get_cycles();
--- a/kernel/kcsan/debugfs.c +++ b/kernel/kcsan/debugfs.c @@ -261,7 +261,9 @@ static const struct file_operations debu .release = single_release };
-void __init kcsan_debugfs_init(void) +static void __init kcsan_debugfs_init(void) { debugfs_create_file("kcsan", 0644, NULL, NULL, &debugfs_ops); } + +late_initcall(kcsan_debugfs_init); --- a/kernel/kcsan/kcsan.h +++ b/kernel/kcsan/kcsan.h @@ -31,11 +31,6 @@ void kcsan_save_irqtrace(struct task_str void kcsan_restore_irqtrace(struct task_struct *task);
/* - * Initialize debugfs file. - */ -void kcsan_debugfs_init(void); - -/* * Statistics counters displayed via debugfs; should only be modified in * slow-paths. */
From: Guochun Mao guochun.mao@mediatek.com
commit 3e903315790baf4a966436e7f32e9c97864570ac upstream.
Conside the following case, it just write a big file into flash, when complete writing, delete the file, and then power off promptly. Next time power on, we'll get a replay list like: ... LEB 1105:211344 len 4144 deletion 0 sqnum 428783 key type 1 inode 80 LEB 15:233544 len 160 deletion 1 sqnum 428785 key type 0 inode 80 LEB 1105:215488 len 4144 deletion 0 sqnum 428787 key type 1 inode 80 ... In the replay list, data nodes' deletion are 0, and the inode node's deletion is 1. In current logic, the file's dentry will be removed, but inode and the flash space it occupied will be reserved. User will see that much free space been disappeared.
We only need to check the deletion value of the following inode type node of the replay entry.
Fixes: e58725d51fa8 ("ubifs: Handle re-linking of inodes correctly while recovery") Cc: stable@vger.kernel.org Signed-off-by: Guochun Mao guochun.mao@mediatek.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ubifs/replay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c @@ -223,7 +223,8 @@ static bool inode_still_linked(struct ub */ list_for_each_entry_reverse(r, &c->replay_list, list) { ubifs_assert(c, r->sqnum >= rino->sqnum); - if (key_inum(c, &r->key) == key_inum(c, &rino->key)) + if (key_inum(c, &r->key) == key_inum(c, &rino->key) && + key_type(c, &r->key) == UBIFS_INO_KEY) return r->deletion == 0;
}
From: Eric Biggers ebiggers@google.com
commit 3c0315424f5e3d2a4113c7272367bee1e8e6a174 upstream.
f2fs didn't properly clean up if verity failed to be enabled on a file:
- It left verity metadata (pages past EOF) in the page cache, which would be exposed to userspace if the file was later extended.
- It didn't truncate the verity metadata at all (either from cache or from disk) if an error occurred while setting the verity bit.
Fix these bugs by adding a call to truncate_inode_pages() and ensuring that we truncate the verity metadata (both from cache and from disk) in all error paths. Also rework the code to cleanly separate the success path from the error paths, which makes it much easier to understand.
Finally, log a message if f2fs_truncate() fails, since it might otherwise fail silently.
Reported-by: Yunlei He heyunlei@hihonor.com Fixes: 95ae251fe828 ("f2fs: add fs-verity support") Cc: stable@vger.kernel.org # v5.4+ Signed-off-by: Eric Biggers ebiggers@google.com Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/verity.c | 79 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 23 deletions(-)
--- a/fs/f2fs/verity.c +++ b/fs/f2fs/verity.c @@ -152,40 +152,73 @@ static int f2fs_end_enable_verity(struct size_t desc_size, u64 merkle_tree_size) { struct inode *inode = file_inode(filp); + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); u64 desc_pos = f2fs_verity_metadata_pos(inode) + merkle_tree_size; struct fsverity_descriptor_location dloc = { .version = cpu_to_le32(F2FS_VERIFY_VER), .size = cpu_to_le32(desc_size), .pos = cpu_to_le64(desc_pos), }; - int err = 0; + int err = 0, err2 = 0;
- if (desc != NULL) { - /* Succeeded; write the verity descriptor. */ - err = pagecache_write(inode, desc, desc_size, desc_pos); - - /* Write all pages before clearing FI_VERITY_IN_PROGRESS. */ - if (!err) - err = filemap_write_and_wait(inode->i_mapping); - } - - /* If we failed, truncate anything we wrote past i_size. */ - if (desc == NULL || err) - f2fs_truncate(inode); + /* + * If an error already occurred (which fs/verity/ signals by passing + * desc == NULL), then only clean-up is needed. + */ + if (desc == NULL) + goto cleanup; + + /* Append the verity descriptor. */ + err = pagecache_write(inode, desc, desc_size, desc_pos); + if (err) + goto cleanup; + + /* + * Write all pages (both data and verity metadata). Note that this must + * happen before clearing FI_VERITY_IN_PROGRESS; otherwise pages beyond + * i_size won't be written properly. For crash consistency, this also + * must happen before the verity inode flag gets persisted. + */ + err = filemap_write_and_wait(inode->i_mapping); + if (err) + goto cleanup; + + /* Set the verity xattr. */ + err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_VERITY, + F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc), + NULL, XATTR_CREATE); + if (err) + goto cleanup; + + /* Finally, set the verity inode flag. */ + file_set_verity(inode); + f2fs_set_inode_flags(inode); + f2fs_mark_inode_dirty_sync(inode, true);
clear_inode_flag(inode, FI_VERITY_IN_PROGRESS); + return 0;
- if (desc != NULL && !err) { - err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_VERITY, - F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc), - NULL, XATTR_CREATE); - if (!err) { - file_set_verity(inode); - f2fs_set_inode_flags(inode); - f2fs_mark_inode_dirty_sync(inode, true); - } +cleanup: + /* + * Verity failed to be enabled, so clean up by truncating any verity + * metadata that was written beyond i_size (both from cache and from + * disk) and clearing FI_VERITY_IN_PROGRESS. + * + * Taking i_gc_rwsem[WRITE] is needed to stop f2fs garbage collection + * from re-instantiating cached pages we are truncating (since unlike + * normal file accesses, garbage collection isn't limited by i_size). + */ + down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + truncate_inode_pages(inode->i_mapping, inode->i_size); + err2 = f2fs_truncate(inode); + if (err2) { + f2fs_err(sbi, "Truncating verity metadata failed (errno=%d)", + err2); + set_sbi_flag(sbi, SBI_NEED_FSCK); } - return err; + up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + clear_inode_flag(inode, FI_VERITY_IN_PROGRESS); + return err ?: err2; }
static int f2fs_get_verity_descriptor(struct inode *inode, void *buf,
From: Chao Yu yuchao0@huawei.com
commit b862676e371715456c9dade7990c8004996d0d9e upstream.
butt3rflyh4ck butterflyhuangxx@gmail.com reported a bug found by syzkaller fuzzer with custom modifications in 5.12.0-rc3+ [1]:
dump_stack+0xfa/0x151 lib/dump_stack.c:120 print_address_description.constprop.0.cold+0x82/0x32c mm/kasan/report.c:232 __kasan_report mm/kasan/report.c:399 [inline] kasan_report.cold+0x7c/0xd8 mm/kasan/report.c:416 f2fs_test_bit fs/f2fs/f2fs.h:2572 [inline] current_nat_addr fs/f2fs/node.h:213 [inline] get_next_nat_page fs/f2fs/node.c:123 [inline] __flush_nat_entry_set fs/f2fs/node.c:2888 [inline] f2fs_flush_nat_entries+0x258e/0x2960 fs/f2fs/node.c:2991 f2fs_write_checkpoint+0x1372/0x6a70 fs/f2fs/checkpoint.c:1640 f2fs_issue_checkpoint+0x149/0x410 fs/f2fs/checkpoint.c:1807 f2fs_sync_fs+0x20f/0x420 fs/f2fs/super.c:1454 __sync_filesystem fs/sync.c:39 [inline] sync_filesystem fs/sync.c:67 [inline] sync_filesystem+0x1b5/0x260 fs/sync.c:48 generic_shutdown_super+0x70/0x370 fs/super.c:448 kill_block_super+0x97/0xf0 fs/super.c:1394
The root cause is, if nat entry in checkpoint journal area is corrupted, e.g. nid of journalled nat entry exceeds max nid value, during checkpoint, once it tries to flush nat journal to NAT area, get_next_nat_page() may access out-of-bounds memory on nat_bitmap due to it uses wrong nid value as bitmap offset.
[1] https://lore.kernel.org/lkml/CAFcO6XOMWdr8pObek6eN6-fs58KG9doRFadgJj-FnF-1x4...
Reported-and-tested-by: butt3rflyh4ck butterflyhuangxx@gmail.com Signed-off-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/node.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -2781,6 +2781,9 @@ static void remove_nats_in_journal(struc struct f2fs_nat_entry raw_ne; nid_t nid = le32_to_cpu(nid_in_journal(journal, i));
+ if (f2fs_check_nid_range(sbi, nid)) + continue; + raw_ne = nat_in_journal(journal, i);
ne = __lookup_nat_cache(nm_i, nid);
From: Ido Schimmel idosch@nvidia.com
commit cbaf3f6af9c268caf558c8e7ec52bcb35c5455dd upstream.
Each multicast route that is forwarding packets (as opposed to trapping them) points to a list of egress router interfaces (RIFs) through which packets are replicated.
A route's action can transition from trap to forward when a RIF is created for one of the route's egress virtual interfaces (eVIF). When this happens, the route's action is first updated and only later the list of egress RIFs is committed to the device.
This results in the route pointing to an invalid list. In case the list pointer is out of range (due to uninitialized memory), the device will complain:
mlxsw_spectrum2 0000:06:00.0: EMAD reg access failed (tid=5733bf490000905c,reg_id=300f(pefa),type=write,status=7(bad parameter))
Fix this by first committing the list of egress RIFs to the device and only later update the route's action.
Note that a fix is not needed in the reverse function (i.e., mlxsw_sp_mr_route_evif_unresolve()), as there the route's action is first updated and only later the RIF is removed from the list.
Cc: stable@vger.kernel.org Fixes: c011ec1bbfd6 ("mlxsw: spectrum: Add the multicast routing offloading logic") Signed-off-by: Ido Schimmel idosch@nvidia.com Reviewed-by: Petr Machata petrm@nvidia.com Link: https://lore.kernel.org/r/20210506072308.3834303-1-idosch@idosch.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-)
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c @@ -535,6 +535,16 @@ mlxsw_sp_mr_route_evif_resolve(struct ml u16 erif_index = 0; int err;
+ /* Add the eRIF */ + if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) { + erif_index = mlxsw_sp_rif_index(rve->mr_vif->rif); + err = mr->mr_ops->route_erif_add(mlxsw_sp, + rve->mr_route->route_priv, + erif_index); + if (err) + return err; + } + /* Update the route action, as the new eVIF can be a tunnel or a pimreg * device which will require updating the action. */ @@ -544,17 +554,7 @@ mlxsw_sp_mr_route_evif_resolve(struct ml rve->mr_route->route_priv, route_action); if (err) - return err; - } - - /* Add the eRIF */ - if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) { - erif_index = mlxsw_sp_rif_index(rve->mr_vif->rif); - err = mr->mr_ops->route_erif_add(mlxsw_sp, - rve->mr_route->route_priv, - erif_index); - if (err) - goto err_route_erif_add; + goto err_route_action_update; }
/* Update the minimum MTU */ @@ -572,14 +572,14 @@ mlxsw_sp_mr_route_evif_resolve(struct ml return 0;
err_route_min_mtu_update: - if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) - mr->mr_ops->route_erif_del(mlxsw_sp, rve->mr_route->route_priv, - erif_index); -err_route_erif_add: if (route_action != rve->mr_route->route_action) mr->mr_ops->route_action_update(mlxsw_sp, rve->mr_route->route_priv, rve->mr_route->route_action); +err_route_action_update: + if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) + mr->mr_ops->route_erif_del(mlxsw_sp, rve->mr_route->route_priv, + erif_index); return err; }
From: Davide Caratti dcaratti@redhat.com
commit 7c0ea5930c1c211931819d83cfb157bff1539a4c upstream.
running openvswitch on kernels built with KASAN, it's possible to see the following splat while testing fragmentation of IPv4 packets:
BUG: KASAN: stack-out-of-bounds in ip_do_fragment+0x1b03/0x1f60 Read of size 1 at addr ffff888112fc713c by task handler2/1367
CPU: 0 PID: 1367 Comm: handler2 Not tainted 5.12.0-rc6+ #418 Hardware name: Red Hat KVM, BIOS 1.11.1-4.module+el8.1.0+4066+0f1aadab 04/01/2014 Call Trace: dump_stack+0x92/0xc1 print_address_description.constprop.7+0x1a/0x150 kasan_report.cold.13+0x7f/0x111 ip_do_fragment+0x1b03/0x1f60 ovs_fragment+0x5bf/0x840 [openvswitch] do_execute_actions+0x1bd5/0x2400 [openvswitch] ovs_execute_actions+0xc8/0x3d0 [openvswitch] ovs_packet_cmd_execute+0xa39/0x1150 [openvswitch] genl_family_rcv_msg_doit.isra.15+0x227/0x2d0 genl_rcv_msg+0x287/0x490 netlink_rcv_skb+0x120/0x380 genl_rcv+0x24/0x40 netlink_unicast+0x439/0x630 netlink_sendmsg+0x719/0xbf0 sock_sendmsg+0xe2/0x110 ____sys_sendmsg+0x5ba/0x890 ___sys_sendmsg+0xe9/0x160 __sys_sendmsg+0xd3/0x170 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f957079db07 Code: c3 66 90 41 54 41 89 d4 55 48 89 f5 53 89 fb 48 83 ec 10 e8 eb ec ff ff 44 89 e2 48 89 ee 89 df 41 89 c0 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 35 44 89 c7 48 89 44 24 08 e8 24 ed ff ff 48 RSP: 002b:00007f956ce35a50 EFLAGS: 00000293 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 0000000000000019 RCX: 00007f957079db07 RDX: 0000000000000000 RSI: 00007f956ce35ae0 RDI: 0000000000000019 RBP: 00007f956ce35ae0 R08: 0000000000000000 R09: 00007f9558006730 R10: 0000000000000000 R11: 0000000000000293 R12: 0000000000000000 R13: 00007f956ce37308 R14: 00007f956ce35f80 R15: 00007f956ce35ae0
The buggy address belongs to the page: page:00000000af2a1d93 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x112fc7 flags: 0x17ffffc0000000() raw: 0017ffffc0000000 0000000000000000 dead000000000122 0000000000000000 raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected
addr ffff888112fc713c is located in stack of task handler2/1367 at offset 180 in frame: ovs_fragment+0x0/0x840 [openvswitch]
this frame has 2 objects: [32, 144) 'ovs_dst' [192, 424) 'ovs_rt'
Memory state around the buggy address: ffff888112fc7000: f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff888112fc7080: 00 f1 f1 f1 f1 00 00 00 00 00 00 00 00 00 00 00
ffff888112fc7100: 00 00 00 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00
^ ffff888112fc7180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff888112fc7200: 00 00 00 00 00 00 f2 f2 f2 00 00 00 00 00 00 00
for IPv4 packets, ovs_fragment() uses a temporary struct dst_entry. Then, in the following call graph:
ip_do_fragment() ip_skb_dst_mtu() ip_dst_mtu_maybe_forward() ip_mtu_locked()
the pointer to struct dst_entry is used as pointer to struct rtable: this turns the access to struct members like rt_mtu_locked into an OOB read in the stack. Fix this changing the temporary variable used for IPv4 packets in ovs_fragment(), similarly to what is done for IPv6 few lines below.
Fixes: d52e5a7e7ca4 ("ipv4: lock mtu in fnhe when received PMTU < net.ipv4.route.min_pmt") Cc: stable@vger.kernel.org Acked-by: Eelco Chaudron echaudro@redhat.com Signed-off-by: Davide Caratti dcaratti@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/openvswitch/actions.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -827,17 +827,17 @@ static void ovs_fragment(struct net *net }
if (key->eth.type == htons(ETH_P_IP)) { - struct dst_entry ovs_dst; + struct rtable ovs_rt = { 0 }; unsigned long orig_dst;
prepare_frag(vport, skb, orig_network_offset, ovs_key_mac_proto(key)); - dst_init(&ovs_dst, &ovs_dst_ops, NULL, 1, + dst_init(&ovs_rt.dst, &ovs_dst_ops, NULL, 1, DST_OBSOLETE_NONE, DST_NOCOUNT); - ovs_dst.dev = vport->dev; + ovs_rt.dst.dev = vport->dev;
orig_dst = skb->_skb_refdst; - skb_dst_set_noref(skb, &ovs_dst); + skb_dst_set_noref(skb, &ovs_rt.dst); IPCB(skb)->frag_max_size = mru;
ip_do_fragment(net, skb->sk, skb, ovs_vport_output);
From: Marc Zyngier maz@kernel.org
commit 1ecd5b129252249b9bc03d7645a7bda512747277 upstream.
When failing the driver probe because of invalid firmware properties, the GTDT driver unmaps the interrupt that it mapped earlier.
However, it never checks whether the mapping of the interrupt actially succeeded. Even more, should the firmware report an illegal interrupt number that overlaps with the GIC SGI range, this can result in an IPI being unmapped, and subsequent fireworks (as reported by Dann Frazier).
Rework the driver to have a slightly saner behaviour and actually check whether the interrupt has been mapped before unmapping things.
Reported-by: dann frazier dann.frazier@canonical.com Fixes: ca9ae5ec4ef0 ("acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver") Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/YH87dtTfwYgavusz@xps13.dannf Cc: stable@vger.kernel.org Cc: Fu Wei wefu@redhat.com Reviewed-by: Sudeep Holla sudeep.holla@arm.com Tested-by: dann frazier dann.frazier@canonical.com Tested-by: Hanjun Guo guohanjun@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Reviewed-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Link: https://lore.kernel.org/r/20210421164317.1718831-2-maz@kernel.org Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/acpi/arm64/gtdt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/acpi/arm64/gtdt.c +++ b/drivers/acpi/arm64/gtdt.c @@ -329,7 +329,7 @@ static int __init gtdt_import_sbsa_gwdt( int index) { struct platform_device *pdev; - int irq = map_gt_gsi(wd->timer_interrupt, wd->timer_flags); + int irq;
/* * According to SBSA specification the size of refresh and control @@ -338,7 +338,7 @@ static int __init gtdt_import_sbsa_gwdt( struct resource res[] = { DEFINE_RES_MEM(wd->control_frame_address, SZ_4K), DEFINE_RES_MEM(wd->refresh_frame_address, SZ_4K), - DEFINE_RES_IRQ(irq), + {}, }; int nr_res = ARRAY_SIZE(res);
@@ -348,10 +348,11 @@ static int __init gtdt_import_sbsa_gwdt(
if (!(wd->refresh_frame_address && wd->control_frame_address)) { pr_err(FW_BUG "failed to get the Watchdog base address.\n"); - acpi_unregister_gsi(wd->timer_interrupt); return -EINVAL; }
+ irq = map_gt_gsi(wd->timer_interrupt, wd->timer_flags); + res[2] = (struct resource)DEFINE_RES_IRQ(irq); if (irq <= 0) { pr_warn("failed to map the Watchdog interrupt.\n"); nr_res--; @@ -364,7 +365,8 @@ static int __init gtdt_import_sbsa_gwdt( */ pdev = platform_device_register_simple("sbsa-gwdt", index, res, nr_res); if (IS_ERR(pdev)) { - acpi_unregister_gsi(wd->timer_interrupt); + if (irq > 0) + acpi_unregister_gsi(wd->timer_interrupt); return PTR_ERR(pdev); }
From: Randy Dunlap rdunlap@infradead.org
commit c09f11ef35955785f92369e25819bf0629df2e59 upstream.
Fix shift out-of-bounds in xprt_calc_majortimeo(). This is caused by a garbage timeout (retrans) mount option being passed to nfs mount, in this case from syzkaller.
If the protocol is XPRT_TRANSPORT_UDP, then 'retrans' is a shift value for a 64-bit long integer, so 'retrans' cannot be >= 64. If it is >= 64, fail the mount and return an error.
Fixes: 9954bf92c0cd ("NFS: Move mount parameterisation bits into their own file") Reported-by: syzbot+ba2e91df8f74809417fa@syzkaller.appspotmail.com Reported-by: syzbot+f3a0fa110fd630ab56c8@syzkaller.appspotmail.com Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Trond Myklebust trond.myklebust@hammerspace.com Cc: Anna Schumaker anna.schumaker@netapp.com Cc: linux-nfs@vger.kernel.org Cc: David Howells dhowells@redhat.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: stable@vger.kernel.org Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/nfs/fs_context.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
--- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -938,6 +938,15 @@ static int nfs23_parse_monolithic(struct sizeof(mntfh->data) - mntfh->size);
/* + * for proto == XPRT_TRANSPORT_UDP, which is what uses + * to_exponential, implying shift: limit the shift value + * to BITS_PER_LONG (majortimeo is unsigned long) + */ + if (!(data->flags & NFS_MOUNT_TCP)) /* this will be UDP */ + if (data->retrans >= 64) /* shift value is too large */ + goto out_invalid_data; + + /* * Translate to nfs_fs_context, which nfs_fill_super * can deal with. */ @@ -1037,6 +1046,9 @@ out_no_address:
out_invalid_fh: return nfs_invalf(fc, "NFS: invalid root filehandle"); + +out_invalid_data: + return nfs_invalf(fc, "NFS: invalid binary mount data"); }
#if IS_ENABLED(CONFIG_NFS_V4)
From: Trond Myklebust trond.myklebust@hammerspace.com
commit 39fd01863616964f009599e50ca5c6ea9ebf88d6 upstream.
If the pNFS layout segment is marked with the NFS_LSEG_LAYOUTRETURN flag, then the assumption is that it has some reporting requirement to perform through a layoutreturn (e.g. flexfiles layout stats or error information).
Fixes: e0b7d420f72a ("pNFS: Don't discard layout segments that are marked for return") Cc: stable@vger.kernel.org Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/nfs/pnfs.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -2470,6 +2470,9 @@ pnfs_mark_matching_lsegs_return(struct p
assert_spin_locked(&lo->plh_inode->i_lock);
+ if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) + tmp_list = &lo->plh_return_segs; + list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) if (pnfs_match_lseg_recall(lseg, return_range, seq)) { dprintk("%s: marking lseg %p iomode %d " @@ -2477,6 +2480,8 @@ pnfs_mark_matching_lsegs_return(struct p lseg, lseg->pls_range.iomode, lseg->pls_range.offset, lseg->pls_range.length); + if (test_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags)) + tmp_list = &lo->plh_return_segs; if (mark_lseg_invalid(lseg, tmp_list)) continue; remaining++;
From: Trond Myklebust trond.myklebust@hammerspace.com
commit de144ff4234f935bd2150108019b5d87a90a8a96 upstream.
If the pNFS layout segment is marked with the NFS_LSEG_LAYOUTRETURN flag, then the assumption is that it has some reporting requirement to perform through a layoutreturn (e.g. flexfiles layout stats or error information).
Fixes: 6d597e175012 ("pnfs: only tear down lsegs that precede seqid in LAYOUTRETURN args") Cc: stable@vger.kernel.org Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/nfs/pnfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1344,7 +1344,7 @@ _pnfs_return_layout(struct inode *ino) } valid_layout = pnfs_layout_is_valid(lo); pnfs_clear_layoutcommit(ino, &tmp_list); - pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL, 0); + pnfs_mark_matching_lsegs_return(lo, &tmp_list, NULL, 0);
if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) { struct pnfs_layout_range range = {
From: Hansem Ro hansemro@outlook.com
commit ac05a8a927e5a1027592d8f98510a511dadeed14 upstream.
This adds the negation needed for proper finger detection on Ilitek ili2107/ili210x. This fixes polling issues (on Amazon Kindle Fire) caused by returning false for the cooresponding finger on the touchscreen.
Signed-off-by: Hansem Ro hansemro@outlook.com Fixes: e3559442afd2a ("ili210x - rework the touchscreen sample processing") Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/input/touchscreen/ili210x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -87,7 +87,7 @@ static bool ili210x_touchdata_to_coords( unsigned int *x, unsigned int *y, unsigned int *z) { - if (touchdata[0] & BIT(finger)) + if (!(touchdata[0] & BIT(finger))) return false;
*x = get_unaligned_be16(touchdata + 1 + (finger * 4) + 0);
From: lizhe lizhe67@huawei.com
commit 960b9a8a7676b9054d8b46a2c7db52a0c8766b56 upstream.
KASAN report a slab-out-of-bounds problem. The logs are listed below. It is because in function jffs2_scan_dirent_node, we alloc "checkedlen+1" bytes for fd->name and we check crc with length rd->nsize. If checkedlen is less than rd->nsize, it will cause the slab-out-of-bounds problem.
jffs2: Dirent at *** has zeroes in name. Truncating to %d char ================================================================== BUG: KASAN: slab-out-of-bounds in crc32_le+0x1ce/0x260 at addr ffff8800842cf2d1 Read of size 1 by task test_JFFS2/915 ============================================================================= BUG kmalloc-64 (Tainted: G B O ): kasan: bad access detected ----------------------------------------------------------------------------- INFO: Allocated in jffs2_alloc_full_dirent+0x2a/0x40 age=0 cpu=1 pid=915 ___slab_alloc+0x580/0x5f0 __slab_alloc.isra.24+0x4e/0x64 __kmalloc+0x170/0x300 jffs2_alloc_full_dirent+0x2a/0x40 jffs2_scan_eraseblock+0x1ca4/0x3b64 jffs2_scan_medium+0x285/0xfe0 jffs2_do_mount_fs+0x5fb/0x1bbc jffs2_do_fill_super+0x245/0x6f0 jffs2_fill_super+0x287/0x2e0 mount_mtd_aux.isra.0+0x9a/0x144 mount_mtd+0x222/0x2f0 jffs2_mount+0x41/0x60 mount_fs+0x63/0x230 vfs_kern_mount.part.6+0x6c/0x1f4 do_mount+0xae8/0x1940 SyS_mount+0x105/0x1d0 INFO: Freed in jffs2_free_full_dirent+0x22/0x40 age=27 cpu=1 pid=915 __slab_free+0x372/0x4e4 kfree+0x1d4/0x20c jffs2_free_full_dirent+0x22/0x40 jffs2_build_remove_unlinked_inode+0x17a/0x1e4 jffs2_do_mount_fs+0x1646/0x1bbc jffs2_do_fill_super+0x245/0x6f0 jffs2_fill_super+0x287/0x2e0 mount_mtd_aux.isra.0+0x9a/0x144 mount_mtd+0x222/0x2f0 jffs2_mount+0x41/0x60 mount_fs+0x63/0x230 vfs_kern_mount.part.6+0x6c/0x1f4 do_mount+0xae8/0x1940 SyS_mount+0x105/0x1d0 entry_SYSCALL_64_fastpath+0x1e/0x97 Call Trace: [<ffffffff815befef>] dump_stack+0x59/0x7e [<ffffffff812d1d65>] print_trailer+0x125/0x1b0 [<ffffffff812d82c8>] object_err+0x34/0x40 [<ffffffff812dadef>] kasan_report.part.1+0x21f/0x534 [<ffffffff81132401>] ? vprintk+0x2d/0x40 [<ffffffff815f1ee2>] ? crc32_le+0x1ce/0x260 [<ffffffff812db41a>] kasan_report+0x26/0x30 [<ffffffff812d9fc1>] __asan_load1+0x3d/0x50 [<ffffffff815f1ee2>] crc32_le+0x1ce/0x260 [<ffffffff814764ae>] ? jffs2_alloc_full_dirent+0x2a/0x40 [<ffffffff81485cec>] jffs2_scan_eraseblock+0x1d0c/0x3b64 [<ffffffff81488813>] ? jffs2_scan_medium+0xccf/0xfe0 [<ffffffff81483fe0>] ? jffs2_scan_make_ino_cache+0x14c/0x14c [<ffffffff812da3e9>] ? kasan_unpoison_shadow+0x35/0x50 [<ffffffff812da3e9>] ? kasan_unpoison_shadow+0x35/0x50 [<ffffffff812da462>] ? kasan_kmalloc+0x5e/0x70 [<ffffffff812d5d90>] ? kmem_cache_alloc_trace+0x10c/0x2cc [<ffffffff818169fb>] ? mtd_point+0xf7/0x130 [<ffffffff81487dc9>] jffs2_scan_medium+0x285/0xfe0 [<ffffffff81487b44>] ? jffs2_scan_eraseblock+0x3b64/0x3b64 [<ffffffff812da3e9>] ? kasan_unpoison_shadow+0x35/0x50 [<ffffffff812da3e9>] ? kasan_unpoison_shadow+0x35/0x50 [<ffffffff812da462>] ? kasan_kmalloc+0x5e/0x70 [<ffffffff812d57df>] ? __kmalloc+0x12b/0x300 [<ffffffff812da462>] ? kasan_kmalloc+0x5e/0x70 [<ffffffff814a2753>] ? jffs2_sum_init+0x9f/0x240 [<ffffffff8148b2ff>] jffs2_do_mount_fs+0x5fb/0x1bbc [<ffffffff8148ad04>] ? jffs2_del_noinode_dirent+0x640/0x640 [<ffffffff812da462>] ? kasan_kmalloc+0x5e/0x70 [<ffffffff81127c5b>] ? __init_rwsem+0x97/0xac [<ffffffff81492349>] jffs2_do_fill_super+0x245/0x6f0 [<ffffffff81493c5b>] jffs2_fill_super+0x287/0x2e0 [<ffffffff814939d4>] ? jffs2_parse_options+0x594/0x594 [<ffffffff81819bea>] mount_mtd_aux.isra.0+0x9a/0x144 [<ffffffff81819eb6>] mount_mtd+0x222/0x2f0 [<ffffffff814939d4>] ? jffs2_parse_options+0x594/0x594 [<ffffffff81819c94>] ? mount_mtd_aux.isra.0+0x144/0x144 [<ffffffff81258757>] ? free_pages+0x13/0x1c [<ffffffff814fa0ac>] ? selinux_sb_copy_data+0x278/0x2e0 [<ffffffff81492b35>] jffs2_mount+0x41/0x60 [<ffffffff81302fb7>] mount_fs+0x63/0x230 [<ffffffff8133755f>] ? alloc_vfsmnt+0x32f/0x3b0 [<ffffffff81337f2c>] vfs_kern_mount.part.6+0x6c/0x1f4 [<ffffffff8133ceec>] do_mount+0xae8/0x1940 [<ffffffff811b94e0>] ? audit_filter_rules.constprop.6+0x1d10/0x1d10 [<ffffffff8133c404>] ? copy_mount_string+0x40/0x40 [<ffffffff812cbf78>] ? alloc_pages_current+0xa4/0x1bc [<ffffffff81253a89>] ? __get_free_pages+0x25/0x50 [<ffffffff81338993>] ? copy_mount_options.part.17+0x183/0x264 [<ffffffff8133e3a9>] SyS_mount+0x105/0x1d0 [<ffffffff8133e2a4>] ? copy_mnt_ns+0x560/0x560 [<ffffffff810e8391>] ? msa_space_switch_handler+0x13d/0x190 [<ffffffff81be184a>] entry_SYSCALL_64_fastpath+0x1e/0x97 [<ffffffff810e9274>] ? msa_space_switch+0xb0/0xe0 Memory state around the buggy address: ffff8800842cf180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff8800842cf200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff8800842cf280: fc fc fc fc fc fc 00 00 00 00 01 fc fc fc fc fc
^ ffff8800842cf300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff8800842cf380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ==================================================================
Cc: stable@vger.kernel.org Reported-by: Kunkun Xu xukunkun1@huawei.com Signed-off-by: lizhe lizhe67@huawei.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/jffs2/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c @@ -1079,7 +1079,7 @@ static int jffs2_scan_dirent_node(struct memcpy(&fd->name, rd->name, checkedlen); fd->name[checkedlen] = 0;
- crc = crc32(0, fd->name, rd->nsize); + crc = crc32(0, fd->name, checkedlen); if (crc != je32_to_cpu(rd->name_crc)) { pr_notice("%s(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", __func__, ofs, je32_to_cpu(rd->name_crc), crc);
From: Joel Stanley joel@jms.id.au
commit 42984af09afc414d540fcc8247f42894b0378a91 upstream.
overlayfs using jffs2 as the upper filesystem would fail in some cases since moving to v5.10. The test case used was to run 'touch' on a file that exists in the lower fs, causing the modification time to be updated. It returns EINVAL when the bug is triggered.
A bisection showed this was introduced in v5.9-rc1, with commit 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops"). Reverting that commit restores the expected behaviour.
Some digging showed that this was due to jffs2 lacking an implementation of splice_write. (For unknown reasons the warn_unsupported that should trigger was not displaying any output).
Adding this patch resolved the issue and the test now passes.
Cc: stable@vger.kernel.org Fixes: 36e2c7421f02 ("fs: don't allow splice read/write without explicit ops") Signed-off-by: Joel Stanley joel@jms.id.au Reviewed-by: Christoph Hellwig hch@lst.de Tested-by: Lei YU yulei.sh@bytedance.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/jffs2/file.c | 1 + 1 file changed, 1 insertion(+)
--- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -57,6 +57,7 @@ const struct file_operations jffs2_file_ .mmap = generic_file_readonly_mmap, .fsync = jffs2_fsync, .splice_read = generic_file_splice_read, + .splice_write = iter_file_splice_write, };
/* jffs2_file_inode_operations */
From: Nicholas Piggin npiggin@gmail.com
commit 49c1d07fd04f54eb588c4a1dfcedc8d22c5ffd50 upstream.
Starting with ISA v3.1, LPCR[AIL] no longer controls the interrupt mode for HV=1 interrupts. Instead, a new LPCR[HAIL] bit is defined which behaves like AIL=3 for HV interrupts when set.
Set HAIL on bare metal to give us mmu-on interrupts and improve performance.
This also fixes an scv bug: we don't implement scv real mode (AIL=0) vectors because they are at an inconvenient location, so we just disable scv support when AIL can not be set. However powernv assumes that LPCR[AIL] will enable AIL mode so it enables scv support despite HV interrupts being AIL=0, which causes scv interrupts to go off into the weeds.
Fixes: 7fa95f9adaee ("powerpc/64s: system call support for scv/rfscv instructions") Cc: stable@vger.kernel.org # v5.9+ Signed-off-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210402024124.545826-1-npiggin@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/include/asm/reg.h | 1 + arch/powerpc/kernel/setup_64.c | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-)
--- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -444,6 +444,7 @@ #define LPCR_VRMA_LP1 ASM_CONST(0x0000800000000000) #define LPCR_RMLS 0x1C000000 /* Implementation dependent RMO limit sel */ #define LPCR_RMLS_SH 26 +#define LPCR_HAIL ASM_CONST(0x0000000004000000) /* HV AIL (ISAv3.1) */ #define LPCR_ILE ASM_CONST(0x0000000002000000) /* !HV irqs set MSR:LE */ #define LPCR_AIL ASM_CONST(0x0000000001800000) /* Alternate interrupt location */ #define LPCR_AIL_0 ASM_CONST(0x0000000000000000) /* MMU off exception offset 0x0 */ --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -231,10 +231,23 @@ static void cpu_ready_for_interrupts(voi * If we are not in hypervisor mode the job is done once for * the whole partition in configure_exceptions(). */ - if (cpu_has_feature(CPU_FTR_HVMODE) && - cpu_has_feature(CPU_FTR_ARCH_207S)) { + if (cpu_has_feature(CPU_FTR_HVMODE)) { unsigned long lpcr = mfspr(SPRN_LPCR); - mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); + unsigned long new_lpcr = lpcr; + + if (cpu_has_feature(CPU_FTR_ARCH_31)) { + /* P10 DD1 does not have HAIL */ + if (pvr_version_is(PVR_POWER10) && + (mfspr(SPRN_PVR) & 0xf00) == 0x100) + new_lpcr |= LPCR_AIL_3; + else + new_lpcr |= LPCR_HAIL; + } else if (cpu_has_feature(CPU_FTR_ARCH_207S)) { + new_lpcr |= LPCR_AIL_3; + } + + if (new_lpcr != lpcr) + mtspr(SPRN_LPCR, new_lpcr); }
/*
From: Mahesh Salgaonkar mahesh@linux.ibm.com
commit 5ae5bc12d0728db60a0aa9b62160ffc038875f1a upstream.
During the EEH MMIO error checking, the current implementation fails to map the (virtual) MMIO address back to the pci device on radix with hugepage mappings for I/O. This results into failure to dispatch EEH event with no recovery even when EEH capability has been enabled on the device.
eeh_check_failure(token) # token = virtual MMIO address addr = eeh_token_to_phys(token); edev = eeh_addr_cache_get_dev(addr); if (!edev) return 0; eeh_dev_check_failure(edev); <= Dispatch the EEH event
In case of hugepage mappings, eeh_token_to_phys() has a bug in virt -> phys translation that results in wrong physical address, which is then passed to eeh_addr_cache_get_dev() to match it against cached pci I/O address ranges to get to a PCI device. Hence, it fails to find a match and the EEH event never gets dispatched leaving the device in failed state.
The commit 33439620680be ("powerpc/eeh: Handle hugepages in ioremap space") introduced following logic to translate virt to phys for hugepage mappings:
eeh_token_to_phys(): + pa = pte_pfn(*ptep); + + /* On radix we can do hugepage mappings for io, so handle that */ + if (hugepage_shift) { + pa <<= hugepage_shift; <= This is wrong + pa |= token & ((1ul << hugepage_shift) - 1); + }
This patch fixes the virt -> phys translation in eeh_token_to_phys() function.
$ cat /sys/kernel/debug/powerpc/eeh_address_cache mem addr range [0x0000040080000000-0x00000400807fffff]: 0030:01:00.1 mem addr range [0x0000040080800000-0x0000040080ffffff]: 0030:01:00.1 mem addr range [0x0000040081000000-0x00000400817fffff]: 0030:01:00.0 mem addr range [0x0000040081800000-0x0000040081ffffff]: 0030:01:00.0 mem addr range [0x0000040082000000-0x000004008207ffff]: 0030:01:00.1 mem addr range [0x0000040082080000-0x00000400820fffff]: 0030:01:00.0 mem addr range [0x0000040082100000-0x000004008210ffff]: 0030:01:00.1 mem addr range [0x0000040082110000-0x000004008211ffff]: 0030:01:00.0
Above is the list of cached io address ranges of pci 0030:01:00.<fn>.
Before this patch:
Tracing 'arg1' of function eeh_addr_cache_get_dev() during error injection clearly shows that 'addr=' contains wrong physical address:
kworker/u16:0-7 [001] .... 108.883775: eeh_addr_cache_get_dev: (eeh_addr_cache_get_dev+0xc/0xf0) addr=0x80103000a510
dmesg shows no EEH recovery messages:
[ 108.563768] bnx2x: [bnx2x_timer:5801(eth2)]MFW seems hanged: drv_pulse (0x9ae) != mcp_pulse (0x7fff) [ 108.563788] bnx2x: [bnx2x_hw_stats_update:870(eth2)]NIG timer max (4294967295) [ 108.883788] bnx2x: [bnx2x_acquire_hw_lock:2013(eth1)]lock_status 0xffffffff resource_bit 0x1 [ 108.884407] bnx2x 0030:01:00.0 eth1: MDC/MDIO access timeout [ 108.884976] bnx2x 0030:01:00.0 eth1: MDC/MDIO access timeout <..>
After this patch:
eeh_addr_cache_get_dev() trace shows correct physical address:
<idle>-0 [001] ..s. 1043.123828: eeh_addr_cache_get_dev: (eeh_addr_cache_get_dev+0xc/0xf0) addr=0x40080bc7cd8
dmesg logs shows EEH recovery getting triggerred:
[ 964.323980] bnx2x: [bnx2x_timer:5801(eth2)]MFW seems hanged: drv_pulse (0x746f) != mcp_pulse (0x7fff) [ 964.323991] EEH: Recovering PHB#30-PE#10000 [ 964.324002] EEH: PE location: N/A, PHB location: N/A [ 964.324006] EEH: Frozen PHB#30-PE#10000 detected <..>
Fixes: 33439620680b ("powerpc/eeh: Handle hugepages in ioremap space") Cc: stable@vger.kernel.org # v5.3+ Reported-by: Dominic DeMarco ddemarc@us.ibm.com Signed-off-by: Mahesh Salgaonkar mahesh@linux.ibm.com Signed-off-by: Aneesh Kumar K.V aneesh.kumar@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/161821396263.48361.2796709239866588652.stgit@jupit... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kernel/eeh.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
--- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -362,14 +362,11 @@ static inline unsigned long eeh_token_to pa = pte_pfn(*ptep);
/* On radix we can do hugepage mappings for io, so handle that */ - if (hugepage_shift) { - pa <<= hugepage_shift; - pa |= token & ((1ul << hugepage_shift) - 1); - } else { - pa <<= PAGE_SHIFT; - pa |= token & (PAGE_SIZE - 1); - } + if (!hugepage_shift) + hugepage_shift = PAGE_SHIFT;
+ pa <<= PAGE_SHIFT; + pa |= token & ((1ul << hugepage_shift) - 1); return pa; }
From: Sourabh Jain sourabhjain@linux.ibm.com
commit 40c753993e3aad51a12c21233486e2037417a4d6 upstream.
kexec_file_load() uses initial_boot_params in setting up the device tree for the kernel to be loaded. Though initial_boot_params holds info about CPUs at the time of boot, it doesn't account for hot added CPUs.
So, kexec'ing with kexec_file_load() syscall leaves the kexec'ed kernel with inaccurate CPU info.
If kdump kernel is loaded with kexec_file_load() syscall and the system crashes on a hot added CPU, the capture kernel hangs failing to identify the boot CPU, with no output.
To avoid this from happening, extract current CPU info from of_root device node and use it for setting up the fdt in kexec_file_load case.
Fixes: 6ecd0163d360 ("powerpc/kexec_file: Add appropriate regions for memory reserve map") Cc: stable@vger.kernel.org # v5.9+ Signed-off-by: Sourabh Jain sourabhjain@linux.ibm.com Reviewed-by: Hari Bathini hbathini@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210429060256.199714-1-sourabhjain@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kexec/file_load_64.c | 92 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+)
--- a/arch/powerpc/kexec/file_load_64.c +++ b/arch/powerpc/kexec/file_load_64.c @@ -961,6 +961,93 @@ unsigned int kexec_fdt_totalsize_ppc64(s }
/** + * add_node_props - Reads node properties from device node structure and add + * them to fdt. + * @fdt: Flattened device tree of the kernel + * @node_offset: offset of the node to add a property at + * @dn: device node pointer + * + * Returns 0 on success, negative errno on error. + */ +static int add_node_props(void *fdt, int node_offset, const struct device_node *dn) +{ + int ret = 0; + struct property *pp; + + if (!dn) + return -EINVAL; + + for_each_property_of_node(dn, pp) { + ret = fdt_setprop(fdt, node_offset, pp->name, pp->value, pp->length); + if (ret < 0) { + pr_err("Unable to add %s property: %s\n", pp->name, fdt_strerror(ret)); + return ret; + } + } + return ret; +} + +/** + * update_cpus_node - Update cpus node of flattened device tree using of_root + * device node. + * @fdt: Flattened device tree of the kernel. + * + * Returns 0 on success, negative errno on error. + */ +static int update_cpus_node(void *fdt) +{ + struct device_node *cpus_node, *dn; + int cpus_offset, cpus_subnode_offset, ret = 0; + + cpus_offset = fdt_path_offset(fdt, "/cpus"); + if (cpus_offset < 0 && cpus_offset != -FDT_ERR_NOTFOUND) { + pr_err("Malformed device tree: error reading /cpus node: %s\n", + fdt_strerror(cpus_offset)); + return cpus_offset; + } + + if (cpus_offset > 0) { + ret = fdt_del_node(fdt, cpus_offset); + if (ret < 0) { + pr_err("Error deleting /cpus node: %s\n", fdt_strerror(ret)); + return -EINVAL; + } + } + + /* Add cpus node to fdt */ + cpus_offset = fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "cpus"); + if (cpus_offset < 0) { + pr_err("Error creating /cpus node: %s\n", fdt_strerror(cpus_offset)); + return -EINVAL; + } + + /* Add cpus node properties */ + cpus_node = of_find_node_by_path("/cpus"); + ret = add_node_props(fdt, cpus_offset, cpus_node); + of_node_put(cpus_node); + if (ret < 0) + return ret; + + /* Loop through all subnodes of cpus and add them to fdt */ + for_each_node_by_type(dn, "cpu") { + cpus_subnode_offset = fdt_add_subnode(fdt, cpus_offset, dn->full_name); + if (cpus_subnode_offset < 0) { + pr_err("Unable to add %s subnode: %s\n", dn->full_name, + fdt_strerror(cpus_subnode_offset)); + ret = cpus_subnode_offset; + goto out; + } + + ret = add_node_props(fdt, cpus_subnode_offset, dn); + if (ret < 0) + goto out; + } +out: + of_node_put(dn); + return ret; +} + +/** * setup_new_fdt_ppc64 - Update the flattend device-tree of the kernel * being loaded. * @image: kexec image being loaded. @@ -1020,6 +1107,11 @@ int setup_new_fdt_ppc64(const struct kim } }
+ /* Update cpus nodes information to account hotplug CPUs. */ + ret = update_cpus_node(fdt); + if (ret < 0) + goto out; + /* Update memory reserve map */ ret = get_reserved_memory_ranges(&rmem); if (ret)
From: Christophe Leroy christophe.leroy@csgroup.eu
commit f5668260b872e89b8d3942a8b7d4278aa9c2c981 upstream.
Commit 7c95d8893fb5 ("powerpc: Change calling convention for create_branch() et. al.") complexified the frame of function do_feature_fixups(), leading to GCC setting up a stack guard when CONFIG_STACKPROTECTOR is selected.
The problem is that do_feature_fixups() is called very early while 'current' in r2 is not set up yet and the code is still not at the final address used at link time.
So, like other instrumentation, stack protection needs to be deactivated for feature-fixups.c and code-patching.c
Fixes: 7c95d8893fb5 ("powerpc: Change calling convention for create_branch() et. al.") Cc: stable@vger.kernel.org # v5.8+ Reported-by: Jonathan Neuschaefer j.neuschaefer@gmx.net Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Tested-by: Jonathan Neuschaefer j.neuschaefer@gmx.net Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/b688fe82927b330349d9e44553363fa451ea4d95.161971511... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/lib/Makefile | 3 +++ 1 file changed, 3 insertions(+)
--- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -5,6 +5,9 @@
ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
+CFLAGS_code-patching.o += -fno-stack-protector +CFLAGS_feature-fixups.o += -fno-stack-protector + CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_feature-fixups.o = $(CC_FLAGS_FTRACE)
From: Tony Ambardar tony.ambardar@gmail.com
commit 7de21e679e6a789f3729e8402bc440b623a28eae upstream.
A few archs like powerpc have different errno.h values for macros EDEADLOCK and EDEADLK. In code including both libc and linux versions of errno.h, this can result in multiple definitions of EDEADLOCK in the include chain. Definitions to the same value (e.g. seen with mips) do not raise warnings, but on powerpc there are redefinitions changing the value, which raise warnings and errors (if using "-Werror").
Guard against these redefinitions to avoid build errors like the following, first seen cross-compiling libbpf v5.8.9 for powerpc using GCC 8.4.0 with musl 1.1.24:
In file included from ../../arch/powerpc/include/uapi/asm/errno.h:5, from ../../include/linux/err.h:8, from libbpf.c:29: ../../include/uapi/asm-generic/errno.h:40: error: "EDEADLOCK" redefined [-Werror] #define EDEADLOCK EDEADLK
In file included from toolchain-powerpc_8540_gcc-8.4.0_musl/include/errno.h:10, from libbpf.c:26: toolchain-powerpc_8540_gcc-8.4.0_musl/include/bits/errno.h:58: note: this is the location of the previous definition #define EDEADLOCK 58
cc1: all warnings being treated as errors
Cc: Stable stable@vger.kernel.org Reported-by: Rosen Penev rosenp@gmail.com Signed-off-by: Tony Ambardar Tony.Ambardar@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20200917135437.1238787-1-Tony.Ambardar@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/include/uapi/asm/errno.h | 1 + 1 file changed, 1 insertion(+)
--- a/arch/powerpc/include/uapi/asm/errno.h +++ b/arch/powerpc/include/uapi/asm/errno.h @@ -2,6 +2,7 @@ #ifndef _ASM_POWERPC_ERRNO_H #define _ASM_POWERPC_ERRNO_H
+#undef EDEADLOCK #include <asm-generic/errno.h>
#undef EDEADLOCK
From: Alexander Shishkin alexander.shishkin@linux.intel.com
commit 48cb17531b15967d9d3f34c770a25cc6c4ca6ad1 upstream.
This adds support for the Trace Hub in Alder Lake-M PCH.
Signed-off-by: Alexander Shishkin alexander.shishkin@linux.intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: stable@vger.kernel.org # v4.14+ Link: https://lore.kernel.org/r/20210414171251.14672-8-alexander.shishkin@linux.in... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -274,6 +274,11 @@ static const struct pci_device_id intel_ .driver_data = (kernel_ulong_t)&intel_th_2x, }, { + /* Alder Lake-M */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x54a6), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { /* Alder Lake CPU */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f), .driver_data = (kernel_ulong_t)&intel_th_2x,
From: Stefan Berger stefanb@linux.ibm.com
commit 48cff270b037022e37835d93361646205ca25101 upstream.
When tpm_read_log_efi is called multiple times, which happens when one loads and unloads a TPM2 driver multiple times, then the global variable efi_tpm_final_log_size will at some point become a negative number due to the subtraction of final_events_preboot_size occurring each time. Use a local variable to avoid this integer underflow.
The following issue is now resolved:
Mar 8 15:35:12 hibinst kernel: Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 Mar 8 15:35:12 hibinst kernel: Workqueue: tpm-vtpm vtpm_proxy_work [tpm_vtpm_proxy] Mar 8 15:35:12 hibinst kernel: RIP: 0010:__memcpy+0x12/0x20 Mar 8 15:35:12 hibinst kernel: Code: 00 b8 01 00 00 00 85 d2 74 0a c7 05 44 7b ef 00 0f 00 00 00 c3 cc cc cc 66 66 90 66 90 48 89 f8 48 89 d1 48 c1 e9 03 83 e2 07 <f3> 48 a5 89 d1 f3 a4 c3 66 0f 1f 44 00 00 48 89 f8 48 89 d1 f3 a4 Mar 8 15:35:12 hibinst kernel: RSP: 0018:ffff9ac4c0fcfde0 EFLAGS: 00010206 Mar 8 15:35:12 hibinst kernel: RAX: ffff88f878cefed5 RBX: ffff88f878ce9000 RCX: 1ffffffffffffe0f Mar 8 15:35:12 hibinst kernel: RDX: 0000000000000003 RSI: ffff9ac4c003bff9 RDI: ffff88f878cf0e4d Mar 8 15:35:12 hibinst kernel: RBP: ffff9ac4c003b000 R08: 0000000000001000 R09: 000000007e9d6073 Mar 8 15:35:12 hibinst kernel: R10: ffff9ac4c003b000 R11: ffff88f879ad3500 R12: 0000000000000ed5 Mar 8 15:35:12 hibinst kernel: R13: ffff88f878ce9760 R14: 0000000000000002 R15: ffff88f77de7f018 Mar 8 15:35:12 hibinst kernel: FS: 0000000000000000(0000) GS:ffff88f87bd00000(0000) knlGS:0000000000000000 Mar 8 15:35:12 hibinst kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 Mar 8 15:35:12 hibinst kernel: CR2: ffff9ac4c003c000 CR3: 00000001785a6004 CR4: 0000000000060ee0 Mar 8 15:35:12 hibinst kernel: Call Trace: Mar 8 15:35:12 hibinst kernel: tpm_read_log_efi+0x152/0x1a7 Mar 8 15:35:12 hibinst kernel: tpm_bios_log_setup+0xc8/0x1c0 Mar 8 15:35:12 hibinst kernel: tpm_chip_register+0x8f/0x260 Mar 8 15:35:12 hibinst kernel: vtpm_proxy_work+0x16/0x60 [tpm_vtpm_proxy] Mar 8 15:35:12 hibinst kernel: process_one_work+0x1b4/0x370 Mar 8 15:35:12 hibinst kernel: worker_thread+0x53/0x3e0 Mar 8 15:35:12 hibinst kernel: ? process_one_work+0x370/0x370
Cc: stable@vger.kernel.org Fixes: 166a2809d65b ("tpm: Don't duplicate events from the final event log in the TCG2 log") Signed-off-by: Stefan Berger stefanb@linux.ibm.com Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/tpm/eventlog/efi.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
--- a/drivers/char/tpm/eventlog/efi.c +++ b/drivers/char/tpm/eventlog/efi.c @@ -17,6 +17,7 @@ int tpm_read_log_efi(struct tpm_chip *ch {
struct efi_tcg2_final_events_table *final_tbl = NULL; + int final_events_log_size = efi_tpm_final_log_size; struct linux_efi_tpm_eventlog *log_tbl; struct tpm_bios_log *log; u32 log_size; @@ -66,12 +67,12 @@ int tpm_read_log_efi(struct tpm_chip *ch ret = tpm_log_version;
if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR || - efi_tpm_final_log_size == 0 || + final_events_log_size == 0 || tpm_log_version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) goto out;
final_tbl = memremap(efi.tpm_final_log, - sizeof(*final_tbl) + efi_tpm_final_log_size, + sizeof(*final_tbl) + final_events_log_size, MEMREMAP_WB); if (!final_tbl) { pr_err("Could not map UEFI TPM final log\n"); @@ -80,10 +81,18 @@ int tpm_read_log_efi(struct tpm_chip *ch goto out; }
- efi_tpm_final_log_size -= log_tbl->final_events_preboot_size; + /* + * The 'final events log' size excludes the 'final events preboot log' + * at its beginning. + */ + final_events_log_size -= log_tbl->final_events_preboot_size;
+ /* + * Allocate memory for the 'combined log' where we will append the + * 'final events log' to. + */ tmp = krealloc(log->bios_event_log, - log_size + efi_tpm_final_log_size, + log_size + final_events_log_size, GFP_KERNEL); if (!tmp) { kfree(log->bios_event_log); @@ -94,15 +103,19 @@ int tpm_read_log_efi(struct tpm_chip *ch log->bios_event_log = tmp;
/* - * Copy any of the final events log that didn't also end up in the - * main log. Events can be logged in both if events are generated + * Append any of the 'final events log' that didn't also end up in the + * 'main log'. Events can be logged in both if events are generated * between GetEventLog() and ExitBootServices(). */ memcpy((void *)log->bios_event_log + log_size, final_tbl->events + log_tbl->final_events_preboot_size, - efi_tpm_final_log_size); + final_events_log_size); + /* + * The size of the 'combined log' is the size of the 'main log' plus + * the size of the 'final events log'. + */ log->bios_event_log_end = log->bios_event_log + - log_size + efi_tpm_final_log_size; + log_size + final_events_log_size;
out: memunmap(final_tbl);
From: Stefan Berger stefanb@linux.ibm.com
commit 9716ac65efc8f780549b03bddf41e60c445d4709 upstream.
Avoid allocating memory and reading the host log when a virtual device is used since this log is of no use to that driver. A virtual device can be identified through the flag TPM_CHIP_FLAG_VIRTUAL, which is only set for the tpm_vtpm_proxy driver.
Cc: stable@vger.kernel.org Fixes: 6f99612e2500 ("tpm: Proxy driver for supporting multiple emulated TPMs") Signed-off-by: Stefan Berger stefanb@linux.ibm.com Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/tpm/eventlog/common.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/char/tpm/eventlog/common.c +++ b/drivers/char/tpm/eventlog/common.c @@ -107,6 +107,9 @@ void tpm_bios_log_setup(struct tpm_chip int log_version; int rc = 0;
+ if (chip->flags & TPM_CHIP_FLAG_VIRTUAL) + return; + rc = tpm_read_log(chip); if (rc < 0) return;
From: Nathan Chancellor nathan@kernel.org
commit 44200f2d9b8b52389c70e6c7bbe51e0dc6eaf938 upstream.
Debian's clang carries a patch that makes the default FPU mode 'vfp3-d16' instead of 'neon' for 'armv7-a' to avoid generating NEON instructions on hardware that does not support them:
https://salsa.debian.org/pkg-llvm-team/llvm-toolchain/-/raw/5a61ca6f21b4ad8c... https://bugs.debian.org/841474 https://bugs.debian.org/842142 https://bugs.debian.org/914268
This results in the following build error when clang's integrated assembler is used because the '.arch' directive overrides the '.fpu' directive:
arch/arm/crypto/curve25519-core.S:25:2: error: instruction requires: NEON vmov.i32 q0, #1 ^ arch/arm/crypto/curve25519-core.S:26:2: error: instruction requires: NEON vshr.u64 q1, q0, #7 ^ arch/arm/crypto/curve25519-core.S:27:2: error: instruction requires: NEON vshr.u64 q0, q0, #8 ^ arch/arm/crypto/curve25519-core.S:28:2: error: instruction requires: NEON vmov.i32 d4, #19 ^
Shuffle the order of the '.arch' and '.fpu' directives so that the code builds regardless of the default FPU mode. This has been tested against both clang with and without Debian's patch and GCC.
Cc: stable@vger.kernel.org Fixes: d8f1308a025f ("crypto: arm/curve25519 - wire up NEON implementation") Link: https://github.com/ClangBuiltLinux/continuous-integration2/issues/118 Reported-by: Arnd Bergmann arnd@arndb.de Suggested-by: Arnd Bergmann arnd@arndb.de Suggested-by: Jessica Clarke jrtc27@jrtc27.com Signed-off-by: Nathan Chancellor nathan@kernel.org Acked-by: Jason A. Donenfeld Jason@zx2c4.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Tested-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/crypto/curve25519-core.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm/crypto/curve25519-core.S +++ b/arch/arm/crypto/curve25519-core.S @@ -10,8 +10,8 @@ #include <linux/linkage.h>
.text -.fpu neon .arch armv7-a +.fpu neon .align 4
ENTRY(curve25519_neon)
From: Eric Biggers ebiggers@google.com
commit 30d0f6a956fc74bb2e948398daf3278c6b08c7e9 upstream.
crypto_stats_get() is a no-op when the kernel is compiled without CONFIG_CRYPTO_STATS, so pairing it with crypto_alg_put() unconditionally (as crypto_rng_reset() does) is wrong.
Fix this by moving the call to crypto_stats_get() to just before the actual algorithm operation which might need it. This makes it always paired with crypto_stats_rng_seed().
Fixes: eed74b3eba9e ("crypto: rng - Fix a refcounting bug in crypto_rng_reset()") Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers ebiggers@google.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- crypto/rng.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
--- a/crypto/rng.c +++ b/crypto/rng.c @@ -34,22 +34,18 @@ int crypto_rng_reset(struct crypto_rng * u8 *buf = NULL; int err;
- crypto_stats_get(alg); if (!seed && slen) { buf = kmalloc(slen, GFP_KERNEL); - if (!buf) { - crypto_alg_put(alg); + if (!buf) return -ENOMEM; - }
err = get_random_bytes_wait(buf, slen); - if (err) { - crypto_alg_put(alg); + if (err) goto out; - } seed = buf; }
+ crypto_stats_get(alg); err = crypto_rng_alg(tfm)->seed(tfm, seed, slen); crypto_stats_rng_seed(alg, err); out:
From: Paul Clements paul.clements@us.sios.com
commit 2417b9869b81882ab90fd5ed1081a1cb2d4db1dd upstream.
This patch addresses a data corruption bug in raid1 arrays using bitmaps. Without this fix, the bitmap bits for the failed I/O end up being cleared.
Since we are in the failure leg of raid1_end_write_request, the request either needs to be retried (R1BIO_WriteError) or failed (R1BIO_Degraded).
Fixes: eeba6809d8d5 ("md/raid1: end bio when the device faulty") Cc: stable@vger.kernel.org # v5.2+ Signed-off-by: Paul Clements paul.clements@us.sios.com Signed-off-by: Song Liu song@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/raid1.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -478,6 +478,8 @@ static void raid1_end_write_request(stru if (!test_bit(Faulty, &rdev->flags)) set_bit(R1BIO_WriteError, &r1_bio->state); else { + /* Fail the request */ + set_bit(R1BIO_Degraded, &r1_bio->state); /* Finished with this branch */ r1_bio->bios[mirror] = NULL; to_put = bio;
From: Heinz Mauelshagen heinzm@redhat.com
commit f99a8e4373eeacb279bc9696937a55adbff7a28a upstream.
If fast table reloads occur during an ongoing reshape of raid4/5/6 devices the target may race reading a superblock vs the the MD resync thread; causing an inconclusive reshape state to be read in its constructor.
lvm2 test lvconvert-raid-reshape-stripes-load-reload.sh can cause BUG_ON() to trigger in md_run(), e.g.: "kernel BUG at drivers/md/raid5.c:7567!".
Scenario triggering the bug:
1. the MD sync thread calls end_reshape() from raid5_sync_request() when done reshaping. However end_reshape() _only_ updates the reshape position to MaxSector keeping the changed layout configuration though (i.e. any delta disks, chunk sector or RAID algorithm changes). That inconclusive configuration is stored in the superblock.
2. dm-raid constructs a mapping, loading named inconsistent superblock as of step 1 before step 3 is able to finish resetting the reshape state completely, and calls md_run() which leads to mentioned bug in raid5.c.
3. the MD RAID personality's finish_reshape() is called; which resets the reshape information on chunk sectors, delta disks, etc. This explains why the bug is rarely seen on multi-core machines, as MD's finish_reshape() superblock update races with the dm-raid constructor's superblock load in step 2.
Fix identifies inconclusive superblock content in the dm-raid constructor and resets it before calling md_run(), factoring out identifying checks into rs_is_layout_change() to share in existing rs_reshape_requested() and new rs_reset_inclonclusive_reshape(). Also enhance a comment and remove an empty line.
Cc: stable@vger.kernel.org Signed-off-by: Heinz Mauelshagen heinzm@redhat.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/dm-raid.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-)
--- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -1869,6 +1869,14 @@ static bool rs_takeover_requested(struct return rs->md.new_level != rs->md.level; }
+/* True if layout is set to reshape. */ +static bool rs_is_layout_change(struct raid_set *rs, bool use_mddev) +{ + return (use_mddev ? rs->md.delta_disks : rs->delta_disks) || + rs->md.new_layout != rs->md.layout || + rs->md.new_chunk_sectors != rs->md.chunk_sectors; +} + /* True if @rs is requested to reshape by ctr */ static bool rs_reshape_requested(struct raid_set *rs) { @@ -1881,9 +1889,7 @@ static bool rs_reshape_requested(struct if (rs_is_raid0(rs)) return false;
- change = mddev->new_layout != mddev->layout || - mddev->new_chunk_sectors != mddev->chunk_sectors || - rs->delta_disks; + change = rs_is_layout_change(rs, false);
/* Historical case to support raid1 reshape without delta disks */ if (rs_is_raid1(rs)) { @@ -2818,7 +2824,7 @@ static sector_t _get_reshape_sectors(str }
/* - * + * Reshape: * - change raid layout * - change chunk size * - add disks @@ -2928,6 +2934,20 @@ static int rs_setup_reshape(struct raid_ }
/* + * If the md resync thread has updated superblock with max reshape position + * at the end of a reshape but not (yet) reset the layout configuration + * changes -> reset the latter. + */ +static void rs_reset_inconclusive_reshape(struct raid_set *rs) +{ + if (!rs_is_reshaping(rs) && rs_is_layout_change(rs, true)) { + rs_set_cur(rs); + rs->md.delta_disks = 0; + rs->md.reshape_backwards = 0; + } +} + +/* * Enable/disable discard support on RAID set depending on * RAID level and discard properties of underlying RAID members. */ @@ -3213,11 +3233,14 @@ size_check: if (r) goto bad;
+ /* Catch any inconclusive reshape superblock content. */ + rs_reset_inconclusive_reshape(rs); + /* Start raid set read-only and assumed clean to change in raid_resume() */ rs->md.ro = 1; rs->md.in_sync = 1;
- /* Keep array frozen */ + /* Keep array frozen until resume. */ set_bit(MD_RECOVERY_FROZEN, &rs->md.recovery);
/* Has to be held on running the array */ @@ -3231,7 +3254,6 @@ size_check: }
r = md_start(&rs->md); - if (r) { ti->error = "Failed to start raid array"; mddev_unlock(&rs->md);
From: Vivek Goyal vgoyal@redhat.com
commit 4f06dd92b5d0a6f8eec6a34b8d6ef3e1f4ac1e10 upstream.
There are two modes for write(2) and friends in fuse:
a) write through (update page cache, send sync WRITE request to userspace)
b) buffered write (update page cache, async writeout later)
The write through method kept all the page cache pages locked that were used for the request. Keeping more than one page locked is deadlock prone and Qian Cai demonstrated this with trinity fuzzing.
The reason for keeping the pages locked is that concurrent mapped reads shouldn't try to pull possibly stale data into the page cache.
For full page writes, the easy way to fix this is to make the cached page be the authoritative source by marking the page PG_uptodate immediately. After this the page can be safely unlocked, since mapped/cached reads will take the written data from the cache.
Concurrent mapped writes will now cause data in the original WRITE request to be updated; this however doesn't cause any data inconsistency and this scenario should be exceedingly rare anyway.
If the WRITE request returns with an error in the above case, currently the page is not marked uptodate; this means that a concurrent read will always read consistent data. After this patch the page is uptodate between writing to the cache and receiving the error: there's window where a cached read will read the wrong data. While theoretically this could be a regression, it is unlikely to be one in practice, since this is normal for buffered writes.
In case of a partial page write to an already uptodate page the locking is also unnecessary, with the above caveats.
Partial write of a not uptodate page still needs to be handled. One way would be to read the complete page before doing the write. This is not possible, since it might break filesystems that don't expect any READ requests when the file was opened O_WRONLY.
The other solution is to serialize the synchronous write with reads from the partial pages. The easiest way to do this is to keep the partial pages locked. The problem is that a write() may involve two such pages (one head and one tail). This patch fixes it by only locking the partial tail page. If there's a partial head page as well, then split that off as a separate WRITE request.
Reported-by: Qian Cai cai@lca.pw Link: https://lore.kernel.org/linux-fsdevel/4794a3fa3742a5e84fb0f934944204b5573082... Fixes: ea9b9907b82a ("fuse: implement perform_write") Cc: stable@vger.kernel.org # v2.6.26 Signed-off-by: Vivek Goyal vgoyal@redhat.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/fuse/file.c | 41 +++++++++++++++++++++++++++++------------ fs/fuse/fuse_i.h | 1 + 2 files changed, 30 insertions(+), 12 deletions(-)
--- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1093,6 +1093,7 @@ static ssize_t fuse_send_write_pages(str struct fuse_file *ff = file->private_data; struct fuse_mount *fm = ff->fm; unsigned int offset, i; + bool short_write; int err;
for (i = 0; i < ap->num_pages; i++) @@ -1105,32 +1106,38 @@ static ssize_t fuse_send_write_pages(str if (!err && ia->write.out.size > count) err = -EIO;
+ short_write = ia->write.out.size < count; offset = ap->descs[0].offset; count = ia->write.out.size; for (i = 0; i < ap->num_pages; i++) { struct page *page = ap->pages[i];
- if (!err && !offset && count >= PAGE_SIZE) - SetPageUptodate(page); - - if (count > PAGE_SIZE - offset) - count -= PAGE_SIZE - offset; - else - count = 0; - offset = 0; - - unlock_page(page); + if (err) { + ClearPageUptodate(page); + } else { + if (count >= PAGE_SIZE - offset) + count -= PAGE_SIZE - offset; + else { + if (short_write) + ClearPageUptodate(page); + count = 0; + } + offset = 0; + } + if (ia->write.page_locked && (i == ap->num_pages - 1)) + unlock_page(page); put_page(page); }
return err; }
-static ssize_t fuse_fill_write_pages(struct fuse_args_pages *ap, +static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia, struct address_space *mapping, struct iov_iter *ii, loff_t pos, unsigned int max_pages) { + struct fuse_args_pages *ap = &ia->ap; struct fuse_conn *fc = get_fuse_conn(mapping->host); unsigned offset = pos & (PAGE_SIZE - 1); size_t count = 0; @@ -1183,6 +1190,16 @@ static ssize_t fuse_fill_write_pages(str if (offset == PAGE_SIZE) offset = 0;
+ /* If we copied full page, mark it uptodate */ + if (tmp == PAGE_SIZE) + SetPageUptodate(page); + + if (PageUptodate(page)) { + unlock_page(page); + } else { + ia->write.page_locked = true; + break; + } if (!fc->big_writes) break; } while (iov_iter_count(ii) && count < fc->max_write && @@ -1226,7 +1243,7 @@ static ssize_t fuse_perform_write(struct break; }
- count = fuse_fill_write_pages(ap, mapping, ii, pos, nr_pages); + count = fuse_fill_write_pages(&ia, mapping, ii, pos, nr_pages); if (count <= 0) { err = count; } else { --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -911,6 +911,7 @@ struct fuse_io_args { struct { struct fuse_write_in in; struct fuse_write_out out; + bool page_locked; } write; }; struct fuse_args_pages ap;
From: Hyeongseok Kim hyeongseok@gmail.com
commit 77edfc6e51055b61cae2f54c8e6c3bb7c762e4fe upstream.
If mounted with discard option, exFAT issues discard command when clear cluster bit to remove file. But the input parameter of cluster-to-sector calculation is abnormally added by reserved cluster size which is 2, leading to discard unrelated sectors included in target+2 cluster. With fixing this, remove the wrong comments in set/clear/find bitmap functions.
Fixes: 1e49a94cf707 ("exfat: add bitmap operations") Cc: stable@vger.kernel.org # v5.7+ Signed-off-by: Hyeongseok Kim hyeongseok@gmail.com Acked-by: Sungjong Seo sj1557.seo@samsung.com Signed-off-by: Namjae Jeon namjae.jeon@samsung.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/exfat/balloc.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-)
--- a/fs/exfat/balloc.c +++ b/fs/exfat/balloc.c @@ -141,10 +141,6 @@ void exfat_free_bitmap(struct exfat_sb_i kfree(sbi->vol_amap); }
-/* - * If the value of "clu" is 0, it means cluster 2 which is the first cluster of - * the cluster heap. - */ int exfat_set_bitmap(struct inode *inode, unsigned int clu) { int i, b; @@ -162,10 +158,6 @@ int exfat_set_bitmap(struct inode *inode return 0; }
-/* - * If the value of "clu" is 0, it means cluster 2 which is the first cluster of - * the cluster heap. - */ void exfat_clear_bitmap(struct inode *inode, unsigned int clu) { int i, b; @@ -186,8 +178,7 @@ void exfat_clear_bitmap(struct inode *in int ret_discard;
ret_discard = sb_issue_discard(sb, - exfat_cluster_to_sector(sbi, clu + - EXFAT_RESERVED_CLUSTERS), + exfat_cluster_to_sector(sbi, clu), (1 << sbi->sect_per_clus_bits), GFP_NOFS, 0);
if (ret_discard == -EOPNOTSUPP) {
From: Edward Cree ecree.xilinx@gmail.com
commit 5b1faa92289b53cad654123ed2bc8e10f6ddd4ac upstream.
We're starting from a TXQ instance number ('qid'), not a TXQ type, so efx_get_tx_queue() is inappropriate (and could return NULL, leading to panics).
Fixes: 12804793b17c ("sfc: decouple TXQ type from label") Reported-by: Trevor Hemsley themsley@voiceflex.com Cc: stable@vger.kernel.org Signed-off-by: Edward Cree ecree.xilinx@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/sfc/farch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c @@ -1081,16 +1081,16 @@ static void efx_farch_handle_tx_flush_done(struct efx_nic *efx, efx_qword_t *event) { struct efx_tx_queue *tx_queue; + struct efx_channel *channel; int qid;
qid = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_SUBDATA); if (qid < EFX_MAX_TXQ_PER_CHANNEL * (efx->n_tx_channels + efx->n_extra_tx_channels)) { - tx_queue = efx_get_tx_queue(efx, qid / EFX_MAX_TXQ_PER_CHANNEL, - qid % EFX_MAX_TXQ_PER_CHANNEL); - if (atomic_cmpxchg(&tx_queue->flush_outstanding, 1, 0)) { + channel = efx_get_tx_channel(efx, qid / EFX_MAX_TXQ_PER_CHANNEL); + tx_queue = channel->tx_queue + (qid % EFX_MAX_TXQ_PER_CHANNEL); + if (atomic_cmpxchg(&tx_queue->flush_outstanding, 1, 0)) efx_farch_magic_event(tx_queue->channel, EFX_CHANNEL_MAGIC_TX_DRAIN(tx_queue)); - } } }
From: Edward Cree ecree.xilinx@gmail.com
commit 83b09a1807415608b387c7bc748d329fefc5617e upstream.
We're starting from a TXQ label, not a TXQ type, so efx_channel_get_tx_queue() is inappropriate (and could return NULL, leading to panics).
Fixes: 12804793b17c ("sfc: decouple TXQ type from label") Cc: stable@vger.kernel.org Signed-off-by: Edward Cree ecree.xilinx@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/sfc/farch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c @@ -835,14 +835,14 @@ efx_farch_handle_tx_event(struct efx_cha /* Transmit completion */ tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR); tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); - tx_queue = efx_channel_get_tx_queue( - channel, tx_ev_q_label % EFX_MAX_TXQ_PER_CHANNEL); + tx_queue = channel->tx_queue + + (tx_ev_q_label % EFX_MAX_TXQ_PER_CHANNEL); efx_xmit_done(tx_queue, tx_ev_desc_ptr); } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) { /* Rewrite the FIFO write pointer */ tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); - tx_queue = efx_channel_get_tx_queue( - channel, tx_ev_q_label % EFX_MAX_TXQ_PER_CHANNEL); + tx_queue = channel->tx_queue + + (tx_ev_q_label % EFX_MAX_TXQ_PER_CHANNEL);
netif_tx_lock(efx->net_dev); efx_farch_notify_tx_desc(tx_queue);
From: Arnd Bergmann arnd@arndb.de
commit 82e5d8cc768b0c7b03c551a9ab1f8f3f68d5f83f upstream.
gcc-11 introdces a harmless warning for cap_inode_getsecurity:
security/commoncap.c: In function ‘cap_inode_getsecurity’: security/commoncap.c:440:33: error: ‘memcpy’ reading 16 bytes from a region of size 0 [-Werror=stringop-overread] 440 | memcpy(&nscap->data, &cap->data, sizeof(__le32) * 2 * VFS_CAP_U32); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The problem here is that tmpbuf is initialized to NULL, so gcc assumes it is not accessible unless it gets set by vfs_getxattr_alloc(). This is a legitimate warning as far as I can tell, but the code is correct since it correctly handles the error when that function fails.
Add a separate NULL check to tell gcc about it as well.
Signed-off-by: Arnd Bergmann arnd@arndb.de Acked-by: Christian Brauner christian.brauner@ubuntu.com Signed-off-by: James Morris jamorris@linux.microsoft.com Cc: Andrey Zhizhikin andrey.z@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/commoncap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/security/commoncap.c +++ b/security/commoncap.c @@ -391,7 +391,7 @@ int cap_inode_getsecurity(struct inode * &tmpbuf, size, GFP_NOFS); dput(dentry);
- if (ret < 0) + if (ret < 0 || !tmpbuf) return ret;
fs_ns = inode->i_sb->s_user_ns;
From: Linus Torvalds torvalds@linux-foundation.org
commit e7c6e405e171fb33990a12ecfd14e6500d9e5cf2 upstream.
It seems like Fedora 34 ends up enabling a few new gcc warnings, notably "-Wstringop-overread" and "-Warray-parameter".
Both of them cause what seem to be valid warnings in the kernel, where we have array size mismatches in function arguments (that are no longer just silently converted to a pointer to element, but actually checked).
This fixes most of the trivial ones, by making the function declaration match the function definition, and in the case of intel_pm.c, removing the over-specified array size from the argument declaration.
At least one 'stringop-overread' warning remains in the i915 driver, but that one doesn't have the same obvious trivial fix, and may or may not actually be indicative of a bug.
[ It was a mistake to upgrade one of my machines to Fedora 34 while being busy with the merge window, but if this is the extent of the compiler upgrade problems, things are better than usual - Linus ]
Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Cc: Andrey Zhizhikin andrey.z@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/intel_pm.c | 2 +- drivers/media/usb/dvb-usb/dvb-usb.h | 2 +- include/scsi/libfcoe.h | 2 +- net/bluetooth/ecdh_helper.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2992,7 +2992,7 @@ int ilk_wm_max_level(const struct drm_i9
static void intel_print_wm_latency(struct drm_i915_private *dev_priv, const char *name, - const u16 wm[8]) + const u16 wm[]) { int level, max_level = ilk_wm_max_level(dev_priv);
--- a/drivers/media/usb/dvb-usb/dvb-usb.h +++ b/drivers/media/usb/dvb-usb/dvb-usb.h @@ -487,7 +487,7 @@ extern int __must_check dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
/* commonly used remote control parsing */ -extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); +extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[5], u32 *, int *);
/* commonly used firmware download types and function */ struct hexline { --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -249,7 +249,7 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctl struct fc_frame *);
/* libfcoe funcs */ -u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); +u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int); int fcoe_libfc_config(struct fc_lport *, struct fcoe_ctlr *, const struct libfc_function_template *, int init_fcp); u32 fcoe_fc_crc(struct fc_frame *fp); --- a/net/bluetooth/ecdh_helper.h +++ b/net/bluetooth/ecdh_helper.h @@ -25,6 +25,6 @@
int compute_ecdh_secret(struct crypto_kpp *tfm, const u8 pair_public_key[64], u8 secret[32]); -int set_ecdh_privkey(struct crypto_kpp *tfm, const u8 *private_key); +int set_ecdh_privkey(struct crypto_kpp *tfm, const u8 private_key[32]); int generate_ecdh_public_key(struct crypto_kpp *tfm, u8 public_key[64]); int generate_ecdh_keys(struct crypto_kpp *tfm, u8 public_key[64]);
From: Yang Yang yang.yang29@zte.com.cn
commit 90ada91f4610c5ef11bc52576516d96c496fc3f1 upstream.
KASAN reports a BUG when download file in jffs2 filesystem.It is because when dstlen == 1, cpage_out will write array out of bounds. Actually, data will not be compressed in jffs2_zlib_compress() if data's length less than 4.
[ 393.799778] BUG: KASAN: slab-out-of-bounds in jffs2_rtime_compress+0x214/0x2f0 at addr ffff800062e3b281 [ 393.809166] Write of size 1 by task tftp/2918 [ 393.813526] CPU: 3 PID: 2918 Comm: tftp Tainted: G B 4.9.115-rt93-EMBSYS-CGEL-6.1.R6-dirty #1 [ 393.823173] Hardware name: LS1043A RDB Board (DT) [ 393.827870] Call trace: [ 393.830322] [<ffff20000808c700>] dump_backtrace+0x0/0x2f0 [ 393.835721] [<ffff20000808ca04>] show_stack+0x14/0x20 [ 393.840774] [<ffff2000086ef700>] dump_stack+0x90/0xb0 [ 393.845829] [<ffff20000827b19c>] kasan_object_err+0x24/0x80 [ 393.851402] [<ffff20000827b404>] kasan_report_error+0x1b4/0x4d8 [ 393.857323] [<ffff20000827bae8>] kasan_report+0x38/0x40 [ 393.862548] [<ffff200008279d44>] __asan_store1+0x4c/0x58 [ 393.867859] [<ffff2000084ce2ec>] jffs2_rtime_compress+0x214/0x2f0 [ 393.873955] [<ffff2000084bb3b0>] jffs2_selected_compress+0x178/0x2a0 [ 393.880308] [<ffff2000084bb530>] jffs2_compress+0x58/0x478 [ 393.885796] [<ffff2000084c5b34>] jffs2_write_inode_range+0x13c/0x450 [ 393.892150] [<ffff2000084be0b8>] jffs2_write_end+0x2a8/0x4a0 [ 393.897811] [<ffff2000081f3008>] generic_perform_write+0x1c0/0x280 [ 393.903990] [<ffff2000081f5074>] __generic_file_write_iter+0x1c4/0x228 [ 393.910517] [<ffff2000081f5210>] generic_file_write_iter+0x138/0x288 [ 393.916870] [<ffff20000829ec1c>] __vfs_write+0x1b4/0x238 [ 393.922181] [<ffff20000829ff00>] vfs_write+0xd0/0x238 [ 393.927232] [<ffff2000082a1ba8>] SyS_write+0xa0/0x110 [ 393.932283] [<ffff20000808429c>] __sys_trace_return+0x0/0x4 [ 393.937851] Object at ffff800062e3b280, in cache kmalloc-64 size: 64 [ 393.944197] Allocated: [ 393.946552] PID = 2918 [ 393.948913] save_stack_trace_tsk+0x0/0x220 [ 393.953096] save_stack_trace+0x18/0x20 [ 393.956932] kasan_kmalloc+0xd8/0x188 [ 393.960594] __kmalloc+0x144/0x238 [ 393.963994] jffs2_selected_compress+0x48/0x2a0 [ 393.968524] jffs2_compress+0x58/0x478 [ 393.972273] jffs2_write_inode_range+0x13c/0x450 [ 393.976889] jffs2_write_end+0x2a8/0x4a0 [ 393.980810] generic_perform_write+0x1c0/0x280 [ 393.985251] __generic_file_write_iter+0x1c4/0x228 [ 393.990040] generic_file_write_iter+0x138/0x288 [ 393.994655] __vfs_write+0x1b4/0x238 [ 393.998228] vfs_write+0xd0/0x238 [ 394.001543] SyS_write+0xa0/0x110 [ 394.004856] __sys_trace_return+0x0/0x4 [ 394.008684] Freed: [ 394.010691] PID = 2918 [ 394.013051] save_stack_trace_tsk+0x0/0x220 [ 394.017233] save_stack_trace+0x18/0x20 [ 394.021069] kasan_slab_free+0x88/0x188 [ 394.024902] kfree+0x6c/0x1d8 [ 394.027868] jffs2_sum_write_sumnode+0x2c4/0x880 [ 394.032486] jffs2_do_reserve_space+0x198/0x598 [ 394.037016] jffs2_reserve_space+0x3f8/0x4d8 [ 394.041286] jffs2_write_inode_range+0xf0/0x450 [ 394.045816] jffs2_write_end+0x2a8/0x4a0 [ 394.049737] generic_perform_write+0x1c0/0x280 [ 394.054179] __generic_file_write_iter+0x1c4/0x228 [ 394.058968] generic_file_write_iter+0x138/0x288 [ 394.063583] __vfs_write+0x1b4/0x238 [ 394.067157] vfs_write+0xd0/0x238 [ 394.070470] SyS_write+0xa0/0x110 [ 394.073783] __sys_trace_return+0x0/0x4 [ 394.077612] Memory state around the buggy address: [ 394.082404] ffff800062e3b180: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc [ 394.089623] ffff800062e3b200: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc [ 394.096842] >ffff800062e3b280: 01 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 394.104056] ^ [ 394.107283] ffff800062e3b300: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc [ 394.114502] ffff800062e3b380: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc [ 394.121718] ==================================================================
Signed-off-by: Yang Yang yang.yang29@zte.com.cn Cc: Joel Stanley joel@jms.id.au Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/jffs2/compr_rtime.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/fs/jffs2/compr_rtime.c +++ b/fs/jffs2/compr_rtime.c @@ -37,6 +37,9 @@ static int jffs2_rtime_compress(unsigned int outpos = 0; int pos=0;
+ if (*dstlen <= 3) + return -1; + memset(positions,0,sizeof(positions));
while (pos < (*sourcelen) && outpos <= (*dstlen)-2) {
From: Steve French stfrench@microsoft.com
commit 679971e7213174efb56abc8fab1299d0a88db0e8 upstream.
In the SMB3/SMB3.1.1 negotiate protocol request, we are supposed to advertise CAP_MULTICHANNEL capability when establishing multiple channels has been requested by the user doing the mount. See MS-SMB2 sections 2.2.3 and 3.2.5.2
Without setting it there is some risk that multichannel could fail if the server interpreted the field strictly.
Reviewed-By: Tom Talpey tom@talpey.com Reviewed-by: Shyam Prasad N sprasad@microsoft.com Cc: stable@vger.kernel.org # v5.8+ Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/smb2pdu.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -840,6 +840,8 @@ SMB2_negotiate(const unsigned int xid, s req->SecurityMode = 0;
req->Capabilities = cpu_to_le32(server->vals->req_capabilities); + if (ses->chan_max > 1) + req->Capabilities |= cpu_to_le32(SMB2_GLOBAL_CAP_MULTI_CHANNEL);
/* ClientGUID must be zero for SMB2.02 dialect */ if (server->vals->protocol_id == SMB20_PROT_ID) @@ -1025,6 +1027,9 @@ int smb3_validate_negotiate(const unsign
pneg_inbuf->Capabilities = cpu_to_le32(server->vals->req_capabilities); + if (tcon->ses->chan_max > 1) + pneg_inbuf->Capabilities |= cpu_to_le32(SMB2_GLOBAL_CAP_MULTI_CHANNEL); + memcpy(pneg_inbuf->Guid, server->client_guid, SMB2_CLIENT_GUID_SIZE);
From: Steve French stfrench@microsoft.com
commit 9c2dc11df50d1c8537075ff6b98472198e24438e upstream.
We were ignoring CAP_MULTI_CHANNEL in the server response - if the server doesn't support multichannel we should not be attempting it.
See MS-SMB2 section 3.2.5.2
Reviewed-by: Shyam Prasad N sprasad@microsoft.com Reviewed-By: Tom Talpey tom@talpey.com Cc: stable@vger.kernel.org # v5.8+ Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/sess.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -92,6 +92,12 @@ int cifs_try_adding_channels(struct cifs return 0; }
+ if (!(ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) { + cifs_dbg(VFS, "server %s does not support multichannel\n", ses->server->hostname); + ses->chan_max = 1; + return 0; + } + /* * Make a copy of the iface list at the time and use that * instead so as to not hold the iface spinlock for opening
From: Thomas Gleixner tglx@linutronix.de
commit 4fbf5d6837bf81fd7a27d771358f4ee6c4f243f8 upstream.
The FUTEX_WAIT operand has historically a relative timeout which means that the clock id is irrelevant as relative timeouts on CLOCK_REALTIME are not subject to wall clock changes and therefore are mapped by the kernel to CLOCK_MONOTONIC for simplicity.
If a caller would set FUTEX_CLOCK_REALTIME for FUTEX_WAIT the timeout is still treated relative vs. CLOCK_MONOTONIC and then the wait arms that timeout based on CLOCK_REALTIME which is broken and obviously has never been used or even tested.
Reject any attempt to use FUTEX_CLOCK_REALTIME with FUTEX_WAIT again.
The desired functionality can be achieved with FUTEX_WAIT_BITSET and a FUTEX_BITSET_MATCH_ANY argument.
Fixes: 337f13046ff0 ("futex: Allow FUTEX_CLOCK_REALTIME with FUTEX_WAIT op") Signed-off-by: Thomas Gleixner tglx@linutronix.de Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210422194704.834797921@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/futex.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/kernel/futex.c +++ b/kernel/futex.c @@ -3714,8 +3714,7 @@ long do_futex(u32 __user *uaddr, int op,
if (op & FUTEX_CLOCK_REALTIME) { flags |= FLAGS_CLOCKRT; - if (cmd != FUTEX_WAIT && cmd != FUTEX_WAIT_BITSET && \ - cmd != FUTEX_WAIT_REQUEUE_PI) + if (cmd != FUTEX_WAIT_BITSET && cmd != FUTEX_WAIT_REQUEUE_PI) return -ENOSYS; }
From: Thomas Gleixner tglx@linutronix.de
commit cdf78db4070967869e4d027c11f4dd825d8f815a upstream.
FUTEX_LOCK_PI does not require to have the FUTEX_CLOCK_REALTIME bit set because it has been using CLOCK_REALTIME based absolute timeouts forever. Due to that, the time namespace adjustment which is applied when FUTEX_CLOCK_REALTIME is not set, will wrongly take place for FUTEX_LOCK_PI and wreckage the timeout.
Exclude it from that procedure.
Fixes: c2f7d08cccf4 ("futex: Adjust absolute futex timeouts with per time namespace offset") Signed-off-by: Thomas Gleixner tglx@linutronix.de Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210422194704.984540159@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/futex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/kernel/futex.c +++ b/kernel/futex.c @@ -3784,7 +3784,7 @@ SYSCALL_DEFINE6(futex, u32 __user *, uad t = timespec64_to_ktime(ts); if (cmd == FUTEX_WAIT) t = ktime_add_safe(ktime_get(), t); - else if (!(op & FUTEX_CLOCK_REALTIME)) + else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME)) t = timens_ktime_to_host(CLOCK_MONOTONIC, t); tp = &t; } @@ -3978,7 +3978,7 @@ SYSCALL_DEFINE6(futex_time32, u32 __user t = timespec64_to_ktime(ts); if (cmd == FUTEX_WAIT) t = ktime_add_safe(ktime_get(), t); - else if (!(op & FUTEX_CLOCK_REALTIME)) + else if (cmd != FUTEX_LOCK_PI && !(op & FUTEX_CLOCK_REALTIME)) t = timens_ktime_to_host(CLOCK_MONOTONIC, t); tp = &t; }
From: Sean Christopherson seanjc@google.com
commit b6b4fbd90b155a0025223df2c137af8a701d53b3 upstream.
Initialize MSR_TSC_AUX with CPU node information if RDTSCP or RDPID is supported. This fixes a bug where vdso_read_cpunode() will read garbage via RDPID if RDPID is supported but RDTSCP is not. While no known CPU supports RDPID but not RDTSCP, both Intel's SDM and AMD's APM allow for RDPID to exist without RDTSCP, e.g. it's technically a legal CPU model for a virtual machine.
Note, technically MSR_TSC_AUX could be initialized if and only if RDPID is supported since RDTSCP is currently not used to retrieve the CPU node. But, the cost of the superfluous WRMSR is negigible, whereas leaving MSR_TSC_AUX uninitialized is just asking for future breakage if someone decides to utilize RDTSCP.
Fixes: a582c540ac1b ("x86/vdso: Use RDPID in preference to LSL when available") Signed-off-by: Sean Christopherson seanjc@google.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210504225632.1532621-2-seanjc@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/cpu/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1847,7 +1847,7 @@ static inline void setup_getcpu(int cpu) unsigned long cpudata = vdso_encode_cpunode(cpu, early_cpu_to_node(cpu)); struct desc_struct d = { };
- if (boot_cpu_has(X86_FEATURE_RDTSCP)) + if (boot_cpu_has(X86_FEATURE_RDTSCP) || boot_cpu_has(X86_FEATURE_RDPID)) write_rdtscp_aux(cpudata);
/* Store CPU and node number in limit. */
From: Masahiro Yamada masahiroy@kernel.org
commit 46b41d5dd8019b264717978c39c43313a524d033 upstream.
If the timestamp of the .config file is updated, config_data.gz is regenerated, then vmlinux is re-linked. This occurs even if the content of the .config has not changed at all.
This issue was mitigated by commit 67424f61f813 ("kconfig: do not write .config if the content is the same"); Kconfig does not update the .config when it ends up with the identical configuration.
The issue is remaining when the .config is created by *_defconfig with some config fragment(s) applied on top.
This is typical for powerpc and mips, where several *_defconfig targets are constructed by using merge_config.sh.
One workaround is to have the copy of the .config. The filechk rule updates the copy, kernel/config_data, by checking the content instead of the timestamp.
With this commit, the second run with the same configuration avoids the needless rebuilds.
$ make ARCH=mips defconfig all [ snip ] $ make ARCH=mips defconfig all *** Default configuration is based on target '32r2el_defconfig' Using ./arch/mips/configs/generic_defconfig as base Merging arch/mips/configs/generic/32r2.config Merging arch/mips/configs/generic/el.config Merging ./arch/mips/configs/generic/board-boston.config Merging ./arch/mips/configs/generic/board-ni169445.config Merging ./arch/mips/configs/generic/board-ocelot.config Merging ./arch/mips/configs/generic/board-ranchu.config Merging ./arch/mips/configs/generic/board-sead-3.config Merging ./arch/mips/configs/generic/board-xilfpga.config # # configuration written to .config # SYNC include/config/auto.conf CALL scripts/checksyscalls.sh CALL scripts/atomic/check-atomics.sh CHK include/generated/compile.h CHK include/generated/autoksyms.h
Reported-by: Elliot Berman eberman@codeaurora.org Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/.gitignore | 1 + kernel/Makefile | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-)
--- a/kernel/.gitignore +++ b/kernel/.gitignore @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only +/config_data kheaders.md5 timeconst.h hz.bc --- a/kernel/Makefile +++ b/kernel/Makefile @@ -134,10 +134,15 @@ obj-$(CONFIG_SCF_TORTURE_TEST) += scftor
$(obj)/configs.o: $(obj)/config_data.gz
-targets += config_data.gz -$(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE +targets += config_data config_data.gz +$(obj)/config_data.gz: $(obj)/config_data FORCE $(call if_changed,gzip)
+filechk_cat = cat $< + +$(obj)/config_data: $(KCONFIG_CONFIG) FORCE + $(call filechk,cat) + $(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz
quiet_cmd_genikh = CHK $(obj)/kheaders_data.tar.xz
From: Jan Kara jack@suse.cz
commit 3b1833e92baba135923af4a07e73fe6e54be5a2f upstream.
Access to journal->j_running_transaction is not protected by appropriate lock and thus is racy. We are well aware of that and the code handles the race properly. Just add a comment and data_race() annotation.
Cc: stable@kernel.org Reported-by: syzbot+30774a6acf6a2cf6d535@syzkaller.appspotmail.com Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20210406161804.20150-1-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/jbd2/transaction.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -349,7 +349,12 @@ static int start_this_handle(journal_t * }
alloc_transaction: - if (!journal->j_running_transaction) { + /* + * This check is racy but it is just an optimization of allocating new + * transaction early if there are high chances we'll need it. If we + * guess wrong, we'll retry or free unused transaction. + */ + if (!data_race(journal->j_running_transaction)) { /* * If __GFP_FS is not present, then we may be being called from * inside the fs writeback layer, so we MUST NOT fail.
From: Jan Kara jack@suse.cz
commit 83fe6b18b8d04c6c849379005e1679bac9752466 upstream.
Assertion checks in jbd2_journal_dirty_metadata() are known to be racy but we don't want to be grabbing locks just for them. We thus recheck them under b_state_lock only if it looks like they would fail. Annotate the checks with data_race().
Cc: stable@kernel.org Reported-by: Hao Sun sunhao.th@gmail.com Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20210406161804.20150-2-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/jbd2/transaction.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -1479,8 +1479,8 @@ int jbd2_journal_dirty_metadata(handle_t * crucial to catch bugs so let's do a reliable check until the * lockless handling is fully proven. */ - if (jh->b_transaction != transaction && - jh->b_next_transaction != transaction) { + if (data_race(jh->b_transaction != transaction && + jh->b_next_transaction != transaction)) { spin_lock(&jh->b_state_lock); J_ASSERT_JH(jh, jh->b_transaction == transaction || jh->b_next_transaction == transaction); @@ -1488,8 +1488,8 @@ int jbd2_journal_dirty_metadata(handle_t } if (jh->b_modified == 1) { /* If it's in our transaction it must be in BJ_Metadata list. */ - if (jh->b_transaction == transaction && - jh->b_jlist != BJ_Metadata) { + if (data_race(jh->b_transaction == transaction && + jh->b_jlist != BJ_Metadata)) { spin_lock(&jh->b_state_lock); if (jh->b_transaction == transaction && jh->b_jlist != BJ_Metadata)
From: Zhang Yi yi.zhang@huawei.com
commit a149d2a5cabbf6507a7832a1c4fd2593c55fd450 upstream.
Commit <50122847007> ("ext4: fix check to prevent initializing reserved inodes") check the block group zero and prevent initializing reserved inodes. But in some special cases, the reserved inode may not all belong to the group zero, it may exist into the second group if we format filesystem below.
mkfs.ext4 -b 4096 -g 8192 -N 1024 -I 4096 /dev/sda
So, it will end up triggering a false positive report of a corrupted file system. This patch fix it by avoid check reserved inodes if no free inode blocks will be zeroed.
Cc: stable@kernel.org Fixes: 50122847007 ("ext4: fix check to prevent initializing reserved inodes") Signed-off-by: Zhang Yi yi.zhang@huawei.com Suggested-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20210331121516.2243099-1-yi.zhang@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/ialloc.c | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-)
--- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -1512,6 +1512,7 @@ int ext4_init_inode_table(struct super_b handle_t *handle; ext4_fsblk_t blk; int num, ret = 0, used_blks = 0; + unsigned long used_inos = 0;
/* This should not happen, but just to be sure check this */ if (sb_rdonly(sb)) { @@ -1542,22 +1543,37 @@ int ext4_init_inode_table(struct super_b * used inodes so we need to skip blocks with used inodes in * inode table. */ - if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) - used_blks = DIV_ROUND_UP((EXT4_INODES_PER_GROUP(sb) - - ext4_itable_unused_count(sb, gdp)), - sbi->s_inodes_per_block); - - if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group) || - ((group == 0) && ((EXT4_INODES_PER_GROUP(sb) - - ext4_itable_unused_count(sb, gdp)) < - EXT4_FIRST_INO(sb)))) { - ext4_error(sb, "Something is wrong with group %u: " - "used itable blocks: %d; " - "itable unused count: %u", - group, used_blks, - ext4_itable_unused_count(sb, gdp)); - ret = 1; - goto err_out; + if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) { + used_inos = EXT4_INODES_PER_GROUP(sb) - + ext4_itable_unused_count(sb, gdp); + used_blks = DIV_ROUND_UP(used_inos, sbi->s_inodes_per_block); + + /* Bogus inode unused count? */ + if (used_blks < 0 || used_blks > sbi->s_itb_per_group) { + ext4_error(sb, "Something is wrong with group %u: " + "used itable blocks: %d; " + "itable unused count: %u", + group, used_blks, + ext4_itable_unused_count(sb, gdp)); + ret = 1; + goto err_out; + } + + used_inos += group * EXT4_INODES_PER_GROUP(sb); + /* + * Are there some uninitialized inodes in the inode table + * before the first normal inode? + */ + if ((used_blks != sbi->s_itb_per_group) && + (used_inos < EXT4_FIRST_INO(sb))) { + ext4_error(sb, "Something is wrong with group %u: " + "itable unused count: %u; " + "itables initialized count: %ld", + group, ext4_itable_unused_count(sb, gdp), + used_inos); + ret = 1; + goto err_out; + } }
blk = ext4_inode_table(sb, gdp) + used_blks;
From: Zhang Yi yi.zhang@huawei.com
commit 72ffb49a7b623c92a37657eda7cc46a06d3e8398 upstream.
When CONFIG_QUOTA is enabled, if we failed to mount the filesystem due to some error happens behind ext4_orphan_cleanup(), it will end up triggering a after free issue of super_block. The problem is that ext4_orphan_cleanup() will set SB_ACTIVE flag if CONFIG_QUOTA is enabled, after we cleanup the truncated inodes, the last iput() will put them into the lru list, and these inodes' pages may probably dirty and will be write back by the writeback thread, so it could be raced by freeing super_block in the error path of mount_bdev().
After check the setting of SB_ACTIVE flag in ext4_orphan_cleanup(), it was used to ensure updating the quota file properly, but evict inode and trash data immediately in the last iput does not affect the quotafile, so setting the SB_ACTIVE flag seems not required[1]. Fix this issue by just remove the SB_ACTIVE setting.
[1] https://lore.kernel.org/linux-ext4/99cce8ca-e4a0-7301-840f-2ace67c551f3@huaw...
Cc: stable@kernel.org Signed-off-by: Zhang Yi yi.zhang@huawei.com Tested-by: Jan Kara jack@suse.cz Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20210331033138.918975-1-yi.zhang@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/super.c | 3 --- 1 file changed, 3 deletions(-)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3039,9 +3039,6 @@ static void ext4_orphan_cleanup(struct s sb->s_flags &= ~SB_RDONLY; } #ifdef CONFIG_QUOTA - /* Needed for iput() to work correctly and not trash data */ - sb->s_flags |= SB_ACTIVE; - /* * Turn on quotas which were not enabled for read-only mounts if * filesystem has quota feature, so that they are updated correctly.
From: Fengnan Chang changfengnan@vivo.com
commit f88f1466e2a2e5ca17dfada436d3efa1b03a3972 upstream.
We should set the error code when ext4_commit_super check argument failed. Found in code review. Fixes: c4be0c1dc4cdc ("filesystem freeze: add error handling of write_super_lockfs/unlockfs").
Cc: stable@kernel.org Signed-off-by: Fengnan Chang changfengnan@vivo.com Reviewed-by: Andreas Dilger adilger@dilger.ca Link: https://lore.kernel.org/r/20210402101631.561-1-changfengnan@vivo.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/super.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -5489,8 +5489,10 @@ static int ext4_commit_super(struct supe struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; int error = 0;
- if (!sbh || block_device_ejected(sb)) - return error; + if (!sbh) + return -EINVAL; + if (block_device_ejected(sb)) + return -ENODEV;
/* * If the file system is mounted read-only, don't update the
From: Ye Bin yebin10@huawei.com
commit 6810fad956df9e5467e8e8a5ac66fda0836c71fa upstream.
Fix As write_mmp_block() so that it returns -EIO instead of 1, so that the correct error gets saved into the superblock.
Cc: stable@kernel.org Fixes: 54d3adbc29f0 ("ext4: save all error info in save_error_info() and drop ext4_set_errno()") Reported-by: Liu Zhi Qiang liuzhiqiang26@huawei.com Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: Andreas Dilger adilger@dilger.ca Link: https://lore.kernel.org/r/20210406025331.148343-1-yebin10@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/mmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/ext4/mmp.c +++ b/fs/ext4/mmp.c @@ -56,7 +56,7 @@ static int write_mmp_block(struct super_ wait_on_buffer(bh); sb_end_write(sb); if (unlikely(!buffer_uptodate(bh))) - return 1; + return -EIO;
return 0; }
From: Xu Yihang xuyihang@huawei.com
commit e1262cd2e68a0870fb9fc95eb202d22e8f0074b7 upstream.
In case of if not ext4_fc_add_tlv branch, an error return code is missing.
Cc: stable@kernel.org Fixes: aa75f4d3daae ("ext4: main fast-commit commit path") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Xu Yihang xuyihang@huawei.com Reviewed-by: Harshad Shirwadkar harshadshirwadkar@gmail.com Link: https://lore.kernel.org/r/20210408070033.123047-1-xuyihang@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/fast_commit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/ext4/fast_commit.c +++ b/fs/ext4/fast_commit.c @@ -1032,8 +1032,10 @@ static int ext4_fc_perform_commit(journa head.fc_tid = cpu_to_le32( sbi->s_journal->j_running_transaction->t_tid); if (!ext4_fc_add_tlv(sb, EXT4_FC_TAG_HEAD, sizeof(head), - (u8 *)&head, &crc)) + (u8 *)&head, &crc)) { + ret = -ENOSPC; goto out; + } }
spin_lock(&sbi->s_fc_lock);
From: Theodore Ts'o tytso@mit.edu
commit 4811d9929cdae4238baf5b2522247bd2f9fa7b50 upstream.
This is needed to allow generic/607 to pass for file systems with the inline data_feature enabled, and it allows the use of file systems where the directories use inline_data, while the files are accessed via DAX.
Cc: stable@kernel.org Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/ialloc.c | 3 ++- fs/ext4/ioctl.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-)
--- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -1291,7 +1291,8 @@ got:
ei->i_extra_isize = sbi->s_want_extra_isize; ei->i_inline_off = 0; - if (ext4_has_feature_inline_data(sb)) + if (ext4_has_feature_inline_data(sb) && + (!(ei->i_flags & EXT4_DAX_FL) || S_ISDIR(mode))) ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); ret = inode; err = dquot_alloc_inode(inode); --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -312,6 +312,12 @@ static void ext4_dax_dontcache(struct in static bool dax_compatible(struct inode *inode, unsigned int oldflags, unsigned int flags) { + /* Allow the DAX flag to be changed on inline directories */ + if (S_ISDIR(inode->i_mode)) { + flags &= ~EXT4_INLINE_DATA_FL; + oldflags &= ~EXT4_INLINE_DATA_FL; + } + if (flags & EXT4_DAX_FL) { if ((oldflags & EXT4_DAX_MUT_EXCL) || ext4_test_inode_state(inode,
From: Jan Kara jack@suse.cz
commit 5899593f51e63dde2f07c67358bd65a641585abb upstream.
Eric has noticed that after pagecache read rework, generic/418 is occasionally failing for ext4 when blocksize < pagesize. In fact, the pagecache rework just made hard to hit race in ext4 more likely. The problem is that since ext4 conversion of direct IO writes to iomap framework (commit 378f32bab371), we update inode size after direct IO write only after invalidating page cache. Thus if buffered read sneaks at unfortunate moment like:
CPU1 - write at offset 1k CPU2 - read from offset 0 iomap_dio_rw(..., IOMAP_DIO_FORCE_WAIT); ext4_readpage(); ext4_handle_inode_extension()
the read will zero out tail of the page as it still sees smaller inode size and thus page cache becomes inconsistent with on-disk contents with all the consequences.
Fix the problem by moving inode size update into end_io handler which gets called before the page cache is invalidated.
Reported-and-tested-by: Eric Whitney enwlinux@gmail.com Fixes: 378f32bab371 ("ext4: introduce direct I/O write using iomap infrastructure") CC: stable@vger.kernel.org Signed-off-by: Jan Kara jack@suse.cz Acked-by: Dave Chinner dchinner@redhat.com Link: https://lore.kernel.org/r/20210415155417.4734-1-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/file.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-)
--- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -372,15 +372,32 @@ truncate: static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size, int error, unsigned int flags) { - loff_t offset = iocb->ki_pos; + loff_t pos = iocb->ki_pos; struct inode *inode = file_inode(iocb->ki_filp);
if (error) return error;
- if (size && flags & IOMAP_DIO_UNWRITTEN) - return ext4_convert_unwritten_extents(NULL, inode, - offset, size); + if (size && flags & IOMAP_DIO_UNWRITTEN) { + error = ext4_convert_unwritten_extents(NULL, inode, pos, size); + if (error < 0) + return error; + } + /* + * If we are extending the file, we have to update i_size here before + * page cache gets invalidated in iomap_dio_rw(). Otherwise racing + * buffered reads could zero out too much from page cache pages. Update + * of on-disk size will happen later in ext4_dio_write_iter() where + * we have enough information to also perform orphan list handling etc. + * Note that we perform all extending writes synchronously under + * i_rwsem held exclusively so i_size update is safe here in that case. + * If the write was not extending, we cannot see pos > i_size here + * because operations reducing i_size like truncate wait for all + * outstanding DIO before updating i_size. + */ + pos += size; + if (pos > i_size_read(inode)) + i_size_write(inode, pos);
return 0; }
From: Peilin Ye yepeilin.cs@gmail.com
commit bf9a40ae8d722f281a2721779595d6df1c33a0bf upstream.
dvb_media_device_free() is leaking memory. Free `dvbdev->adapter->conn` before setting it to NULL, as documented in include/media/media-device.h: "The media_entity instance itself must be freed explicitly by the driver if required."
Link: https://syzkaller.appspot.com/bug?id=9bbe4b842c98f0ed05c5eed77a226e9de33bf29...
Link: https://lore.kernel.org/linux-media/20201211083039.521617-1-yepeilin.cs@gmai... Cc: stable@vger.kernel.org Fixes: 0230d60e4661 ("[media] dvbdev: Add RF connector if needed") Reported-by: syzbot+7f09440acc069a0d38ac@syzkaller.appspotmail.com Signed-off-by: Peilin Ye yepeilin.cs@gmail.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/dvb-core/dvbdev.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -241,6 +241,7 @@ static void dvb_media_device_free(struct
if (dvbdev->adapter->conn) { media_device_unregister_entity(dvbdev->adapter->conn); + kfree(dvbdev->adapter->conn); dvbdev->adapter->conn = NULL; kfree(dvbdev->adapter->conn_pads); dvbdev->adapter->conn_pads = NULL;
From: Takashi Iwai tiwai@suse.de
commit c49206786ee252f28b7d4d155d1fff96f145a05d upstream.
dvb_usb_device_init() copies the properties to the own data, so that the callers can release the original properties later (as done in the commit 299c7007e936 ("media: dw2102: Fix memleak on sequence of probes")). However, it also stores dev->desc pointer that is a reference to the original properties data. Since dev->desc is referred later, it may result in use-after-free, in the worst case, leading to a kernel Oops as reported.
This patch addresses the problem by allocating and copying the properties at first, then get the desc from the copied properties.
Reported-and-tested-by: Stefan Seyfried seife+kernel@b1-systems.com BugLink: http://bugzilla.opensuse.org/show_bug.cgi?id=1181104
Reviewed-by: Robert Foss robert.foss@linaro.org Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/usb/dvb-usb/dvb-usb-init.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c @@ -267,27 +267,30 @@ int dvb_usb_device_init(struct usb_inter if (du != NULL) *du = NULL;
- if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) { + d = kzalloc(sizeof(*d), GFP_KERNEL); + if (!d) { + err("no memory for 'struct dvb_usb_device'"); + return -ENOMEM; + } + + memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); + + desc = dvb_usb_find_device(udev, &d->props, &cold); + if (!desc) { deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); - return -ENODEV; + ret = -ENODEV; + goto error; }
if (cold) { info("found a '%s' in cold state, will try to load a firmware", desc->name); ret = dvb_usb_download_firmware(udev, props); if (!props->no_reconnect || ret != 0) - return ret; + goto error; }
info("found a '%s' in warm state.", desc->name); - d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL); - if (d == NULL) { - err("no memory for 'struct dvb_usb_device'"); - return -ENOMEM; - } - d->udev = udev; - memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); d->desc = desc; d->owner = owner;
From: Takashi Iwai tiwai@suse.de
commit 13a79f14ab285120bc4977e00a7c731e8143f548 upstream.
dvb_usb_device_init() allocates a dvb_usb_device object, but it doesn't release the object by itself even at errors. The object is released in the callee side (dvb_usb_init()) in some error cases via dvb_usb_exit() call, but it also missed the object free in other error paths. And, the caller (it's only dvb_usb_device_init()) doesn't seem caring the resource management as well, hence those memories are leaked.
This patch assures releasing the memory at the error path in dvb_usb_device_init(). Now dvb_usb_init() frees the resources it allocated but leaves the passed dvb_usb_device object intact. In turn, the dvb_usb_device object is released in dvb_usb_device_init() instead. We could use dvb_usb_exit() function for releasing everything in the callee (as it was used for some error cases in the original code), but releasing the passed object in the callee is non-intuitive and error-prone. So I took this approach (which is more standard in Linus kernel code) although it ended with a bit more open codes.
Along with the change, the patch makes sure that USB intfdata is reset and don't return the bogus pointer to the caller of dvb_usb_device_init() at the error path, too.
Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/usb/dvb-usb/dvb-usb-init.c | 47 ++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 16 deletions(-)
--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c @@ -170,22 +170,20 @@ static int dvb_usb_init(struct dvb_usb_d
if (d->props.priv_init != NULL) { ret = d->props.priv_init(d); - if (ret != 0) { - kfree(d->priv); - d->priv = NULL; - return ret; - } + if (ret != 0) + goto err_priv_init; } }
/* check the capabilities and set appropriate variables */ dvb_usb_device_power_ctrl(d, 1);
- if ((ret = dvb_usb_i2c_init(d)) || - (ret = dvb_usb_adapter_init(d, adapter_nums))) { - dvb_usb_exit(d); - return ret; - } + ret = dvb_usb_i2c_init(d); + if (ret) + goto err_i2c_init; + ret = dvb_usb_adapter_init(d, adapter_nums); + if (ret) + goto err_adapter_init;
if ((ret = dvb_usb_remote_init(d))) err("could not initialize remote control."); @@ -193,6 +191,17 @@ static int dvb_usb_init(struct dvb_usb_d dvb_usb_device_power_ctrl(d, 0);
return 0; + +err_adapter_init: + dvb_usb_adapter_exit(d); +err_i2c_init: + dvb_usb_i2c_exit(d); + if (d->priv && d->props.priv_destroy) + d->props.priv_destroy(d); +err_priv_init: + kfree(d->priv); + d->priv = NULL; + return ret; }
/* determine the name and the state of the just found USB device */ @@ -296,15 +305,21 @@ int dvb_usb_device_init(struct usb_inter
usb_set_intfdata(intf, d);
- if (du != NULL) + ret = dvb_usb_init(d, adapter_nums); + if (ret) { + info("%s error while loading driver (%d)", desc->name, ret); + goto error; + } + + if (du) *du = d;
- ret = dvb_usb_init(d, adapter_nums); + info("%s successfully initialized and connected.", desc->name); + return 0;
- if (ret == 0) - info("%s successfully initialized and connected.", desc->name); - else - info("%s error while loading driver (%d)", desc->name, ret); + error: + usb_set_intfdata(intf, NULL); + kfree(d); return ret; } EXPORT_SYMBOL(dvb_usb_device_init);
From: Ricardo Ribalda ribalda@chromium.org
commit 3630901933afba1d16c462b04d569b7576339223 upstream.
We are losing the reference to an allocated memory if try. Change the order of the check to avoid that.
Cc: stable@vger.kernel.org Fixes: 6d5f26f2e045 ("media: staging/intel-ipu3-v4l: reduce kernel stack usage") Signed-off-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/media/ipu3/ipu3-v4l2.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
--- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -693,6 +693,13 @@ static int imgu_fmt(struct imgu_device * if (inode == IMGU_NODE_STAT_3A || inode == IMGU_NODE_PARAMS) continue;
+ /* CSS expects some format on OUT queue */ + if (i != IPU3_CSS_QUEUE_OUT && + !imgu_pipe->nodes[inode].enabled) { + fmts[i] = NULL; + continue; + } + if (try) { fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, sizeof(struct v4l2_pix_format_mplane), @@ -705,10 +712,6 @@ static int imgu_fmt(struct imgu_device * fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; }
- /* CSS expects some format on OUT queue */ - if (i != IPU3_CSS_QUEUE_OUT && - !imgu_pipe->nodes[inode].enabled) - fmts[i] = NULL; }
if (!try) {
From: Ricardo Ribalda ribalda@chromium.org
commit ad91849996f9dd79741a961fd03585a683b08356 upstream.
If there in an error during a set_fmt, do not overwrite the previous sizes with the invalid config.
Without this patch, v4l2-compliance ends up allocating 4GiB of RAM and causing the following OOPs
[ 38.662975] ipu3-imgu 0000:00:05.0: swiotlb buffer is full (sz: 4096 bytes) [ 38.662980] DMA: Out of SW-IOMMU space for 4096 bytes at device 0000:00:05.0 [ 38.663010] general protection fault: 0000 [#1] PREEMPT SMP
Cc: stable@vger.kernel.org Fixes: 6d5f26f2e045 ("media: staging/intel-ipu3-v4l: reduce kernel stack usage") Signed-off-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/media/ipu3/ipu3-v4l2.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -669,6 +669,7 @@ static int imgu_fmt(struct imgu_device * struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; + struct v4l2_pix_format_mplane fmt_backup;
dev_dbg(dev, "set fmt node [%u][%u](try = %u)", pipe, node, try);
@@ -737,6 +738,7 @@ static int imgu_fmt(struct imgu_device * ret = -EINVAL; goto out; } + fmt_backup = *fmts[css_q]; *fmts[css_q] = f->fmt.pix_mp;
if (try) @@ -744,6 +746,9 @@ static int imgu_fmt(struct imgu_device * else ret = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe);
+ if (try || ret < 0) + *fmts[css_q] = fmt_backup; + /* ret is the binary number in the firmware blob */ if (ret < 0) goto out;
From: Ricardo Ribalda ribalda@chromium.org
commit dccfe2548746ca9cca3a20401ece4cf255d1f171 upstream.
Do not modify imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, until the format has been correctly validated.
Otherwise, even if we use a backup variable, there is a period of time where imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp might have an invalid value that can be used by other functions.
Cc: stable@vger.kernel.org Fixes: ad91849996f9 ("media: staging/intel-ipu3: Fix set_fmt error handling") Reviewed-by: Tomasz Figa tfiga@chromium.org Signed-off-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/media/ipu3/ipu3-v4l2.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-)
--- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -669,7 +669,6 @@ static int imgu_fmt(struct imgu_device * struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; - struct v4l2_pix_format_mplane fmt_backup;
dev_dbg(dev, "set fmt node [%u][%u](try = %u)", pipe, node, try);
@@ -687,6 +686,7 @@ static int imgu_fmt(struct imgu_device *
dev_dbg(dev, "IPU3 pipe %u pipe_id = %u", pipe, css_pipe->pipe_id);
+ css_q = imgu_node_to_queue(node); for (i = 0; i < IPU3_CSS_QUEUES; i++) { unsigned int inode = imgu_map_node(imgu, i);
@@ -701,6 +701,11 @@ static int imgu_fmt(struct imgu_device * continue; }
+ if (i == css_q) { + fmts[i] = &f->fmt.pix_mp; + continue; + } + if (try) { fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, sizeof(struct v4l2_pix_format_mplane), @@ -729,39 +734,32 @@ static int imgu_fmt(struct imgu_device * rects[IPU3_CSS_RECT_GDC]->height = pad_fmt.height; }
- /* - * imgu doesn't set the node to the value given by user - * before we return success from this function, so set it here. - */ - css_q = imgu_node_to_queue(node); if (!fmts[css_q]) { ret = -EINVAL; goto out; } - fmt_backup = *fmts[css_q]; - *fmts[css_q] = f->fmt.pix_mp;
if (try) ret = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe); else ret = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe);
- if (try || ret < 0) - *fmts[css_q] = fmt_backup; - /* ret is the binary number in the firmware blob */ if (ret < 0) goto out;
- if (try) - f->fmt.pix_mp = *fmts[css_q]; - else - f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt; + /* + * imgu doesn't set the node to the value given by user + * before we return success from this function, so set it here. + */ + if (!try) + imgu_pipe->nodes[node].vdev_fmt.fmt.pix_mp = f->fmt.pix_mp;
out: if (try) { for (i = 0; i < IPU3_CSS_QUEUES; i++) - kfree(fmts[i]); + if (i != css_q) + kfree(fmts[i]); }
return ret;
From: Hans Verkuil hverkuil-cisco@xs4all.nl
commit ac34b79da14d67a9b494f6125186becbd067e225 upstream.
When controls are used together with the Request API, then for each request a v4l2_ctrl_handler struct is allocated. This contains the controls that can be set in a request. If a control is *not* set in the request, then the value used in the most recent previous request must be used, or the current value if it is not found in any outstanding requests.
The framework tried to find such a previous request and it would set the 'req' pointer in struct v4l2_ctrl_ref to the v4l2_ctrl_ref of the control in such a previous request. So far, so good. However, when that previous request was applied to the hardware, returned to userspace, and then userspace would re-init or free that request, any 'ref' pointer in still-queued requests would suddenly point to freed memory.
This was not noticed before since the drivers that use this expected that each request would always have the controls set, so there was never any need to find a control in older requests. This requirement was relaxed, and now this bug surfaced.
It was also made worse by changeset 2fae4d6aabc8 ("media: v4l2-ctrls: v4l2_ctrl_request_complete() should always set ref->req") which increased the chance of this happening.
The use of the 'req' pointer in v4l2_ctrl_ref was very fragile, so drop this entirely. Instead add a valid_p_req bool to indicate that p_req contains a valid value for this control. And if it is false, then just use the current value of the control.
Note that VIDIOC_G_EXT_CTRLS will always return -EACCES when attempting to get a control from a request until the request is completed. And in that case, all controls in the request will have the control value set (i.e. valid_p_req is true). This means that the whole 'find the most recent previous request containing a control' idea is pointless, and the code can be simplified considerably.
The v4l2_g_ext_ctrls_common() function was refactored a bit to make it more understandable. It also avoids updating volatile controls in a completed request since that was already done when the request was completed.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Fixes: 2fae4d6aabc8 ("media: v4l2-ctrls: v4l2_ctrl_request_complete() should always set ref->req") Fixes: 6fa6f831f095 ("media: v4l2-ctrls: add core request support") Cc: stable@vger.kernel.org # for v5.9 and up Tested-by: Alexandre Courbot acourbot@chromium.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/v4l2-core/v4l2-ctrls.c | 137 ++++++++++++++++------------------- include/media/v4l2-ctrls.h | 12 +-- 2 files changed, 70 insertions(+), 79 deletions(-)
--- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -2201,7 +2201,16 @@ static void new_to_req(struct v4l2_ctrl_ if (!ref) return; ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req); - ref->req = ref; + ref->valid_p_req = true; +} + +/* Copy the current value to the request value */ +static void cur_to_req(struct v4l2_ctrl_ref *ref) +{ + if (!ref) + return; + ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->p_req); + ref->valid_p_req = true; }
/* Copy the request value to the new value */ @@ -2209,8 +2218,8 @@ static void req_to_new(struct v4l2_ctrl_ { if (!ref) return; - if (ref->req) - ptr_to_ptr(ref->ctrl, ref->req->p_req, ref->ctrl->p_new); + if (ref->valid_p_req) + ptr_to_ptr(ref->ctrl, ref->p_req, ref->ctrl->p_new); else ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->ctrl->p_new); } @@ -3380,39 +3389,8 @@ static void v4l2_ctrl_request_queue(stru struct v4l2_ctrl_handler *hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); struct v4l2_ctrl_handler *main_hdl = obj->priv; - struct v4l2_ctrl_handler *prev_hdl = NULL; - struct v4l2_ctrl_ref *ref_ctrl, *ref_ctrl_prev = NULL;
mutex_lock(main_hdl->lock); - if (list_empty(&main_hdl->requests_queued)) - goto queue; - - prev_hdl = list_last_entry(&main_hdl->requests_queued, - struct v4l2_ctrl_handler, requests_queued); - /* - * Note: prev_hdl and hdl must contain the same list of control - * references, so if any differences are detected then that is a - * driver bug and the WARN_ON is triggered. - */ - mutex_lock(prev_hdl->lock); - ref_ctrl_prev = list_first_entry(&prev_hdl->ctrl_refs, - struct v4l2_ctrl_ref, node); - list_for_each_entry(ref_ctrl, &hdl->ctrl_refs, node) { - if (ref_ctrl->req) - continue; - while (ref_ctrl_prev->ctrl->id < ref_ctrl->ctrl->id) { - /* Should never happen, but just in case... */ - if (list_is_last(&ref_ctrl_prev->node, - &prev_hdl->ctrl_refs)) - break; - ref_ctrl_prev = list_next_entry(ref_ctrl_prev, node); - } - if (WARN_ON(ref_ctrl_prev->ctrl->id != ref_ctrl->ctrl->id)) - break; - ref_ctrl->req = ref_ctrl_prev->req; - } - mutex_unlock(prev_hdl->lock); -queue: list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued); hdl->request_is_queued = true; mutex_unlock(main_hdl->lock); @@ -3469,7 +3447,7 @@ v4l2_ctrl_request_hdl_ctrl_find(struct v { struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id);
- return (ref && ref->req == ref) ? ref->ctrl : NULL; + return (ref && ref->valid_p_req) ? ref->ctrl : NULL; } EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find);
@@ -3655,7 +3633,13 @@ static int class_check(struct v4l2_ctrl_ return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL; }
-/* Get extended controls. Allocates the helpers array if needed. */ +/* + * Get extended controls. Allocates the helpers array if needed. + * + * Note that v4l2_g_ext_ctrls_common() with 'which' set to + * V4L2_CTRL_WHICH_REQUEST_VAL is only called if the request was + * completed, and in that case valid_p_req is true for all controls. + */ static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs, struct video_device *vdev) @@ -3664,9 +3648,10 @@ static int v4l2_g_ext_ctrls_common(struc struct v4l2_ctrl_helper *helpers = helper; int ret; int i, j; - bool def_value; + bool is_default, is_request;
- def_value = (cs->which == V4L2_CTRL_WHICH_DEF_VAL); + is_default = (cs->which == V4L2_CTRL_WHICH_DEF_VAL); + is_request = (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL);
cs->error_idx = cs->count; cs->which = V4L2_CTRL_ID2WHICH(cs->which); @@ -3692,11 +3677,9 @@ static int v4l2_g_ext_ctrls_common(struc ret = -EACCES;
for (i = 0; !ret && i < cs->count; i++) { - int (*ctrl_to_user)(struct v4l2_ext_control *c, - struct v4l2_ctrl *ctrl); struct v4l2_ctrl *master; - - ctrl_to_user = def_value ? def_to_user : cur_to_user; + bool is_volatile = false; + u32 idx = i;
if (helpers[i].mref == NULL) continue; @@ -3706,31 +3689,48 @@ static int v4l2_g_ext_ctrls_common(struc
v4l2_ctrl_lock(master);
- /* g_volatile_ctrl will update the new control values */ - if (!def_value && + /* + * g_volatile_ctrl will update the new control values. + * This makes no sense for V4L2_CTRL_WHICH_DEF_VAL and + * V4L2_CTRL_WHICH_REQUEST_VAL. In the case of requests + * it is v4l2_ctrl_request_complete() that copies the + * volatile controls at the time of request completion + * to the request, so you don't want to do that again. + */ + if (!is_default && !is_request && ((master->flags & V4L2_CTRL_FLAG_VOLATILE) || (master->has_volatiles && !is_cur_manual(master)))) { for (j = 0; j < master->ncontrols; j++) cur_to_new(master->cluster[j]); ret = call_op(master, g_volatile_ctrl); - ctrl_to_user = new_to_user; + is_volatile = true; } - /* If OK, then copy the current (for non-volatile controls) - or the new (for volatile controls) control values to the - caller */ - if (!ret) { - u32 idx = i;
- do { - if (helpers[idx].ref->req) - ret = req_to_user(cs->controls + idx, - helpers[idx].ref->req); - else - ret = ctrl_to_user(cs->controls + idx, - helpers[idx].ref->ctrl); - idx = helpers[idx].next; - } while (!ret && idx); + if (ret) { + v4l2_ctrl_unlock(master); + break; } + + /* + * Copy the default value (if is_default is true), the + * request value (if is_request is true and p_req is valid), + * the new volatile value (if is_volatile is true) or the + * current value. + */ + do { + struct v4l2_ctrl_ref *ref = helpers[idx].ref; + + if (is_default) + ret = def_to_user(cs->controls + idx, ref->ctrl); + else if (is_request && ref->valid_p_req) + ret = req_to_user(cs->controls + idx, ref); + else if (is_volatile) + ret = new_to_user(cs->controls + idx, ref->ctrl); + else + ret = cur_to_user(cs->controls + idx, ref->ctrl); + idx = helpers[idx].next; + } while (!ret && idx); + v4l2_ctrl_unlock(master); }
@@ -4368,8 +4368,6 @@ void v4l2_ctrl_request_complete(struct m unsigned int i;
if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { - ref->req = ref; - v4l2_ctrl_lock(master); /* g_volatile_ctrl will update the current control values */ for (i = 0; i < master->ncontrols; i++) @@ -4379,21 +4377,12 @@ void v4l2_ctrl_request_complete(struct m v4l2_ctrl_unlock(master); continue; } - if (ref->req == ref) + if (ref->valid_p_req) continue;
+ /* Copy the current control value into the request */ v4l2_ctrl_lock(ctrl); - if (ref->req) { - ptr_to_ptr(ctrl, ref->req->p_req, ref->p_req); - } else { - ptr_to_ptr(ctrl, ctrl->p_cur, ref->p_req); - /* - * Set ref->req to ensure that when userspace wants to - * obtain the controls of this request it will take - * this value and not the current value of the control. - */ - ref->req = ref; - } + cur_to_req(ref); v4l2_ctrl_unlock(ctrl); }
@@ -4458,7 +4447,7 @@ int v4l2_ctrl_request_setup(struct media struct v4l2_ctrl_ref *r = find_ref(hdl, master->cluster[i]->id);
- if (r->req && r == r->req) { + if (r->valid_p_req) { have_new_data = true; break; } --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -303,12 +303,14 @@ struct v4l2_ctrl { * the control has been applied. This prevents applying controls * from a cluster with multiple controls twice (when the first * control of a cluster is applied, they all are). - * @req: If set, this refers to another request that sets this control. + * @valid_p_req: If set, then p_req contains the control value for the request. * @p_req: If the control handler containing this control reference * is bound to a media request, then this points to the - * value of the control that should be applied when the request + * value of the control that must be applied when the request * is executed, or to the value of the control at the time - * that the request was completed. + * that the request was completed. If @valid_p_req is false, + * then this control was never set for this request and the + * control will not be updated when this request is applied. * * Each control handler has a list of these refs. The list_head is used to * keep a sorted-by-control-ID list of all controls, while the next pointer @@ -321,7 +323,7 @@ struct v4l2_ctrl_ref { struct v4l2_ctrl_helper *helper; bool from_other_dev; bool req_done; - struct v4l2_ctrl_ref *req; + bool valid_p_req; union v4l2_ctrl_ptr p_req; };
@@ -348,7 +350,7 @@ struct v4l2_ctrl_ref { * @error: The error code of the first failed control addition. * @request_is_queued: True if the request was queued. * @requests: List to keep track of open control handler request objects. - * For the parent control handler (@req_obj.req == NULL) this + * For the parent control handler (@req_obj.ops == NULL) this * is the list header. When the parent control handler is * removed, it has to unbind and put all these requests since * they refer to the parent.
From: Stanimir Varbanov stanimir.varbanov@linaro.org
commit 834124c596e2dddbbdba06620835710ccca32fd0 upstream.
The Venus v1 behaves differently comparing with the other Venus version in respect to capability parsing and when they are send to the driver. So we don't need to initialize hfi parser for multiple invocations like what we do for > v1 Venus versions.
Fixes: 10865c98986b ("media: venus: parser: Prepare parser for multiple invocations") Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: Stanimir Varbanov stanimir.varbanov@linaro.org Tested-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/platform/qcom/venus/hfi_parser.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/media/platform/qcom/venus/hfi_parser.c +++ b/drivers/media/platform/qcom/venus/hfi_parser.c @@ -239,8 +239,10 @@ u32 hfi_parser(struct venus_core *core,
parser_init(inst, &codecs, &domain);
- core->codecs_count = 0; - memset(core->caps, 0, sizeof(core->caps)); + if (core->res->hfi_version > HFI_VERSION_1XX) { + core->codecs_count = 0; + memset(core->caps, 0, sizeof(core->caps)); + }
while (words_count) { data = word + 1;
From: Anirudh Rayabharam mail@anirudhrb.com
commit 4a5d797a9f9c4f18585544237216d7812686a71f upstream.
Fix a general protection fault reported by syzbot due to a race between gadget_setup() and gadget_unbind() in raw_gadget.
The gadget core is supposed to guarantee that there won't be any more callbacks to the gadget driver once the driver's unbind routine is called. That guarantee is enforced in usb_gadget_remove_driver as follows:
usb_gadget_disconnect(udc->gadget); if (udc->gadget->irq) synchronize_irq(udc->gadget->irq); udc->driver->unbind(udc->gadget); usb_gadget_udc_stop(udc);
usb_gadget_disconnect turns off the pullup resistor, telling the host that the gadget is no longer connected and preventing the transmission of any more USB packets. Any packets that have already been received are sure to processed by the UDC driver's interrupt handler by the time synchronize_irq returns.
But this doesn't work with dummy_hcd, because dummy_hcd doesn't use interrupts; it uses a timer instead. It does have code to emulate the effect of synchronize_irq, but that code doesn't get invoked at the right time -- it currently runs in usb_gadget_udc_stop, after the unbind callback instead of before. Indeed, there's no way for usb_gadget_remove_driver to invoke this code before the unbind callback.
To fix this, move the synchronize_irq() emulation code to dummy_pullup so that it runs before unbind. Also, add a comment explaining why it is necessary to have it there.
Reported-by: syzbot+eb4674092e6cc8d9e0bd@syzkaller.appspotmail.com Suggested-by: Alan Stern stern@rowland.harvard.edu Acked-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: Anirudh Rayabharam mail@anirudhrb.com Link: https://lore.kernel.org/r/20210419033713.3021-1-mail@anirudhrb.com Cc: stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/gadget/udc/dummy_hcd.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
--- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -901,6 +901,21 @@ static int dummy_pullup(struct usb_gadge spin_lock_irqsave(&dum->lock, flags); dum->pullup = (value != 0); set_link_state(dum_hcd); + if (value == 0) { + /* + * Emulate synchronize_irq(): wait for callbacks to finish. + * This seems to be the best place to emulate the call to + * synchronize_irq() that's in usb_gadget_remove_driver(). + * Doing it in dummy_udc_stop() would be too late since it + * is called after the unbind callback and unbind shouldn't + * be invoked until all the other callbacks are finished. + */ + while (dum->callback_usage > 0) { + spin_unlock_irqrestore(&dum->lock, flags); + usleep_range(1000, 2000); + spin_lock_irqsave(&dum->lock, flags); + } + } spin_unlock_irqrestore(&dum->lock, flags);
usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd)); @@ -1002,14 +1017,6 @@ static int dummy_udc_stop(struct usb_gad spin_lock_irq(&dum->lock); dum->ints_enabled = 0; stop_activity(dum); - - /* emulate synchronize_irq(): wait for callbacks to finish */ - while (dum->callback_usage > 0) { - spin_unlock_irq(&dum->lock); - usleep_range(1000, 2000); - spin_lock_irq(&dum->lock); - } - dum->driver = NULL; spin_unlock_irq(&dum->lock);
From: Hemant Kumar hemantk@codeaurora.org
commit 43c4cab006f55b6ca549dd1214e22f5965a8675f upstream.
Upon driver unbind usb_free_all_descriptors() function frees all speed descriptor pointers without setting them to NULL. In case gadget speed changes (i.e from super speed plus to super speed) after driver unbind only upto super speed descriptor pointers get populated. Super speed plus desc still holds the stale (already freed) pointer. Fix this issue by setting all descriptor pointers to NULL after freeing them in usb_free_all_descriptors().
Fixes: f5c61225cf29 ("usb: gadget: Update function for SuperSpeedPlus") cc: stable@vger.kernel.org Reviewed-by: Peter Chen peter.chen@kernel.org Signed-off-by: Hemant Kumar hemantk@codeaurora.org Signed-off-by: Wesley Cheng wcheng@codeaurora.org Link: https://lore.kernel.org/r/1619034452-17334-1-git-send-email-wcheng@codeauror... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/gadget/config.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -194,9 +194,13 @@ EXPORT_SYMBOL_GPL(usb_assign_descriptors void usb_free_all_descriptors(struct usb_function *f) { usb_free_descriptors(f->fs_descriptors); + f->fs_descriptors = NULL; usb_free_descriptors(f->hs_descriptors); + f->hs_descriptors = NULL; usb_free_descriptors(f->ss_descriptors); + f->ss_descriptors = NULL; usb_free_descriptors(f->ssp_descriptors); + f->ssp_descriptors = NULL; } EXPORT_SYMBOL_GPL(usb_free_all_descriptors);
From: Dean Anderson dean@sensoray.com
commit 55b74ce7d2ce0b0058f3e08cab185a0afacfe39e upstream.
Fixes bug with the handling of more than one language in the string table in f_fs.c. str_count was not reset for subsequent language codes. str_count-- "rolls under" and processes u32 max strings on the processing of the second language entry. The existing bug can be reproduced by adding a second language table to the structure "strings" in tools/usb/ffs-test.c.
Signed-off-by: Dean Anderson dean@sensoray.com Link: https://lore.kernel.org/r/20210317224109.21534-1-dean@sensoray.com Cc: stable stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/gadget/function/f_fs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -2639,6 +2639,7 @@ static int __ffs_data_got_strings(struct
do { /* lang_count > 0 so we can use do-while */ unsigned needed = needed_count; + u32 str_per_lang = str_count;
if (unlikely(len < 3)) goto error_free; @@ -2674,7 +2675,7 @@ static int __ffs_data_got_strings(struct
data += length + 1; len -= length + 1; - } while (--str_count); + } while (--str_per_lang);
s->id = 0; /* terminator */ s->s = NULL;
From: Thinh Nguyen Thinh.Nguyen@synopsys.com
commit 3232a3ce55edfc0d7f8904543b4088a5339c2b2b upstream.
The programming guide incorrectly stated that the DCFG.bInterval_m1 must be set to 0 when operating in fullspeed. There's no such limitation for all IPs. See DWC_usb3x programming guide section 3.2.2.1.
Fixes: a1679af85b2a ("usb: dwc3: gadget: Fix setting of DEPCFG.bInterval_m1") Cc: stable@vger.kernel.org Acked-by: Felipe Balbi balbi@kernel.org Signed-off-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Link: https://lore.kernel.org/r/5d4139ae89d810eb0a2d8577fb096fc88e87bfab.161847245... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/dwc3/gadget.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -608,12 +608,14 @@ static int dwc3_gadget_set_ep_config(str u8 bInterval_m1;
/* - * Valid range for DEPCFG.bInterval_m1 is from 0 to 13, and it - * must be set to 0 when the controller operates in full-speed. + * Valid range for DEPCFG.bInterval_m1 is from 0 to 13. + * + * NOTE: The programming guide incorrectly stated bInterval_m1 + * must be set to 0 when operating in fullspeed. Internally the + * controller does not have this limitation. See DWC_usb3x + * programming guide section 3.2.2.1. */ bInterval_m1 = min_t(u8, desc->bInterval - 1, 13); - if (dwc->gadget->speed == USB_SPEED_FULL) - bInterval_m1 = 0;
if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_INT && dwc->gadget->speed == USB_SPEED_FULL)
From: Thinh Nguyen Thinh.Nguyen@synopsys.com
commit c560e76319a94a3b9285bc426c609903408e4826 upstream.
The START_TRANSFER command needs to be executed while in ON/U0 link state (with an exception during register initialization). Don't use dwc->link_state to check this since the driver only tracks the link state when the link state change interrupt is enabled. Check the link state from DSTS register instead.
Note that often the host already brings the device out of low power before it sends/requests the next transfer. So, the user won't see any issue when the device starts transfer then. This issue is more noticeable in cases when the device delays starting transfer, which can happen during delayed control status after the host put the device in low power.
Fixes: 799e9dc82968 ("usb: dwc3: gadget: conditionally disable Link State change events") Cc: stable@vger.kernel.org Acked-by: Felipe Balbi balbi@kernel.org Signed-off-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Link: https://lore.kernel.org/r/bcefaa9ecbc3e1936858c0baa14de6612960e909.161888422... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/dwc3/gadget.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
--- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -308,13 +308,12 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ }
if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) { - int needs_wakeup; + int link_state;
- needs_wakeup = (dwc->link_state == DWC3_LINK_STATE_U1 || - dwc->link_state == DWC3_LINK_STATE_U2 || - dwc->link_state == DWC3_LINK_STATE_U3); - - if (unlikely(needs_wakeup)) { + link_state = dwc3_gadget_get_link_state(dwc); + if (link_state == DWC3_LINK_STATE_U1 || + link_state == DWC3_LINK_STATE_U2 || + link_state == DWC3_LINK_STATE_U3) { ret = __dwc3_gadget_wakeup(dwc); dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n", ret); @@ -1975,6 +1974,8 @@ static int __dwc3_gadget_wakeup(struct d case DWC3_LINK_STATE_RESET: case DWC3_LINK_STATE_RX_DET: /* in HS, means Early Suspend */ case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */ + case DWC3_LINK_STATE_U2: /* in HS, means Sleep (L1) */ + case DWC3_LINK_STATE_U1: case DWC3_LINK_STATE_RESUME: break; default:
From: Yu Chen chenyu56@huawei.com
commit f88359e1588b85cf0e8209ab7d6620085f3441d9 upstream.
From: John Stultz john.stultz@linaro.org
According to the programming guide, to switch mode for DRD controller, the driver needs to do the following.
To switch from device to host: 1. Reset controller with GCTL.CoreSoftReset 2. Set GCTL.PrtCapDir(host mode) 3. Reset the host with USBCMD.HCRESET 4. Then follow up with the initializing host registers sequence
To switch from host to device: 1. Reset controller with GCTL.CoreSoftReset 2. Set GCTL.PrtCapDir(device mode) 3. Reset the device with DCTL.CSftRst 4. Then follow up with the initializing registers sequence
Currently we're missing step 1) to do GCTL.CoreSoftReset and step 3) of switching from host to device. John Stult reported a lockup issue seen with HiKey960 platform without these steps[1]. Similar issue is observed with Ferry's testing platform[2].
So, apply the required steps along with some fixes to Yu Chen's and John Stultz's version. The main fixes to their versions are the missing wait for clocks synchronization before clearing GCTL.CoreSoftReset and only apply DCTL.CSftRst when switching from host to device.
[1] https://lore.kernel.org/linux-usb/20210108015115.27920-1-john.stultz@linaro.... [2] https://lore.kernel.org/linux-usb/0ba7a6ba-e6a7-9cd4-0695-64fc927e01f1@gmail...
Fixes: 41ce1456e1db ("usb: dwc3: core: make dwc3_set_mode() work properly") Cc: Andy Shevchenko andy.shevchenko@gmail.com Cc: Ferry Toth fntoth@gmail.com Cc: Wesley Cheng wcheng@codeaurora.org Cc: stable@vger.kernel.org Tested-by: John Stultz john.stultz@linaro.org Tested-by: Wesley Cheng wcheng@codeaurora.org Signed-off-by: Yu Chen chenyu56@huawei.com Signed-off-by: John Stultz john.stultz@linaro.org Signed-off-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Link: https://lore.kernel.org/r/374440f8dcd4f06c02c2caf4b1efde86774e02d9.161852166... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/dwc3/core.c | 27 +++++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 5 +++++ 2 files changed, 32 insertions(+)
--- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -114,6 +114,8 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u dwc->current_dr_role = mode; }
+static int dwc3_core_soft_reset(struct dwc3 *dwc); + static void __dwc3_set_mode(struct work_struct *work) { struct dwc3 *dwc = work_to_dwc(work); @@ -121,6 +123,8 @@ static void __dwc3_set_mode(struct work_ int ret; u32 reg;
+ mutex_lock(&dwc->mutex); + pm_runtime_get_sync(dwc->dev);
if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG) @@ -154,6 +158,25 @@ static void __dwc3_set_mode(struct work_ break; }
+ /* For DRD host or device mode only */ + if (dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { + reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg |= DWC3_GCTL_CORESOFTRESET; + dwc3_writel(dwc->regs, DWC3_GCTL, reg); + + /* + * Wait for internal clocks to synchronized. DWC_usb31 and + * DWC_usb32 may need at least 50ms (less for DWC_usb3). To + * keep it consistent across different IPs, let's wait up to + * 100ms before clearing GCTL.CORESOFTRESET. + */ + msleep(100); + + reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg &= ~DWC3_GCTL_CORESOFTRESET; + dwc3_writel(dwc->regs, DWC3_GCTL, reg); + } + spin_lock_irqsave(&dwc->lock, flags);
dwc3_set_prtcap(dwc, dwc->desired_dr_role); @@ -178,6 +201,8 @@ static void __dwc3_set_mode(struct work_ } break; case DWC3_GCTL_PRTCAP_DEVICE: + dwc3_core_soft_reset(dwc); + dwc3_event_buffers_setup(dwc);
if (dwc->usb2_phy) @@ -200,6 +225,7 @@ static void __dwc3_set_mode(struct work_ out: pm_runtime_mark_last_busy(dwc->dev); pm_runtime_put_autosuspend(dwc->dev); + mutex_unlock(&dwc->mutex); }
void dwc3_set_mode(struct dwc3 *dwc, u32 mode) @@ -1529,6 +1555,7 @@ static int dwc3_probe(struct platform_de dwc3_cache_hwparams(dwc);
spin_lock_init(&dwc->lock); + mutex_init(&dwc->mutex);
pm_runtime_set_active(dev); pm_runtime_use_autosuspend(dev); --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -13,6 +13,7 @@
#include <linux/device.h> #include <linux/spinlock.h> +#include <linux/mutex.h> #include <linux/ioport.h> #include <linux/list.h> #include <linux/bitops.h> @@ -942,6 +943,7 @@ struct dwc3_scratchpad_array { * @scratch_addr: dma address of scratchbuf * @ep0_in_setup: one control transfer is completed and enter setup phase * @lock: for synchronizing + * @mutex: for mode switching * @dev: pointer to our struct device * @sysdev: pointer to the DMA-capable device * @xhci: pointer to our xHCI child @@ -1078,6 +1080,9 @@ struct dwc3 { /* device lock */ spinlock_t lock;
+ /* mode switching lock */ + struct mutex mutex; + struct device *dev; struct device *sysdev;
From: Artur Petrosyan Arthur.Petrosyan@synopsys.com
commit 42b32b164acecd850edef010915a02418345a033 upstream.
According to programming guide in host mode, port power must be turned on in session request interrupt handlers.
Fixes: 21795c826a45 ("usb: dwc2: exit hibernation on session request") Cc: stable@vger.kernel.org Acked-by: Minas Harutyunyan Minas.Harutyunyan@synopsys.com Signed-off-by: Artur Petrosyan Arthur.Petrosyan@synopsys.com Link: https://lore.kernel.org/r/20210408094550.75484A0094@mailhost.synopsys.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/dwc2/core_intr.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -307,6 +307,7 @@ static void dwc2_handle_conn_id_status_c static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) { int ret; + u32 hprt0;
/* Clear interrupt */ dwc2_writel(hsotg, GINTSTS_SESSREQINT, GINTSTS); @@ -327,6 +328,13 @@ static void dwc2_handle_session_req_intr * established */ dwc2_hsotg_disconnect(hsotg); + } else { + /* Turn on the port power bit. */ + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_PWR; + dwc2_writel(hsotg, hprt0, HPRT0); + /* Connect hcd after port power is set. */ + dwc2_hcd_connect(hsotg); } }
From: Pavel Skripkin paskripkin@gmail.com
commit 211b4d42b70f1c1660feaa968dac0efc2a96ac4d upstream.
syzbot reported memory leak in tty/vt. The problem was in VT_DISALLOCATE ioctl cmd. After allocating unimap with PIO_UNIMAP it wasn't freed via VT_DISALLOCATE, but vc_cons[currcons].d was zeroed.
Reported-by: syzbot+bcc922b19ccc64240b42@syzkaller.appspotmail.com Signed-off-by: Pavel Skripkin paskripkin@gmail.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20210327214443.21548-1-paskripkin@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/vt/vt.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1382,6 +1382,7 @@ struct vc_data *vc_deallocate(unsigned i atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, ¶m); vcs_remove_sysfs(currcons); visual_deinit(vc); + con_free_unimap(vc); put_pid(vc->vt_pid); vc_uniscr_set(vc, NULL); kfree(vc->vc_screenbuf);
From: Marek Vasut marex@denx.de
commit c434e5e48dc4e626364491455f97e2db0aa137b1 upstream.
The rsi_resume() does access the bus to enable interrupts on the RSI SDIO WiFi card, however when calling sdio_claim_host() in the resume path, it is possible the bus is already claimed and sdio_claim_host() spins indefinitelly. Enable the SDIO card interrupts in resume_noirq instead to prevent anything else from claiming the SDIO bus first.
Fixes: 20db07332736 ("rsi: sdio suspend and resume support") Signed-off-by: Marek Vasut marex@denx.de Cc: Amitkumar Karwar amit.karwar@redpinesignals.com Cc: Angus Ainslie angus@akkea.ca Cc: David S. Miller davem@davemloft.net Cc: Jakub Kicinski kuba@kernel.org Cc: Kalle Valo kvalo@codeaurora.org Cc: Karun Eagalapati karun256@gmail.com Cc: Martin Kepplinger martink@posteo.de Cc: Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm Cc: Siva Rebbagondla siva8118@gmail.com Cc: netdev@vger.kernel.org Cc: stable@vger.kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210327235932.175896-1-marex@denx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/rsi/rsi_91x_sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -1513,7 +1513,7 @@ static int rsi_restore(struct device *de } static const struct dev_pm_ops rsi_pm_ops = { .suspend = rsi_suspend, - .resume = rsi_resume, + .resume_noirq = rsi_resume, .freeze = rsi_freeze, .thaw = rsi_thaw, .restore = rsi_restore,
From: Calvin Walton calvin.walton@kepstin.ca
commit 13a779de4175df602366d129e41782ad7168cef0 upstream.
The idx_to_offset() function returns type int (32-bit signed), but MSR_PKG_ENERGY_STAT is u32 and would be interpreted as a negative number. The end result is that it hits the if (offset < 0) check in update_msr_sum() which prevents the timer callback from updating the stat in the background when long durations are used. The similar issue exists in offset_to_idx() and update_msr_sum(). Fix this issue by converting the 'int' to 'off_t' accordingly.
Fixes: 9972d5d84d76 ("tools/power turbostat: Enable accumulate RAPL display") Signed-off-by: Calvin Walton calvin.walton@kepstin.ca Signed-off-by: Len Brown len.brown@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/power/x86/turbostat/turbostat.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
--- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -291,9 +291,9 @@ struct msr_sum_array { /* The percpu MSR sum array.*/ struct msr_sum_array *per_cpu_msr_sum;
-int idx_to_offset(int idx) +off_t idx_to_offset(int idx) { - int offset; + off_t offset;
switch (idx) { case IDX_PKG_ENERGY: @@ -323,7 +323,7 @@ int idx_to_offset(int idx) return offset; }
-int offset_to_idx(int offset) +int offset_to_idx(off_t offset) { int idx;
@@ -3249,7 +3249,7 @@ static int update_msr_sum(struct thread_
for (i = IDX_PKG_ENERGY; i < IDX_COUNT; i++) { unsigned long long msr_cur, msr_last; - int offset; + off_t offset;
if (!idx_valid(i)) continue; @@ -3258,7 +3258,8 @@ static int update_msr_sum(struct thread_ continue; ret = get_msr(cpu, offset, &msr_cur); if (ret) { - fprintf(outf, "Can not update msr(0x%x)\n", offset); + fprintf(outf, "Can not update msr(0x%llx)\n", + (unsigned long long)offset); continue; }
From: Steven Rostedt (VMware) rostedt@goodmis.org
commit 785e3c0a3a870e72dc530856136ab4c8dd207128 upstream.
The default max PID is set by PID_MAX_DEFAULT, and the tracing infrastructure uses this number to map PIDs to the comm names of the tasks, such output of the trace can show names from the recorded PIDs in the ring buffer. This mapping is also exported to user space via the "saved_cmdlines" file in the tracefs directory.
But currently the mapping expects the PIDs to be less than PID_MAX_DEFAULT, which is the default maximum and not the real maximum. Recently, systemd will increases the maximum value of a PID on the system, and when tasks are traced that have a PID higher than PID_MAX_DEFAULT, its comm is not recorded. This leads to the entire trace to have "<...>" as the comm name, which is pretty useless.
Instead, keep the array mapping the size of PID_MAX_DEFAULT, but instead of just mapping the index to the comm, map a mask of the PID (PID_MAX_DEFAULT - 1) to the comm, and find the full PID from the map_cmdline_to_pid array (that already exists).
This bug goes back to the beginning of ftrace, but hasn't been an issue until user space started increasing the maximum value of PIDs.
Link: https://lkml.kernel.org/r/20210427113207.3c601884@gandalf.local.home
Cc: stable@vger.kernel.org Fixes: bc0c38d139ec7 ("ftrace: latency tracer infrastructure") Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/trace.c | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-)
--- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2387,14 +2387,13 @@ static void tracing_stop_tr(struct trace
static int trace_save_cmdline(struct task_struct *tsk) { - unsigned pid, idx; + unsigned tpid, idx;
/* treat recording of idle task as a success */ if (!tsk->pid) return 1;
- if (unlikely(tsk->pid > PID_MAX_DEFAULT)) - return 0; + tpid = tsk->pid & (PID_MAX_DEFAULT - 1);
/* * It's not the end of the world if we don't get @@ -2405,26 +2404,15 @@ static int trace_save_cmdline(struct tas if (!arch_spin_trylock(&trace_cmdline_lock)) return 0;
- idx = savedcmd->map_pid_to_cmdline[tsk->pid]; + idx = savedcmd->map_pid_to_cmdline[tpid]; if (idx == NO_CMDLINE_MAP) { idx = (savedcmd->cmdline_idx + 1) % savedcmd->cmdline_num;
- /* - * Check whether the cmdline buffer at idx has a pid - * mapped. We are going to overwrite that entry so we - * need to clear the map_pid_to_cmdline. Otherwise we - * would read the new comm for the old pid. - */ - pid = savedcmd->map_cmdline_to_pid[idx]; - if (pid != NO_CMDLINE_MAP) - savedcmd->map_pid_to_cmdline[pid] = NO_CMDLINE_MAP; - - savedcmd->map_cmdline_to_pid[idx] = tsk->pid; - savedcmd->map_pid_to_cmdline[tsk->pid] = idx; - + savedcmd->map_pid_to_cmdline[tpid] = idx; savedcmd->cmdline_idx = idx; }
+ savedcmd->map_cmdline_to_pid[idx] = tsk->pid; set_cmdline(idx, tsk->comm);
arch_spin_unlock(&trace_cmdline_lock); @@ -2435,6 +2423,7 @@ static int trace_save_cmdline(struct tas static void __trace_find_cmdline(int pid, char comm[]) { unsigned map; + int tpid;
if (!pid) { strcpy(comm, "<idle>"); @@ -2446,16 +2435,16 @@ static void __trace_find_cmdline(int pid return; }
- if (pid > PID_MAX_DEFAULT) { - strcpy(comm, "<...>"); - return; + tpid = pid & (PID_MAX_DEFAULT - 1); + map = savedcmd->map_pid_to_cmdline[tpid]; + if (map != NO_CMDLINE_MAP) { + tpid = savedcmd->map_cmdline_to_pid[map]; + if (tpid == pid) { + strlcpy(comm, get_saved_cmdlines(map), TASK_COMM_LEN); + return; + } } - - map = savedcmd->map_pid_to_cmdline[pid]; - if (map != NO_CMDLINE_MAP) - strlcpy(comm, get_saved_cmdlines(map), TASK_COMM_LEN); - else - strcpy(comm, "<...>"); + strcpy(comm, "<...>"); }
void trace_find_cmdline(int pid, char comm[])
From: Steven Rostedt (VMware) rostedt@goodmis.org
commit aafe104aa9096827a429bc1358f8260ee565b7cc upstream.
It was reported that a fix to the ring buffer recursion detection would cause a hung machine when performing suspend / resume testing. The following backtrace was extracted from debugging that case:
Call Trace: trace_clock_global+0x91/0xa0 __rb_reserve_next+0x237/0x460 ring_buffer_lock_reserve+0x12a/0x3f0 trace_buffer_lock_reserve+0x10/0x50 __trace_graph_return+0x1f/0x80 trace_graph_return+0xb7/0xf0 ? trace_clock_global+0x91/0xa0 ftrace_return_to_handler+0x8b/0xf0 ? pv_hash+0xa0/0xa0 return_to_handler+0x15/0x30 ? ftrace_graph_caller+0xa0/0xa0 ? trace_clock_global+0x91/0xa0 ? __rb_reserve_next+0x237/0x460 ? ring_buffer_lock_reserve+0x12a/0x3f0 ? trace_event_buffer_lock_reserve+0x3c/0x120 ? trace_event_buffer_reserve+0x6b/0xc0 ? trace_event_raw_event_device_pm_callback_start+0x125/0x2d0 ? dpm_run_callback+0x3b/0xc0 ? pm_ops_is_empty+0x50/0x50 ? platform_get_irq_byname_optional+0x90/0x90 ? trace_device_pm_callback_start+0x82/0xd0 ? dpm_run_callback+0x49/0xc0
With the following RIP:
RIP: 0010:native_queued_spin_lock_slowpath+0x69/0x200
Since the fix to the recursion detection would allow a single recursion to happen while tracing, this lead to the trace_clock_global() taking a spin lock and then trying to take it again:
ring_buffer_lock_reserve() { trace_clock_global() { arch_spin_lock() { queued_spin_lock_slowpath() { /* lock taken */ (something else gets traced by function graph tracer) ring_buffer_lock_reserve() { trace_clock_global() { arch_spin_lock() { queued_spin_lock_slowpath() { /* DEAD LOCK! */
Tracing should *never* block, as it can lead to strange lockups like the above.
Restructure the trace_clock_global() code to instead of simply taking a lock to update the recorded "prev_time" simply use it, as two events happening on two different CPUs that calls this at the same time, really doesn't matter which one goes first. Use a trylock to grab the lock for updating the prev_time, and if it fails, simply try again the next time. If it failed to be taken, that means something else is already updating it.
Link: https://lkml.kernel.org/r/20210430121758.650b6e8a@gandalf.local.home
Cc: stable@vger.kernel.org Tested-by: Konstantin Kharlamov hi-angel@yandex.ru Tested-by: Todd Brandt todd.e.brandt@linux.intel.com Fixes: b02414c8f045 ("ring-buffer: Fix recursion protection transitions between interrupt context") # started showing the problem Fixes: 14131f2f98ac3 ("tracing: implement trace_clock_*() APIs") # where the bug happened Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=212761 Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/trace_clock.c | 48 ++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 16 deletions(-)
--- a/kernel/trace/trace_clock.c +++ b/kernel/trace/trace_clock.c @@ -95,33 +95,49 @@ u64 notrace trace_clock_global(void) { unsigned long flags; int this_cpu; - u64 now; + u64 now, prev_time;
raw_local_irq_save(flags);
this_cpu = raw_smp_processor_id(); - now = sched_clock_cpu(this_cpu); + /* - * If in an NMI context then dont risk lockups and return the - * cpu_clock() time: + * The global clock "guarantees" that the events are ordered + * between CPUs. But if two events on two different CPUS call + * trace_clock_global at roughly the same time, it really does + * not matter which one gets the earlier time. Just make sure + * that the same CPU will always show a monotonic clock. + * + * Use a read memory barrier to get the latest written + * time that was recorded. */ - if (unlikely(in_nmi())) - goto out; + smp_rmb(); + prev_time = READ_ONCE(trace_clock_struct.prev_time); + now = sched_clock_cpu(this_cpu);
- arch_spin_lock(&trace_clock_struct.lock); + /* Make sure that now is always greater than prev_time */ + if ((s64)(now - prev_time) < 0) + now = prev_time + 1;
/* - * TODO: if this happens often then maybe we should reset - * my_scd->clock to prev_time+1, to make sure - * we start ticking with the local clock from now on? + * If in an NMI context then dont risk lockups and simply return + * the current time. */ - if ((s64)(now - trace_clock_struct.prev_time) < 0) - now = trace_clock_struct.prev_time + 1; - - trace_clock_struct.prev_time = now; - - arch_spin_unlock(&trace_clock_struct.lock); + if (unlikely(in_nmi())) + goto out;
+ /* Tracing can cause strange recursion, always use a try lock */ + if (arch_spin_trylock(&trace_clock_struct.lock)) { + /* Reread prev_time in case it was already updated */ + prev_time = READ_ONCE(trace_clock_struct.prev_time); + if ((s64)(now - prev_time) < 0) + now = prev_time + 1; + + trace_clock_struct.prev_time = now; + + /* The unlock acts as the wmb for the above rmb */ + arch_spin_unlock(&trace_clock_struct.lock); + } out: raw_local_irq_restore(flags);
From: Joe Thornber ejt@redhat.com
commit a88b2358f1da2c9f9fcc432f2e0a79617fea397c upstream.
Otherwise most non-x86 architectures (e.g. riscv, arm) will resort to byte-by-byte access.
Cc: stable@vger.kernel.org Signed-off-by: Joe Thornber ejt@redhat.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/persistent-data/dm-btree-internal.h | 4 ++-- drivers/md/persistent-data/dm-space-map-common.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/md/persistent-data/dm-btree-internal.h +++ b/drivers/md/persistent-data/dm-btree-internal.h @@ -34,12 +34,12 @@ struct node_header { __le32 max_entries; __le32 value_size; __le32 padding; -} __packed; +} __attribute__((packed, aligned(8)));
struct btree_node { struct node_header header; __le64 keys[]; -} __packed; +} __attribute__((packed, aligned(8)));
/* --- a/drivers/md/persistent-data/dm-space-map-common.h +++ b/drivers/md/persistent-data/dm-space-map-common.h @@ -33,7 +33,7 @@ struct disk_index_entry { __le64 blocknr; __le32 nr_free; __le32 none_free_before; -} __packed; +} __attribute__ ((packed, aligned(8)));
#define MAX_METADATA_BITMAPS 255 @@ -43,7 +43,7 @@ struct disk_metadata_index { __le64 blocknr;
struct disk_index_entry index[MAX_METADATA_BITMAPS]; -} __packed; +} __attribute__ ((packed, aligned(8)));
struct ll_disk;
@@ -86,7 +86,7 @@ struct disk_sm_root { __le64 nr_allocated; __le64 bitmap_root; __le64 ref_count_root; -} __packed; +} __attribute__ ((packed, aligned(8)));
#define ENTRIES_PER_BYTE 4
@@ -94,7 +94,7 @@ struct disk_bitmap_header { __le32 csum; __le32 not_used; __le64 blocknr; -} __packed; +} __attribute__ ((packed, aligned(8)));
enum allocation_event { SM_NONE,
From: Joe Thornber ejt@redhat.com
commit 5208692e80a1f3c8ce2063a22b675dd5589d1d80 upstream.
This division bug meant the search for free metadata space could skip the final allocation bitmap's worth of entries. Fix affects DM thinp, cache and era targets.
Cc: stable@vger.kernel.org Signed-off-by: Joe Thornber ejt@redhat.com Tested-by: Ming-Hung Tsai mtsai@redhat.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/persistent-data/dm-space-map-common.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/md/persistent-data/dm-space-map-common.c +++ b/drivers/md/persistent-data/dm-space-map-common.c @@ -339,6 +339,8 @@ int sm_ll_find_free_block(struct ll_disk */ begin = do_div(index_begin, ll->entries_per_block); end = do_div(end, ll->entries_per_block); + if (end == 0) + end = ll->entries_per_block;
for (i = index_begin; i < index_end; i++, begin = 0) { struct dm_block *blk;
From: Tian Tao tiantao6@hisilicon.com
commit 17e9e134a8efabbbf689a0904eee92bb5a868172 upstream.
Fixes: 468dfca38b1a ("dm integrity: add a bitmap mode") Cc: stable@vger.kernel.org Signed-off-by: Tian Tao tiantao6@hisilicon.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/dm-integrity.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -3929,6 +3929,7 @@ static int dm_integrity_ctr(struct dm_ta if (val >= (uint64_t)UINT_MAX * 1000 / HZ) { r = -EINVAL; ti->error = "Invalid bitmap_flush_interval argument"; + goto bad; } ic->bitmap_flush_interval = msecs_to_jiffies(val); } else if (!strncmp(opt_string, "internal_hash:", strlen("internal_hash:"))) {
From: Benjamin Block bblock@linux.ibm.com
commit 8e947c8f4a5620df77e43c9c75310dc510250166 upstream.
When loading a device-mapper table for a request-based mapped device, and the allocation/initialization of the blk_mq_tag_set for the device fails, a following device remove will cause a double free.
E.g. (dmesg): device-mapper: core: Cannot initialize queue for request-based dm-mq mapped device device-mapper: ioctl: unable to set up device queue for new table. Unable to handle kernel pointer dereference in virtual kernel address space Failing address: 0305e098835de000 TEID: 0305e098835de803 Fault in home space mode while using kernel ASCE. AS:000000025efe0007 R3:0000000000000024 Oops: 0038 ilc:3 [#1] SMP Modules linked in: ... lots of modules ... Supported: Yes, External CPU: 0 PID: 7348 Comm: multipathd Kdump: loaded Tainted: G W X 5.3.18-53-default #1 SLE15-SP3 Hardware name: IBM 8561 T01 7I2 (LPAR) Krnl PSW : 0704e00180000000 000000025e368eca (kfree+0x42/0x330) R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 RI:0 EA:3 Krnl GPRS: 000000000000004a 000000025efe5230 c1773200d779968d 0000000000000000 000000025e520270 000000025e8d1b40 0000000000000003 00000007aae10000 000000025e5202a2 0000000000000001 c1773200d779968d 0305e098835de640 00000007a8170000 000003ff80138650 000000025e5202a2 000003e00396faa8 Krnl Code: 000000025e368eb8: c4180041e100 lgrl %r1,25eba50b8 000000025e368ebe: ecba06b93a55 risbg %r11,%r10,6,185,58 #000000025e368ec4: e3b010000008 ag %r11,0(%r1) >000000025e368eca: e310b0080004 lg %r1,8(%r11) 000000025e368ed0: a7110001 tmll %r1,1 000000025e368ed4: a7740129 brc 7,25e369126 000000025e368ed8: e320b0080004 lg %r2,8(%r11) 000000025e368ede: b904001b lgr %r1,%r11 Call Trace: [<000000025e368eca>] kfree+0x42/0x330 [<000000025e5202a2>] blk_mq_free_tag_set+0x72/0xb8 [<000003ff801316a8>] dm_mq_cleanup_mapped_device+0x38/0x50 [dm_mod] [<000003ff80120082>] free_dev+0x52/0xd0 [dm_mod] [<000003ff801233f0>] __dm_destroy+0x150/0x1d0 [dm_mod] [<000003ff8012bb9a>] dev_remove+0x162/0x1c0 [dm_mod] [<000003ff8012a988>] ctl_ioctl+0x198/0x478 [dm_mod] [<000003ff8012ac8a>] dm_ctl_ioctl+0x22/0x38 [dm_mod] [<000000025e3b11ee>] ksys_ioctl+0xbe/0xe0 [<000000025e3b127a>] __s390x_sys_ioctl+0x2a/0x40 [<000000025e8c15ac>] system_call+0xd8/0x2c8 Last Breaking-Event-Address: [<000000025e52029c>] blk_mq_free_tag_set+0x6c/0xb8 Kernel panic - not syncing: Fatal exception: panic_on_oops
When allocation/initialization of the blk_mq_tag_set fails in dm_mq_init_request_queue(), it is uninitialized/freed, but the pointer is not reset to NULL; so when dev_remove() later gets into dm_mq_cleanup_mapped_device() it sees the pointer and tries to uninitialize and free it again.
Fix this by setting the pointer to NULL in dm_mq_init_request_queue() error-handling. Also set it to NULL in dm_mq_cleanup_mapped_device().
Cc: stable@vger.kernel.org # 4.6+ Fixes: 1c357a1e86a4 ("dm: allocate blk_mq_tag_set rather than embed in mapped_device") Signed-off-by: Benjamin Block bblock@linux.ibm.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/dm-rq.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/md/dm-rq.c +++ b/drivers/md/dm-rq.c @@ -569,6 +569,7 @@ out_tag_set: blk_mq_free_tag_set(md->tag_set); out_kfree_tag_set: kfree(md->tag_set); + md->tag_set = NULL;
return err; } @@ -578,6 +579,7 @@ void dm_mq_cleanup_mapped_device(struct if (md->tag_set) { blk_mq_free_tag_set(md->tag_set); kfree(md->tag_set); + md->tag_set = NULL; } }
From: Rasmus Villemoes linux@rasmusvillemoes.dk
commit 84696cfaf4d90945eb2a8302edc6cf627db56b84 upstream.
Commit 9af7706492f9 ("lib/vsprintf: Remove support for %pF and %pf in favour of %pS and %ps") removed support for %pF and %pf, and correctly removed the handling of those cases in vbin_printf(). However, the corresponding cases in bstr_printf() were left behind.
In the same series, %pf was re-purposed for dealing with fwnodes (3bd32d6a2ee6, "lib/vsprintf: Add %pfw conversion specifier for printing fwnode names").
So should anyone use %pf with the binary printf routines, vbin_printf() would (correctly, as it involves dereferencing the pointer) do the string formatting to the u32 array, but bstr_printf() would not copy the string from the u32 array, but instead interpret the first sizeof(void*) bytes of the formatted string as a pointer - which generally won't end well (also, all subsequent get_args would be out of sync).
Fixes: 9af7706492f9 ("lib/vsprintf: Remove support for %pF and %pf in favour of %pS and %ps") Cc: stable@vger.kernel.org Signed-off-by: Rasmus Villemoes linux@rasmusvillemoes.dk Reviewed-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Petr Mladek pmladek@suse.com Link: https://lore.kernel.org/r/20210423094529.1862521-1-linux@rasmusvillemoes.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- lib/vsprintf.c | 2 -- 1 file changed, 2 deletions(-)
--- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -3102,8 +3102,6 @@ int bstr_printf(char *buf, size_t size, switch (*fmt) { case 'S': case 's': - case 'F': - case 'f': case 'x': case 'K': case 'e':
From: brian-sy yang brian-sy.yang@mediatek.com
commit 34ab17cc6c2c1ac93d7e5d53bb972df9a968f085 upstream.
Slab OOB issue is scanned by KASAN in cpu_power_to_freq(). If power is limited below the power of OPP0 in EM table, it will cause slab out-of-bound issue with negative array index.
Return the lowest frequency if limited power cannot found a suitable OPP in EM table to fix this issue.
Backtrace: [<ffffffd02d2a37f0>] die+0x104/0x5ac [<ffffffd02d2a5630>] bug_handler+0x64/0xd0 [<ffffffd02d288ce4>] brk_handler+0x160/0x258 [<ffffffd02d281e5c>] do_debug_exception+0x248/0x3f0 [<ffffffd02d284488>] el1_dbg+0x14/0xbc [<ffffffd02d75d1d4>] __kasan_report+0x1dc/0x1e0 [<ffffffd02d75c2e0>] kasan_report+0x10/0x20 [<ffffffd02d75def8>] __asan_report_load8_noabort+0x18/0x28 [<ffffffd02e6fce5c>] cpufreq_power2state+0x180/0x43c [<ffffffd02e6ead80>] power_actor_set_power+0x114/0x1d4 [<ffffffd02e6fac24>] allocate_power+0xaec/0xde0 [<ffffffd02e6f9f80>] power_allocator_throttle+0x3ec/0x5a4 [<ffffffd02e6ea888>] handle_thermal_trip+0x160/0x294 [<ffffffd02e6edd08>] thermal_zone_device_check+0xe4/0x154 [<ffffffd02d351cb4>] process_one_work+0x5e4/0xe28 [<ffffffd02d352f44>] worker_thread+0xa4c/0xfac [<ffffffd02d360124>] kthread+0x33c/0x358 [<ffffffd02d289940>] ret_from_fork+0xc/0x18
Fixes: 371a3bc79c11b ("thermal/drivers/cpufreq_cooling: Fix wrong frequency converted from power") Signed-off-by: brian-sy yang brian-sy.yang@mediatek.com Signed-off-by: Michael Kao michael.kao@mediatek.com Reviewed-by: Lukasz Luba lukasz.luba@arm.com Cc: stable@vger.kernel.org #v5.7 Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/20201229050831.19493-1-michael.kao@mediatek.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/thermal/cpufreq_cooling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -123,7 +123,7 @@ static u32 cpu_power_to_freq(struct cpuf { int i;
- for (i = cpufreq_cdev->max_level; i >= 0; i--) { + for (i = cpufreq_cdev->max_level; i > 0; i--) { if (power >= cpufreq_cdev->em->table[i].power) break; }
From: Lukasz Luba lukasz.luba@arm.com
commit fef05776eb02238dcad8d5514e666a42572c3f32 upstream.
The tz->lock must be hold during the looping over the instances in that thermal zone. This lock was missing in the governor code since the beginning, so it's hard to point into a particular commit.
CC: stable@vger.kernel.org # 4.4+ Signed-off-by: Lukasz Luba lukasz.luba@arm.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/20210422153624.6074-2-lukasz.luba@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/thermal/gov_fair_share.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/thermal/gov_fair_share.c +++ b/drivers/thermal/gov_fair_share.c @@ -82,6 +82,8 @@ static int fair_share_throttle(struct th int total_instance = 0; int cur_trip_level = get_trip_level(tz);
+ mutex_lock(&tz->lock); + list_for_each_entry(instance, &tz->thermal_instances, tz_node) { if (instance->trip != trip) continue; @@ -110,6 +112,8 @@ static int fair_share_throttle(struct th mutex_unlock(&instance->cdev->lock); thermal_cdev_update(cdev); } + + mutex_unlock(&tz->lock); return 0; }
Hi!
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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.
CIP testing did not find any kernel problems here: (Siemens board is unavailable): https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-5...
Tested-by: Pavel Machek (CIP) pavel@denx.de
Best regards, Pavel
On Mon, 10 May 2021 12:16:37 +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y and the diffstat can be found below.
thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.10: 12 builds: 12 pass, 0 fail 28 boots: 28 pass, 0 fail 70 tests: 70 pass, 0 fail
Linux version: 5.10.36-rc1-g4edc8f7e8676 Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000, tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000, tegra20-ventana, tegra210-p2371-2180, tegra210-p3450-0000, tegra30-cardhu-a04
Tested-by: Jon Hunter jonathanh@nvidia.com
Jon
On 5/10/2021 3:16 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y and the diffstat can be found below.
thanks,
greg k-h
On ARCH_BRCMSTB, using 32-bit and 64-bit ARM kernels:
Reviewed-by: Florian Fainelli f.fainelli@gmail.com
On Mon, 10 May 2021 12:16:37 +0200, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y and the diffstat can be found below.
thanks,
greg k-h
5.10.36-rc1 Successfully Compiled and booted on my Raspberry PI 4b (8g) (bcm2711)
Tested-by: Fox Chen foxhlchen@gmail.com
On Mon, May 10, 2021 at 12:16:37PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +0000. Anything received after that time might be too late.
Build results: total: 156 pass: 156 fail: 0 Qemu test results: total: 455 pass: 455 fail: 0
Tested-by: Guenter Roeck linux@roeck-us.net
Guenter
On 5/10/21 4:16 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Tested-by: Shuah Khan skhan@linuxfoundation.org
thanks, -- Shuah
On Mon, 10 May 2021 at 10:51, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y and the diffstat can be found below.
Boot tested in qemu for the 32 bit ARM aspeed_g5 and aspeed_g4 defconfigs.
Tested-by: Joel Stanley joel@jms.id.au
Cheers,
Joel
On Mon, 10 May 2021 at 16:01, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Tested-by: Linux Kernel Functional Testing lkft@linaro.org
## Build * kernel: 5.10.36-rc1 * git: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git * git branch: linux-5.10.y * git commit: 4edc8f7e8676bbfdec9d67dc6b90ec72fd3bacaa * git describe: v5.10.35-300-g4edc8f7e8676 * test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.10.y/build/v5.10....
## No regressions (compared to v5.10.35-221-gbb0eba64e018)
## No fixes (compared to v5.10.35-221-gbb0eba64e018)
## Test result summary total: 78630, pass: 64381, fail: 2948, skip: 11032, xfail: 269,
## Build Summary * arc: 10 total, 10 passed, 0 failed * arm: 193 total, 193 passed, 0 failed * arm64: 27 total, 27 passed, 0 failed * dragonboard-410c: 1 total, 1 passed, 0 failed * hi6220-hikey: 1 total, 1 passed, 0 failed * i386: 26 total, 26 passed, 0 failed * juno-r2: 1 total, 1 passed, 0 failed * mips: 45 total, 45 passed, 0 failed * parisc: 9 total, 9 passed, 0 failed * powerpc: 27 total, 27 passed, 0 failed * riscv: 21 total, 21 passed, 0 failed * s390: 18 total, 18 passed, 0 failed * sh: 18 total, 18 passed, 0 failed * sparc: 9 total, 9 passed, 0 failed * x15: 1 total, 1 passed, 0 failed * x86: 1 total, 1 passed, 0 failed * x86_64: 27 total, 27 passed, 0 failed
## Test suites summary * fwts * install-android-platform-tools-r2600 * kselftest- * kselftest-android * kselftest-bpf * kselftest-breakpoints * kselftest-capabilities * kselftest-cgroup * kselftest-clone3 * kselftest-core * kselftest-cpu-hotplug * kselftest-cpufreq * kselftest-drivers * kselftest-efivarfs * kselftest-filesystems * kselftest-firmware * kselftest-fpu * kselftest-futex * kselftest-gpio * kselftest-intel_pstate * kselftest-ipc * kselftest-ir * kselftest-kcmp * kselftest-kexec * kselftest-kvm * kselftest-lib * kselftest-livepatch * kselftest-lkdtm * kselftest-membarrier * kselftest-memfd * kselftest-memory-hotplug * kselftest-mincore * kselftest-mount * kselftest-mqueue * kselftest-net * kselftest-netfilter * kselftest-nsfs * kselftest-openat2 * kselftest-pid_namespace * kselftest-pidfd * kselftest-proc * kselftest-pstore * kselftest-ptrace * kselftest-rseq * kselftest-rtc * kselftest-seccomp * kselftest-sigaltstack * kselftest-size * kselftest-splice * kselftest-static_keys * kselftest-sync * kselftest-sysctl * kselftest-tc-testing * kselftest-timens * kselftest-timers * kselftest-tmpfs * kselftest-tpm2 * kselftest-user * kselftest-vm * kselftest-vsyscall-mode-native- * kselftest-vsyscall-mode-none- * kselftest-x86 * kselftest-zram * kunit * kvm-unit-tests * libhugetlbfs * linux-log-parser * ltp-cap_bounds-tests * ltp-commands-tests * ltp-containers-tests * ltp-controllers-tests * ltp-cpuhotplug-tests * ltp-crypto-tests * ltp-cve-tests * ltp-dio-tests * ltp-fcntl-locktests-tests * ltp-filecaps-tests * ltp-fs-tests * ltp-fs_bind-tests * ltp-fs_perms_simple-tests * ltp-fsx-tests * ltp-hugetlb-tests * ltp-io-tests * ltp-ipc-tests * ltp-math-tests * ltp-mm-tests * ltp-nptl-tests * ltp-open-posix-tests * ltp-pty-tests * ltp-sched-tests * ltp-securebits-tests * ltp-syscalls-tests * ltp-tracing-tests * network-basic-tests * packetdrill * perf * rcutorture * ssuite * v4l2-compliance
-- Linaro LKFT https://lkft.linaro.org
Hi Greg,
On Mon, May 10, 2021 at 12:16:37PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +0000. Anything received after that time might be too late.
Build test: mips (gcc version 11.1.1 20210430): 63 configs -> no new failure arm (gcc version 11.1.1 20210430): 105 configs -> no new failure x86_64 (gcc version 10.2.1 20210110): 2 configs -> no failure
Boot test: x86_64: Booted on my test laptop. No regression. x86_64: Booted on qemu. No regression.
Tested-by: Sudip Mukherjee sudip.mukherjee@codethink.co.uk
-- Regards Sudip
On 2021/5/10 18:16, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.36 release. There are 299 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 Wed, 12 May 2021 10:19:23 +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/v5.x/stable-review/patch-5.10.36-rc1... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y and the diffstat can be found below.
thanks,
greg k-h
Tested on arm64 and x86 for 5.10.36-rc1,
Kernel repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git Branch: linux-5.10.y Version: 5.10.36-rc1 Commit: 4edc8f7e8676bbfdec9d67dc6b90ec72fd3bacaa Compiler: gcc version 7.3.0 (GCC)
arm64: -------------------------------------------------------------------- Testcase Result Summary: total: 8476 passed: 8476 failed: 0 timeout: 0 --------------------------------------------------------------------
x86: -------------------------------------------------------------------- Testcase Result Summary: total: 8476 passed: 8476 failed: 0 timeout: 0 --------------------------------------------------------------------
Tested-by: Hulk Robot hulkrobot@huawei.com
linux-stable-mirror@lists.linaro.org