This is the start of the stable review cycle for the 5.10.180 release. There are 381 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, 17 May 2023 16:16:37 +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.180-rc... 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.180-rc1
Aurabindo Pillai aurabindo.pillai@amd.com drm/amd/display: Fix hang when skipping modeset
Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp mm/page_alloc: fix potential deadlock on zonelist_update_seq seqlock
Tian Tao tiantao6@hisilicon.com drm/exynos: move to use request_irq by IRQF_NO_AUTOEN flag
Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp printk: declare printk_deferred_{enter,safe}() in include/linux/printk.h
Rishabh Bhatnagar risbhat@amazon.com KVM: x86: move guest_pv_has out of user_access section
Rishabh Bhatnagar risbhat@amazon.com KVM: x86: do not report preemption if the steal time cache is stale
Rishabh Bhatnagar risbhat@amazon.com KVM: x86: revalidate steal time cache if MSR value changes
Rishabh Bhatnagar risbhat@amazon.com KVM: x86: do not set st->preempted when going back to user space
Rishabh Bhatnagar risbhat@amazon.com KVM: x86: Remove obsolete disabling of page faults in kvm_arch_vcpu_put()
Rishabh Bhatnagar risbhat@amazon.com KVM: Fix steal time asm constraints
Rishabh Bhatnagar risbhat@amazon.com KVM: x86: Fix recording of guest steal time / preempted status
Rishabh Bhatnagar risbhat@amazon.com KVM: x86: Ensure PV TLB flush tracepoint reflects KVM behavior
Christoph Böhmwalder christoph.boehmwalder@linbit.com drbd: correctly submit flush bio on barrier
Ilpo Järvinen ilpo.jarvinen@linux.intel.com serial: 8250: Fix serial8250_tx_empty() race with DMA Tx
Theodore Ts'o tytso@mit.edu ext4: fix invalid free tracking in ext4_xattr_move_to_block()
Theodore Ts'o tytso@mit.edu ext4: remove a BUG_ON in ext4_mb_release_group_pa()
Theodore Ts'o tytso@mit.edu ext4: bail out of ext4_xattr_ibody_get() fails for any reason
Theodore Ts'o tytso@mit.edu ext4: add bounds checking in get_max_inline_xattr_value_size()
Theodore Ts'o tytso@mit.edu ext4: fix deadlock when converting an inline directory in nojournal mode
Theodore Ts'o tytso@mit.edu ext4: improve error recovery code paths in __ext4_remount()
Baokun Li libaokun1@huawei.com ext4: check iomap type only if ext4_iomap_begin() does not fail
Jan Kara jack@suse.cz ext4: fix data races when using cached status extents
Tudor Ambarus tudor.ambarus@linaro.org ext4: avoid a potential slab-out-of-bounds in ext4_group_desc_csum
Ye Bin yebin10@huawei.com ext4: fix WARNING in mb_find_extent
Paolo Bonzini pbonzini@redhat.com KVM: x86: do not report a vCPU as preempted outside instruction boundaries
Vitaly Kuznetsov vkuznets@redhat.com KVM: x86: hyper-v: Avoid calling kvm_make_vcpus_request_mask() with vcpu_mask==NULL
Ping Cheng pinglinux@gmail.com HID: wacom: insert timestamp to packed Bluetooth (BT) events
Ping Cheng pinglinux@gmail.com HID: wacom: Set a default resolution for older tablets
Guchun Chen guchun.chen@amd.com drm/amdgpu: disable sdma ecc irq only when sdma RAS is enabled in suspend
Guchun Chen guchun.chen@amd.com drm/amdgpu/gfx: disable gfx9 cp_ecc_error_irq only when enabling legacy gfx ras
Hamza Mahfooz hamza.mahfooz@amd.com drm/amdgpu: fix an amdgpu_irq_put() issue in gmc_v9_0_hw_fini()
James Cowgill james.cowgill@blaize.com drm/panel: otm8009a: Set backlight parent to panel device
Jaegeuk Kim jaegeuk@kernel.org f2fs: fix potential corruption when moving a directory
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: s5pv210: correct MIPI CSIS clock name
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: exynos: fix WM8960 clock name in Itop Elite
Mathieu Poirier mathieu.poirier@linaro.org remoteproc: st: Call of_node_put() on iteration error
Mathieu Poirier mathieu.poirier@linaro.org remoteproc: stm32: Call of_node_put() on iteration error
Randy Dunlap rdunlap@infradead.org sh: nmi_debug: fix return value of __setup handler
Randy Dunlap rdunlap@infradead.org sh: init: use OF_EARLY_FLATTREE for early init
Randy Dunlap rdunlap@infradead.org sh: mcount.S: fix build error when PRINTK is not enabled
Randy Dunlap rdunlap@infradead.org sh: math-emu: fix macro redefined warning
Jan Kara jack@suse.cz inotify: Avoid reporting event with invalid wd
Andrey Avdeev jamesstoun@gmail.com platform/x86: touchscreen_dmi: Add info for the Dexp Ursus KX210i
Hans de Goede hdegoede@redhat.com platform/x86: touchscreen_dmi: Add upside-down quirk for GDIX1002 ts on the Juno Tablet
Pawel Witek pawel.ireneusz.witek@gmail.com cifs: fix pcchunk length type in smb2_copychunk_range
Anastasia Belova abelova@astralinux.ru btrfs: print-tree: parent bytenr must be aligned to sector size
Josef Bacik josef@toxicpanda.com btrfs: don't free qgroup space unless specified
Filipe Manana fdmanana@suse.com btrfs: fix btrfs_prev_leaf() to not return the same key twice
Yang Jihong yangjihong1@huawei.com perf symbols: Fix return incorrect build_id size in elf_read_build_id()
Christophe JAILLET christophe.jaillet@wanadoo.fr crypto: sun8i-ss - Fix a test in sun8i_ss_setup_ivs()
Markus Elfring Markus.Elfring@web.de perf map: Delete two variable initialisations before null pointer checks in sort__sym_from_cmp()
Arnaldo Carvalho de Melo acme@redhat.com perf pmu: zfree() expects a pointer to a pointer to zero it after freeing its contents
Kajol Jain kjain@linux.ibm.com perf vendor events power9: Remove UTF-8 characters from JSON files
Florian Fainelli f.fainelli@gmail.com net: bcmgenet: Remove phy_stop() from bcmgenet_netif_stop()
Wei Fang wei.fang@nxp.com net: enetc: check the index of the SFI rather than the handle
Wenliang Wang wangwenliang.1995@bytedance.com virtio_net: suppress cpu stall when free_unused_bufs
Xuan Zhuo xuanzhuo@linux.alibaba.com virtio_net: split free_unused_bufs()
Arınç ÜNAL arinc.unal@arinc9.com net: dsa: mt7530: fix corrupt frames using trgmii on 40 MHz XTAL MT7621
Ruliang Lin u202112092@hust.edu.cn ALSA: caiaq: input: Add error handling for unsupported input methods in `snd_usb_caiaq_input_init`
Chia-I Wu olvaffe@gmail.com drm/amdgpu: add a missing lock for AMDGPU_SCHED
Kuniyuki Iwashima kuniyu@amazon.com af_packet: Don't send zero-byte data in packet_sendmsg_spkt().
Shannon Nelson shannon.nelson@amd.com ionic: remove noise from ethtool rxnfc error msg
Subbaraya Sundeep sbhatta@marvell.com octeontx2-vf: Detach LF resources on probe cleanup
Subbaraya Sundeep sbhatta@marvell.com octeontx2-pf: Disable packet I/O for graceful exit
David Howells dhowells@redhat.com rxrpc: Fix hard call timeout units
Andy Moreton andy.moreton@amd.com sfc: Fix module EEPROM reporting for QSFP modules
Victor Nogueira victor@mojatatu.com net/sched: act_mirred: Add carrier check
Christophe JAILLET christophe.jaillet@wanadoo.fr watchdog: dw_wdt: Fix the error handling path of dw_wdt_drv_probe()
Maxim Korotkov korotkov.maxim.s@gmail.com writeback: fix call of incorrect macro
Angelo Dureghello angelo.dureghello@timesys.com net: dsa: mv88e6xxx: add mv88e6321 rsvd2cpu
Cong Wang cong.wang@bytedance.com sit: update dev->needed_headroom in ipip6_tunnel_bind_dev()
Vlad Buslov vladbu@nvidia.com net/sched: cls_api: remove block_cb from driver_list before freeing
Cosmo Chou chou.cosmo@gmail.com net/ncsi: clear Tx enable mode when handling a Config required AEN
Zheng Wang zyytlz.wz@163.com scsi: qedi: Fix use after free bug in qedi_remove()
Yeongjin Gil youngjin.gil@samsung.com dm verity: fix error handling for check_at_most_once on FEC
Akilesh Kailash akailash@google.com dm verity: skip redundant verity_handle_err() on I/O errors
Tanmay Shah tanmay.shah@amd.com mailbox: zynqmp: Fix counts of child nodes
Christophe JAILLET christophe.jaillet@wanadoo.fr mailbox: zynq: Switch to flexible array to simplify code
Jeremi Piotrowski jpiotrowski@linux.microsoft.com crypto: ccp - Clear PSP interrupt status register before calling handler
Tze-nan Wu Tze-nan.Wu@mediatek.com ring-buffer: Ensure proper resetting of atomic variables in ring_buffer_reset_online_cpus
Ilpo Järvinen ilpo.jarvinen@linux.intel.com tty: Prevent writing chars during tcsetattr TCSADRAIN/FLUSH
Greg Kroah-Hartman gregkh@linuxfoundation.org tty: clean include/linux/tty.h up
Greg Kroah-Hartman gregkh@linuxfoundation.org tty: move some tty-only functions to drivers/tty/tty.h
Greg Kroah-Hartman gregkh@linuxfoundation.org tty: move some internal tty lock enums and functions out of tty.h
Greg Kroah-Hartman gregkh@linuxfoundation.org tty: audit: move some local functions out of tty.h
Greg Kroah-Hartman gregkh@linuxfoundation.org tty: create internal tty.h file
Pablo Neira Ayuso pablo@netfilter.org netfilter: nf_tables: deactivate anonymous set from preparation phase
Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com scsi: target: core: Avoid smp_processor_id() in preemptible code
Vincent Guittot vincent.guittot@linaro.org arm64: dts: qcom: sdm845: correct dynamic power coefficients - again
Miles Chen miles.chen@mediatek.com sound/oss/dmasound: fix 'dmasound_setup' defined but not used
Thomas Gleixner tglx@linutronix.de debugobject: Ensure pool refill (again)
Ard Biesheuvel ardb@kernel.org arm64: Stash shadow stack pointer in the task struct on interrupt
Ard Biesheuvel ardb@kernel.org arm64: Always load shadow stack pointer directly from the task struct
Adrian Hunter adrian.hunter@intel.com perf intel-pt: Fix CYC timestamps after standalone CBR
Adrian Hunter adrian.hunter@intel.com perf auxtrace: Fix address filter entire kernel size
Mike Snitzer snitzer@kernel.org dm ioctl: fix nested locking in table_clear() to remove deadlock concern
Mikulas Patocka mpatocka@redhat.com dm flakey: fix a crash with invalid table line
Mike Snitzer snitzer@kernel.org dm integrity: call kmem_cache_destroy() in dm_integrity_init() error path
Mike Snitzer snitzer@kernel.org dm clone: call kmem_cache_destroy() in dm_clone_init() error path
Hugh Dickins hughd@google.com ia64: fix an addr to taddr in huge_pte_offset()
Stefan Haberland sth@linux.ibm.com s390/dasd: fix hanging blockdevice after request requeue
Qu Wenruo wqu@suse.com btrfs: scrub: reject unsupported scrub flags
Peng Liu liupeng17@lenovo.com scripts/gdb: fix lx-timerlist for Python3
Marc Dionne marc.dionne@auristor.com afs: Fix updating of i_size with dv jump from server
Matthias Schiffer matthias.schiffer@ew.tq-group.com mfd: tqmx86: Correct board names for TQMxE39x
Matthias Schiffer matthias.schiffer@ew.tq-group.com mfd: tqmx86: Specify IO port register range more precisely
Matthias Schiffer matthias.schiffer@ew.tq-group.com mfd: tqmx86: Add support for TQMx110EB and TQMxE40x
Matthias Schiffer matthias.schiffer@ew.tq-group.com mfd: tqmx86: Remove incorrect TQMx90UC board ID
Matthias Schiffer matthias.schiffer@ew.tq-group.com mfd: tqmx86: Do not access I2C_DETECT register through io_base
Kang Chen void0red@hust.edu.cn thermal/drivers/mediatek: Use devm_of_iomap to avoid resource leak in mtk_thermal_probe
Claudiu Beznea claudiu.beznea@microchip.com dmaengine: at_xdmac: do not enable all cyclic channels
Shunsuke Mie mie@igel.co.jp dmaengine: dw-edma: Fix to enable to issue dma request on DMA processing
Shunsuke Mie mie@igel.co.jp dmaengine: dw-edma: Fix to change for continuous transfer
Gaosheng Cui cuigaosheng1@huawei.com phy: tegra: xusb: Add missing tegra_xusb_port_unregister for usb2_port and ulpi_port
AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com pwm: mtk-disp: Disable shadow registers before setting backlight values
Jitao Shi jitao.shi@mediatek.com pwm: mtk-disp: Adjust the clocks to avoid them mismatch
Uwe Kleine-König u.kleine-koenig@pengutronix.de pwm: mtk-disp: Don't check the return code of pwmchip_remove()
H. Nikolaus Schaller hns@goldelico.com leds: tca6507: Fix error handling of using fwnode_property_read_string
Christophe JAILLET christophe.jaillet@wanadoo.fr dmaengine: mv_xor_v2: Fix an error code.
Randy Dunlap rdunlap@infradead.org leds: TI_LMU_COMMON: select REGMAP instead of depending on it
Ye Bin yebin10@huawei.com ext4: fix use-after-free read in ext4_find_extent for bigalloc + inline
Stafford Horne shorne@gmail.com openrisc: Properly store r31 to pt_regs on unhandled exceptions
Qinrun Dai flno@hust.edu.cn clocksource/drivers/davinci: Fix memory leak in davinci_timer_register when init fails
Mark Zhang markzhang@nvidia.com RDMA/mlx5: Use correct device num_ports when modify DC
Dai Ngo dai.ngo@oracle.com SUNRPC: remove the maximum number of retries in call_bind_status
Mark Bloch mbloch@nvidia.com RDMA/mlx5: Fix flow counter query via DEVX
Miaoqian Lin linmq006@gmail.com Input: raspberrypi-ts - fix refcount leak in rpi_ts_probe
Nicolas Saenz Julienne nsaenzjulienne@suse.de input: raspberrypi-ts: Release firmware handle when not needed
Nicolas Saenz Julienne nsaenzjulienne@suse.de firmware: raspberrypi: Introduce devm_rpi_firmware_get()
Trond Myklebust trond.myklebust@hammerspace.com NFSv4.1: Always send a RECLAIM_COMPLETE after establishing lease
Patrick Kelsey pat.kelsey@cornelisnetworks.com IB/hfi1: Fix bugs with non-PAGE_SIZE-end multi-iovec user SDMA requests
Mike Marciniszyn mike.marciniszyn@cornelisnetworks.com IB/hfi1: Add additional usdma traces
Mike Marciniszyn mike.marciniszyn@cornelisnetworks.com IB/hfi1: Add AIP tx traces
Patrick Kelsey pat.kelsey@cornelisnetworks.com IB/hfi1: Fix SDMA mmu_rb_node not being evicted in LRU order
Saravanan Vajravel saravanan.vajravel@broadcom.com RDMA/srpt: Add a check for valid 'mad_agent' pointer
Mark Zhang markzhang@nvidia.com RDMA/cm: Trace icm_send_rej event before the cm state is reset
Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp RDMA/siw: Remove namespace check from siw_netdev_event()
Clément Léger clement.leger@bootlin.com clk: add missing of_node_put() in "assigned-clocks" property parsing
Sebastian Reichel sre@kernel.org power: supply: generic-adc-battery: fix unit scaling
Martin Blumenstingl martin.blumenstingl@googlemail.com rtc: meson-vrtc: Use ktime_get_real_ts64() to get the current time
Dan Carpenter error27@gmail.com RDMA/mlx4: Prevent shift wrapping in set_user_sq_size()
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org rtc: omap: include header for omap_rtc_power_off_program prototype
Petr Mladek pmladek@suse.com workqueue: Fix hung time report of worker pools
Lai Jiangshan laijs@linux.alibaba.com workqueue: Rename "delayed" (delayed by active management) to "inactive"
Natalia Petrova n.petrova@fintech.ru RDMA/rdmavt: Delete unnecessary NULL check
Daniil Dulov d.dulov@aladdin.ru RDMA/siw: Fix potential page_array out of range access
Claudiu Beznea claudiu.beznea@microchip.com clk: at91: clk-sam9x60-pll: fix return value check
Yang Jihong yangjihong1@huawei.com perf/core: Fix hardlockup failure caused by perf throttle
Nathan Lynch nathanl@linux.ibm.com powerpc/rtas: use memmove for potentially overlapping buffer copy
Randy Dunlap rdunlap@infradead.org macintosh: via-pmu-led: requires ATA to be set
Randy Dunlap rdunlap@infradead.org powerpc/sysdev/tsi108: fix resource printk format warnings
Randy Dunlap rdunlap@infradead.org powerpc/wii: fix resource printk format warnings
Randy Dunlap rdunlap@infradead.org powerpc/mpc512x: fix resource printk format warning
Liang He windhl@126.com macintosh/windfarm_smu_sat: Add missing of_node_put()
Jishnu Prakash quic_jprakash@quicinc.com spmi: Add a check for remove callback when removing a SPMI driver
Philipp Hortmann philipp.g.hortmann@gmail.com staging: rtl8192e: Fix W_DISABLE# does not work after stop/start
Florian Fainelli f.fainelli@gmail.com serial: 8250: Add missing wakeup event reporting
Shenwei Wang shenwei.wang@nxp.com tty: serial: fsl_lpuart: adjust buffer length to the intended size
Dan Carpenter dan.carpenter@linaro.org firmware: stratix10-svc: Fix an NULL vs IS_ERR() bug in probe
Chunfeng Yun chunfeng.yun@mediatek.com usb: mtu3: fix kernel panic at qmu transfer done irq handler
Yinhao Hu dddddd@hust.edu.cn usb: chipidea: fix missing goto in `ci_hdrc_probe`
Jon Hunter jonathanh@nvidia.com usb: gadget: tegra-xudc: Fix crash in vbus_draw
John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de sh: sq: Fix incorrect element size for allocating bitmap buffer
Kevin Brodsky kevin.brodsky@arm.com uapi/linux/const.h: prefer ISO-friendly __typeof__
Lars-Peter Clausen lars@metafoo.de i2c: cadence: cdns_i2c_master_xfer(): Fix runtime PM leak on error path
Dhruva Gole d-gole@ti.com spi: cadence-quadspi: fix suspend-resume implementations
Liliang Ye yll@hust.edu.cn ASoC: fsl_mqs: move of_node_put() to the correct location
Suzuki K Poulose suzuki.poulose@arm.com coresight: etm_pmu: Set the module field
Florian Fainelli f.fainelli@gmail.com scripts/gdb: bail early if there are no generic PD
Florian Fainelli f.fainelli@gmail.com scripts/gdb: bail early if there are no clocks
Randy Dunlap rdunlap@infradead.org ia64: salinfo: placate defined-but-not-used warning
Randy Dunlap rdunlap@infradead.org ia64: mm/contig: fix section mismatch warning/error
Kuppuswamy Sathyanarayanan sathyanarayanan.kuppuswamy@linux.intel.com PCI/EDR: Clear Device Status after EDR error recovery
Miquel Raynal miquel.raynal@bootlin.com of: Fix modalias string generation
Dae R. Jeong threeearcat@gmail.com vmci_host: fix a race condition in vmci_host_poll() causing GPF
Christophe Leroy christophe.leroy@csgroup.eu spi: fsl-spi: Fix CPM/QE mode Litte Endian
Uwe Kleine-König u.kleine-koenig@pengutronix.de spi: qup: Don't skip cleanup in remove's error path
Randy Dunlap rdunlap@infradead.org linux/vt_buffer.h: allow either builtin or modular for macros
Cristian Ciocaltea cristian.ciocaltea@collabora.com ASoC: es8316: Handle optional IRQ assignment
Hans de Goede hdegoede@redhat.com ASoC: es8316: Use IRQF_NO_AUTOEN when requesting the IRQ
H. Nikolaus Schaller hns@goldelico.com PCI: imx6: Install the fault handler only on compatible match
Zheng Wang zyytlz.wz@163.com usb: gadget: udc: renesas_usb3: Fix use after free bug in renesas_usb3_remove due to race condition
Uwe Kleine-König u.kleine-koenig@pengutronix.de spi: imx: Don't skip cleanup in remove's error path
Minghao Chi chi.minghao@zte.com.cn spi: spi-imx: using pm_runtime_resume_and_get instead of pm_runtime_get_sync
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org iio: light: max44009: add missing OF device matching
Marco Pagani marpagan@redhat.com fpga: bridge: fix kernel-doc parameter description
Prashanth K quic_prashk@quicinc.com usb: dwc3: gadget: Change condition for processing suspend event
Wolfram Sang wsa+renesas@sang-engineering.com usb: host: xhci-rcar: remove leftover quirk handling
John Stultz jstultz@google.com pstore: Revert pmsg_lock back to a normal mutex
Randy Dunlap rdunlap@infradead.org ipmi: ASPEED_BT_IPMI_BMC: select REGMAP_MMIO instead of depending on it
Kuniyuki Iwashima kuniyu@amazon.com tcp/udp: Fix memleaks of sk and zerocopy skbs with TX timestamp.
Gencen Gan gangecen@hust.edu.cn net: amd: Fix link leak when verifying config failed
Kuniyuki Iwashima kuniyu@amazon.com netlink: Use copy_to_user() for optval in netlink_getsockopt().
Liu Jian liujian56@huawei.com Revert "Bluetooth: btsdio: fix use after free bug in btsdio_remove due to unfinished work"
Ziyang Xuan william.xuanziyang@huawei.com ipv4: Fix potential uninit variable access bug in __ip_make_skb()
Davide Caratti dcaratti@redhat.com net/sched: sch_fq: fix integer overflow of "credit"
Florian Westphal fw@strlen.de netfilter: nf_tables: don't write table validation state without mutex
Stanislav Fomichev sdf@google.com bpf: Don't EFAULT for getsockopt with optval=NULL
Joe Damato jdamato@fastly.com ixgbe: Enable setting RSS table to default values
Joe Damato jdamato@fastly.com ixgbe: Allow flow hash to be set via ethtool
Johannes Berg johannes.berg@intel.com wifi: iwlwifi: fw: fix memory leak in debugfs
Johannes Berg johannes.berg@intel.com wifi: iwlwifi: mvm: check firmware response size
Emmanuel Grumbach emmanuel.grumbach@intel.com wifi: iwlwifi: make the loop for card preparation effective
Jan Kara jack@suse.cz jdb2: Don't refuse invalidation of already invalidated buffers
Tom Rix trix@redhat.com wifi: iwlwifi: fw: move memset before early return
Daniel Gabay daniel.gabay@intel.com wifi: iwlwifi: yoyo: Fix possible division by zero
Yu Kuai yukuai3@huawei.com md/raid10: fix memleak of md thread
Yu Kuai yukuai3@huawei.com md/raid10: fix memleak for 'conf->bio_split'
Yu Kuai yukuai3@huawei.com md/raid10: fix leak of 'r10bio->remaining' for recovery
Daniel Borkmann daniel@iogearbox.net bpf, sockmap: Revert buggy deadlock fix in the sockhash and sockmap
Ming Lei ming.lei@redhat.com nvme-fcloop: fix "inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage"
Keith Busch kbusch@kernel.org nvme: fix async event trace event
Michael Kelley mikelley@microsoft.com nvme: handle the persistent internal error AER
Xin Liu liuxin350@huawei.com bpf, sockmap: fix deadlocks in the sockhash and sockmap
Sebastian Reichel sebastian.reichel@collabora.com net: ethernet: stmmac: dwmac-rk: fix optional phy regulator handling
Shuchang Li lishuchang@hust.edu.cn scsi: lpfc: Fix ioremap issues in lpfc_sli4_pci_mem_setup()
Chao Yu chao@kernel.org f2fs: fix to avoid use-after-free for cached IPU bio
Kal Conley kal.conley@dectris.com xsk: Fix unaligned descriptor validation
Herbert Xu herbert@gondor.apana.org.au crypto: drbg - Only fail when jent is unavailable in FIPS mode
Nicolai Stange nstange@suse.de crypto: drbg - make drbg_prepare_hrng() handle jent instantiation errors
Quentin Monnet quentin@isovalent.com bpftool: Fix bug for long instructions in program CFG dumps
YiFei Zhu zhuyifei@google.com selftests/bpf: Wait for receive in cg_storage_multi test
Simon Horman horms@kernel.org net: qrtr: correct types of trace event parameters
Wei Chen harperchen1110@gmail.com wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_reg()
Wei Chen harperchen1110@gmail.com wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_rfreg()
Suman Anna s-anna@ti.com crypto: sa2ul - Select CRYPTO_DES
Christophe JAILLET christophe.jaillet@wanadoo.fr crypto: caam - Clear some memory in instantiate_rng
Yangtao Li frank.li@vivo.com f2fs: compress: fix to call f2fs_wait_on_page_writeback() in f2fs_write_raw_pages()
Jaegeuk Kim jaegeuk@kernel.org f2fs: apply zone capacity to all zone type
Jaegeuk Kim jaegeuk@kernel.org f2fs: enforce single zone capacity
Yangtao Li frank.li@vivo.com f2fs: handle dqget error in f2fs_transfer_project_quota()
Danila Chernetsov listdansp@mail.ru scsi: megaraid: Fix mega_cmd_done() CMDID_INT_CMDS
Mike Christie michael.christie@oracle.com scsi: target: iscsit: Fix TAS handling during conn cleanup
Mike Christie michael.christie@oracle.com scsi: target: Fix multiple LUN_RESET handling
Mike Christie michael.christie@oracle.com scsi: target: Make state_list per CPU
David Disseldorp ddiss@suse.de scsi: target: Rename cmd.bad_sector to cmd.sense_info
David Disseldorp ddiss@suse.de scsi: target: Rename struct sense_info to sense_detail
Eric Dumazet edumazet@google.com net/packet: convert po->auxdata to an atomic flag
Eric Dumazet edumazet@google.com net/packet: convert po->origdev to an atomic flag
Eric Dumazet edumazet@google.com net/packet: annotate accesses to po->xmit
Vadim Fedorenko vadim.fedorenko@linux.dev vlan: partially enable SIOCSHWTSTAMP in container
Luis Gerhorst gerhorst@cs.fau.de bpf: Remove misleading spec_v1 check on var-offset stack read
Alexander Mikhalitsyn aleksandr.mikhalitsyn@canonical.com scm: fix MSG_CTRUNC setting condition for SO_PASSSEC
Andrii Nakryiko andrii@kernel.org bpf: fix precision propagation verbose logging
Andrii Nakryiko andrii@kernel.org bpf: take into account liveness when propagating precision
Martin Blumenstingl martin.blumenstingl@googlemail.com wifi: rtw88: mac: Return the original error from rtw_mac_power_switch()
Martin Blumenstingl martin.blumenstingl@googlemail.com wifi: rtw88: mac: Return the original error from rtw_pwr_seq_parser()
Luis Gerhorst gerhorst@cs.fau.de tools: bpftool: Remove invalid ' json escape
Fedor Pchelkin pchelkin@ispras.ru wifi: ath6kl: reduce WARN to dev_dbg() in callback
Dan Carpenter error27@gmail.com wifi: ath5k: fix an off by one check in ath5k_eeprom_read_freq_list()
Fedor Pchelkin pchelkin@ispras.ru wifi: ath9k: hif_usb: fix memory leak of remain_skbs
Alexey V. Vissarionov gremlin@altlinux.org wifi: ath6kl: minor fix for allocation size
Sebastian Andrzej Siewior bigeasy@linutronix.de tick/common: Align tick period with the HZ tick.
Thomas Gleixner tglx@linutronix.de tick: Get rid of tick_period
Thomas Gleixner tglx@linutronix.de tick/sched: Optimize tick_do_update_jiffies64() further
Yunfeng Ye yeyunfeng@huawei.com tick/sched: Reduce seqcount held scope in tick_do_update_jiffies64()
Thomas Gleixner tglx@linutronix.de tick/sched: Use tick_next_period for lockless quick check
Ville Syrjälä ville.syrjala@linux.intel.com drm/i915: Make intel_get_crtc_new_encoder() less oopsy
Thomas Gleixner tglx@linutronix.de debugobject: Prevent init race with static objects
Sumit Garg sumit.garg@linaro.org arm64: kgdb: Set PSTATE.SS to 1 to re-enable single-step
Saurabh Sengar ssengar@linux.microsoft.com x86/ioapic: Don't return 0 from arch_dynirq_lower_bound()
YAN SHI m202071378@hust.edu.cn regulator: stm32-pwr: fix of_iomap leak
Michał Krawczyk mk@semihalf.com media: venus: dec: Fix handling of the start cmd
Fritz Koenig frkoenig@chromium.org media: venus: vdec: Handle DRC after drain
Alexandre Courbot acourbot@chromium.org media: venus: preserve DRC state across seeks
Stanimir Varbanov stanimir.varbanov@linaro.org media: venus: vdec: Make decoder return LAST flag for sufficient event
Stanimir Varbanov stanimir.varbanov@linaro.org media: venus: vdec: Fix non reliable setting of LAST flag
Florian Fainelli f.fainelli@gmail.com media: rc: gpio-ir-recv: Fix support for wake-up
Miaoqian Lin linmq006@gmail.com media: rcar_fdp1: Fix refcount leak in probe and remove function
Tang Bin tangbin@cmss.chinamobile.com media: rcar_fdp1: Fix the correct variable assignments
Cai Huoqing caihuoqing@baidu.com media: rcar_fdp1: Make use of the helper function devm_platform_ioremap_resource()
Mauro Carvalho Chehab mchehab+huawei@kernel.org media: rcar_fdp1: fix pm_runtime_get_sync() usage count
Mauro Carvalho Chehab mchehab+huawei@kernel.org media: rcar_fdp1: simplify error check logic at fdp_open()
Zheng Wang zyytlz.wz@163.com media: saa7134: fix use after free bug in saa7134_finidev due to race condition
Zheng Wang zyytlz.wz@163.com media: dm1105: Fix use after free bug in dm1105_remove due to race condition
Zheng Wang zyytlz.wz@163.com media: rkvdec: fix use after free bug in rkvdec_remove
Uros Bizjak ubizjak@gmail.com x86/apic: Fix atomic update of offset in reserve_eilvt_offset()
Douglas Anderson dianders@chromium.org regulator: core: Avoid lockdep reports when resolving supplies
Douglas Anderson dianders@chromium.org regulator: core: Consistently set mutex_owner when using ww_mutex_lock_slow()
Harshit Mogalapalli harshit.m.mogalapalli@oracle.com drm/lima/lima_drv: Add missing unwind goto in lima_pdev_probe()
H. Nikolaus Schaller hns@goldelico.com ARM: dts: gta04: fix excess dma channel usage
Georgii Kruglov georgy.kruglov@yandex.ru mmc: sdhci-of-esdhc: fix quirk to ignore command inhibit for data
Roger Pau Monne roger.pau@citrix.com ACPI: processor: Fix evaluating _PDC method when running as Xen dom0
Adam Skladowski a39.skl@gmail.com drm: msm: adreno: Disable preemption on Adreno 510
Johan Hovold johan+linaro@kernel.org drm/msm/adreno: drop bogus pm_runtime_set_active()
Rob Clark robdclark@chromium.org drm/msm/adreno: Defer enabling runpm until hw_init()
Laurent Pinchart laurent.pinchart@ideasonboard.com media: max9286: Free control handler
Adam Ford aford173@gmail.com drm/bridge: adv7533: Fix adv7533_mode_valid for adv7533 and adv7535
Mukesh Ojha quic_mojha@quicinc.com firmware: qcom_scm: Clear download bit during reboot
Jiasheng Jiang jiasheng@iscas.ac.cn media: bdisp: Add missing check for create_workqueue
Muralidhara M K muralimk@amd.com x86/MCE/AMD: Use an u64 for bank_map
Manivannan Sadhasivam manivannan.sadhasivam@linaro.org ARM: dts: qcom: ipq8064: Fix the PCI I/O port range
Christian Marangi ansuelsmth@gmail.com ARM: dts: qcom: ipq8064: reduce pci IO size to 64K
Manivannan Sadhasivam manivannan.sadhasivam@linaro.org ARM: dts: qcom: ipq4019: Fix the PCI I/O port range
Manivannan Sadhasivam manivannan.sadhasivam@linaro.org arm64: dts: qcom: msm8996: Fix the PCI I/O port range
Manivannan Sadhasivam manivannan.sadhasivam@linaro.org arm64: dts: qcom: ipq8074: Fix the PCI I/O port range
Manivannan Sadhasivam manivannan.sadhasivam@linaro.org arm64: dts: qcom: msm8998: Fix the PCI I/O port range
Manivannan Sadhasivam manivannan.sadhasivam@linaro.org arm64: dts: qcom: sdm845: Fix the PCI I/O port range
Dmitry Baryshkov dmitry.baryshkov@linaro.org arm64: dts: qcom: sdm845: correct dynamic power coefficients
Konrad Dybcio konrad.dybcio@linaro.org arm64: dts: qcom: msm8998: Fix stm-stimulus-base reg name
Qiuxu Zhuo qiuxu.zhuo@intel.com EDAC/skx: Fix overflows on the DRAM row address mapping arrays
Vinod Polimera quic_vpolimer@quicinc.com drm/msm/disp/dpu: check for crtc enable rather than crtc active to release shared resources
Geert Uytterhoeven geert+renesas@glider.be arm64: dts: renesas: r8a774c0: Remove bogus voltages from OPP table
Geert Uytterhoeven geert+renesas@glider.be arm64: dts: renesas: r8a77990: Remove bogus voltages from OPP table
Miaoqian Lin linmq006@gmail.com soc: ti: pm33xx: Fix refcount leak in am33xx_pm_probe
Tony Lindgren tony@atomide.com soc: ti: pm33xx: Enable basic PM runtime support for genpd
Dom Cobley popcornmix@gmail.com drm/probe-helper: Cancel previous job before starting new one
Maíra Canal mcanal@igalia.com drm/vgem: add missing mutex_destroy
Rob Clark robdclark@chromium.org drm/rockchip: Drop unbalanced obj unref
Jingbo Xu jefflexu@linux.alibaba.com erofs: fix potential overflow calculating xattr_isize
Gao Xiang hsiangkao@linux.alibaba.com erofs: stop parsing non-compact HEAD index if clusterofs is invalid
Lino Sanfilippo l.sanfilippo@kunbus.com tpm, tpm_tis: Claim locality when interrupts are reenabled on resume
Lino Sanfilippo l.sanfilippo@kunbus.com tpm, tpm: Implement usage counter for locality
Lino Sanfilippo l.sanfilippo@kunbus.com tpm, tpm_tis: Claim locality before writing interrupt registers
Lino Sanfilippo l.sanfilippo@kunbus.com tpm, tpm_tis: Disable interrupts if tpm_tis_probe_irq() failed
Lino Sanfilippo l.sanfilippo@kunbus.com tpm, tpm_tis: Claim locality before writing TPM_INT_ENABLE register
Lino Sanfilippo l.sanfilippo@kunbus.com tpm, tpm_tis: Do not skip reset of original interrupt vector
Paul Moore paul@paul-moore.com selinux: ensure av_permissions.h is built when needed
Ondrej Mosnacek omosnace@redhat.com selinux: fix Makefile dependencies of flask.h
Ilpo Järvinen ilpo.jarvinen@linux.intel.com selftests/resctrl: Check for return value after write_schemata()
Ilpo Järvinen ilpo.jarvinen@linux.intel.com selftests/resctrl: Return NULL if malloc_and_init_memory() did not alloc mem
Zqiang qiang1.zhang@intel.com rcu: Fix missing TICK_DEP_MASK_RCU_EXP dependency check
Quentin Schulz quentin.schulz@theobroma-systems.com clk: rockchip: rk3399: allow clk_cifout to force clk_cifout_src to reparent
Bitterblue Smith rtl8821cerfe2@gmail.com wifi: rtl8xxxu: RTL8192EU always needs full init
Tanmay Shah tanmay.shah@amd.com mailbox: zynqmp: Fix typo in IPI documentation
Tanmay Shah tanmay.shah@amd.com mailbox: zynqmp: Fix IPI isr handling
Li Nan linan122@huawei.com md/raid10: fix null-ptr-deref in raid10_sync_request
Ryusuke Konishi konishi.ryusuke@gmail.com nilfs2: fix infinite loop in nilfs_mdt_get_block()
Ryusuke Konishi konishi.ryusuke@gmail.com nilfs2: do not write dirty data after degenerating to read-only
Helge Deller deller@gmx.de parisc: Fix argument pointer in real64_call_asm()
Randy Dunlap rdunlap@infradead.org sound/oss/dmasound: fix build when drivers are mixed =y/=m
Mårten Lindahl marten.lindahl@axis.com ubifs: Free memory for tmpfile name
Wang YanQing udknight@gmail.com ubi: Fix return value overwrite issue in try_write_vid_and_data()
Zhihao Cheng chengzhihao1@huawei.com ubifs: Fix memleak when insert_old_idx() failed
Zhihao Cheng chengzhihao1@huawei.com Revert "ubifs: dirty_cow_znode: Fix memleak in error handling path"
Kishon Vijay Abraham I kvijayab@amd.com iommu/amd: Fix "Guest Virtual APIC Table Root Pointer" configuration in IRTE
Reid Tonking reidt@ti.com i2c: omap: Fix standard mode false ACK readings
Baokun Li libaokun1@huawei.com writeback, cgroup: fix null-ptr-deref write in bdi_split_work_to_wbs
Zhang Zhengming zhang.zhengming@h3c.com relayfs: fix out-of-bounds access in relay_file_read
Sean Christopherson seanjc@google.com KVM: nVMX: Emulate NOPs in L2, and PAUSE if it's not intercepted
Roberto Sassu roberto.sassu@huawei.com reiserfs: Add security prefix to xattr name in reiserfs_security_write()
Zheng Yejian zhengyejian1@huawei.com rcu: Avoid stack overflow due to __rcu_irq_enter_check_tick() being kprobe-ed
Jonathan McDowell noodles@earth.li crypto: safexcel - Cleanup ring IRQ workqueues on load failure
Toke Høiland-Jørgensen toke@redhat.com crypto: api - Demote BUG_ON() in crypto_unregister_alg() to a WARN_ON()
Johannes Berg johannes.berg@intel.com ring-buffer: Sync IRQ works before buffer destruction
Heiner Kallweit hkallweit1@gmail.com pwm: meson: Fix g12a ao clk81 name
Heiner Kallweit hkallweit1@gmail.com pwm: meson: Fix axg ao mux parents
Kees Cook keescook@chromium.org kheaders: Use array declaration instead of char
Zhang Yuchen zhangyuchen.lcr@bytedance.com ipmi: fix SSIF not responding under certain cond.
Corey Minyard minyard@acm.org ipmi:ssif: Add send_retries increment
Jiaxun Yang jiaxun.yang@flygoat.com MIPS: fw: Allow firmware to pass a empty env
Joel Fernandes (Google) joel@joelfernandes.org tick/nohz: Fix cpu_is_hotpluggable() by checking with nohz subsystem
Johan Hovold johan+linaro@kernel.org xhci: fix debugfs register accesses while suspended
Nuno Sá nuno.sa@analog.com staging: iio: resolver: ads1210: fix config mode
Harshad Shirwadkar harshadshirwadkar@gmail.com ext4: use ext4_journal_start/stop for fast commit transactions
Eric Biggers ebiggers@google.com blk-crypto: make blk_crypto_evict_key() more robust
Eric Biggers ebiggers@google.com blk-crypto: make blk_crypto_evict_key() return void
Eric Biggers ebiggers@google.com blk-mq: release crypto keyslot before reporting I/O complete
Arnaldo Carvalho de Melo acme@redhat.com perf sched: Cast PTHREAD_STACK_MIN to int as it may turn into sysconf(__SC_THREAD_STACK_MIN_VALUE)
Thomas Gleixner tglx@linutronix.de posix-cpu-timers: Implement the missing timer_wait_running callback
Chris Packham chris.packham@alliedtelesis.co.nz hwmon: (adt7475) Use device_property APIs when configuring polarity
Babu Moger Babu.Moger@amd.com hwmon: (k10temp) Check range scale when CUR_TEMP register is read-write
Johan Hovold johan+linaro@kernel.org USB: dwc3: fix runtime pm imbalance on unbind
Johan Hovold johan+linaro@kernel.org USB: dwc3: fix runtime pm imbalance on probe errors
Randy Dunlap rdunlap@infradead.org IMA: allow/fix UML builds
Manivannan Sadhasivam manivannan.sadhasivam@linaro.org PCI: qcom: Fix the incorrect register usage in v2.7.0 config
Lukas Wunner lukas@wunner.de PCI: pciehp: Fix AB-BA deadlock between reset_lock and device_lock
Jiri Slaby (SUSE) jirislaby@kernel.org wireguard: timers: cast enum limits members to int in prints
Vladimir Oltean vladimir.oltean@nxp.com asm-generic/io.h: suppress endianness warnings for readq() and writeq()
Hans de Goede hdegoede@redhat.com ASoC: Intel: bytcr_rt5640: Add quirk for the Acer Iconia One 7 B1-750
Patrik Dahlström risca@dalakolonin.se iio: adc: palmas_gpadc: fix NULL dereference on rmmod
Eugene Huang eugene.huang99@gmail.com ASOC: Intel: sof_sdw: add quirk for Intel 'Rooks County' NUC M15
Stephen Boyd swboyd@chromium.org driver core: Don't require dynamic_debug for initcall_debug probe timing
Arınç ÜNAL arinc.unal@arinc9.com USB: serial: option: add UNISOC vendor and TOZED LT70C product
Thomas Gleixner tglx@linutronix.de x86/fpu: Prevent FPU state corruption
Ruihan Li lrh2000@pku.edu.cn bluetooth: Perform careful capability checks in hci_sock_ioctl()
Daniel Vetter daniel.vetter@ffwll.ch drm/fb-helper: set x/yres_virtual in drm_fb_helper_check_var
Jisoo Jang jisoo.jang@yonsei.ac.kr wifi: brcmfmac: slab-out-of-bounds read in brcmf_get_assoc_ies()
Dan Carpenter dan.carpenter@linaro.org KVM: arm64: Fix buffer overflow in kvm_arm_set_fw_reg()
William Breathitt Gray william.gray@linaro.org counter: 104-quad-8: Fix race condition between FLAG and CNTR reads
Kuniyuki Iwashima kuniyu@amazon.com seccomp: Move copy_seccomp() to no failure path.
-------------
Diffstat:
Makefile | 4 +- arch/arm/boot/dts/exynos4412-itop-elite.dts | 2 +- arch/arm/boot/dts/omap3-gta04.dtsi | 16 + arch/arm/boot/dts/qcom-ipq4019.dtsi | 4 +- arch/arm/boot/dts/qcom-ipq8064.dtsi | 12 +- arch/arm/boot/dts/s5pv210.dtsi | 2 +- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 12 +- arch/arm64/boot/dts/qcom/msm8996.dtsi | 12 +- arch/arm64/boot/dts/qcom/msm8998.dtsi | 4 +- arch/arm64/boot/dts/qcom/sdm845.dtsi | 30 +- arch/arm64/boot/dts/renesas/r8a774c0.dtsi | 3 - arch/arm64/boot/dts/renesas/r8a77990.dtsi | 3 - arch/arm64/include/asm/debug-monitors.h | 1 + arch/arm64/include/asm/scs.h | 7 +- arch/arm64/kernel/debug-monitors.c | 5 + arch/arm64/kernel/entry.S | 12 +- arch/arm64/kernel/head.S | 2 +- arch/arm64/kernel/kgdb.c | 2 + arch/arm64/kvm/psci.c | 2 + arch/ia64/kernel/salinfo.c | 2 +- arch/ia64/mm/contig.c | 2 +- arch/ia64/mm/hugetlbpage.c | 2 +- arch/mips/fw/lib/cmdline.c | 2 +- arch/openrisc/kernel/entry.S | 6 +- arch/parisc/kernel/real2.S | 5 +- arch/powerpc/kernel/rtas.c | 2 +- arch/powerpc/platforms/512x/clock-commonclk.c | 2 +- arch/powerpc/platforms/embedded6xx/flipper-pic.c | 2 +- arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 2 +- arch/powerpc/platforms/embedded6xx/wii.c | 4 +- arch/powerpc/sysdev/tsi108_pci.c | 5 +- arch/sh/Kconfig.debug | 2 +- arch/sh/kernel/cpu/sh4/sq.c | 2 +- arch/sh/kernel/head_32.S | 6 +- arch/sh/kernel/nmi_debug.c | 4 +- arch/sh/kernel/setup.c | 4 +- arch/sh/math-emu/sfp-util.h | 4 - arch/x86/include/asm/kvm_host.h | 5 +- arch/x86/kernel/apic/apic.c | 5 +- arch/x86/kernel/apic/io_apic.c | 14 +- arch/x86/kernel/cpu/mce/amd.c | 14 +- arch/x86/kernel/fpu/core.c | 67 +-- arch/x86/kvm/hyperv.c | 15 +- arch/x86/kvm/svm/svm.c | 2 + arch/x86/kvm/vmx/vmx.c | 16 + arch/x86/kvm/x86.c | 164 ++++-- block/blk-core.c | 7 + block/blk-crypto-internal.h | 25 +- block/blk-crypto.c | 69 ++- block/blk-merge.c | 2 + block/blk-mq.c | 2 +- block/keyslot-manager.c | 43 +- crypto/algapi.c | 4 +- crypto/drbg.c | 16 +- drivers/acpi/processor_pdc.c | 11 + drivers/base/cpu.c | 3 +- drivers/base/dd.c | 7 +- drivers/block/drbd/drbd_receiver.c | 2 +- drivers/bluetooth/btsdio.c | 1 - drivers/char/ipmi/Kconfig | 3 +- drivers/char/ipmi/ipmi_ssif.c | 8 +- drivers/char/tpm/tpm_tis_core.c | 135 +++-- drivers/char/tpm/tpm_tis_core.h | 2 + drivers/clk/at91/clk-sam9x60-pll.c | 2 +- drivers/clk/clk-conf.c | 12 +- drivers/clk/rockchip/clk-rk3399.c | 2 +- drivers/clocksource/timer-davinci.c | 30 +- drivers/counter/104-quad-8.c | 28 +- drivers/crypto/Kconfig | 1 + .../crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 2 +- drivers/crypto/caam/ctrl.c | 6 +- drivers/crypto/ccp/psp-dev.c | 6 +- drivers/crypto/inside-secure/safexcel.c | 37 +- drivers/dma/at_xdmac.c | 5 +- drivers/dma/dw-edma/dw-edma-core.c | 27 +- drivers/dma/mv_xor_v2.c | 2 +- drivers/edac/skx_base.c | 4 +- drivers/firmware/qcom_scm.c | 3 +- drivers/firmware/raspberrypi.c | 29 + drivers/firmware/stratix10-svc.c | 4 +- drivers/fpga/fpga-bridge.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 6 +- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 3 +- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 1 - drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 8 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 3 + drivers/gpu/drm/bridge/adv7511/adv7533.c | 23 +- drivers/gpu/drm/drm_fb_helper.c | 3 + drivers/gpu/drm/drm_probe_helper.c | 5 +- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 4 +- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 7 +- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/lima/lima_drv.c | 6 +- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 8 +- drivers/gpu/drm/msm/adreno/adreno_device.c | 7 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +- drivers/gpu/drm/panel/panel-orisetech-otm8009a.c | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 3 - drivers/gpu/drm/vgem/vgem_fence.c | 1 + drivers/hid/wacom_wac.c | 38 +- drivers/hid/wacom_wac.h | 1 + drivers/hwmon/adt7475.c | 6 +- drivers/hwmon/k10temp.c | 4 +- drivers/hwtracing/coresight/coresight-etm-perf.c | 1 + drivers/i2c/busses/i2c-cadence.c | 6 +- drivers/i2c/busses/i2c-omap.c | 2 +- drivers/iio/adc/palmas_gpadc.c | 2 +- drivers/iio/light/max44009.c | 13 +- drivers/infiniband/core/cm.c | 3 +- drivers/infiniband/hw/hfi1/ipoib_tx.c | 19 +- drivers/infiniband/hw/hfi1/mmu_rb.c | 73 +-- drivers/infiniband/hw/hfi1/mmu_rb.h | 8 +- drivers/infiniband/hw/hfi1/sdma.c | 21 +- drivers/infiniband/hw/hfi1/sdma.h | 16 +- drivers/infiniband/hw/hfi1/sdma_txreq.h | 1 + drivers/infiniband/hw/hfi1/trace_mmu.h | 4 - drivers/infiniband/hw/hfi1/trace_tx.h | 179 ++++++ drivers/infiniband/hw/hfi1/user_sdma.c | 612 +++++++++++++-------- drivers/infiniband/hw/hfi1/user_sdma.h | 6 +- drivers/infiniband/hw/hfi1/verbs.c | 4 +- drivers/infiniband/hw/hfi1/vnic_sdma.c | 1 + drivers/infiniband/hw/mlx4/qp.c | 8 +- drivers/infiniband/hw/mlx5/devx.c | 31 +- drivers/infiniband/hw/mlx5/qp.c | 2 +- drivers/infiniband/sw/rdmavt/qp.c | 2 - drivers/infiniband/sw/siw/siw_main.c | 3 - drivers/infiniband/sw/siw/siw_qp_tx.c | 2 +- drivers/infiniband/ulp/isert/ib_isert.c | 4 +- drivers/infiniband/ulp/srpt/ib_srpt.c | 23 +- drivers/input/touchscreen/raspberrypi-ts.c | 3 +- drivers/iommu/amd/amd_iommu_types.h | 4 +- drivers/leds/Kconfig | 2 +- drivers/leds/leds-tca6507.c | 5 +- drivers/macintosh/Kconfig | 1 + drivers/macintosh/windfarm_smu_sat.c | 1 + drivers/mailbox/zynqmp-ipi-mailbox.c | 19 +- drivers/md/dm-clone-target.c | 1 + drivers/md/dm-flakey.c | 4 +- drivers/md/dm-integrity.c | 8 +- drivers/md/dm-ioctl.c | 7 +- drivers/md/dm-verity-target.c | 17 +- drivers/md/raid10.c | 74 +-- drivers/media/i2c/max9286.c | 1 + drivers/media/pci/dm1105/dm1105.c | 1 + drivers/media/pci/saa7134/saa7134-ts.c | 1 + drivers/media/pci/saa7134/saa7134-vbi.c | 1 + drivers/media/pci/saa7134/saa7134-video.c | 1 + drivers/media/platform/qcom/venus/core.h | 6 +- drivers/media/platform/qcom/venus/helpers.c | 6 + drivers/media/platform/qcom/venus/vdec.c | 120 ++-- drivers/media/platform/rcar_fdp1.c | 50 +- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 2 + drivers/media/rc/gpio-ir-recv.c | 2 + drivers/mfd/tqmx86.c | 76 ++- drivers/misc/vmw_vmci/vmci_host.c | 8 +- drivers/mmc/host/sdhci-of-esdhc.c | 24 +- drivers/mtd/ubi/eba.c | 19 +- drivers/net/dsa/mt7530.c | 4 +- drivers/net/dsa/mv88e6xxx/chip.c | 1 + drivers/net/ethernet/amd/nmclan_cs.c | 2 +- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 1 - drivers/net/ethernet/freescale/enetc/enetc_qos.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 23 +- .../net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 11 +- .../net/ethernet/marvell/octeontx2/nic/otx2_vf.c | 2 +- .../net/ethernet/pensando/ionic/ionic_ethtool.c | 2 +- drivers/net/ethernet/sfc/mcdi_port_common.c | 11 +- drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 14 +- drivers/net/virtio_net.c | 43 +- drivers/net/wireguard/timers.c | 8 +- drivers/net/wireless/ath/ath5k/eeprom.c | 2 +- drivers/net/wireless/ath/ath6kl/bmi.c | 2 +- drivers/net/wireless/ath/ath6kl/htc_pipe.c | 4 +- drivers/net/wireless/ath/ath9k/hif_usb.c | 19 + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 5 + drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 +- drivers/net/wireless/intel/iwlwifi/fw/debugfs.c | 4 +- drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 6 + drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 10 + drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 +- .../net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c | 1 + drivers/net/wireless/realtek/rtlwifi/debug.c | 12 +- drivers/net/wireless/realtek/rtw88/mac.c | 8 +- drivers/nvme/host/core.c | 34 +- drivers/nvme/host/trace.h | 15 +- drivers/nvme/target/fcloop.c | 48 +- drivers/of/device.c | 7 +- drivers/pci/controller/dwc/pci-imx6.c | 7 + drivers/pci/controller/dwc/pcie-qcom.c | 8 +- drivers/pci/hotplug/pciehp_pci.c | 15 + drivers/pci/pcie/edr.c | 1 + drivers/phy/tegra/xusb.c | 2 + drivers/platform/x86/touchscreen_dmi.c | 41 ++ drivers/power/supply/generic-adc-battery.c | 3 + drivers/pwm/pwm-meson.c | 6 +- drivers/pwm/pwm-mtk-disp.c | 98 ++-- drivers/regulator/core.c | 93 +++- drivers/regulator/stm32-pwr.c | 7 +- drivers/remoteproc/st_remoteproc.c | 5 +- drivers/remoteproc/stm32_rproc.c | 6 +- drivers/rtc/rtc-meson-vrtc.c | 4 +- drivers/rtc/rtc-omap.c | 1 + drivers/s390/block/dasd.c | 2 +- drivers/scsi/lpfc/lpfc_init.c | 10 +- drivers/scsi/megaraid.c | 1 + drivers/scsi/qedi/qedi_main.c | 3 + drivers/soc/ti/pm33xx.c | 22 +- drivers/spi/spi-cadence-quadspi.c | 19 +- drivers/spi/spi-fsl-spi.c | 12 +- drivers/spi/spi-imx.c | 14 +- drivers/spi/spi-qup.c | 22 +- drivers/spmi/spmi.c | 3 +- drivers/staging/iio/resolver/ad2s1210.c | 2 +- drivers/staging/media/rkvdec/rkvdec.c | 2 + drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 1 + drivers/target/iscsi/iscsi_target.c | 16 +- drivers/target/target_core_device.c | 17 +- drivers/target/target_core_sbc.c | 2 +- drivers/target/target_core_tmr.c | 164 +++--- drivers/target/target_core_transport.c | 59 +- drivers/target/tcm_fc/tfc_cmd.c | 2 +- drivers/thermal/mtk_thermal.c | 14 +- drivers/tty/n_gsm.c | 1 + drivers/tty/n_hdlc.c | 1 + drivers/tty/n_tty.c | 1 + drivers/tty/pty.c | 1 + drivers/tty/serial/8250/8250.h | 12 + drivers/tty/serial/8250/8250_port.c | 16 +- drivers/tty/serial/fsl_lpuart.c | 2 +- drivers/tty/tty.h | 117 ++++ drivers/tty/tty_audit.c | 1 + drivers/tty/tty_baudrate.c | 1 + drivers/tty/tty_buffer.c | 2 +- drivers/tty/tty_io.c | 5 +- drivers/tty/tty_ioctl.c | 48 +- drivers/tty/tty_jobctrl.c | 1 + drivers/tty/tty_ldisc.c | 1 + drivers/tty/tty_mutex.c | 1 + drivers/tty/tty_port.c | 1 + drivers/usb/chipidea/core.c | 2 +- drivers/usb/dwc3/core.c | 15 +- drivers/usb/dwc3/gadget.c | 11 +- drivers/usb/gadget/udc/renesas_usb3.c | 1 + drivers/usb/gadget/udc/tegra-xudc.c | 2 +- drivers/usb/host/xhci-debugfs.c | 1 + drivers/usb/host/xhci-rcar.c | 3 - drivers/usb/mtu3/mtu3_qmu.c | 5 +- drivers/usb/serial/option.c | 6 + drivers/watchdog/dw_wdt.c | 7 +- drivers/xen/pcpu.c | 20 + fs/afs/inode.c | 1 + fs/btrfs/block-rsv.c | 3 +- fs/btrfs/ctree.c | 32 +- fs/btrfs/ioctl.c | 5 + fs/btrfs/print-tree.c | 6 +- fs/cifs/smb2ops.c | 2 +- fs/erofs/internal.h | 2 +- fs/erofs/zmap.c | 4 + fs/ext4/acl.c | 2 - fs/ext4/balloc.c | 25 + fs/ext4/extents.c | 5 +- fs/ext4/extents_status.c | 30 +- fs/ext4/file.c | 4 - fs/ext4/inline.c | 17 +- fs/ext4/inode.c | 9 +- fs/ext4/ioctl.c | 8 +- fs/ext4/mballoc.c | 6 +- fs/ext4/super.c | 19 +- fs/ext4/xattr.c | 5 +- fs/f2fs/compress.c | 6 + fs/f2fs/data.c | 5 +- fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 15 +- fs/f2fs/namei.c | 16 +- fs/f2fs/segment.c | 76 +-- fs/f2fs/segment.h | 6 + fs/f2fs/super.c | 33 +- fs/fs-writeback.c | 19 +- fs/jbd2/journal.c | 2 + fs/jbd2/transaction.c | 3 + fs/nfs/nfs4state.c | 4 + fs/nilfs2/bmap.c | 16 +- fs/nilfs2/segment.c | 5 +- fs/notify/inotify/inotify_fsnotify.c | 11 +- fs/pstore/pmsg.c | 7 +- fs/reiserfs/xattr_security.c | 8 +- fs/ubifs/dir.c | 1 + fs/ubifs/tnc.c | 144 +++-- include/asm-generic/io.h | 4 +- include/linux/blk-crypto.h | 4 +- include/linux/mailbox/zynqmp-ipi-message.h | 2 +- include/linux/mlx5/mlx5_ifc.h | 3 +- include/linux/netfilter/nfnetlink.h | 1 - include/linux/nvme.h | 4 + include/linux/posix-timers.h | 17 +- include/linux/printk.h | 19 + include/linux/sunrpc/sched.h | 3 +- include/linux/tick.h | 2 + include/linux/tty.h | 97 ---- include/linux/vt_buffer.h | 2 +- include/linux/workqueue.h | 4 +- include/net/netfilter/nf_tables.h | 1 + include/net/scm.h | 13 +- include/net/xsk_buff_pool.h | 9 +- include/soc/bcm2835/raspberrypi-firmware.h | 8 + include/target/target_core_base.h | 16 +- include/trace/events/qrtr.h | 33 +- include/trace/events/timer.h | 3 +- include/uapi/linux/btrfs.h | 1 + include/uapi/linux/const.h | 2 +- include/xen/xen.h | 11 + kernel/bpf/cgroup.c | 9 +- kernel/bpf/verifier.c | 26 +- kernel/events/core.c | 4 +- kernel/fork.c | 17 +- kernel/kheaders.c | 10 +- kernel/rcu/tree.c | 1 + kernel/relay.c | 3 +- kernel/time/posix-cpu-timers.c | 81 ++- kernel/time/posix-timers.c | 4 + kernel/time/tick-broadcast.c | 2 +- kernel/time/tick-common.c | 20 +- kernel/time/tick-internal.h | 1 - kernel/time/tick-sched.c | 110 ++-- kernel/trace/ring_buffer.c | 20 +- kernel/workqueue.c | 67 +-- lib/debugobjects.c | 141 +++-- mm/backing-dev.c | 11 +- mm/page_alloc.c | 16 + net/8021q/vlan_dev.c | 2 +- net/bluetooth/hci_sock.c | 9 +- net/core/skbuff.c | 3 + net/ipv4/ip_output.c | 16 +- net/ipv6/sit.c | 8 +- net/ncsi/ncsi-aen.c | 1 + net/netfilter/nf_tables_api.c | 20 +- net/netfilter/nfnetlink.c | 2 - net/netfilter/nft_dynset.c | 2 +- net/netfilter/nft_lookup.c | 2 +- net/netfilter/nft_objref.c | 2 +- net/netlink/af_netlink.c | 75 +-- net/packet/af_packet.c | 32 +- net/packet/diag.c | 4 +- net/packet/internal.h | 26 +- net/rxrpc/sendmsg.c | 2 +- net/sched/act_mirred.c | 2 +- net/sched/cls_api.c | 1 + net/sched/sch_fq.c | 6 +- net/sunrpc/clnt.c | 3 - net/sunrpc/sched.c | 1 - net/xdp/xsk_queue.h | 1 + scripts/gdb/linux/clk.py | 2 + scripts/gdb/linux/genpd.py | 4 +- scripts/gdb/linux/timerlist.py | 4 +- scripts/gdb/linux/utils.py | 5 +- security/integrity/ima/Kconfig | 2 +- security/selinux/Makefile | 4 +- sound/oss/dmasound/dmasound.h | 6 - sound/oss/dmasound/dmasound_core.c | 26 +- sound/soc/codecs/es8316.c | 17 +- sound/soc/fsl/fsl_mqs.c | 15 +- sound/soc/intel/boards/bytcr_rt5640.c | 12 + sound/soc/intel/boards/sof_sdw.c | 11 + sound/usb/caiaq/input.c | 1 + tools/bpf/bpftool/json_writer.c | 3 - tools/bpf/bpftool/xlated_dumper.c | 7 + tools/perf/builtin-sched.c | 2 +- .../perf/pmu-events/arch/powerpc/power9/other.json | 4 +- .../pmu-events/arch/powerpc/power9/pipeline.json | 2 +- tools/perf/util/auxtrace.c | 5 +- .../perf/util/intel-pt-decoder/intel-pt-decoder.c | 2 + tools/perf/util/pmu.c | 2 +- tools/perf/util/sort.c | 3 +- tools/perf/util/symbol-elf.c | 2 +- .../selftests/bpf/prog_tests/cg_storage_multi.c | 8 +- tools/testing/selftests/resctrl/fill_buf.c | 2 + tools/testing/selftests/resctrl/mba_test.c | 7 +- 379 files changed, 3626 insertions(+), 2091 deletions(-)
From: Kuniyuki Iwashima kuniyu@amazon.com
commit a1140cb215fa13dcec06d12ba0c3ee105633b7c4 upstream.
Our syzbot instance reported memory leaks in do_seccomp() [0], similar to the report [1]. It shows that we miss freeing struct seccomp_filter and some objects included in it.
We can reproduce the issue with the program below [2] which calls one seccomp() and two clone() syscalls.
The first clone()d child exits earlier than its parent and sends a signal to kill it during the second clone(), more precisely before the fatal_signal_pending() test in copy_process(). When the parent receives the signal, it has to destroy the embryonic process and return -EINTR to user space. In the failure path, we have to call seccomp_filter_release() to decrement the filter's refcount.
Initially, we called it in free_task() called from the failure path, but the commit 3a15fb6ed92c ("seccomp: release filter after task is fully dead") moved it to release_task() to notify user space as early as possible that the filter is no longer used.
To keep the change and current seccomp refcount semantics, let's move copy_seccomp() just after the signal check and add a WARN_ON_ONCE() in free_task() for future debugging.
[0]: unreferenced object 0xffff8880063add00 (size 256): comm "repro_seccomp", pid 230, jiffies 4294687090 (age 9.914s) hex dump (first 32 bytes): 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................ ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ backtrace: do_seccomp (./include/linux/slab.h:600 ./include/linux/slab.h:733 kernel/seccomp.c:666 kernel/seccomp.c:708 kernel/seccomp.c:1871 kernel/seccomp.c:1991) do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120) unreferenced object 0xffffc90000035000 (size 4096): comm "repro_seccomp", pid 230, jiffies 4294687090 (age 9.915s) hex dump (first 32 bytes): 01 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: __vmalloc_node_range (mm/vmalloc.c:3226) __vmalloc_node (mm/vmalloc.c:3261 (discriminator 4)) bpf_prog_alloc_no_stats (kernel/bpf/core.c:91) bpf_prog_alloc (kernel/bpf/core.c:129) bpf_prog_create_from_user (net/core/filter.c:1414) do_seccomp (kernel/seccomp.c:671 kernel/seccomp.c:708 kernel/seccomp.c:1871 kernel/seccomp.c:1991) do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120) unreferenced object 0xffff888003fa1000 (size 1024): comm "repro_seccomp", pid 230, jiffies 4294687090 (age 9.915s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: bpf_prog_alloc_no_stats (./include/linux/slab.h:600 ./include/linux/slab.h:733 kernel/bpf/core.c:95) bpf_prog_alloc (kernel/bpf/core.c:129) bpf_prog_create_from_user (net/core/filter.c:1414) do_seccomp (kernel/seccomp.c:671 kernel/seccomp.c:708 kernel/seccomp.c:1871 kernel/seccomp.c:1991) do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120) unreferenced object 0xffff888006360240 (size 16): comm "repro_seccomp", pid 230, jiffies 4294687090 (age 9.915s) hex dump (first 16 bytes): 01 00 37 00 76 65 72 6c e0 83 01 06 80 88 ff ff ..7.verl........ backtrace: bpf_prog_store_orig_filter (net/core/filter.c:1137) bpf_prog_create_from_user (net/core/filter.c:1428) do_seccomp (kernel/seccomp.c:671 kernel/seccomp.c:708 kernel/seccomp.c:1871 kernel/seccomp.c:1991) do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120) unreferenced object 0xffff8880060183e0 (size 8): comm "repro_seccomp", pid 230, jiffies 4294687090 (age 9.915s) hex dump (first 8 bytes): 06 00 00 00 00 00 ff 7f ........ backtrace: kmemdup (mm/util.c:129) bpf_prog_store_orig_filter (net/core/filter.c:1144) bpf_prog_create_from_user (net/core/filter.c:1428) do_seccomp (kernel/seccomp.c:671 kernel/seccomp.c:708 kernel/seccomp.c:1871 kernel/seccomp.c:1991) do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120)
[1]: https://syzkaller.appspot.com/bug?id=2809bb0ac77ad9aa3f4afe42d6a610aba594a98...
[2]: #define _GNU_SOURCE #include <sched.h> #include <signal.h> #include <unistd.h> #include <sys/syscall.h> #include <linux/filter.h> #include <linux/seccomp.h>
void main(void) { struct sock_filter filter[] = { BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), }; struct sock_fprog fprog = { .len = sizeof(filter) / sizeof(filter[0]), .filter = filter, }; long i, pid;
syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER, 0, &fprog);
for (i = 0; i < 2; i++) { pid = syscall(__NR_clone, CLONE_NEWNET | SIGKILL, NULL, NULL, 0); if (pid == 0) return; } }
Fixes: 3a15fb6ed92c ("seccomp: release filter after task is fully dead") Reported-by: syzbot+ab17848fe269b573eb71@syzkaller.appspotmail.com Reported-by: Ayushman Dutta ayudutta@amazon.com Suggested-by: Kees Cook keescook@chromium.org Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Reviewed-by: Christian Brauner (Microsoft) brauner@kernel.org Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20220823154532.82913-1-kuniyu@amazon.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/fork.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
--- a/kernel/fork.c +++ b/kernel/fork.c @@ -441,6 +441,9 @@ void put_task_stack(struct task_struct *
void free_task(struct task_struct *tsk) { +#ifdef CONFIG_SECCOMP + WARN_ON_ONCE(tsk->seccomp.filter); +#endif scs_release(tsk);
#ifndef CONFIG_THREAD_INFO_IN_TASK @@ -2248,12 +2251,6 @@ static __latent_entropy struct task_stru
spin_lock(¤t->sighand->siglock);
- /* - * Copy seccomp details explicitly here, in case they were changed - * before holding sighand lock. - */ - copy_seccomp(p); - rseq_fork(p, clone_flags);
/* Don't start children in a dying pid namespace */ @@ -2268,6 +2265,14 @@ static __latent_entropy struct task_stru goto bad_fork_cancel_cgroup; }
+ /* No more failure paths after this point. */ + + /* + * Copy seccomp details explicitly here, in case they were changed + * before holding sighand lock. + */ + copy_seccomp(p); + init_task_pid_links(p); if (likely(p->pid)) { ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
From: William Breathitt Gray william.gray@linaro.org
commit 4aa3b75c74603c3374877d5fd18ad9cc3a9a62ed upstream.
The Counter (CNTR) register is 24 bits wide, but we can have an effective 25-bit count value by setting bit 24 to the XOR of the Borrow flag and Carry flag. The flags can be read from the FLAG register, but a race condition exists: the Borrow flag and Carry flag are instantaneous and could change by the time the count value is read from the CNTR register.
Since the race condition could result in an incorrect 25-bit count value, remove support for 25-bit count values from this driver; hard-coded maximum count values are replaced by a LS7267_CNTR_MAX define for consistency and clarity.
Fixes: 28e5d3bb0325 ("iio: 104-quad-8: Add IIO support for the ACCES 104-QUAD-8") Cc: stable@vger.kernel.org # 6.1.x Cc: stable@vger.kernel.org # 6.2.x Link: https://lore.kernel.org/r/20230312231554.134858-1-william.gray@linaro.org/ Signed-off-by: William Breathitt Gray william.gray@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/counter/104-quad-8.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-)
--- a/drivers/counter/104-quad-8.c +++ b/drivers/counter/104-quad-8.c @@ -62,10 +62,6 @@ struct quad8_iio { #define QUAD8_REG_CHAN_OP 0x11 #define QUAD8_REG_INDEX_INPUT_LEVELS 0x16 #define QUAD8_DIFF_ENCODER_CABLE_STATUS 0x17 -/* Borrow Toggle flip-flop */ -#define QUAD8_FLAG_BT BIT(0) -/* Carry Toggle flip-flop */ -#define QUAD8_FLAG_CT BIT(1) /* Error flag */ #define QUAD8_FLAG_E BIT(4) /* Up/Down flag */ @@ -104,9 +100,6 @@ static int quad8_read_raw(struct iio_dev { struct quad8_iio *const priv = iio_priv(indio_dev); const int base_offset = priv->base + 2 * chan->channel; - unsigned int flags; - unsigned int borrow; - unsigned int carry; int i;
switch (mask) { @@ -117,12 +110,7 @@ static int quad8_read_raw(struct iio_dev return IIO_VAL_INT; }
- flags = inb(base_offset + 1); - borrow = flags & QUAD8_FLAG_BT; - carry = !!(flags & QUAD8_FLAG_CT); - - /* Borrow XOR Carry effectively doubles count range */ - *val = (borrow ^ carry) << 24; + *val = 0;
mutex_lock(&priv->lock);
@@ -643,17 +631,9 @@ static int quad8_count_read(struct count { struct quad8_iio *const priv = counter->priv; const int base_offset = priv->base + 2 * count->id; - unsigned int flags; - unsigned int borrow; - unsigned int carry; int i;
- flags = inb(base_offset + 1); - borrow = flags & QUAD8_FLAG_BT; - carry = !!(flags & QUAD8_FLAG_CT); - - /* Borrow XOR Carry effectively doubles count range */ - *val = (unsigned long)(borrow ^ carry) << 24; + *val = 0;
mutex_lock(&priv->lock);
@@ -1198,8 +1178,8 @@ static ssize_t quad8_count_ceiling_read(
mutex_unlock(&priv->lock);
- /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */ - return sprintf(buf, "33554431\n"); + /* By default 0xFFFFFF (24 bits unsigned) is maximum count */ + return sprintf(buf, "16777215\n"); }
static ssize_t quad8_count_ceiling_write(struct counter_device *counter,
From: Dan Carpenter dan.carpenter@linaro.org
commit a25bc8486f9c01c1af6b6c5657234b2eee2c39d6 upstream.
The KVM_REG_SIZE() comes from the ioctl and it can be a power of two between 0-32768 but if it is more than sizeof(long) this will corrupt memory.
Fixes: 99adb567632b ("KVM: arm/arm64: Add save/restore support for firmware workaround state") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Reviewed-by: Steven Price steven.price@arm.com Reviewed-by: Eric Auger eric.auger@redhat.com Reviewed-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/4efbab8c-640f-43b2-8ac6-6d68e08280fe@kili.mountain Signed-off-by: Oliver Upton oliver.upton@linux.dev [will: kvm_arm_set_fw_reg() lives in psci.c not hypercalls.c] Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/kvm/psci.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/arch/arm64/kvm/psci.c +++ b/arch/arm64/kvm/psci.c @@ -499,6 +499,8 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu * u64 val; int wa_level;
+ if (KVM_REG_SIZE(reg->id) != sizeof(val)) + return -ENOENT; if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id))) return -EFAULT;
From: Jisoo Jang jisoo.jang@yonsei.ac.kr
commit 0da40e018fd034d87c9460123fa7f897b69fdee7 upstream.
Fix a slab-out-of-bounds read that occurs in kmemdup() called from brcmf_get_assoc_ies(). The bug could occur when assoc_info->req_len, data from a URB provided by a USB device, is bigger than the size of buffer which is defined as WL_EXTRA_BUF_MAX.
Add the size check for req_len/resp_len of assoc_info.
Found by a modified version of syzkaller.
[ 46.592467][ T7] ================================================================== [ 46.594687][ T7] BUG: KASAN: slab-out-of-bounds in kmemdup+0x3e/0x50 [ 46.596572][ T7] Read of size 3014656 at addr ffff888019442000 by task kworker/0:1/7 [ 46.598575][ T7] [ 46.599157][ T7] CPU: 0 PID: 7 Comm: kworker/0:1 Tainted: G O 5.14.0+ #145 [ 46.601333][ T7] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 [ 46.604360][ T7] Workqueue: events brcmf_fweh_event_worker [ 46.605943][ T7] Call Trace: [ 46.606584][ T7] dump_stack_lvl+0x8e/0xd1 [ 46.607446][ T7] print_address_description.constprop.0.cold+0x93/0x334 [ 46.608610][ T7] ? kmemdup+0x3e/0x50 [ 46.609341][ T7] kasan_report.cold+0x79/0xd5 [ 46.610151][ T7] ? kmemdup+0x3e/0x50 [ 46.610796][ T7] kasan_check_range+0x14e/0x1b0 [ 46.611691][ T7] memcpy+0x20/0x60 [ 46.612323][ T7] kmemdup+0x3e/0x50 [ 46.612987][ T7] brcmf_get_assoc_ies+0x967/0xf60 [ 46.613904][ T7] ? brcmf_notify_vif_event+0x3d0/0x3d0 [ 46.614831][ T7] ? lock_chain_count+0x20/0x20 [ 46.615683][ T7] ? mark_lock.part.0+0xfc/0x2770 [ 46.616552][ T7] ? lock_chain_count+0x20/0x20 [ 46.617409][ T7] ? mark_lock.part.0+0xfc/0x2770 [ 46.618244][ T7] ? lock_chain_count+0x20/0x20 [ 46.619024][ T7] brcmf_bss_connect_done.constprop.0+0x241/0x2e0 [ 46.620019][ T7] ? brcmf_parse_configure_security.isra.0+0x2a0/0x2a0 [ 46.620818][ T7] ? __lock_acquire+0x181f/0x5790 [ 46.621462][ T7] brcmf_notify_connect_status+0x448/0x1950 [ 46.622134][ T7] ? rcu_read_lock_bh_held+0xb0/0xb0 [ 46.622736][ T7] ? brcmf_cfg80211_join_ibss+0x7b0/0x7b0 [ 46.623390][ T7] ? find_held_lock+0x2d/0x110 [ 46.623962][ T7] ? brcmf_fweh_event_worker+0x19f/0xc60 [ 46.624603][ T7] ? mark_held_locks+0x9f/0xe0 [ 46.625145][ T7] ? lockdep_hardirqs_on_prepare+0x3e0/0x3e0 [ 46.625871][ T7] ? brcmf_cfg80211_join_ibss+0x7b0/0x7b0 [ 46.626545][ T7] brcmf_fweh_call_event_handler.isra.0+0x90/0x100 [ 46.627338][ T7] brcmf_fweh_event_worker+0x557/0xc60 [ 46.627962][ T7] ? brcmf_fweh_call_event_handler.isra.0+0x100/0x100 [ 46.628736][ T7] ? rcu_read_lock_sched_held+0xa1/0xd0 [ 46.629396][ T7] ? rcu_read_lock_bh_held+0xb0/0xb0 [ 46.629970][ T7] ? lockdep_hardirqs_on_prepare+0x273/0x3e0 [ 46.630649][ T7] process_one_work+0x92b/0x1460 [ 46.631205][ T7] ? pwq_dec_nr_in_flight+0x330/0x330 [ 46.631821][ T7] ? rwlock_bug.part.0+0x90/0x90 [ 46.632347][ T7] worker_thread+0x95/0xe00 [ 46.632832][ T7] ? __kthread_parkme+0x115/0x1e0 [ 46.633393][ T7] ? process_one_work+0x1460/0x1460 [ 46.633957][ T7] kthread+0x3a1/0x480 [ 46.634369][ T7] ? set_kthread_struct+0x120/0x120 [ 46.634933][ T7] ret_from_fork+0x1f/0x30 [ 46.635431][ T7] [ 46.635687][ T7] Allocated by task 7: [ 46.636151][ T7] kasan_save_stack+0x1b/0x40 [ 46.636628][ T7] __kasan_kmalloc+0x7c/0x90 [ 46.637108][ T7] kmem_cache_alloc_trace+0x19e/0x330 [ 46.637696][ T7] brcmf_cfg80211_attach+0x4a0/0x4040 [ 46.638275][ T7] brcmf_attach+0x389/0xd40 [ 46.638739][ T7] brcmf_usb_probe+0x12de/0x1690 [ 46.639279][ T7] usb_probe_interface+0x2aa/0x760 [ 46.639820][ T7] really_probe+0x205/0xb70 [ 46.640342][ T7] __driver_probe_device+0x311/0x4b0 [ 46.640876][ T7] driver_probe_device+0x4e/0x150 [ 46.641445][ T7] __device_attach_driver+0x1cc/0x2a0 [ 46.642000][ T7] bus_for_each_drv+0x156/0x1d0 [ 46.642543][ T7] __device_attach+0x23f/0x3a0 [ 46.643065][ T7] bus_probe_device+0x1da/0x290 [ 46.643644][ T7] device_add+0xb7b/0x1eb0 [ 46.644130][ T7] usb_set_configuration+0xf59/0x16f0 [ 46.644720][ T7] usb_generic_driver_probe+0x82/0xa0 [ 46.645295][ T7] usb_probe_device+0xbb/0x250 [ 46.645786][ T7] really_probe+0x205/0xb70 [ 46.646258][ T7] __driver_probe_device+0x311/0x4b0 [ 46.646804][ T7] driver_probe_device+0x4e/0x150 [ 46.647387][ T7] __device_attach_driver+0x1cc/0x2a0 [ 46.647926][ T7] bus_for_each_drv+0x156/0x1d0 [ 46.648454][ T7] __device_attach+0x23f/0x3a0 [ 46.648939][ T7] bus_probe_device+0x1da/0x290 [ 46.649478][ T7] device_add+0xb7b/0x1eb0 [ 46.649936][ T7] usb_new_device.cold+0x49c/0x1029 [ 46.650526][ T7] hub_event+0x1c98/0x3950 [ 46.650975][ T7] process_one_work+0x92b/0x1460 [ 46.651535][ T7] worker_thread+0x95/0xe00 [ 46.651991][ T7] kthread+0x3a1/0x480 [ 46.652413][ T7] ret_from_fork+0x1f/0x30 [ 46.652885][ T7] [ 46.653131][ T7] The buggy address belongs to the object at ffff888019442000 [ 46.653131][ T7] which belongs to the cache kmalloc-2k of size 2048 [ 46.654669][ T7] The buggy address is located 0 bytes inside of [ 46.654669][ T7] 2048-byte region [ffff888019442000, ffff888019442800) [ 46.656137][ T7] The buggy address belongs to the page: [ 46.656720][ T7] page:ffffea0000651000 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x19440 [ 46.657792][ T7] head:ffffea0000651000 order:3 compound_mapcount:0 compound_pincount:0 [ 46.658673][ T7] flags: 0x100000000010200(slab|head|node=0|zone=1) [ 46.659422][ T7] raw: 0100000000010200 0000000000000000 dead000000000122 ffff888100042000 [ 46.660363][ T7] raw: 0000000000000000 0000000000080008 00000001ffffffff 0000000000000000 [ 46.661236][ T7] page dumped because: kasan: bad access detected [ 46.661956][ T7] page_owner tracks the page as allocated [ 46.662588][ T7] page last allocated via order 3, migratetype Unmovable, gfp_mask 0x52a20(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP), pid 7, ts 31136961085, free_ts 0 [ 46.664271][ T7] prep_new_page+0x1aa/0x240 [ 46.664763][ T7] get_page_from_freelist+0x159a/0x27c0 [ 46.665340][ T7] __alloc_pages+0x2da/0x6a0 [ 46.665847][ T7] alloc_pages+0xec/0x1e0 [ 46.666308][ T7] allocate_slab+0x380/0x4e0 [ 46.666770][ T7] ___slab_alloc+0x5bc/0x940 [ 46.667264][ T7] __slab_alloc+0x6d/0x80 [ 46.667712][ T7] kmem_cache_alloc_trace+0x30a/0x330 [ 46.668299][ T7] brcmf_usbdev_qinit.constprop.0+0x50/0x470 [ 46.668885][ T7] brcmf_usb_probe+0xc97/0x1690 [ 46.669438][ T7] usb_probe_interface+0x2aa/0x760 [ 46.669988][ T7] really_probe+0x205/0xb70 [ 46.670487][ T7] __driver_probe_device+0x311/0x4b0 [ 46.671031][ T7] driver_probe_device+0x4e/0x150 [ 46.671604][ T7] __device_attach_driver+0x1cc/0x2a0 [ 46.672192][ T7] bus_for_each_drv+0x156/0x1d0 [ 46.672739][ T7] page_owner free stack trace missing [ 46.673335][ T7] [ 46.673620][ T7] Memory state around the buggy address: [ 46.674213][ T7] ffff888019442700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 46.675083][ T7] ffff888019442780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 46.675994][ T7] >ffff888019442800: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 46.676875][ T7] ^ [ 46.677323][ T7] ffff888019442880: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 46.678190][ T7] ffff888019442900: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 46.679052][ T7] ================================================================== [ 46.679945][ T7] Disabling lock debugging due to kernel taint [ 46.680725][ T7] Kernel panic - not syncing:
Reviewed-by: Arend van Spriel arend.vanspriel@broadcom.com Signed-off-by: Jisoo Jang jisoo.jang@yonsei.ac.kr Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230309104457.22628-1-jisoo.jang@yonsei.ac.kr Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -5834,6 +5834,11 @@ static s32 brcmf_get_assoc_ies(struct br (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf; req_len = le32_to_cpu(assoc_info->req_len); resp_len = le32_to_cpu(assoc_info->resp_len); + if (req_len > WL_EXTRA_BUF_MAX || resp_len > WL_EXTRA_BUF_MAX) { + bphy_err(drvr, "invalid lengths in assoc info: req %u resp %u\n", + req_len, resp_len); + return -EINVAL; + } if (req_len) { err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies", cfg->extra_buf,
From: Daniel Vetter daniel.vetter@ffwll.ch
commit 1935f0deb6116dd785ea64d8035eab0ff441255b upstream.
Drivers are supposed to fix this up if needed if they don't outright reject it. Uncovered by 6c11df58fd1a ("fbmem: Check virtual screen sizes in fb_set_var()").
Reported-by: syzbot+20dcf81733d43ddff661@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=c5faf983bfa4a607de530cd3bb008888bf06cef... Cc: stable@vger.kernel.org # v5.4+ Cc: Daniel Vetter daniel@ffwll.ch Cc: Javier Martinez Canillas javierm@redhat.com Cc: Thomas Zimmermann tzimmermann@suse.de Reviewed-by: Javier Martinez Canillas javierm@redhat.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230404194038.472803-1-daniel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/drm_fb_helper.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1299,6 +1299,9 @@ int drm_fb_helper_check_var(struct fb_va return -EINVAL; }
+ var->xres_virtual = fb->width; + var->yres_virtual = fb->height; + /* * Workaround for SDL 1.2, which is known to be setting all pixel format * fields values to zero in some cases. We treat this situation as a
From: Ruihan Li lrh2000@pku.edu.cn
commit 25c150ac103a4ebeed0319994c742a90634ddf18 upstream.
Previously, capability was checked using capable(), which verified that the caller of the ioctl system call had the required capability. In addition, the result of the check would be stored in the HCI_SOCK_TRUSTED flag, making it persistent for the socket.
However, malicious programs can abuse this approach by deliberately sharing an HCI socket with a privileged task. The HCI socket will be marked as trusted when the privileged task occasionally makes an ioctl call.
This problem can be solved by using sk_capable() to check capability, which ensures that not only the current task but also the socket opener has the specified capability, thus reducing the risk of privilege escalation through the previously identified vulnerability.
Cc: stable@vger.kernel.org Fixes: f81f5b2db869 ("Bluetooth: Send control open and close messages for HCI raw sockets") Signed-off-by: Ruihan Li lrh2000@pku.edu.cn Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/bluetooth/hci_sock.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -996,7 +996,14 @@ static int hci_sock_ioctl(struct socket if (hci_sock_gen_cookie(sk)) { struct sk_buff *skb;
- if (capable(CAP_NET_ADMIN)) + /* Perform careful checks before setting the HCI_SOCK_TRUSTED + * flag. Make sure that not only the current task but also + * the socket opener has the required capability, since + * privileged programs can be tricked into making ioctl calls + * on HCI sockets, and the socket should not be marked as + * trusted simply because the ioctl caller is privileged. + */ + if (sk_capable(sk, CAP_NET_ADMIN)) hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
/* Send event to monitor */
From: Thomas Gleixner tglx@linutronix.de
commit 59f5ede3bc0f00eb856425f636dab0c10feb06d8 upstream.
The FPU usage related to task FPU management is either protected by disabling interrupts (switch_to, return to user) or via fpregs_lock() which is a wrapper around local_bh_disable(). When kernel code wants to use the FPU then it has to check whether it is possible by calling irq_fpu_usable().
But the condition in irq_fpu_usable() is wrong. It allows FPU to be used when:
!in_interrupt() || interrupted_user_mode() || interrupted_kernel_fpu_idle()
The latter is checking whether some other context already uses FPU in the kernel, but if that's not the case then it allows FPU to be used unconditionally even if the calling context interrupted a fpregs_lock() critical region. If that happens then the FPU state of the interrupted context becomes corrupted.
Allow in kernel FPU usage only when no other context has in kernel FPU usage and either the calling context is not hard interrupt context or the hard interrupt did not interrupt a local bottomhalf disabled region.
It's hard to find a proper Fixes tag as the condition was broken in one way or the other for a very long time and the eager/lazy FPU changes caused a lot of churn. Picked something remotely connected from the history.
This survived undetected for quite some time as FPU usage in interrupt context is rare, but the recent changes to the random code unearthed it at least on a kernel which had FPU debugging enabled. There is probably a higher rate of silent corruption as not all issues can be detected by the FPU debugging code. This will be addressed in a subsequent change.
Fixes: 5d2bd7009f30 ("x86, fpu: decouple non-lazy/eager fpu restore from xsave") Reported-by: Filipe Manana fdmanana@suse.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Tested-by: Filipe Manana fdmanana@suse.com Reviewed-by: Borislav Petkov bp@suse.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220501193102.588689270@linutronix.de Signed-off-by: Can Sun cansun@arista.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/kernel/fpu/core.c | 67 +++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 41 deletions(-)
--- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -25,17 +25,7 @@ */ union fpregs_state init_fpstate __read_mostly;
-/* - * Track whether the kernel is using the FPU state - * currently. - * - * This flag is used: - * - * - by IRQ context code to potentially use the FPU - * if it's unused. - * - * - to debug kernel_fpu_begin()/end() correctness - */ +/* Track in-kernel FPU usage */ static DEFINE_PER_CPU(bool, in_kernel_fpu);
/* @@ -43,42 +33,37 @@ static DEFINE_PER_CPU(bool, in_kernel_fp */ DEFINE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx);
-static bool kernel_fpu_disabled(void) -{ - return this_cpu_read(in_kernel_fpu); -} - -static bool interrupted_kernel_fpu_idle(void) -{ - return !kernel_fpu_disabled(); -} - -/* - * Were we in user mode (or vm86 mode) when we were - * interrupted? - * - * Doing kernel_fpu_begin/end() is ok if we are running - * in an interrupt context from user mode - we'll just - * save the FPU state as required. - */ -static bool interrupted_user_mode(void) -{ - struct pt_regs *regs = get_irq_regs(); - return regs && user_mode(regs); -} - /* * Can we use the FPU in kernel mode with the * whole "kernel_fpu_begin/end()" sequence? - * - * It's always ok in process context (ie "not interrupt") - * but it is sometimes ok even from an irq. */ bool irq_fpu_usable(void) { - return !in_interrupt() || - interrupted_user_mode() || - interrupted_kernel_fpu_idle(); + if (WARN_ON_ONCE(in_nmi())) + return false; + + /* In kernel FPU usage already active? */ + if (this_cpu_read(in_kernel_fpu)) + return false; + + /* + * When not in NMI or hard interrupt context, FPU can be used in: + * + * - Task context except from within fpregs_lock()'ed critical + * regions. + * + * - Soft interrupt processing context which cannot happen + * while in a fpregs_lock()'ed critical region. + */ + if (!in_irq()) + return true; + + /* + * In hard interrupt context it's safe when soft interrupts + * are enabled, which means the interrupt did not hit in + * a fpregs_lock()'ed critical region. + */ + return !softirq_count(); } EXPORT_SYMBOL(irq_fpu_usable);
From: Arınç ÜNAL arinc.unal@arinc9.com
commit a095edfc15f0832e046ae23964e249ef5c95af87 upstream.
Add UNISOC vendor ID and TOZED LT70-C modem which is based from UNISOC SL8563. The modem supports the NCM mode. Interface 0 is used for running the AT commands. Interface 12 is the ADB interface.
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 6 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1782 ProdID=4055 Rev=04.04 S: Manufacturer=Unisoc Phone S: Product=Unisoc Phone S: SerialNumber=<redacted> C: #Ifs=14 Cfg#= 1 Atr=c0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0d Prot=00 Driver=cdc_ncm E: Ad=82(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#=10 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#=11 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=08(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#=12 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=09(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8d(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#=13 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0d Prot=00 Driver=cdc_ncm E: Ad=84(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 3 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 4 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0d Prot=00 Driver=cdc_ncm E: Ad=86(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 5 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 6 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0d Prot=00 Driver=cdc_ncm E: Ad=88(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 7 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=01 Driver=cdc_ncm E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 8 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 9 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8a(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
Signed-off-by: Arınç ÜNAL arinc.unal@arinc9.com Link: https://lore.kernel.org/r/20230417152003.243248-1-arinc.unal@arinc9.com Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/serial/option.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -595,6 +595,11 @@ static void option_instat_callback(struc #define SIERRA_VENDOR_ID 0x1199 #define SIERRA_PRODUCT_EM9191 0x90d3
+/* UNISOC (Spreadtrum) products */ +#define UNISOC_VENDOR_ID 0x1782 +/* TOZED LT70-C based on UNISOC SL8563 uses UNISOC's vendor ID */ +#define TOZED_PRODUCT_LT70C 0x4055 + /* Device flags */
/* Highest interface number which can be used with NCTRL() and RSVD() */ @@ -2225,6 +2230,7 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids);
From: Stephen Boyd swboyd@chromium.org
commit e2f06aa885081e1391916367f53bad984714b4db upstream.
Don't require the use of dynamic debug (or modification of the kernel to add a #define DEBUG to the top of this file) to get the printk message about driver probe timing. This printk is only emitted when initcall_debug is enabled on the kernel commandline, and it isn't immediately obvious that you have to do something else to debug boot timing issues related to driver probe. Add a comment too so it doesn't get converted back to pr_debug().
Fixes: eb7fbc9fb118 ("driver core: Add missing '\n' in log messages") Cc: stable stable@kernel.org Cc: Christophe JAILLET christophe.jaillet@wanadoo.fr Cc: Brian Norris briannorris@chromium.org Reviewed-by: Brian Norris briannorris@chromium.org Acked-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Stephen Boyd swboyd@chromium.org Link: https://lore.kernel.org/r/20230412225842.3196599-1-swboyd@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/base/dd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -677,7 +677,12 @@ static int really_probe_debug(struct dev calltime = ktime_get(); ret = really_probe(dev, drv); rettime = ktime_get(); - pr_debug("probe of %s returned %d after %lld usecs\n", + /* + * Don't change this to pr_debug() because that requires + * CONFIG_DYNAMIC_DEBUG and we want a simple 'initcall_debug' on the + * kernel commandline to print this all the time at the debug level. + */ + printk(KERN_DEBUG "probe of %s returned %d after %lld usecs\n", dev_name(dev), ret, ktime_us_delta(rettime, calltime)); return ret; }
From: Eugene Huang eugene.huang99@gmail.com
[ Upstream commit 3c728b1bc5b99c5275ac5c7788ef814c0e51ef54 ]
Same quirks as the 'Bishop County' NUC M15, except the rt711 is in the 'JD2 100K' jack detection mode.
Link: https://github.com/thesofproject/linux/issues/4088 Signed-off-by: Eugene Huang eugene.huang99@gmail.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Péter Ujfalusi peter.ujfalusi@linux.intel.com Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Link: https://lore.kernel.org/r/20230314090553.498664-2-yung-chuan.liao@linux.inte... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/boards/sof_sdw.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index f5d8f7951cfc3..eb713e9c2bd22 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -175,6 +175,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { SOF_SDW_PCH_DMIC | SOF_RT711_JD_SRC_JD2), }, + { + /* NUC15 'Rooks County' LAPRC510 and LAPRC710 skews */ + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"), + DMI_MATCH(DMI_PRODUCT_NAME, "LAPRC"), + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_SDW_PCH_DMIC | + RT711_JD2_100K), + }, /* TigerLake-SDCA devices */ { .callback = sof_sdw_quirk_cb,
From: Patrik Dahlström risca@dalakolonin.se
[ Upstream commit 49f76c499d38bf67803438eee88c8300d0f6ce09 ]
Calling dev_to_iio_dev() on a platform device pointer is undefined and will make adc NULL.
Signed-off-by: Patrik Dahlström risca@dalakolonin.se Link: https://lore.kernel.org/r/20230313205029.1881745-1-risca@dalakolonin.se Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/palmas_gpadc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c index f4756671cddb6..6ed0d151ad21a 100644 --- a/drivers/iio/adc/palmas_gpadc.c +++ b/drivers/iio/adc/palmas_gpadc.c @@ -628,7 +628,7 @@ static int palmas_gpadc_probe(struct platform_device *pdev)
static int palmas_gpadc_remove(struct platform_device *pdev) { - struct iio_dev *indio_dev = dev_to_iio_dev(&pdev->dev); + struct iio_dev *indio_dev = dev_get_drvdata(&pdev->dev); struct palmas_gpadc *adc = iio_priv(indio_dev);
if (adc->wakeup1_enable || adc->wakeup2_enable)
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit e38c5e80c3d293a883c6f1d553f2146ec0bda35e ]
The Acer Iconia One 7 B1-750 tablet mostly works fine with the defaults for an Bay Trail CR tablet. Except for the internal mic, instead of an analog mic on IN3 a digital mic on DMIC1 is uses.
Add a quirk with these settings for this tablet.
Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230322145332.131525-1-hdegoede@redhat.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/boards/bytcr_rt5640.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 8a99cb6dfcd69..9a5ab96f917d3 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -393,6 +393,18 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
/* Please keep this list alphabetically sorted */ static const struct dmi_system_id byt_rt5640_quirk_table[] = { + { /* Acer Iconia One 7 B1-750 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "VESPA2"), + }, + .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | + BYT_RT5640_JD_SRC_JD1_IN4P | + BYT_RT5640_OVCD_TH_1500UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { /* Acer Iconia Tab 8 W1-810 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit d564fa1ff19e893e2971d66e5c8f49dc1cdc8ffc ]
Commit c1d55d50139b ("asm-generic/io.h: Fix sparse warnings on big-endian architectures") missed fixing the 64-bit accessors.
Arnd explains in the attached link why the casts are necessary, even if __raw_readq() and __raw_writeq() do not take endian-specific types.
Link: https://lore.kernel.org/lkml/9105d6fc-880b-4734-857d-e3d30b87ccf6@app.fastma... Suggested-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Sasha Levin sashal@kernel.org --- include/asm-generic/io.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index 9ea83d80eb6f9..dcbd41048b4e7 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h @@ -190,7 +190,7 @@ static inline u64 readq(const volatile void __iomem *addr) u64 val;
__io_br(); - val = __le64_to_cpu(__raw_readq(addr)); + val = __le64_to_cpu((__le64 __force)__raw_readq(addr)); __io_ar(val); return val; } @@ -233,7 +233,7 @@ static inline void writel(u32 value, volatile void __iomem *addr) static inline void writeq(u64 value, volatile void __iomem *addr) { __io_bw(); - __raw_writeq(__cpu_to_le64(value), addr); + __raw_writeq((u64 __force)__cpu_to_le64(value), addr); __io_aw(); } #endif
From: Jiri Slaby (SUSE) jirislaby@kernel.org
commit 2d4ee16d969c97996e80e4c9cb6de0acaff22c9f upstream.
Since gcc13, each member of an enum has the same type as the enum. And that is inherited from its members. Provided "REKEY_AFTER_MESSAGES = 1ULL << 60", the named type is unsigned long.
This generates warnings with gcc-13: error: format '%d' expects argument of type 'int', but argument 6 has type 'long unsigned int'
Cast those particular enum members to int when printing them.
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36113 Cc: Martin Liska mliska@suse.cz Signed-off-by: Jiri Slaby (SUSE) jirislaby@kernel.org Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Link: https://lore.kernel.org/all/20221213225208.3343692-2-Jason@zx2c4.com/ Signed-off-by: Jakub Kicinski kuba@kernel.org Cc: Chris Clayton chris2553@googlemail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireguard/timers.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/net/wireguard/timers.c +++ b/drivers/net/wireguard/timers.c @@ -46,7 +46,7 @@ static void wg_expired_retransmit_handsh if (peer->timer_handshake_attempts > MAX_TIMER_HANDSHAKES) { pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d attempts, giving up\n", peer->device->dev->name, peer->internal_id, - &peer->endpoint.addr, MAX_TIMER_HANDSHAKES + 2); + &peer->endpoint.addr, (int)MAX_TIMER_HANDSHAKES + 2);
del_timer(&peer->timer_send_keepalive); /* We drop all packets without a keypair and don't try again, @@ -64,7 +64,7 @@ static void wg_expired_retransmit_handsh ++peer->timer_handshake_attempts; pr_debug("%s: Handshake for peer %llu (%pISpfsc) did not complete after %d seconds, retrying (try %d)\n", peer->device->dev->name, peer->internal_id, - &peer->endpoint.addr, REKEY_TIMEOUT, + &peer->endpoint.addr, (int)REKEY_TIMEOUT, peer->timer_handshake_attempts + 1);
/* We clear the endpoint address src address, in case this is @@ -94,7 +94,7 @@ static void wg_expired_new_handshake(str
pr_debug("%s: Retrying handshake with peer %llu (%pISpfsc) because we stopped hearing back after %d seconds\n", peer->device->dev->name, peer->internal_id, - &peer->endpoint.addr, KEEPALIVE_TIMEOUT + REKEY_TIMEOUT); + &peer->endpoint.addr, (int)(KEEPALIVE_TIMEOUT + REKEY_TIMEOUT)); /* We clear the endpoint address src address, in case this is the cause * of trouble. */ @@ -126,7 +126,7 @@ static void wg_queued_expired_zero_key_m
pr_debug("%s: Zeroing out all keys for peer %llu (%pISpfsc), since we haven't received a new one in %d seconds\n", peer->device->dev->name, peer->internal_id, - &peer->endpoint.addr, REJECT_AFTER_TIME * 3); + &peer->endpoint.addr, (int)REJECT_AFTER_TIME * 3); wg_noise_handshake_clear(&peer->handshake); wg_noise_keypairs_clear(&peer->keypairs); wg_peer_put(peer);
From: Lukas Wunner lukas@wunner.de
commit f5eff5591b8f9c5effd25c92c758a127765f74c1 upstream.
In 2013, commits
2e35afaefe64 ("PCI: pciehp: Add reset_slot() method") 608c388122c7 ("PCI: Add slot reset option to pci_dev_reset()")
amended PCIe hotplug to mask Presence Detect Changed events during a Secondary Bus Reset. The reset thus no longer causes gratuitous slot bringdown and bringup.
However the commits neglected to serialize reset with code paths reading slot registers. For instance, a slot bringup due to an earlier hotplug event may see the Presence Detect State bit cleared during a concurrent Secondary Bus Reset.
In 2018, commit
5b3f7b7d062b ("PCI: pciehp: Avoid slot access during reset")
retrofitted the missing locking. It introduced a reset_lock which serializes a Secondary Bus Reset with other parts of pciehp.
Unfortunately the locking turns out to be overzealous: reset_lock is held for the entire enumeration and de-enumeration of hotplugged devices, including driver binding and unbinding.
Driver binding and unbinding acquires device_lock while the reset_lock of the ancestral hotplug port is held. A concurrent Secondary Bus Reset acquires the ancestral reset_lock while already holding the device_lock. The asymmetric locking order in the two code paths can lead to AB-BA deadlocks.
Michael Haeuptle reports such deadlocks on simultaneous hot-removal and vfio release (the latter implies a Secondary Bus Reset):
pciehp_ist() # down_read(reset_lock) pciehp_handle_presence_or_link_change() pciehp_disable_slot() __pciehp_disable_slot() remove_board() pciehp_unconfigure_device() pci_stop_and_remove_bus_device() pci_stop_bus_device() pci_stop_dev() device_release_driver() device_release_driver_internal() __device_driver_lock() # device_lock()
SYS_munmap() vfio_device_fops_release() vfio_device_group_close() vfio_device_close() vfio_device_last_close() vfio_pci_core_close_device() vfio_pci_core_disable() # device_lock() __pci_reset_function_locked() pci_reset_bus_function() pci_dev_reset_slot_function() pci_reset_hotplug_slot() pciehp_reset_slot() # down_write(reset_lock)
Ian May reports the same deadlock on simultaneous hot-removal and an AER-induced Secondary Bus Reset:
aer_recover_work_func() pcie_do_recovery() aer_root_reset() pci_bus_error_reset() pci_slot_reset() pci_slot_lock() # device_lock() pci_reset_hotplug_slot() pciehp_reset_slot() # down_write(reset_lock)
Fix by releasing the reset_lock during driver binding and unbinding, thereby splitting and shrinking the critical section.
Driver binding and unbinding is protected by the device_lock() and thus serialized with a Secondary Bus Reset. There's no need to additionally protect it with the reset_lock. However, pciehp does not bind and unbind devices directly, but rather invokes PCI core functions which also perform certain enumeration and de-enumeration steps.
The reset_lock's purpose is to protect slot registers, not enumeration and de-enumeration of hotplugged devices. That would arguably be the job of the PCI core, not the PCIe hotplug driver. After all, an AER-induced Secondary Bus Reset may as well happen during boot-time enumeration of the PCI hierarchy and there's no locking to prevent that either.
Exempting *de-enumeration* from the reset_lock is relatively harmless: A concurrent Secondary Bus Reset may foil config space accesses such as PME interrupt disablement. But if the device is physically gone, those accesses are pointless anyway. If the device is physically present and only logically removed through an Attention Button press or the sysfs "power" attribute, PME interrupts as well as DMA cannot come through because pciehp_unconfigure_device() disables INTx and Bus Master bits. That's still protected by the reset_lock in the present commit.
Exempting *enumeration* from the reset_lock also has limited impact: The exempted call to pci_bus_add_device() may perform device accesses through pcibios_bus_add_device() and pci_fixup_device() which are now no longer protected from a concurrent Secondary Bus Reset. Otherwise there should be no impact.
In essence, the present commit seeks to fix the AB-BA deadlocks while still retaining a best-effort reset protection for enumeration and de-enumeration of hotplugged devices -- until a general solution is implemented in the PCI core.
Link: https://lore.kernel.org/linux-pci/CS1PR8401MB0728FC6FDAB8A35C22BD90EC95F10@C... Link: https://lore.kernel.org/linux-pci/20200615143250.438252-1-ian.may@canonical.... Link: https://lore.kernel.org/linux-pci/ce878dab-c0c4-5bd0-a725-9805a075682d@amd.c... Link: https://lore.kernel.org/linux-pci/ed831249-384a-6d35-0831-70af191e9bce@huawe... Link: https://bugzilla.kernel.org/show_bug.cgi?id=215590 Fixes: 5b3f7b7d062b ("PCI: pciehp: Avoid slot access during reset") Link: https://lore.kernel.org/r/fef2b2e9edf245c049a8c5b94743c0f74ff5008a.168119190... Reported-by: Michael Haeuptle michael.haeuptle@hpe.com Reported-by: Ian May ian.may@canonical.com Reported-by: Andrey Grodzovsky andrey2805@gmail.com Reported-by: Rahul Kumar rahul.kumar1@amd.com Reported-by: Jialin Zhang zhangjialin11@huawei.com Tested-by: Anatoli Antonovitch Anatoli.Antonovitch@amd.com Signed-off-by: Lukas Wunner lukas@wunner.de Signed-off-by: Bjorn Helgaas bhelgaas@google.com Cc: stable@vger.kernel.org # v4.19+ Cc: Dan Stein dstein@hpe.com Cc: Ashok Raj ashok.raj@intel.com Cc: Alex Michon amichon@kalrayinc.com Cc: Xiongfeng Wang wangxiongfeng2@huawei.com Cc: Alex Williamson alex.williamson@redhat.com Cc: Mika Westerberg mika.westerberg@linux.intel.com Cc: Sathyanarayanan Kuppuswamy sathyanarayanan.kuppuswamy@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/hotplug/pciehp_pci.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
--- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -63,7 +63,14 @@ int pciehp_configure_device(struct contr
pci_assign_unassigned_bridge_resources(bridge); pcie_bus_configure_settings(parent); + + /* + * Release reset_lock during driver binding + * to avoid AB-BA deadlock with device_lock. + */ + up_read(&ctrl->reset_lock); pci_bus_add_devices(parent); + down_read_nested(&ctrl->reset_lock, ctrl->depth);
out: pci_unlock_rescan_remove(); @@ -104,7 +111,15 @@ void pciehp_unconfigure_device(struct co list_for_each_entry_safe_reverse(dev, temp, &parent->devices, bus_list) { pci_dev_get(dev); + + /* + * Release reset_lock during driver unbinding + * to avoid AB-BA deadlock with device_lock. + */ + up_read(&ctrl->reset_lock); pci_stop_and_remove_bus_device(dev); + down_read_nested(&ctrl->reset_lock, ctrl->depth); + /* * Ensure that no new Requests will be generated from * the device.
From: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
commit 2542e16c392508800f1d9037feee881a9c444951 upstream.
Qcom PCIe IP version v2.7.0 and its derivatives don't contain the PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT register. Instead, they have the new PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2 register. So fix the incorrect register usage which is modifying a different register.
Also in this IP version, this register change doesn't depend on MSI being enabled. So remove that check also.
Link: https://lore.kernel.org/r/20230316081117.14288-2-manivannan.sadhasivam@linar... Fixes: ed8cc3b1fc84 ("PCI: qcom: Add support for SDM845 PCIe controller") Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Cc: stable@vger.kernel.org # 5.6+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/dwc/pcie-qcom.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
--- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1210,11 +1210,9 @@ static int qcom_pcie_init_2_7_0(struct q val |= BIT(4); writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
- if (IS_ENABLED(CONFIG_PCI_MSI)) { - val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT); - val |= BIT(31); - writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT); - } + val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2); + val |= BIT(31); + writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
return 0; err_disable_clocks:
From: Randy Dunlap rdunlap@infradead.org
commit 644f17412f5acf01a19af9d04a921937a2bc86c6 upstream.
UML supports HAS_IOMEM since 0bbadafdc49d (um: allow disabling NO_IOMEM).
Current IMA build on UML fails on allmodconfig (with TCG_TPM=m):
ld: security/integrity/ima/ima_queue.o: in function `ima_add_template_entry': ima_queue.c:(.text+0x2d9): undefined reference to `tpm_pcr_extend' ld: security/integrity/ima/ima_init.o: in function `ima_init': ima_init.c:(.init.text+0x43f): undefined reference to `tpm_default_chip' ld: security/integrity/ima/ima_crypto.o: in function `ima_calc_boot_aggregate_tfm': ima_crypto.c:(.text+0x1044): undefined reference to `tpm_pcr_read' ld: ima_crypto.c:(.text+0x10d8): undefined reference to `tpm_pcr_read'
Modify the IMA Kconfig entry so that it selects TCG_TPM if HAS_IOMEM is set, regardless of the UML Kconfig setting. This updates TCG_TPM from =m to =y and fixes the linker errors.
Fixes: f4a0391dfa91 ("ima: fix Kconfig dependencies") Cc: Stable stable@vger.kernel.org # v5.14+ Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Fabio Estevam festevam@gmail.com Cc: Richard Weinberger richard@nod.at Cc: Anton Ivanov anton.ivanov@cambridgegreys.com Cc: Johannes Berg johannes@sipsolutions.net Cc: linux-um@lists.infradead.org Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/integrity/ima/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -8,7 +8,7 @@ config IMA select CRYPTO_HMAC select CRYPTO_SHA1 select CRYPTO_HASH_INFO - select TCG_TPM if HAS_IOMEM && !UML + select TCG_TPM if HAS_IOMEM select TCG_TIS if TCG_TPM && X86 select TCG_CRB if TCG_TPM && ACPI select TCG_IBMVTPM if TCG_TPM && PPC_PSERIES
From: Johan Hovold johan+linaro@kernel.org
commit 9a8ad10c9f2e0925ff26308ec6756b93fc2f4977 upstream.
Make sure not to suspend the device when probe fails to avoid disabling clocks and phys multiple times.
Fixes: 328082376aea ("usb: dwc3: fix runtime PM in error path") Cc: stable@vger.kernel.org # 4.8 Cc: Roger Quadros rogerq@ti.com Acked-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Signed-off-by: Johan Hovold johan+linaro@kernel.org Link: https://lore.kernel.org/r/20230404072524.19014-2-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/dwc3/core.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
--- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1567,13 +1567,11 @@ static int dwc3_probe(struct platform_de spin_lock_init(&dwc->lock); mutex_init(&dwc->mutex);
+ pm_runtime_get_noresume(dev); pm_runtime_set_active(dev); pm_runtime_use_autosuspend(dev); pm_runtime_set_autosuspend_delay(dev, DWC3_DEFAULT_AUTOSUSPEND_DELAY); pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); - if (ret < 0) - goto err1;
pm_runtime_forbid(dev);
@@ -1633,12 +1631,10 @@ err3: dwc3_free_event_buffers(dwc);
err2: - pm_runtime_allow(&pdev->dev); - -err1: - pm_runtime_put_sync(&pdev->dev); - pm_runtime_disable(&pdev->dev); - + pm_runtime_allow(dev); + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_put_noidle(dev); disable_clks: clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks); assert_reset:
From: Johan Hovold johan+linaro@kernel.org
commit 44d257e9012ee8040e41d224d0e5bfb5ef5427ea upstream.
Make sure to balance the runtime PM usage count on driver unbind by adding back the pm_runtime_allow() call that had been erroneously removed.
Fixes: 266d0493900a ("usb: dwc3: core: don't trigger runtime pm when remove driver") Cc: stable@vger.kernel.org # 5.9 Cc: Li Jun jun.li@nxp.com Acked-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Signed-off-by: Johan Hovold johan+linaro@kernel.org Link: https://lore.kernel.org/r/20230404072524.19014-3-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/dwc3/core.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1655,6 +1655,7 @@ static int dwc3_remove(struct platform_d dwc3_core_exit(dwc); dwc3_ulpi_exit(dwc);
+ pm_runtime_allow(&pdev->dev); pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); pm_runtime_set_suspended(&pdev->dev);
From: Babu Moger Babu.Moger@amd.com
commit 0c072385348e3ac5229145644055d3e2afb5b3db upstream.
Spec says, when CUR_TEMP_TJ_SEL == 3 and CUR_TEMP_RANGE_SEL == 0, it should use RangeUnadjusted is 0, which is (CurTmp*0.125 -49) C. The CUR_TEMP register is read-write when CUR_TEMP_TJ_SEL == 3 (bit 17-16).
Add the check to detect it.
Sensors command's output before the patch. $sensors k10temp-pci-00c3 Adapter: PCI adapter Tctl: +76.6°C <- Wrong value Tccd1: +26.5°C Tccd2: +27.5°C Tccd3: +27.2°C Tccd4: +27.5°C Tccd5: +26.0°C Tccd6: +26.2°C Tccd7: +25.0°C Tccd8: +26.5°C
Sensors command's output after the patch. $sensors k10temp-pci-00c3 Adapter: PCI adapter Tctl: +28.8°C <- corrected value Tccd1: +27.5°C Tccd2: +28.5°C Tccd3: +28.5°C Tccd4: +28.5°C Tccd5: +27.0°C Tccd6: +27.5°C Tccd7: +27.0°C Tccd8: +27.5°C
Signed-off-by: Babu Moger babu.moger@amd.com Fixes: 1b59788979ac ("hwmon: (k10temp) Add temperature offset for Ryzen 2700X") Link: https://lore.kernel.org/r/20230413213958.847634-1-babu.moger@amd.com Cc: stable@vger.kernel.org Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hwmon/k10temp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -74,6 +74,7 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
#define ZEN_CUR_TEMP_SHIFT 21 #define ZEN_CUR_TEMP_RANGE_SEL_MASK BIT(19) +#define ZEN_CUR_TEMP_TJ_SEL_MASK GENMASK(17, 16)
#define ZEN_SVI_BASE 0x0005A000
@@ -173,7 +174,8 @@ static long get_raw_temp(struct k10temp_
data->read_tempreg(data->pdev, ®val); temp = (regval >> ZEN_CUR_TEMP_SHIFT) * 125; - if (regval & data->temp_adjust_mask) + if ((regval & data->temp_adjust_mask) || + (regval & ZEN_CUR_TEMP_TJ_SEL_MASK) == ZEN_CUR_TEMP_TJ_SEL_MASK) temp -= 49000; return temp; }
From: Chris Packham chris.packham@alliedtelesis.co.nz
commit 2a8e41ad337508fc5d598c0f9288890214f8e318 upstream.
On DT unaware platforms of_property_read_u32_array() returns -ENOSYS which wasn't handled by the code treating adi,pwm-active-state as optional. Update the code to use device_property_read_u32_array() which deals gracefully with DT unaware platforms.
Fixes: 86da28eed4fb ("hwmon: (adt7475) Add support for inverting pwm output") Reported-by: Mariusz Białończyk manio@skyboo.net Link: https://lore.kernel.org/linux-hwmon/52e26a67-9131-2dc0-40cb-db5c07370027@all... Signed-off-by: Chris Packham chris.packham@alliedtelesis.co.nz Link: https://lore.kernel.org/r/20230418233656.869055-2-chris.packham@alliedtelesi... Cc: stable@vger.kernel.org Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hwmon/adt7475.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/hwmon/adt7475.c +++ b/drivers/hwmon/adt7475.c @@ -1515,9 +1515,9 @@ static int adt7475_set_pwm_polarity(stru int ret, i; u8 val;
- ret = of_property_read_u32_array(client->dev.of_node, - "adi,pwm-active-state", states, - ARRAY_SIZE(states)); + ret = device_property_read_u32_array(&client->dev, + "adi,pwm-active-state", states, + ARRAY_SIZE(states)); if (ret) return ret;
From: Thomas Gleixner tglx@linutronix.de
commit f7abf14f0001a5a47539d9f60bbdca649e43536b upstream.
For some unknown reason the introduction of the timer_wait_running callback missed to fixup posix CPU timers, which went unnoticed for almost four years. Marco reported recently that the WARN_ON() in timer_wait_running() triggers with a posix CPU timer test case.
Posix CPU timers have two execution models for expiring timers depending on CONFIG_POSIX_CPU_TIMERS_TASK_WORK:
1) If not enabled, the expiry happens in hard interrupt context so spin waiting on the remote CPU is reasonably time bound.
Implement an empty stub function for that case.
2) If enabled, the expiry happens in task work before returning to user space or guest mode. The expired timers are marked as firing and moved from the timer queue to a local list head with sighand lock held. Once the timers are moved, sighand lock is dropped and the expiry happens in fully preemptible context. That means the expiring task can be scheduled out, migrated, interrupted etc. So spin waiting on it is more than suboptimal.
The timer wheel has a timer_wait_running() mechanism for RT, which uses a per CPU timer-base expiry lock which is held by the expiry code and the task waiting for the timer function to complete blocks on that lock.
This does not work in the same way for posix CPU timers as there is no timer base and expiry for process wide timers can run on any task belonging to that process, but the concept of waiting on an expiry lock can be used too in a slightly different way:
- Add a mutex to struct posix_cputimers_work. This struct is per task and used to schedule the expiry task work from the timer interrupt.
- Add a task_struct pointer to struct cpu_timer which is used to store a the task which runs the expiry. That's filled in when the task moves the expired timers to the local expiry list. That's not affecting the size of the k_itimer union as there are bigger union members already
- Let the task take the expiry mutex around the expiry function
- Let the waiter acquire a task reference with rcu_read_lock() held and block on the expiry mutex
This avoids spin-waiting on a task which might not even be on a CPU and works nicely for RT too.
Fixes: ec8f954a40da ("posix-timers: Use a callback for cancel synchronization on PREEMPT_RT") Reported-by: Marco Elver elver@google.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Tested-by: Marco Elver elver@google.com Tested-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Reviewed-by: Frederic Weisbecker frederic@kernel.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/87zg764ojw.ffs@tglx Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/posix-timers.h | 17 +++++--- kernel/time/posix-cpu-timers.c | 81 +++++++++++++++++++++++++++++++++-------- kernel/time/posix-timers.c | 4 ++ 3 files changed, 82 insertions(+), 20 deletions(-)
--- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -4,6 +4,7 @@
#include <linux/spinlock.h> #include <linux/list.h> +#include <linux/mutex.h> #include <linux/alarmtimer.h> #include <linux/timerqueue.h> #include <linux/task_work.h> @@ -63,16 +64,18 @@ static inline int clockid_to_fd(const cl * cpu_timer - Posix CPU timer representation for k_itimer * @node: timerqueue node to queue in the task/sig * @head: timerqueue head on which this timer is queued - * @task: Pointer to target task + * @pid: Pointer to target task PID * @elist: List head for the expiry list * @firing: Timer is currently firing + * @handling: Pointer to the task which handles expiry */ struct cpu_timer { - struct timerqueue_node node; - struct timerqueue_head *head; - struct pid *pid; - struct list_head elist; - int firing; + struct timerqueue_node node; + struct timerqueue_head *head; + struct pid *pid; + struct list_head elist; + int firing; + struct task_struct __rcu *handling; };
static inline bool cpu_timer_enqueue(struct timerqueue_head *head, @@ -129,10 +132,12 @@ struct posix_cputimers { /** * posix_cputimers_work - Container for task work based posix CPU timer expiry * @work: The task work to be scheduled + * @mutex: Mutex held around expiry in context of this task work * @scheduled: @work has been scheduled already, no further processing */ struct posix_cputimers_work { struct callback_head work; + struct mutex mutex; unsigned int scheduled; };
--- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -782,6 +782,8 @@ static u64 collect_timerqueue(struct tim return expires;
ctmr->firing = 1; + /* See posix_cpu_timer_wait_running() */ + rcu_assign_pointer(ctmr->handling, current); cpu_timer_dequeue(ctmr); list_add_tail(&ctmr->elist, firing); } @@ -1097,7 +1099,49 @@ static void handle_posix_cpu_timers(stru #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK static void posix_cpu_timers_work(struct callback_head *work) { + struct posix_cputimers_work *cw = container_of(work, typeof(*cw), work); + + mutex_lock(&cw->mutex); handle_posix_cpu_timers(current); + mutex_unlock(&cw->mutex); +} + +/* + * Invoked from the posix-timer core when a cancel operation failed because + * the timer is marked firing. The caller holds rcu_read_lock(), which + * protects the timer and the task which is expiring it from being freed. + */ +static void posix_cpu_timer_wait_running(struct k_itimer *timr) +{ + struct task_struct *tsk = rcu_dereference(timr->it.cpu.handling); + + /* Has the handling task completed expiry already? */ + if (!tsk) + return; + + /* Ensure that the task cannot go away */ + get_task_struct(tsk); + /* Now drop the RCU protection so the mutex can be locked */ + rcu_read_unlock(); + /* Wait on the expiry mutex */ + mutex_lock(&tsk->posix_cputimers_work.mutex); + /* Release it immediately again. */ + mutex_unlock(&tsk->posix_cputimers_work.mutex); + /* Drop the task reference. */ + put_task_struct(tsk); + /* Relock RCU so the callsite is balanced */ + rcu_read_lock(); +} + +static void posix_cpu_timer_wait_running_nsleep(struct k_itimer *timr) +{ + /* Ensure that timr->it.cpu.handling task cannot go away */ + rcu_read_lock(); + spin_unlock_irq(&timr->it_lock); + posix_cpu_timer_wait_running(timr); + rcu_read_unlock(); + /* @timr is on stack and is valid */ + spin_lock_irq(&timr->it_lock); }
/* @@ -1113,6 +1157,7 @@ void clear_posix_cputimers_work(struct t sizeof(p->posix_cputimers_work.work)); init_task_work(&p->posix_cputimers_work.work, posix_cpu_timers_work); + mutex_init(&p->posix_cputimers_work.mutex); p->posix_cputimers_work.scheduled = false; }
@@ -1191,6 +1236,18 @@ static inline void __run_posix_cpu_timer lockdep_posixtimer_exit(); }
+static void posix_cpu_timer_wait_running(struct k_itimer *timr) +{ + cpu_relax(); +} + +static void posix_cpu_timer_wait_running_nsleep(struct k_itimer *timr) +{ + spin_unlock_irq(&timr->it_lock); + cpu_relax(); + spin_lock_irq(&timr->it_lock); +} + static inline bool posix_cpu_timers_work_scheduled(struct task_struct *tsk) { return false; @@ -1299,6 +1356,8 @@ static void handle_posix_cpu_timers(stru */ if (likely(cpu_firing >= 0)) cpu_timer_fire(timer); + /* See posix_cpu_timer_wait_running() */ + rcu_assign_pointer(timer->it.cpu.handling, NULL); spin_unlock(&timer->it_lock); } } @@ -1434,23 +1493,16 @@ static int do_cpu_nanosleep(const clocki expires = cpu_timer_getexpires(&timer.it.cpu); error = posix_cpu_timer_set(&timer, 0, &zero_it, &it); if (!error) { - /* - * Timer is now unarmed, deletion can not fail. - */ + /* Timer is now unarmed, deletion can not fail. */ posix_cpu_timer_del(&timer); + } else { + while (error == TIMER_RETRY) { + posix_cpu_timer_wait_running_nsleep(&timer); + error = posix_cpu_timer_del(&timer); + } } - spin_unlock_irq(&timer.it_lock);
- while (error == TIMER_RETRY) { - /* - * We need to handle case when timer was or is in the - * middle of firing. In other cases we already freed - * resources. - */ - spin_lock_irq(&timer.it_lock); - error = posix_cpu_timer_del(&timer); - spin_unlock_irq(&timer.it_lock); - } + spin_unlock_irq(&timer.it_lock);
if ((it.it_value.tv_sec | it.it_value.tv_nsec) == 0) { /* @@ -1560,6 +1612,7 @@ const struct k_clock clock_posix_cpu = { .timer_del = posix_cpu_timer_del, .timer_get = posix_cpu_timer_get, .timer_rearm = posix_cpu_timer_rearm, + .timer_wait_running = posix_cpu_timer_wait_running, };
const struct k_clock clock_process = { --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -846,6 +846,10 @@ static struct k_itimer *timer_wait_runni rcu_read_lock(); unlock_timer(timer, *flags);
+ /* + * kc->timer_wait_running() might drop RCU lock. So @timer + * cannot be touched anymore after the function returns! + */ if (!WARN_ON_ONCE(!kc->timer_wait_running)) kc->timer_wait_running(timer);
From: Arnaldo Carvalho de Melo acme@redhat.com
commit d08c84e01afa7a7eee6badab25d5420fa847f783 upstream.
In fedora rawhide the PTHREAD_STACK_MIN define may end up expanded to a sysconf() call, and that will return 'long int', breaking the build:
45 fedora:rawhide : FAIL gcc version 11.1.1 20210623 (Red Hat 11.1.1-6) (GCC) builtin-sched.c: In function 'create_tasks': /git/perf-5.14.0-rc1/tools/include/linux/kernel.h:43:24: error: comparison of distinct pointer types lacks a cast [-Werror] 43 | (void) (&_max1 == &_max2); \ | ^~ builtin-sched.c:673:34: note: in expansion of macro 'max' 673 | (size_t) max(16 * 1024, PTHREAD_STACK_MIN)); | ^~~ cc1: all warnings being treated as errors
$ grep __sysconf /usr/include/*/*.h /usr/include/bits/pthread_stack_min-dynamic.h:extern long int __sysconf (int __name) __THROW; /usr/include/bits/pthread_stack_min-dynamic.h:# define PTHREAD_STACK_MIN __sysconf (__SC_THREAD_STACK_MIN_VALUE) /usr/include/bits/time.h:extern long int __sysconf (int); /usr/include/bits/time.h:# define CLK_TCK ((__clock_t) __sysconf (2)) /* 2 is _SC_CLK_TCK */ $
So cast it to int to cope with that.
Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Cc: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/perf/builtin-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -670,7 +670,7 @@ static void create_tasks(struct perf_sch err = pthread_attr_init(&attr); BUG_ON(err); err = pthread_attr_setstacksize(&attr, - (size_t) max(16 * 1024, PTHREAD_STACK_MIN)); + (size_t) max(16 * 1024, (int)PTHREAD_STACK_MIN)); BUG_ON(err); err = pthread_mutex_lock(&sched->start_work_mutex); BUG_ON(err);
From: Eric Biggers ebiggers@google.com
commit 9cd1e566676bbcb8a126acd921e4e194e6339603 upstream.
Once all I/O using a blk_crypto_key has completed, filesystems can call blk_crypto_evict_key(). However, the block layer currently doesn't call blk_crypto_put_keyslot() until the request is being freed, which happens after upper layers have been told (via bio_endio()) the I/O has completed. This causes a race condition where blk_crypto_evict_key() can see 'slot_refs != 0' without there being an actual bug.
This makes __blk_crypto_evict_key() hit the 'WARN_ON_ONCE(atomic_read(&slot->slot_refs) != 0)' and return without doing anything, eventually causing a use-after-free in blk_crypto_reprogram_all_keys(). (This is a very rare bug and has only been seen when per-file keys are being used with fscrypt.)
There are two options to fix this: either release the keyslot before bio_endio() is called on the request's last bio, or make __blk_crypto_evict_key() ignore slot_refs. Let's go with the first solution, since it preserves the ability to report bugs (via WARN_ON_ONCE) where a key is evicted while still in-use.
Fixes: a892c8d52c02 ("block: Inline encryption support for blk-mq") Cc: stable@vger.kernel.org Reviewed-by: Nathan Huckleberry nhuck@google.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Eric Biggers ebiggers@google.com Link: https://lore.kernel.org/r/20230315183907.53675-2-ebiggers@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/blk-core.c | 7 +++++++ block/blk-crypto-internal.h | 25 +++++++++++++++++++++---- block/blk-crypto.c | 24 ++++++++++++------------ block/blk-merge.c | 2 ++ block/blk-mq.c | 2 +- 5 files changed, 43 insertions(+), 17 deletions(-)
--- a/block/blk-core.c +++ b/block/blk-core.c @@ -1444,6 +1444,13 @@ bool blk_update_request(struct request * req->q->integrity.profile->complete_fn(req, nr_bytes); #endif
+ /* + * Upper layers may call blk_crypto_evict_key() anytime after the last + * bio_endio(). Therefore, the keyslot must be released before that. + */ + if (blk_crypto_rq_has_keyslot(req) && nr_bytes >= blk_rq_bytes(req)) + __blk_crypto_rq_put_keyslot(req); + if (unlikely(error && !blk_rq_is_passthrough(req) && !(req->rq_flags & RQF_QUIET))) print_req_error(req, error, __func__); --- a/block/blk-crypto-internal.h +++ b/block/blk-crypto-internal.h @@ -60,6 +60,11 @@ static inline bool blk_crypto_rq_is_encr return rq->crypt_ctx; }
+static inline bool blk_crypto_rq_has_keyslot(struct request *rq) +{ + return rq->crypt_keyslot; +} + #else /* CONFIG_BLK_INLINE_ENCRYPTION */
static inline bool bio_crypt_rq_ctx_compatible(struct request *rq, @@ -93,6 +98,11 @@ static inline bool blk_crypto_rq_is_encr return false; }
+static inline bool blk_crypto_rq_has_keyslot(struct request *rq) +{ + return false; +} + #endif /* CONFIG_BLK_INLINE_ENCRYPTION */
void __bio_crypt_advance(struct bio *bio, unsigned int bytes); @@ -127,14 +137,21 @@ static inline bool blk_crypto_bio_prep(s return true; }
-blk_status_t __blk_crypto_init_request(struct request *rq); -static inline blk_status_t blk_crypto_init_request(struct request *rq) +blk_status_t __blk_crypto_rq_get_keyslot(struct request *rq); +static inline blk_status_t blk_crypto_rq_get_keyslot(struct request *rq) { if (blk_crypto_rq_is_encrypted(rq)) - return __blk_crypto_init_request(rq); + return __blk_crypto_rq_get_keyslot(rq); return BLK_STS_OK; }
+void __blk_crypto_rq_put_keyslot(struct request *rq); +static inline void blk_crypto_rq_put_keyslot(struct request *rq) +{ + if (blk_crypto_rq_has_keyslot(rq)) + __blk_crypto_rq_put_keyslot(rq); +} + void __blk_crypto_free_request(struct request *rq); static inline void blk_crypto_free_request(struct request *rq) { @@ -173,7 +190,7 @@ static inline blk_status_t blk_crypto_in {
if (blk_crypto_rq_is_encrypted(rq)) - return blk_crypto_init_request(rq); + return blk_crypto_rq_get_keyslot(rq); return BLK_STS_OK; }
--- a/block/blk-crypto.c +++ b/block/blk-crypto.c @@ -216,26 +216,26 @@ static bool bio_crypt_check_alignment(st return true; }
-blk_status_t __blk_crypto_init_request(struct request *rq) +blk_status_t __blk_crypto_rq_get_keyslot(struct request *rq) { return blk_ksm_get_slot_for_key(rq->q->ksm, rq->crypt_ctx->bc_key, &rq->crypt_keyslot); }
-/** - * __blk_crypto_free_request - Uninitialize the crypto fields of a request. - * - * @rq: The request whose crypto fields to uninitialize. - * - * Completely uninitializes the crypto fields of a request. If a keyslot has - * been programmed into some inline encryption hardware, that keyslot is - * released. The rq->crypt_ctx is also freed. - */ -void __blk_crypto_free_request(struct request *rq) +void __blk_crypto_rq_put_keyslot(struct request *rq) { blk_ksm_put_slot(rq->crypt_keyslot); + rq->crypt_keyslot = NULL; +} + +void __blk_crypto_free_request(struct request *rq) +{ + /* The keyslot, if one was needed, should have been released earlier. */ + if (WARN_ON_ONCE(rq->crypt_keyslot)) + __blk_crypto_rq_put_keyslot(rq); + mempool_free(rq->crypt_ctx, bio_crypt_ctx_pool); - blk_crypto_rq_set_defaults(rq); + rq->crypt_ctx = NULL; }
/** --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -801,6 +801,8 @@ static struct request *attempt_merge(str if (!blk_discard_mergable(req)) elv_merge_requests(q, req, next);
+ blk_crypto_rq_put_keyslot(next); + /* * 'next' is going away, so update stats accordingly */ --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2193,7 +2193,7 @@ blk_qc_t blk_mq_submit_bio(struct bio *b
blk_mq_bio_to_request(rq, bio, nr_segs);
- ret = blk_crypto_init_request(rq); + ret = blk_crypto_rq_get_keyslot(rq); if (ret != BLK_STS_OK) { bio->bi_status = ret; bio_endio(bio);
From: Eric Biggers ebiggers@google.com
commit 70493a63ba04f754f7a7dd53a4fcc82700181490 upstream.
blk_crypto_evict_key() is only called in contexts such as inode eviction where failure is not an option. So there is nothing the caller can do with errors except log them. (dm-table.c does "use" the error code, but only to pass on to upper layers, so it doesn't really count.)
Just make blk_crypto_evict_key() return void and log errors itself.
Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers ebiggers@google.com Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20230315183907.53675-2-ebiggers@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/blk-crypto.c | 22 ++++++++++------------ include/linux/blk-crypto.h | 4 ++-- 2 files changed, 12 insertions(+), 14 deletions(-)
--- a/block/blk-crypto.c +++ b/block/blk-crypto.c @@ -13,6 +13,7 @@ #include <linux/blkdev.h> #include <linux/keyslot-manager.h> #include <linux/module.h> +#include <linux/ratelimit.h> #include <linux/slab.h>
#include "blk-crypto-internal.h" @@ -393,19 +394,16 @@ int blk_crypto_start_using_key(const str * Upper layers (filesystems) must call this function to ensure that a key is * evicted from any hardware that it might have been programmed into. The key * must not be in use by any in-flight IO when this function is called. - * - * Return: 0 on success or if key is not present in the q's ksm, -err on error. */ -int blk_crypto_evict_key(struct request_queue *q, - const struct blk_crypto_key *key) +void blk_crypto_evict_key(struct request_queue *q, + const struct blk_crypto_key *key) { - if (blk_ksm_crypto_cfg_supported(q->ksm, &key->crypto_cfg)) - return blk_ksm_evict_key(q->ksm, key); + int err;
- /* - * If the request queue's associated inline encryption hardware didn't - * have support for the key, then the key might have been programmed - * into the fallback keyslot manager, so try to evict from there. - */ - return blk_crypto_fallback_evict_key(key); + if (blk_ksm_crypto_cfg_supported(q->ksm, &key->crypto_cfg)) + err = blk_ksm_evict_key(q->ksm, key); + else + err = blk_crypto_fallback_evict_key(key); + if (err) + pr_warn_ratelimited("error %d evicting key\n", err); } --- a/include/linux/blk-crypto.h +++ b/include/linux/blk-crypto.h @@ -97,8 +97,8 @@ int blk_crypto_init_key(struct blk_crypt int blk_crypto_start_using_key(const struct blk_crypto_key *key, struct request_queue *q);
-int blk_crypto_evict_key(struct request_queue *q, - const struct blk_crypto_key *key); +void blk_crypto_evict_key(struct request_queue *q, + const struct blk_crypto_key *key);
bool blk_crypto_config_supported(struct request_queue *q, const struct blk_crypto_config *cfg);
From: Eric Biggers ebiggers@google.com
commit 5c7cb94452901a93e90c2230632e2c12a681bc92 upstream.
If blk_crypto_evict_key() sees that the key is still in-use (due to a bug) or that ->keyslot_evict failed, it currently just returns while leaving the key linked into the keyslot management structures.
However, blk_crypto_evict_key() is only called in contexts such as inode eviction where failure is not an option. So actually the caller proceeds with freeing the blk_crypto_key regardless of the return value of blk_crypto_evict_key().
These two assumptions don't match, and the result is that there can be a use-after-free in blk_crypto_reprogram_all_keys() after one of these errors occurs. (Note, these errors *shouldn't* happen; we're just talking about what happens if they do anyway.)
Fix this by making blk_crypto_evict_key() unlink the key from the keyslot management structures even on failure.
Also improve some comments.
Fixes: 1b2628397058 ("block: Keyslot Manager for Inline Encryption") Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers ebiggers@google.com Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20230315183907.53675-2-ebiggers@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/blk-crypto.c | 29 +++++++++++++++++++++-------- block/keyslot-manager.c | 43 +++++++++++++++++++++---------------------- 2 files changed, 42 insertions(+), 30 deletions(-)
--- a/block/blk-crypto.c +++ b/block/blk-crypto.c @@ -385,15 +385,20 @@ int blk_crypto_start_using_key(const str }
/** - * blk_crypto_evict_key() - Evict a key from any inline encryption hardware - * it may have been programmed into - * @q: The request queue who's associated inline encryption hardware this key - * might have been programmed into - * @key: The key to evict + * blk_crypto_evict_key() - Evict a blk_crypto_key from a request_queue + * @q: a request_queue on which I/O using the key may have been done + * @key: the key to evict * - * Upper layers (filesystems) must call this function to ensure that a key is - * evicted from any hardware that it might have been programmed into. The key - * must not be in use by any in-flight IO when this function is called. + * For a given request_queue, this function removes the given blk_crypto_key + * from the keyslot management structures and evicts it from any underlying + * hardware keyslot(s) or blk-crypto-fallback keyslot it may have been + * programmed into. + * + * Upper layers must call this before freeing the blk_crypto_key. It must be + * called for every request_queue the key may have been used on. The key must + * no longer be in use by any I/O when this function is called. + * + * Context: May sleep. */ void blk_crypto_evict_key(struct request_queue *q, const struct blk_crypto_key *key) @@ -404,6 +409,14 @@ void blk_crypto_evict_key(struct request err = blk_ksm_evict_key(q->ksm, key); else err = blk_crypto_fallback_evict_key(key); + /* + * An error can only occur here if the key failed to be evicted from a + * keyslot (due to a hardware or driver issue) or is allegedly still in + * use by I/O (due to a kernel bug). Even in these cases, the key is + * still unlinked from the keyslot management structures, and the caller + * is allowed and expected to free it right away. There's nothing + * callers can do to handle errors, so just log them and return void. + */ if (err) pr_warn_ratelimited("error %d evicting key\n", err); } --- a/block/keyslot-manager.c +++ b/block/keyslot-manager.c @@ -305,44 +305,43 @@ bool blk_ksm_crypto_cfg_supported(struct return true; }
-/** - * blk_ksm_evict_key() - Evict a key from the lower layer device. - * @ksm: The keyslot manager to evict from - * @key: The key to evict - * - * Find the keyslot that the specified key was programmed into, and evict that - * slot from the lower layer device. The slot must not be in use by any - * in-flight IO when this function is called. - * - * Context: Process context. Takes and releases ksm->lock. - * Return: 0 on success or if there's no keyslot with the specified key, -EBUSY - * if the keyslot is still in use, or another -errno value on other - * error. +/* + * This is an internal function that evicts a key from an inline encryption + * device that can be either a real device or the blk-crypto-fallback "device". + * It is used only by blk_crypto_evict_key(); see that function for details. */ int blk_ksm_evict_key(struct blk_keyslot_manager *ksm, const struct blk_crypto_key *key) { struct blk_ksm_keyslot *slot; - int err = 0; + int err;
blk_ksm_hw_enter(ksm); slot = blk_ksm_find_keyslot(ksm, key); - if (!slot) - goto out_unlock; + if (!slot) { + /* + * Not an error, since a key not in use by I/O is not guaranteed + * to be in a keyslot. There can be more keys than keyslots. + */ + err = 0; + goto out; + }
if (WARN_ON_ONCE(atomic_read(&slot->slot_refs) != 0)) { + /* BUG: key is still in use by I/O */ err = -EBUSY; - goto out_unlock; + goto out_remove; } err = ksm->ksm_ll_ops.keyslot_evict(ksm, key, blk_ksm_get_slot_idx(slot)); - if (err) - goto out_unlock; - +out_remove: + /* + * Callers free the key even on error, so unlink the key from the hash + * table and clear slot->key even on error. + */ hlist_del(&slot->hash_node); slot->key = NULL; - err = 0; -out_unlock: +out: blk_ksm_hw_exit(ksm); return err; }
From: Harshad Shirwadkar harshadshirwadkar@gmail.com
commit 2729cfdcfa1cc49bef5a90d046fa4a187fdfcc69 upstream.
This patch drops all calls to ext4_fc_start_update() and ext4_fc_stop_update(). To ensure that there are no ongoing journal updates during fast commit, we also make jbd2_fc_begin_commit() lock journal for updates. This way we don't have to maintain two different transaction start stop APIs for fast commit and full commit. This patch doesn't remove the functions altogether since in future we want to have inode level locking for fast commits.
Signed-off-by: Harshad Shirwadkar harshadshirwadkar@gmail.com Link: https://lore.kernel.org/r/20211223202140.2061101-2-harshads@google.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/acl.c | 2 -- fs/ext4/extents.c | 2 -- fs/ext4/file.c | 4 ---- fs/ext4/inode.c | 7 +------ fs/ext4/ioctl.c | 8 +------- fs/jbd2/journal.c | 2 ++ 6 files changed, 4 insertions(+), 21 deletions(-)
--- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -242,7 +242,6 @@ retry: handle = ext4_journal_start(inode, EXT4_HT_XATTR, credits); if (IS_ERR(handle)) return PTR_ERR(handle); - ext4_fc_start_update(inode);
if ((type == ACL_TYPE_ACCESS) && acl) { error = posix_acl_update_mode(inode, &mode, &acl); @@ -260,7 +259,6 @@ retry: } out_stop: ext4_journal_stop(handle); - ext4_fc_stop_update(inode); if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) goto retry; return error; --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4694,7 +4694,6 @@ long ext4_fallocate(struct file *file, i FALLOC_FL_INSERT_RANGE)) return -EOPNOTSUPP;
- ext4_fc_start_update(inode); inode_lock(inode); ret = ext4_convert_inline_data(inode); inode_unlock(inode); @@ -4764,7 +4763,6 @@ out: inode_unlock(inode); trace_ext4_fallocate_exit(inode, offset, max_blocks, ret); exit: - ext4_fc_stop_update(inode); return ret; }
--- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -260,7 +260,6 @@ static ssize_t ext4_buffered_write_iter( if (iocb->ki_flags & IOCB_NOWAIT) return -EOPNOTSUPP;
- ext4_fc_start_update(inode); inode_lock(inode); ret = ext4_write_checks(iocb, from); if (ret <= 0) @@ -272,7 +271,6 @@ static ssize_t ext4_buffered_write_iter(
out: inode_unlock(inode); - ext4_fc_stop_update(inode); if (likely(ret > 0)) { iocb->ki_pos += ret; ret = generic_write_sync(iocb, ret); @@ -559,9 +557,7 @@ static ssize_t ext4_dio_write_iter(struc goto out; }
- ext4_fc_start_update(inode); ret = ext4_orphan_add(handle, inode); - ext4_fc_stop_update(inode); if (ret) { ext4_journal_stop(handle); goto out; --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5437,7 +5437,7 @@ int ext4_setattr(struct dentry *dentry, if (error) return error; } - ext4_fc_start_update(inode); + if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) || (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) { handle_t *handle; @@ -5461,7 +5461,6 @@ int ext4_setattr(struct dentry *dentry,
if (error) { ext4_journal_stop(handle); - ext4_fc_stop_update(inode); return error; } /* Update corresponding info in inode so that everything is in @@ -5473,7 +5472,6 @@ int ext4_setattr(struct dentry *dentry, error = ext4_mark_inode_dirty(handle, inode); ext4_journal_stop(handle); if (unlikely(error)) { - ext4_fc_stop_update(inode); return error; } } @@ -5488,12 +5486,10 @@ int ext4_setattr(struct dentry *dentry, struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
if (attr->ia_size > sbi->s_bitmap_maxbytes) { - ext4_fc_stop_update(inode); return -EFBIG; } } if (!S_ISREG(inode->i_mode)) { - ext4_fc_stop_update(inode); return -EINVAL; }
@@ -5619,7 +5615,6 @@ err_out: ext4_std_error(inode->i_sb, error); if (!error) error = rc; - ext4_fc_stop_update(inode); return error; }
--- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -1322,13 +1322,7 @@ out:
long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - long ret; - - ext4_fc_start_update(file_inode(filp)); - ret = __ext4_ioctl(filp, cmd, arg); - ext4_fc_stop_update(file_inode(filp)); - - return ret; + return __ext4_ioctl(filp, cmd, arg); }
#ifdef CONFIG_COMPAT --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -757,6 +757,7 @@ int jbd2_fc_begin_commit(journal_t *jour } journal->j_flags |= JBD2_FAST_COMMIT_ONGOING; write_unlock(&journal->j_state_lock); + jbd2_journal_lock_updates(journal);
return 0; } @@ -768,6 +769,7 @@ EXPORT_SYMBOL(jbd2_fc_begin_commit); */ static int __jbd2_fc_end_commit(journal_t *journal, tid_t tid, bool fallback) { + jbd2_journal_unlock_updates(journal); if (journal->j_fc_cleanup_callback) journal->j_fc_cleanup_callback(journal, 0); write_lock(&journal->j_state_lock);
From: Nuno Sá nuno.sa@analog.com
commit 16313403d873ff17a587818b61f84c8cb4971cef upstream.
As stated in the device datasheet [1], bits a0 and a1 have to be set to 1 for the configuration mode.
[1]: https://www.analog.com/media/en/technical-documentation/data-sheets/ad2s1210...
Fixes: b19e9ad5e2cb9 ("staging:iio:resolver:ad2s1210 general driver cleanup") Cc: stable stable@kernel.org Signed-off-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20230327145414.1505537-1-nuno.sa@analog.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/iio/resolver/ad2s1210.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -101,7 +101,7 @@ struct ad2s1210_state { static const int ad2s1210_mode_vals[4][2] = { [MOD_POS] = { 0, 0 }, [MOD_VEL] = { 0, 1 }, - [MOD_CONFIG] = { 1, 0 }, + [MOD_CONFIG] = { 1, 1 }, };
static inline void ad2s1210_set_mode(enum ad2s1210_mode mode,
From: Johan Hovold johan+linaro@kernel.org
commit 735baf1b23458f71a8b15cb924af22c9ff9cd125 upstream.
Wire up the debugfs regset device pointer so that the controller is resumed before accessing registers to avoid crashing or locking up if it happens to be runtime suspended.
Fixes: 02b6fdc2a153 ("usb: xhci: Add debugfs interface for xHCI driver") Cc: stable@vger.kernel.org # 4.15: 30332eeefec8: debugfs: regset32: Add Runtime PM support Cc: stable@vger.kernel.org # 4.15 Signed-off-by: Johan Hovold johan+linaro@kernel.org Link: https://lore.kernel.org/r/20230405090342.7363-1-johan+linaro@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/xhci-debugfs.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/usb/host/xhci-debugfs.c +++ b/drivers/usb/host/xhci-debugfs.c @@ -133,6 +133,7 @@ static void xhci_debugfs_regset(struct x regset->regs = regs; regset->nregs = nregs; regset->base = hcd->regs + base; + regset->dev = hcd->self.controller;
debugfs_create_regset32((const char *)rgs->name, 0444, parent, regset); }
From: Joel Fernandes (Google) joel@joelfernandes.org
commit 58d7668242647e661a20efe065519abd6454287e upstream.
For CONFIG_NO_HZ_FULL systems, the tick_do_timer_cpu cannot be offlined. However, cpu_is_hotpluggable() still returns true for those CPUs. This causes torture tests that do offlining to end up trying to offline this CPU causing test failures. Such failure happens on all architectures.
Fix the repeated error messages thrown by this (even if the hotplug errors are harmless) by asking the opinion of the nohz subsystem on whether the CPU can be hotplugged.
[ Apply Frederic Weisbecker feedback on refactoring tick_nohz_cpu_down(). ]
For drivers/base/ portion: Acked-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Acked-by: Frederic Weisbecker frederic@kernel.org Cc: Frederic Weisbecker frederic@kernel.org Cc: "Paul E. McKenney" paulmck@kernel.org Cc: Zhouyi Zhou zhouzhouyi@gmail.com Cc: Will Deacon will@kernel.org Cc: Marc Zyngier maz@kernel.org Cc: rcu rcu@vger.kernel.org Cc: stable@vger.kernel.org Fixes: 2987557f52b9 ("driver-core/cpu: Expose hotpluggability to the rest of the kernel") Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Joel Fernandes (Google) joel@joelfernandes.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/base/cpu.c | 3 ++- include/linux/tick.h | 2 ++ kernel/time/tick-sched.c | 11 ++++++++--- 3 files changed, 12 insertions(+), 4 deletions(-)
--- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -489,7 +489,8 @@ static const struct attribute_group *cpu bool cpu_is_hotpluggable(unsigned cpu) { struct device *dev = get_cpu_device(cpu); - return dev && container_of(dev, struct cpu, dev)->hotpluggable; + return dev && container_of(dev, struct cpu, dev)->hotpluggable + && tick_nohz_cpu_hotpluggable(cpu); } EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
--- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -211,6 +211,7 @@ extern void tick_nohz_dep_set_signal(str enum tick_dep_bits bit); extern void tick_nohz_dep_clear_signal(struct signal_struct *signal, enum tick_dep_bits bit); +extern bool tick_nohz_cpu_hotpluggable(unsigned int cpu);
/* * The below are tick_nohz_[set,clear]_dep() wrappers that optimize off-cases @@ -275,6 +276,7 @@ static inline void tick_nohz_full_add_cp
static inline void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit) { } static inline void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit) { } +static inline bool tick_nohz_cpu_hotpluggable(unsigned int cpu) { return true; }
static inline void tick_dep_set(enum tick_dep_bits bit) { } static inline void tick_dep_clear(enum tick_dep_bits bit) { } --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -426,7 +426,7 @@ void __init tick_nohz_full_setup(cpumask tick_nohz_full_running = true; }
-static int tick_nohz_cpu_down(unsigned int cpu) +bool tick_nohz_cpu_hotpluggable(unsigned int cpu) { /* * The tick_do_timer_cpu CPU handles housekeeping duty (unbound @@ -434,8 +434,13 @@ static int tick_nohz_cpu_down(unsigned i * CPUs. It must remain online when nohz full is enabled. */ if (tick_nohz_full_running && tick_do_timer_cpu == cpu) - return -EBUSY; - return 0; + return false; + return true; +} + +static int tick_nohz_cpu_down(unsigned int cpu) +{ + return tick_nohz_cpu_hotpluggable(cpu) ? 0 : -EBUSY; }
void __init tick_nohz_init(void)
From: Jiaxun Yang jiaxun.yang@flygoat.com
commit ee1809ed7bc456a72dc8410b475b73021a3a68d5 upstream.
fw_getenv will use env entry to determine style of env, however it is legal for firmware to just pass a empty list.
Check if first entry exist before running strchr to avoid null pointer dereference.
Cc: stable@vger.kernel.org Link: https://github.com/clbr/n64bootloader/issues/5 Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/mips/fw/lib/cmdline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/mips/fw/lib/cmdline.c +++ b/arch/mips/fw/lib/cmdline.c @@ -53,7 +53,7 @@ char *fw_getenv(char *envname) { char *result = NULL;
- if (_fw_envp != NULL) { + if (_fw_envp != NULL && fw_envp(0) != NULL) { /* * Return a pointer to the given environment variable. * YAMON uses "name", "value" pairs, while U-Boot uses
From: Corey Minyard minyard@acm.org
commit 6ce7995a43febe693d4894033c6e29314970646a upstream.
A recent change removed an increment of send_retries, re-add it.
Fixes: 95767ed78a18 ipmi:ssif: resend_msg() cannot fail Reported-by: Pavel Machek pavel@denx.de Cc: stable@vger.kernel.org Signed-off-by: Corey Minyard minyard@acm.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/ipmi/ipmi_ssif.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -564,8 +564,10 @@ static void retry_timeout(struct timer_l
if (waiting) start_get(ssif_info); - if (resend) + if (resend) { start_resend(ssif_info); + ssif_inc_stat(ssif_info, send_retries); + } }
static void watch_timeout(struct timer_list *t)
From: Zhang Yuchen zhangyuchen.lcr@bytedance.com
commit 6d2555cde2918409b0331560e66f84a0ad4849c6 upstream.
The ipmi communication is not restored after a specific version of BMC is upgraded on our server. The ipmi driver does not respond after printing the following log:
ipmi_ssif: Invalid response getting flags: 1c 1
I found that after entering this branch, ssif_info->ssif_state always holds SSIF_GETTING_FLAGS and never return to IDLE.
As a result, the driver cannot be loaded, because the driver status is checked during the unload process and must be IDLE in shutdown_ssif():
while (ssif_info->ssif_state != SSIF_IDLE) schedule_timeout(1);
The process trigger this problem is:
1. One msg timeout and next msg start send, and call ssif_set_need_watch().
2. ssif_set_need_watch()->watch_timeout()->start_flag_fetch() change ssif_state to SSIF_GETTING_FLAGS.
3. In msg_done_handler() ssif_state == SSIF_GETTING_FLAGS, if an error message is received, the second branch does not modify the ssif_state.
4. All retry action need IS_SSIF_IDLE() == True. Include retry action in watch_timeout(), msg_done_handler(). Sending msg does not work either. SSIF_IDLE is also checked in start_next_msg().
5. The only thing that can be triggered in the SSIF driver is watch_timeout(), after destory_user(), this timer will stop too.
So, if enter this branch, the ssif_state will remain SSIF_GETTING_FLAGS and can't send msg, no timer started, can't unload.
We did a comparative test before and after adding this patch, and the result is effective.
Fixes: 259307074bfc ("ipmi: Add SMBus interface driver (SSIF)")
Cc: stable@vger.kernel.org Signed-off-by: Zhang Yuchen zhangyuchen.lcr@bytedance.com Message-Id: 20230412074907.80046-1-zhangyuchen.lcr@bytedance.com Signed-off-by: Corey Minyard minyard@acm.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/ipmi/ipmi_ssif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -794,9 +794,9 @@ static void msg_done_handler(struct ssif } else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || data[1] != IPMI_GET_MSG_FLAGS_CMD) { /* - * Don't abort here, maybe it was a queued - * response to a previous command. + * Recv error response, give up. */ + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); dev_warn(&ssif_info->client->dev, "Invalid response getting flags: %x %x\n",
From: Kees Cook keescook@chromium.org
commit b69edab47f1da8edd8e7bfdf8c70f51a2a5d89fb upstream.
Under CONFIG_FORTIFY_SOURCE, memcpy() will check the size of destination and source buffers. Defining kernel_headers_data as "char" would trip this check. Since these addresses are treated as byte arrays, define them as arrays (as done everywhere else).
This was seen with:
$ cat /sys/kernel/kheaders.tar.xz >> /dev/null
detected buffer overflow in memcpy kernel BUG at lib/string_helpers.c:1027! ... RIP: 0010:fortify_panic+0xf/0x20 [...] Call Trace: <TASK> ikheaders_read+0x45/0x50 [kheaders] kernfs_fop_read_iter+0x1a4/0x2f0 ...
Reported-by: Jakub Kicinski kuba@kernel.org Link: https://lore.kernel.org/bpf/20230302112130.6e402a98@kernel.org/ Acked-by: Joel Fernandes (Google) joel@joelfernandes.org Reviewed-by: Alexander Lobakin aleksander.lobakin@intel.com Tested-by: Jakub Kicinski kuba@kernel.org Fixes: 43d8ce9d65a5 ("Provide in-kernel headers to make extending kernel easier") Cc: stable@vger.kernel.org Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20230302224946.never.243-kees@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/kheaders.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
--- a/kernel/kheaders.c +++ b/kernel/kheaders.c @@ -26,15 +26,15 @@ asm ( " .popsection \n" );
-extern char kernel_headers_data; -extern char kernel_headers_data_end; +extern char kernel_headers_data[]; +extern char kernel_headers_data_end[];
static ssize_t ikheaders_read(struct file *file, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t len) { - memcpy(buf, &kernel_headers_data + off, len); + memcpy(buf, &kernel_headers_data[off], len); return len; }
@@ -48,8 +48,8 @@ static struct bin_attribute kheaders_att
static int __init ikheaders_init(void) { - kheaders_attr.size = (&kernel_headers_data_end - - &kernel_headers_data); + kheaders_attr.size = (kernel_headers_data_end - + kernel_headers_data); return sysfs_create_bin_file(kernel_kobj, &kheaders_attr); }
From: Heiner Kallweit hkallweit1@gmail.com
commit eb411c0cf59ae6344b34bc6f0d298a22b300627e upstream.
This fix is basically the same as 9bce02ef0dfa ("pwm: meson: Fix the G12A AO clock parents order"). Vendor driver referenced there has xtal as first parent also for axg ao. In addition fix the name of the aoclk81 clock. Apparently name aoclk81 as used by the vendor driver was changed when mainlining the axg clock driver.
Fixes: bccaa3f917c9 ("pwm: meson: Add clock source configuration for Meson-AXG") Cc: stable@vger.kernel.org Signed-off-by: Heiner Kallweit hkallweit1@gmail.com Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pwm/pwm-meson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/pwm/pwm-meson.c +++ b/drivers/pwm/pwm-meson.c @@ -424,7 +424,7 @@ static const struct meson_pwm_data pwm_a };
static const char * const pwm_axg_ao_parent_names[] = { - "aoclk81", "xtal", "fclk_div4", "fclk_div5" + "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5" };
static const struct meson_pwm_data pwm_axg_ao_data = {
From: Heiner Kallweit hkallweit1@gmail.com
commit 9e4fa80ab7ef9eb4f7b1ea9fc31e0eb040e85e25 upstream.
Fix the name of the aoclk81 clock. Apparently name aoclk81 as used by the vendor driver was changed when mainlining the g12a clock driver.
Fixes: f41efceb46e6 ("pwm: meson: Add clock source configuration for Meson G12A") Cc: stable@vger.kernel.org Signed-off-by: Heiner Kallweit hkallweit1@gmail.com Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pwm/pwm-meson.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/pwm/pwm-meson.c +++ b/drivers/pwm/pwm-meson.c @@ -433,7 +433,7 @@ static const struct meson_pwm_data pwm_a };
static const char * const pwm_g12a_ao_ab_parent_names[] = { - "xtal", "aoclk81", "fclk_div4", "fclk_div5" + "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5" };
static const struct meson_pwm_data pwm_g12a_ao_ab_data = { @@ -442,7 +442,7 @@ static const struct meson_pwm_data pwm_g };
static const char * const pwm_g12a_ao_cd_parent_names[] = { - "xtal", "aoclk81", + "xtal", "g12a_ao_clk81", };
static const struct meson_pwm_data pwm_g12a_ao_cd_data = {
From: Johannes Berg johannes.berg@intel.com
commit 675751bb20634f981498c7d66161584080cc061e upstream.
If something was written to the buffer just before destruction, it may be possible (maybe not in a real system, but it did happen in ARCH=um with time-travel) to destroy the ringbuffer before the IRQ work ran, leading this KASAN report (or a crash without KASAN):
BUG: KASAN: slab-use-after-free in irq_work_run_list+0x11a/0x13a Read of size 8 at addr 000000006d640a48 by task swapper/0
CPU: 0 PID: 0 Comm: swapper Tainted: G W O 6.3.0-rc1 #7 Stack: 60c4f20f 0c203d48 41b58ab3 60f224fc 600477fa 60f35687 60c4f20f 601273dd 00000008 6101eb00 6101eab0 615be548 Call Trace: [<60047a58>] show_stack+0x25e/0x282 [<60c609e0>] dump_stack_lvl+0x96/0xfd [<60c50d4c>] print_report+0x1a7/0x5a8 [<603078d3>] kasan_report+0xc1/0xe9 [<60308950>] __asan_report_load8_noabort+0x1b/0x1d [<60232844>] irq_work_run_list+0x11a/0x13a [<602328b4>] irq_work_tick+0x24/0x34 [<6017f9dc>] update_process_times+0x162/0x196 [<6019f335>] tick_sched_handle+0x1a4/0x1c3 [<6019fd9e>] tick_sched_timer+0x79/0x10c [<601812b9>] __hrtimer_run_queues.constprop.0+0x425/0x695 [<60182913>] hrtimer_interrupt+0x16c/0x2c4 [<600486a3>] um_timer+0x164/0x183 [...]
Allocated by task 411: save_stack_trace+0x99/0xb5 stack_trace_save+0x81/0x9b kasan_save_stack+0x2d/0x54 kasan_set_track+0x34/0x3e kasan_save_alloc_info+0x25/0x28 ____kasan_kmalloc+0x8b/0x97 __kasan_kmalloc+0x10/0x12 __kmalloc+0xb2/0xe8 load_elf_phdrs+0xee/0x182 [...]
The buggy address belongs to the object at 000000006d640800 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 584 bytes inside of freed 1024-byte region [000000006d640800, 000000006d640c00)
Add the appropriate irq_work_sync() so the work finishes before the buffers are destroyed.
Prior to the commit in the Fixes tag below, there was only a single global IRQ work, so this issue didn't exist.
Link: https://lore.kernel.org/linux-trace-kernel/20230427175920.a76159263122.I8295...
Cc: stable@vger.kernel.org Cc: Masami Hiramatsu mhiramat@kernel.org Fixes: 15693458c4bc ("tracing/ring-buffer: Move poll wake ups into ring buffer code") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ring_buffer.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1644,6 +1644,8 @@ static void rb_free_cpu_buffer(struct ri struct list_head *head = cpu_buffer->pages; struct buffer_page *bpage, *tmp;
+ irq_work_sync(&cpu_buffer->irq_work.work); + free_buffer_page(cpu_buffer->reader_page);
if (head) { @@ -1750,6 +1752,8 @@ ring_buffer_free(struct trace_buffer *bu
cpuhp_state_remove_instance(CPUHP_TRACE_RB_PREPARE, &buffer->node);
+ irq_work_sync(&buffer->irq_work.work); + for_each_buffer_cpu(buffer, cpu) rb_free_cpu_buffer(buffer->buffers[cpu]);
From: Toke Høiland-Jørgensen toke@redhat.com
commit a543ada7db729514ddd3ba4efa45f4c7b802ad85 upstream.
The crypto_unregister_alg() function expects callers to ensure that any algorithm that is unregistered has a refcnt of exactly 1, and issues a BUG_ON() if this is not the case. However, there are in fact drivers that will call crypto_unregister_alg() without ensuring that the refcnt has been lowered first, most notably on system shutdown. This causes the BUG_ON() to trigger, which prevents a clean shutdown and hangs the system.
To avoid such hangs on shutdown, demote the BUG_ON() in crypto_unregister_alg() to a WARN_ON() with early return. Cc stable because this problem was observed on a 6.2 kernel, cf the link below.
Link: https://lore.kernel.org/r/87r0tyq8ph.fsf@toke.dk Cc: stable@vger.kernel.org Signed-off-by: Toke Høiland-Jørgensen toke@redhat.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- crypto/algapi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -456,7 +456,9 @@ void crypto_unregister_alg(struct crypto if (WARN(ret, "Algorithm %s is not registered", alg->cra_driver_name)) return;
- BUG_ON(refcount_read(&alg->cra_refcnt) != 1); + if (WARN_ON(refcount_read(&alg->cra_refcnt) != 1)) + return; + if (alg->cra_destroy) alg->cra_destroy(alg);
From: Jonathan McDowell noodles@earth.li
commit ca25c00ccbc5f942c63897ed23584cfc66e8ec81 upstream.
A failure loading the safexcel driver results in the following warning on boot, because the IRQ affinity has not been correctly cleaned up. Ensure we clean up the affinity and workqueues on a failure to load the driver.
crypto-safexcel: probe of f2800000.crypto failed with error -2 ------------[ cut here ]------------ WARNING: CPU: 1 PID: 232 at kernel/irq/manage.c:1913 free_irq+0x300/0x340 Modules linked in: hwmon mdio_i2c crypto_safexcel(+) md5 sha256_generic libsha256 authenc libdes omap_rng rng_core nft_masq nft_nat nft_chain_nat nf_nat nft_ct nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables libcrc32c nfnetlink fuse autofs4 CPU: 1 PID: 232 Comm: systemd-udevd Tainted: G W 6.1.6-00002-g9d4898824677 #3 Hardware name: MikroTik RB5009 (DT) pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : free_irq+0x300/0x340 lr : free_irq+0x2e0/0x340 sp : ffff800008fa3890 x29: ffff800008fa3890 x28: 0000000000000000 x27: 0000000000000000 x26: ffff8000008e6dc0 x25: ffff000009034cac x24: ffff000009034d50 x23: 0000000000000000 x22: 000000000000004a x21: ffff0000093e0d80 x20: ffff000009034c00 x19: ffff00000615fc00 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: 000075f5c1584c5e x14: 0000000000000017 x13: 0000000000000000 x12: 0000000000000040 x11: ffff000000579b60 x10: ffff000000579b62 x9 : ffff800008bbe370 x8 : ffff000000579dd0 x7 : 0000000000000000 x6 : ffff000000579e18 x5 : ffff000000579da8 x4 : ffff800008ca0000 x3 : ffff800008ca0188 x2 : 0000000013033204 x1 : ffff000009034c00 x0 : ffff8000087eadf0 Call trace: free_irq+0x300/0x340 devm_irq_release+0x14/0x20 devres_release_all+0xa0/0x100 device_unbind_cleanup+0x14/0x60 really_probe+0x198/0x2d4 __driver_probe_device+0x74/0xdc driver_probe_device+0x3c/0x110 __driver_attach+0x8c/0x190 bus_for_each_dev+0x6c/0xc0 driver_attach+0x20/0x30 bus_add_driver+0x148/0x1fc driver_register+0x74/0x120 __platform_driver_register+0x24/0x30 safexcel_init+0x48/0x1000 [crypto_safexcel] do_one_initcall+0x4c/0x1b0 do_init_module+0x44/0x1cc load_module+0x1724/0x1be4 __do_sys_finit_module+0xbc/0x110 __arm64_sys_finit_module+0x1c/0x24 invoke_syscall+0x44/0x110 el0_svc_common.constprop.0+0xc0/0xe0 do_el0_svc+0x20/0x80 el0_svc+0x14/0x4c el0t_64_sync_handler+0xb0/0xb4 el0t_64_sync+0x148/0x14c ---[ end trace 0000000000000000 ]---
Fixes: 1b44c5a60c13 ("inside-secure - add SafeXcel EIP197 crypto engine driver") Signed-off-by: Jonathan McDowell noodles@earth.li Cc: stable@vger.kernel.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/crypto/inside-secure/safexcel.c | 37 +++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-)
--- a/drivers/crypto/inside-secure/safexcel.c +++ b/drivers/crypto/inside-secure/safexcel.c @@ -1634,19 +1634,23 @@ static int safexcel_probe_generic(void * &priv->ring[i].rdr); if (ret) { dev_err(dev, "Failed to initialize rings\n"); - return ret; + goto err_cleanup_rings; }
priv->ring[i].rdr_req = devm_kcalloc(dev, EIP197_DEFAULT_RING_SIZE, sizeof(*priv->ring[i].rdr_req), GFP_KERNEL); - if (!priv->ring[i].rdr_req) - return -ENOMEM; + if (!priv->ring[i].rdr_req) { + ret = -ENOMEM; + goto err_cleanup_rings; + }
ring_irq = devm_kzalloc(dev, sizeof(*ring_irq), GFP_KERNEL); - if (!ring_irq) - return -ENOMEM; + if (!ring_irq) { + ret = -ENOMEM; + goto err_cleanup_rings; + }
ring_irq->priv = priv; ring_irq->ring = i; @@ -1660,7 +1664,8 @@ static int safexcel_probe_generic(void * ring_irq); if (irq < 0) { dev_err(dev, "Failed to get IRQ ID for ring %d\n", i); - return irq; + ret = irq; + goto err_cleanup_rings; }
priv->ring[i].irq = irq; @@ -1672,8 +1677,10 @@ static int safexcel_probe_generic(void * snprintf(wq_name, 9, "wq_ring%d", i); priv->ring[i].workqueue = create_singlethread_workqueue(wq_name); - if (!priv->ring[i].workqueue) - return -ENOMEM; + if (!priv->ring[i].workqueue) { + ret = -ENOMEM; + goto err_cleanup_rings; + }
priv->ring[i].requests = 0; priv->ring[i].busy = false; @@ -1690,16 +1697,26 @@ static int safexcel_probe_generic(void * ret = safexcel_hw_init(priv); if (ret) { dev_err(dev, "HW init failed (%d)\n", ret); - return ret; + goto err_cleanup_rings; }
ret = safexcel_register_algorithms(priv); if (ret) { dev_err(dev, "Failed to register algorithms (%d)\n", ret); - return ret; + goto err_cleanup_rings; }
return 0; + +err_cleanup_rings: + for (i = 0; i < priv->config.rings; i++) { + if (priv->ring[i].irq) + irq_set_affinity_hint(priv->ring[i].irq, NULL); + if (priv->ring[i].workqueue) + destroy_workqueue(priv->ring[i].workqueue); + } + + return ret; }
static void safexcel_hw_reset_rings(struct safexcel_crypto_priv *priv)
From: Zheng Yejian zhengyejian1@huawei.com
commit 7a29fb4a4771124bc61de397dbfc1554dbbcc19c upstream.
Registering a kprobe on __rcu_irq_enter_check_tick() can cause kernel stack overflow as shown below. This issue can be reproduced by enabling CONFIG_NO_HZ_FULL and booting the kernel with argument "nohz_full=", and then giving the following commands at the shell prompt:
# cd /sys/kernel/tracing/ # echo 'p:mp1 __rcu_irq_enter_check_tick' >> kprobe_events # echo 1 > events/kprobes/enable
This commit therefore adds __rcu_irq_enter_check_tick() to the kprobes blacklist using NOKPROBE_SYMBOL().
Insufficient stack space to handle exception! ESR: 0x00000000f2000004 -- BRK (AArch64) FAR: 0x0000ffffccf3e510 Task stack: [0xffff80000ad30000..0xffff80000ad38000] IRQ stack: [0xffff800008050000..0xffff800008058000] Overflow stack: [0xffff089c36f9f310..0xffff089c36fa0310] CPU: 5 PID: 190 Comm: bash Not tainted 6.2.0-rc2-00320-g1f5abbd77e2c #19 Hardware name: linux,dummy-virt (DT) pstate: 400003c5 (nZcv DAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __rcu_irq_enter_check_tick+0x0/0x1b8 lr : ct_nmi_enter+0x11c/0x138 sp : ffff80000ad30080 x29: ffff80000ad30080 x28: ffff089c82e20000 x27: 0000000000000000 x26: 0000000000000000 x25: ffff089c02a8d100 x24: 0000000000000000 x23: 00000000400003c5 x22: 0000ffffccf3e510 x21: ffff089c36fae148 x20: ffff80000ad30120 x19: ffffa8da8fcce148 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: ffffa8da8e44ea6c x14: ffffa8da8e44e968 x13: ffffa8da8e03136c x12: 1fffe113804d6809 x11: ffff6113804d6809 x10: 0000000000000a60 x9 : dfff800000000000 x8 : ffff089c026b404f x7 : 00009eec7fb297f7 x6 : 0000000000000001 x5 : ffff80000ad30120 x4 : dfff800000000000 x3 : ffffa8da8e3016f4 x2 : 0000000000000003 x1 : 0000000000000000 x0 : 0000000000000000 Kernel panic - not syncing: kernel stack overflow CPU: 5 PID: 190 Comm: bash Not tainted 6.2.0-rc2-00320-g1f5abbd77e2c #19 Hardware name: linux,dummy-virt (DT) Call trace: dump_backtrace+0xf8/0x108 show_stack+0x20/0x30 dump_stack_lvl+0x68/0x84 dump_stack+0x1c/0x38 panic+0x214/0x404 add_taint+0x0/0xf8 panic_bad_stack+0x144/0x160 handle_bad_stack+0x38/0x58 __bad_stack+0x78/0x7c __rcu_irq_enter_check_tick+0x0/0x1b8 arm64_enter_el1_dbg.isra.0+0x14/0x20 el1_dbg+0x2c/0x90 el1h_64_sync_handler+0xcc/0xe8 el1h_64_sync+0x64/0x68 __rcu_irq_enter_check_tick+0x0/0x1b8 arm64_enter_el1_dbg.isra.0+0x14/0x20 el1_dbg+0x2c/0x90 el1h_64_sync_handler+0xcc/0xe8 el1h_64_sync+0x64/0x68 __rcu_irq_enter_check_tick+0x0/0x1b8 arm64_enter_el1_dbg.isra.0+0x14/0x20 el1_dbg+0x2c/0x90 el1h_64_sync_handler+0xcc/0xe8 el1h_64_sync+0x64/0x68 __rcu_irq_enter_check_tick+0x0/0x1b8 [...] el1_dbg+0x2c/0x90 el1h_64_sync_handler+0xcc/0xe8 el1h_64_sync+0x64/0x68 __rcu_irq_enter_check_tick+0x0/0x1b8 arm64_enter_el1_dbg.isra.0+0x14/0x20 el1_dbg+0x2c/0x90 el1h_64_sync_handler+0xcc/0xe8 el1h_64_sync+0x64/0x68 __rcu_irq_enter_check_tick+0x0/0x1b8 arm64_enter_el1_dbg.isra.0+0x14/0x20 el1_dbg+0x2c/0x90 el1h_64_sync_handler+0xcc/0xe8 el1h_64_sync+0x64/0x68 __rcu_irq_enter_check_tick+0x0/0x1b8 el1_interrupt+0x28/0x60 el1h_64_irq_handler+0x18/0x28 el1h_64_irq+0x64/0x68 __ftrace_set_clr_event_nolock+0x98/0x198 __ftrace_set_clr_event+0x58/0x80 system_enable_write+0x144/0x178 vfs_write+0x174/0x738 ksys_write+0xd0/0x188 __arm64_sys_write+0x4c/0x60 invoke_syscall+0x64/0x180 el0_svc_common.constprop.0+0x84/0x160 do_el0_svc+0x48/0xe8 el0_svc+0x34/0xd0 el0t_64_sync_handler+0xb8/0xc0 el0t_64_sync+0x190/0x194 SMP: stopping secondary CPUs Kernel Offset: 0x28da86000000 from 0xffff800008000000 PHYS_OFFSET: 0xfffff76600000000 CPU features: 0x00000,01a00100,0000421b Memory Limit: none
Acked-by: Joel Fernandes (Google) joel@joelfernandes.org Link: https://lore.kernel.org/all/20221119040049.795065-1-zhengyejian1@huawei.com/ Fixes: aaf2bc50df1f ("rcu: Abstract out rcu_irq_enter_check_tick() from rcu_nmi_enter()") Signed-off-by: Zheng Yejian zhengyejian1@huawei.com Cc: stable@vger.kernel.org Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Joel Fernandes (Google) joel@joelfernandes.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/rcu/tree.c | 1 + 1 file changed, 1 insertion(+)
--- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -964,6 +964,7 @@ void __rcu_irq_enter_check_tick(void) } raw_spin_unlock_rcu_node(rdp->mynode); } +NOKPROBE_SYMBOL(__rcu_irq_enter_check_tick); #endif /* CONFIG_NO_HZ_FULL */
/**
From: Roberto Sassu roberto.sassu@huawei.com
commit d82dcd9e21b77d338dc4875f3d4111f0db314a7c upstream.
Reiserfs sets a security xattr at inode creation time in two stages: first, it calls reiserfs_security_init() to obtain the xattr from active LSMs; then, it calls reiserfs_security_write() to actually write that xattr.
Unfortunately, it seems there is a wrong expectation that LSMs provide the full xattr name in the form 'security.<suffix>'. However, LSMs always provided just the suffix, causing reiserfs to not write the xattr at all (if the suffix is shorter than the prefix), or to write an xattr with the wrong name.
Add a temporary buffer in reiserfs_security_write(), and write to it the full xattr name, before passing it to reiserfs_xattr_set_handle().
Also replace the name length check with a check that the full xattr name is not larger than XATTR_NAME_MAX.
Cc: stable@vger.kernel.org # v2.6.x Fixes: 57fe60df6241 ("reiserfs: add atomic addition of selinux attributes during inode creation") Signed-off-by: Roberto Sassu roberto.sassu@huawei.com Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/reiserfs/xattr_security.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c @@ -81,11 +81,15 @@ int reiserfs_security_write(struct reise struct inode *inode, struct reiserfs_security_handle *sec) { + char xattr_name[XATTR_NAME_MAX + 1] = XATTR_SECURITY_PREFIX; int error; - if (strlen(sec->name) < sizeof(XATTR_SECURITY_PREFIX)) + + if (XATTR_SECURITY_PREFIX_LEN + strlen(sec->name) > XATTR_NAME_MAX) return -EINVAL;
- error = reiserfs_xattr_set_handle(th, inode, sec->name, sec->value, + strlcat(xattr_name, sec->name, sizeof(xattr_name)); + + error = reiserfs_xattr_set_handle(th, inode, xattr_name, sec->value, sec->length, XATTR_CREATE); if (error == -ENODATA || error == -EOPNOTSUPP) error = 0;
From: Sean Christopherson seanjc@google.com
commit 4984563823f0034d3533854c1b50e729f5191089 upstream.
Extend VMX's nested intercept logic for emulated instructions to handle "pause" interception, in quotes because KVM's emulator doesn't filter out NOPs when checking for nested intercepts. Failure to allow emulation of NOPs results in KVM injecting a #UD into L2 on any NOP that collides with the emulator's definition of PAUSE, i.e. on all single-byte NOPs.
For PAUSE itself, honor L1's PAUSE-exiting control, but ignore PLE to avoid unnecessarily injecting a #UD into L2. Per the SDM, the first execution of PAUSE after VM-Entry is treated as the beginning of a new loop, i.e. will never trigger a PLE VM-Exit, and so L1 can't expect any given execution of PAUSE to deterministically exit.
... the processor considers this execution to be the first execution of PAUSE in a loop. (It also does so for the first execution of PAUSE at CPL 0 after VM entry.)
All that said, the PLE side of things is currently a moot point, as KVM doesn't expose PLE to L1.
Note, vmx_check_intercept() is still wildly broken when L1 wants to intercept an instruction, as KVM injects a #UD instead of synthesizing a nested VM-Exit. That issue extends far beyond NOP/PAUSE and needs far more effort to fix, i.e. is a problem for the future.
Fixes: 07721feee46b ("KVM: nVMX: Don't emulate instructions in guest mode") Cc: Mathias Krause minipli@grsecurity.net Cc: stable@vger.kernel.org Reviewed-by: Paolo Bonzini pbonzini@redhat.com Link: https://lore.kernel.org/r/20230405002359.418138-1-seanjc@google.com Signed-off-by: Sean Christopherson seanjc@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/vmx/vmx.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
--- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7536,6 +7536,21 @@ static int vmx_check_intercept(struct kv /* FIXME: produce nested vmexit and return X86EMUL_INTERCEPTED. */ break;
+ case x86_intercept_pause: + /* + * PAUSE is a single-byte NOP with a REPE prefix, i.e. collides + * with vanilla NOPs in the emulator. Apply the interception + * check only to actual PAUSE instructions. Don't check + * PAUSE-loop-exiting, software can't expect a given PAUSE to + * exit, i.e. KVM is within its rights to allow L2 to execute + * the PAUSE. + */ + if ((info->rep_prefix != REPE_PREFIX) || + !nested_cpu_has2(vmcs12, CPU_BASED_PAUSE_EXITING)) + return X86EMUL_CONTINUE; + + break; + /* TODO: check more intercepts... */ default: break;
From: Zhang Zhengming zhang.zhengming@h3c.com
commit 43ec16f1450f4936025a9bdf1a273affdb9732c1 upstream.
There is a crash in relay_file_read, as the var from point to the end of last subbuf.
The oops looks something like: pc : __arch_copy_to_user+0x180/0x310 lr : relay_file_read+0x20c/0x2c8 Call trace: __arch_copy_to_user+0x180/0x310 full_proxy_read+0x68/0x98 vfs_read+0xb0/0x1d0 ksys_read+0x6c/0xf0 __arm64_sys_read+0x20/0x28 el0_svc_common.constprop.3+0x84/0x108 do_el0_svc+0x74/0x90 el0_svc+0x1c/0x28 el0_sync_handler+0x88/0xb0 el0_sync+0x148/0x180
We get the condition by analyzing the vmcore:
1). The last produced byte and last consumed byte both at the end of the last subbuf
2). A softirq calls function(e.g __blk_add_trace) to write relay buffer occurs when an program is calling relay_file_read_avail().
relay_file_read relay_file_read_avail relay_file_read_consume(buf, 0, 0); //interrupted by softirq who will write subbuf .... return 1; //read_start point to the end of the last subbuf read_start = relay_file_read_start_pos //avail is equal to subsize avail = relay_file_read_subbuf_avail //from points to an invalid memory address from = buf->start + read_start //system is crashed copy_to_user(buffer, from, avail)
Link: https://lkml.kernel.org/r/20230419040203.37676-1-zhang.zhengming@h3c.com Fixes: 8d62fdebdaf9 ("relay file read: start-pos fix") Signed-off-by: Zhang Zhengming zhang.zhengming@h3c.com Reviewed-by: Zhao Lei zhao_lei1@hoperun.com Reviewed-by: Zhou Kete zhou.kete@h3c.com Reviewed-by: Pengcheng Yang yangpc@wangsu.com Cc: Jens Axboe axboe@kernel.dk Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/relay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/kernel/relay.c +++ b/kernel/relay.c @@ -1077,7 +1077,8 @@ static size_t relay_file_read_start_pos( size_t subbuf_size = buf->chan->subbuf_size; size_t n_subbufs = buf->chan->n_subbufs; size_t consumed = buf->subbufs_consumed % n_subbufs; - size_t read_pos = consumed * subbuf_size + buf->bytes_consumed; + size_t read_pos = (consumed * subbuf_size + buf->bytes_consumed) + % (n_subbufs * subbuf_size);
read_subbuf = read_pos / subbuf_size; padding = buf->padding[read_subbuf];
From: Baokun Li libaokun1@huawei.com
[ Upstream commit 1ba1199ec5747f475538c0d25a32804e5ba1dfde ]
KASAN report null-ptr-deref: ================================================================== BUG: KASAN: null-ptr-deref in bdi_split_work_to_wbs+0x5c5/0x7b0 Write of size 8 at addr 0000000000000000 by task sync/943 CPU: 5 PID: 943 Comm: sync Tainted: 6.3.0-rc5-next-20230406-dirty #461 Call Trace: <TASK> dump_stack_lvl+0x7f/0xc0 print_report+0x2ba/0x340 kasan_report+0xc4/0x120 kasan_check_range+0x1b7/0x2e0 __kasan_check_write+0x24/0x40 bdi_split_work_to_wbs+0x5c5/0x7b0 sync_inodes_sb+0x195/0x630 sync_inodes_one_sb+0x3a/0x50 iterate_supers+0x106/0x1b0 ksys_sync+0x98/0x160 [...] ==================================================================
The race that causes the above issue is as follows:
cpu1 cpu2 -------------------------|------------------------- inode_switch_wbs INIT_WORK(&isw->work, inode_switch_wbs_work_fn) queue_rcu_work(isw_wq, &isw->work) // queue_work async inode_switch_wbs_work_fn wb_put_many(old_wb, nr_switched) percpu_ref_put_many ref->data->release(ref) cgwb_release queue_work(cgwb_release_wq, &wb->release_work) // queue_work async &wb->release_work cgwb_release_workfn ksys_sync iterate_supers sync_inodes_one_sb sync_inodes_sb bdi_split_work_to_wbs kmalloc(sizeof(*work), GFP_ATOMIC) // alloc memory failed percpu_ref_exit ref->data = NULL kfree(data) wb_get(wb) percpu_ref_get(&wb->refcnt) percpu_ref_get_many(ref, 1) atomic_long_add(nr, &ref->data->count) atomic64_add(i, v) // trigger null-ptr-deref
bdi_split_work_to_wbs() traverses &bdi->wb_list to split work into all wbs. If the allocation of new work fails, the on-stack fallback will be used and the reference count of the current wb is increased afterwards. If cgroup writeback membership switches occur before getting the reference count and the current wb is released as old_wd, then calling wb_get() or wb_put() will trigger the null pointer dereference above.
This issue was introduced in v4.3-rc7 (see fix tag1). Both sync_inodes_sb() and __writeback_inodes_sb_nr() calls to bdi_split_work_to_wbs() can trigger this issue. For scenarios called via sync_inodes_sb(), originally commit 7fc5854f8c6e ("writeback: synchronize sync(2) against cgroup writeback membership switches") reduced the possibility of the issue by adding wb_switch_rwsem, but in v5.14-rc1 (see fix tag2) removed the "inode_io_list_del_locked(inode, old_wb)" from inode_switch_wbs_work_fn() so that wb->state contains WB_has_dirty_io, thus old_wb is not skipped when traversing wbs in bdi_split_work_to_wbs(), and the issue becomes easily reproducible again.
To solve this problem, percpu_ref_exit() is called under RCU protection to avoid race between cgwb_release_workfn() and bdi_split_work_to_wbs(). Moreover, replace wb_get() with wb_tryget() in bdi_split_work_to_wbs(), and skip the current wb if wb_tryget() fails because the wb has already been shutdown.
Link: https://lkml.kernel.org/r/20230410130826.1492525-1-libaokun1@huawei.com Fixes: b817525a4a80 ("writeback: bdi_writeback iteration must not skip dying ones") Signed-off-by: Baokun Li libaokun1@huawei.com Reviewed-by: Jan Kara jack@suse.cz Acked-by: Tejun Heo tj@kernel.org Cc: Alexander Viro viro@zeniv.linux.org.uk Cc: Andreas Dilger adilger.kernel@dilger.ca Cc: Christian Brauner brauner@kernel.org Cc: Dennis Zhou dennis@kernel.org Cc: Hou Tao houtao1@huawei.com Cc: yangerkun yangerkun@huawei.com Cc: Zhang Yi yi.zhang@huawei.com Cc: Jens Axboe axboe@kernel.dk Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/fs-writeback.c | 17 ++++++++++------- mm/backing-dev.c | 11 ++++++++++- 2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 46c15dd2405c6..6f18459f5e381 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -884,6 +884,16 @@ static void bdi_split_work_to_wbs(struct backing_dev_info *bdi, continue; }
+ /* + * If wb_tryget fails, the wb has been shutdown, skip it. + * + * Pin @wb so that it stays on @bdi->wb_list. This allows + * continuing iteration from @wb after dropping and + * regrabbing rcu read lock. + */ + if (!wb_tryget(wb)) + continue; + /* alloc failed, execute synchronously using on-stack fallback */ work = &fallback_work; *work = *base_work; @@ -892,13 +902,6 @@ static void bdi_split_work_to_wbs(struct backing_dev_info *bdi, work->done = &fallback_work_done;
wb_queue_work(wb, work); - - /* - * Pin @wb so that it stays on @bdi->wb_list. This allows - * continuing iteration from @wb after dropping and - * regrabbing rcu read lock. - */ - wb_get(wb); last_wb = wb;
rcu_read_unlock(); diff --git a/mm/backing-dev.c b/mm/backing-dev.c index ca770a783a9f9..b28f629c35271 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -378,6 +378,15 @@ static void wb_exit(struct bdi_writeback *wb) static DEFINE_SPINLOCK(cgwb_lock); static struct workqueue_struct *cgwb_release_wq;
+static void cgwb_free_rcu(struct rcu_head *rcu_head) +{ + struct bdi_writeback *wb = container_of(rcu_head, + struct bdi_writeback, rcu); + + percpu_ref_exit(&wb->refcnt); + kfree(wb); +} + static void cgwb_release_workfn(struct work_struct *work) { struct bdi_writeback *wb = container_of(work, struct bdi_writeback, @@ -397,7 +406,7 @@ static void cgwb_release_workfn(struct work_struct *work) fprop_local_destroy_percpu(&wb->memcg_completions); percpu_ref_exit(&wb->refcnt); wb_exit(wb); - kfree_rcu(wb, rcu); + call_rcu(&wb->rcu, cgwb_free_rcu); }
static void cgwb_release(struct percpu_ref *refcnt)
From: Reid Tonking reidt@ti.com
commit c770657bd2611b077ec1e7b1fe6aa92f249399bd upstream.
Using standard mode, rare false ACK responses were appearing with i2cdetect tool. This was happening due to NACK interrupt triggering ISR thread before register access interrupt was ready. Removing the NACK interrupt's ability to trigger ISR thread lets register access ready interrupt do this instead.
Cc: stable@vger.kernel.org # v3.7+ Fixes: 3b2f8f82dad7 ("i2c: omap: switch to threaded IRQ support") Signed-off-by: Reid Tonking reidt@ti.com Acked-by: Vignesh Raghavendra vigneshr@ti.com Reviewed-by: Tony Lindgren tony@atomide.com Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/i2c/busses/i2c-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1058,7 +1058,7 @@ omap_i2c_isr(int irq, void *dev_id) u16 stat;
stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG); - mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG); + mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG) & ~OMAP_I2C_STAT_NACK;
if (stat & mask) ret = IRQ_WAKE_THREAD;
From: Kishon Vijay Abraham I kvijayab@amd.com
commit ccc62b827775915a9b82db42a29813d04f92df7a upstream.
commit b9c6ff94e43a ("iommu/amd: Re-factor guest virtual APIC (de-)activation code") while refactoring guest virtual APIC activation/de-activation code, stored information for activate/de-activate in "struct amd_ir_data". It used 32-bit integer data type for storing the "Guest Virtual APIC Table Root Pointer" (ga_root_ptr), though the "ga_root_ptr" is actually a 40-bit field in IRTE (Interrupt Remapping Table Entry).
This causes interrupts from PCIe devices to not reach the guest in the case of PCIe passthrough with SME (Secure Memory Encryption) enabled as _SME_ bit in the "ga_root_ptr" is lost before writing it to the IRTE.
Fix it by using 64-bit data type for storing the "ga_root_ptr". While at that also change the data type of "ga_tag" to u32 in order to match the IOMMU spec.
Fixes: b9c6ff94e43a ("iommu/amd: Re-factor guest virtual APIC (de-)activation code") Cc: stable@vger.kernel.org # v5.4+ Reported-by: Alejandro Jimenez alejandro.j.jimenez@oracle.com Reviewed-by: Suravee Suthikulpanit suravee.suthikulpanit@amd.com Signed-off-by: Kishon Vijay Abraham I kvijayab@amd.com Link: https://lore.kernel.org/r/20230405130317.9351-1-kvijayab@amd.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iommu/amd/amd_iommu_types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/iommu/amd/amd_iommu_types.h +++ b/drivers/iommu/amd/amd_iommu_types.h @@ -897,8 +897,8 @@ struct amd_ir_data { */ struct irq_cfg *cfg; int ga_vector; - int ga_root_ptr; - int ga_tag; + u64 ga_root_ptr; + u32 ga_tag; };
struct amd_irte_ops {
From: Zhihao Cheng chengzhihao1@huawei.com
commit 7d01cb27f6aebc54efbe28d8961a973b8f795b13 upstream.
This reverts commit 122deabfe1428 (ubifs: dirty_cow_znode: Fix memleak in error handling path). After commit 122deabfe1428 applied, if insert_old_idx() failed, old index neither exists in TNC nor in old-index tree. Which means that old index node could be overwritten in layout_leb_in_gaps(), then ubifs image will be corrupted in power-cut.
Fixes: 122deabfe1428 (ubifs: dirty_cow_znode: Fix memleak ... path) Cc: stable@vger.kernel.org Signed-off-by: Zhihao Cheng chengzhihao1@huawei.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ubifs/tnc.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
--- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -267,18 +267,11 @@ static struct ubifs_znode *dirty_cow_zno if (zbr->len) { err = insert_old_idx(c, zbr->lnum, zbr->offs); if (unlikely(err)) - /* - * Obsolete znodes will be freed by tnc_destroy_cnext() - * or free_obsolete_znodes(), copied up znodes should - * be added back to tnc and freed by - * ubifs_destroy_tnc_subtree(). - */ - goto out; + return ERR_PTR(err); err = add_idx_dirt(c, zbr->lnum, zbr->len); } else err = 0;
-out: zbr->znode = zn; zbr->lnum = 0; zbr->offs = 0;
From: Zhihao Cheng chengzhihao1@huawei.com
commit b5fda08ef213352ac2df7447611eb4d383cce929 upstream.
Following process will cause a memleak for copied up znode:
dirty_cow_znode zn = copy_znode(c, znode); err = insert_old_idx(c, zbr->lnum, zbr->offs); if (unlikely(err)) return ERR_PTR(err); // No one refers to zn.
Fetch a reproducer in [Link].
Function copy_znode() is split into 2 parts: resource allocation and znode replacement, insert_old_idx() is split in similar way, so resource cleanup could be done in error handling path without corrupting metadata(mem & disk). It's okay that old index inserting is put behind of add_idx_dirt(), old index is used in layout_leb_in_gaps(), so the two processes do not depend on each other.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216705 Fixes: 1e51764a3c2a ("UBIFS: add new flash file system") Cc: stable@vger.kernel.org Signed-off-by: Zhihao Cheng chengzhihao1@huawei.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ubifs/tnc.c | 137 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 50 deletions(-)
--- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -44,6 +44,33 @@ enum { NOT_ON_MEDIA = 3, };
+static void do_insert_old_idx(struct ubifs_info *c, + struct ubifs_old_idx *old_idx) +{ + struct ubifs_old_idx *o; + struct rb_node **p, *parent = NULL; + + p = &c->old_idx.rb_node; + while (*p) { + parent = *p; + o = rb_entry(parent, struct ubifs_old_idx, rb); + if (old_idx->lnum < o->lnum) + p = &(*p)->rb_left; + else if (old_idx->lnum > o->lnum) + p = &(*p)->rb_right; + else if (old_idx->offs < o->offs) + p = &(*p)->rb_left; + else if (old_idx->offs > o->offs) + p = &(*p)->rb_right; + else { + ubifs_err(c, "old idx added twice!"); + kfree(old_idx); + } + } + rb_link_node(&old_idx->rb, parent, p); + rb_insert_color(&old_idx->rb, &c->old_idx); +} + /** * insert_old_idx - record an index node obsoleted since the last commit start. * @c: UBIFS file-system description object @@ -69,35 +96,15 @@ enum { */ static int insert_old_idx(struct ubifs_info *c, int lnum, int offs) { - struct ubifs_old_idx *old_idx, *o; - struct rb_node **p, *parent = NULL; + struct ubifs_old_idx *old_idx;
old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS); if (unlikely(!old_idx)) return -ENOMEM; old_idx->lnum = lnum; old_idx->offs = offs; + do_insert_old_idx(c, old_idx);
- p = &c->old_idx.rb_node; - while (*p) { - parent = *p; - o = rb_entry(parent, struct ubifs_old_idx, rb); - if (lnum < o->lnum) - p = &(*p)->rb_left; - else if (lnum > o->lnum) - p = &(*p)->rb_right; - else if (offs < o->offs) - p = &(*p)->rb_left; - else if (offs > o->offs) - p = &(*p)->rb_right; - else { - ubifs_err(c, "old idx added twice!"); - kfree(old_idx); - return 0; - } - } - rb_link_node(&old_idx->rb, parent, p); - rb_insert_color(&old_idx->rb, &c->old_idx); return 0; }
@@ -199,23 +206,6 @@ static struct ubifs_znode *copy_znode(st __set_bit(DIRTY_ZNODE, &zn->flags); __clear_bit(COW_ZNODE, &zn->flags);
- ubifs_assert(c, !ubifs_zn_obsolete(znode)); - __set_bit(OBSOLETE_ZNODE, &znode->flags); - - if (znode->level != 0) { - int i; - const int n = zn->child_cnt; - - /* The children now have new parent */ - for (i = 0; i < n; i++) { - struct ubifs_zbranch *zbr = &zn->zbranch[i]; - - if (zbr->znode) - zbr->znode->parent = zn; - } - } - - atomic_long_inc(&c->dirty_zn_cnt); return zn; }
@@ -234,6 +224,42 @@ static int add_idx_dirt(struct ubifs_inf }
/** + * replace_znode - replace old znode with new znode. + * @c: UBIFS file-system description object + * @new_zn: new znode + * @old_zn: old znode + * @zbr: the branch of parent znode + * + * Replace old znode with new znode in TNC. + */ +static void replace_znode(struct ubifs_info *c, struct ubifs_znode *new_zn, + struct ubifs_znode *old_zn, struct ubifs_zbranch *zbr) +{ + ubifs_assert(c, !ubifs_zn_obsolete(old_zn)); + __set_bit(OBSOLETE_ZNODE, &old_zn->flags); + + if (old_zn->level != 0) { + int i; + const int n = new_zn->child_cnt; + + /* The children now have new parent */ + for (i = 0; i < n; i++) { + struct ubifs_zbranch *child = &new_zn->zbranch[i]; + + if (child->znode) + child->znode->parent = new_zn; + } + } + + zbr->znode = new_zn; + zbr->lnum = 0; + zbr->offs = 0; + zbr->len = 0; + + atomic_long_inc(&c->dirty_zn_cnt); +} + +/** * dirty_cow_znode - ensure a znode is not being committed. * @c: UBIFS file-system description object * @zbr: branch of znode to check @@ -265,21 +291,32 @@ static struct ubifs_znode *dirty_cow_zno return zn;
if (zbr->len) { - err = insert_old_idx(c, zbr->lnum, zbr->offs); - if (unlikely(err)) - return ERR_PTR(err); + struct ubifs_old_idx *old_idx; + + old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS); + if (unlikely(!old_idx)) { + err = -ENOMEM; + goto out; + } + old_idx->lnum = zbr->lnum; + old_idx->offs = zbr->offs; + err = add_idx_dirt(c, zbr->lnum, zbr->len); - } else - err = 0; + if (err) { + kfree(old_idx); + goto out; + }
- zbr->znode = zn; - zbr->lnum = 0; - zbr->offs = 0; - zbr->len = 0; + do_insert_old_idx(c, old_idx); + } + + replace_znode(c, zn, znode, zbr);
- if (unlikely(err)) - return ERR_PTR(err); return zn; + +out: + kfree(zn); + return ERR_PTR(err); }
/**
From: Wang YanQing udknight@gmail.com
commit 31a149d5c13c4cbcf97de3435817263a2d8c9d6e upstream.
The commit 2d78aee426d8 ("UBI: simplify LEB write and atomic LEB change code") adds helper function, try_write_vid_and_data(), to simplify the code, but this helper function has bug, it will return 0 (success) when ubi_io_write_vid_hdr() or the ubi_io_write_data() return error number (-EIO, etc), because the return value of ubi_wl_put_peb() will overwrite the original return value.
This issue will cause unexpected data loss issue, because the caller of this function and UBIFS willn't know the data is lost.
Fixes: 2d78aee426d8 ("UBI: simplify LEB write and atomic LEB change code") Cc: stable@vger.kernel.org Signed-off-by: Wang YanQing udknight@gmail.com Reviewed-by: Zhihao Cheng chengzhihao1@huawei.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/ubi/eba.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
--- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -947,7 +947,7 @@ static int try_write_vid_and_data(struct int offset, int len) { struct ubi_device *ubi = vol->ubi; - int pnum, opnum, err, vol_id = vol->vol_id; + int pnum, opnum, err, err2, vol_id = vol->vol_id;
pnum = ubi_wl_get_peb(ubi); if (pnum < 0) { @@ -982,10 +982,19 @@ static int try_write_vid_and_data(struct out_put: up_read(&ubi->fm_eba_sem);
- if (err && pnum >= 0) - err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); - else if (!err && opnum >= 0) - err = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0); + if (err && pnum >= 0) { + err2 = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); + if (err2) { + ubi_warn(ubi, "failed to return physical eraseblock %d, error %d", + pnum, err2); + } + } else if (!err && opnum >= 0) { + err2 = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0); + if (err2) { + ubi_warn(ubi, "failed to return physical eraseblock %d, error %d", + opnum, err2); + } + }
return err; }
From: Mårten Lindahl marten.lindahl@axis.com
commit 1fb815b38bb31d6af9bd0540b8652a0d6fe6cfd3 upstream.
When opening a ubifs tmpfile on an encrypted directory, function fscrypt_setup_filename allocates memory for the name that is to be stored in the directory entry, but after the name has been copied to the directory entry inode, the memory is not freed.
When running kmemleak on it we see that it is registered as a leak. The report below is triggered by a simple program 'tmpfile' just opening a tmpfile:
unreferenced object 0xffff88810178f380 (size 32): comm "tmpfile", pid 509, jiffies 4294934744 (age 1524.742s) backtrace: __kmem_cache_alloc_node __kmalloc fscrypt_setup_filename ubifs_tmpfile vfs_tmpfile path_openat
Free this memory after it has been copied to the inode.
Signed-off-by: Mårten Lindahl marten.lindahl@axis.com Reviewed-by: Zhihao Cheng chengzhihao1@huawei.com Cc: stable@vger.kernel.org Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ubifs/dir.c | 1 + 1 file changed, 1 insertion(+)
--- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -425,6 +425,7 @@ static int do_tmpfile(struct inode *dir, mutex_unlock(&dir_ui->ui_mutex);
ubifs_release_budget(c, &req); + fscrypt_free_filename(&nm);
return 0;
From: Randy Dunlap rdunlap@infradead.org
commit 9dd7c46346ca4390f84a7ea9933005eb1b175c15 upstream.
When CONFIG_DMASOUND_ATARI=m and CONFIG_DMASOUND_Q40=y (or vice versa), dmasound_core.o can be built without dmasound_deinit() being defined, causing a build error:
ERROR: modpost: "dmasound_deinit" [sound/oss/dmasound/dmasound_atari.ko] undefined!
Modify dmasound_core.c and dmasound.h so that dmasound_deinit() is always available.
The mixed modes (=y/=m) also mean that several variables and structs have to be declared in all cases.
Suggested-by: Arnd Bergmann arnd@arndb.de Suggested-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com Link: lore.kernel.org/r/202204032138.EFT9qGEd-lkp@intel.com Cc: Geert Uytterhoeven geert@linux-m68k.org Cc: Jaroslav Kysela perex@perex.cz Cc: Takashi Iwai tiwai@suse.com Cc: alsa-devel@alsa-project.org Link: https://lore.kernel.org/r/20220405234118.24830-1-rdunlap@infradead.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/oss/dmasound/dmasound.h | 6 ------ sound/oss/dmasound/dmasound_core.c | 24 +----------------------- 2 files changed, 1 insertion(+), 29 deletions(-)
--- a/sound/oss/dmasound/dmasound.h +++ b/sound/oss/dmasound/dmasound.h @@ -88,11 +88,7 @@ static inline int ioctl_return(int __use */
extern int dmasound_init(void); -#ifdef MODULE extern void dmasound_deinit(void); -#else -#define dmasound_deinit() do { } while (0) -#endif
/* description of the set-up applies to either hard or soft settings */
@@ -114,9 +110,7 @@ typedef struct { void *(*dma_alloc)(unsigned int, gfp_t); void (*dma_free)(void *, unsigned int); int (*irqinit)(void); -#ifdef MODULE void (*irqcleanup)(void); -#endif void (*init)(void); void (*silence)(void); int (*setFormat)(int); --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -206,12 +206,10 @@ module_param(writeBufSize, int, 0);
MODULE_LICENSE("GPL");
-#ifdef MODULE static int sq_unit = -1; static int mixer_unit = -1; static int state_unit = -1; static int irq_installed; -#endif /* MODULE */
/* control over who can modify resources shared between play/record */ static fmode_t shared_resource_owner; @@ -391,9 +389,6 @@ static const struct file_operations mixe
static void mixer_init(void) { -#ifndef MODULE - int mixer_unit; -#endif mixer_unit = register_sound_mixer(&mixer_fops, -1); if (mixer_unit < 0) return; @@ -1176,9 +1171,6 @@ static const struct file_operations sq_f static int sq_init(void) { const struct file_operations *fops = &sq_fops; -#ifndef MODULE - int sq_unit; -#endif
sq_unit = register_sound_dsp(fops, -1); if (sq_unit < 0) { @@ -1380,9 +1372,6 @@ static const struct file_operations stat
static int state_init(void) { -#ifndef MODULE - int state_unit; -#endif state_unit = register_sound_special(&state_fops, SND_DEV_STATUS); if (state_unit < 0) return state_unit ; @@ -1400,10 +1389,9 @@ static int state_init(void) int dmasound_init(void) { int res ; -#ifdef MODULE + if (irq_installed) return -EBUSY; -#endif
/* Set up sound queue, /dev/audio and /dev/dsp. */
@@ -1422,9 +1410,7 @@ int dmasound_init(void) printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n"); return -ENODEV; } -#ifdef MODULE irq_installed = 1; -#endif
printk(KERN_INFO "%s DMA sound driver rev %03d installed\n", dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) + @@ -1438,8 +1424,6 @@ int dmasound_init(void) return 0; }
-#ifdef MODULE - void dmasound_deinit(void) { if (irq_installed) { @@ -1458,8 +1442,6 @@ void dmasound_deinit(void) unregister_sound_dsp(sq_unit); }
-#else /* !MODULE */ - static int dmasound_setup(char *str) { int ints[6], size; @@ -1503,8 +1485,6 @@ static int dmasound_setup(char *str)
__setup("dmasound=", dmasound_setup);
-#endif /* !MODULE */ - /* * Conversion tables */ @@ -1591,9 +1571,7 @@ char dmasound_alaw2dma8[] = {
EXPORT_SYMBOL(dmasound); EXPORT_SYMBOL(dmasound_init); -#ifdef MODULE EXPORT_SYMBOL(dmasound_deinit); -#endif EXPORT_SYMBOL(dmasound_write_sq); EXPORT_SYMBOL(dmasound_catchRadius); #ifdef HAS_8BIT_TABLES
From: Helge Deller deller@gmx.de
commit 6e3220ba3323a2c24be834aebf5d6e9f89d0993f upstream.
Fix the argument pointer (ap) to point to real-mode memory instead of virtual memory.
It's interesting that this issue hasn't shown up earlier, as this could have happened with any 64-bit PDC ROM code.
I just noticed it because I suddenly faced a HPMC while trying to execute the 64-bit STI ROM code of an Visualize-FXe graphics card for the STI text console.
Signed-off-by: Helge Deller deller@gmx.de Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/kernel/real2.S | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/arch/parisc/kernel/real2.S +++ b/arch/parisc/kernel/real2.S @@ -248,9 +248,6 @@ ENTRY_CFI(real64_call_asm) /* save fn */ copy %arg2, %r31
- /* set up the new ap */ - ldo 64(%arg1), %r29 - /* load up the arg registers from the saved arg area */ /* 32-bit calling convention passes first 4 args in registers */ ldd 0*REG_SZ(%arg1), %arg0 /* note overwriting arg0 */ @@ -262,7 +259,9 @@ ENTRY_CFI(real64_call_asm) ldd 7*REG_SZ(%arg1), %r19 ldd 1*REG_SZ(%arg1), %arg1 /* do this one last! */
+ /* set up real-mode stack and real-mode ap */ tophys_r1 %sp + ldo -16(%sp), %r29 /* Reference param save area */
b,l rfi_virt2real,%r2 nop
From: Ryusuke Konishi konishi.ryusuke@gmail.com
commit 28a65b49eb53e172d23567005465019658bfdb4d upstream.
According to syzbot's report, mark_buffer_dirty() called from nilfs_segctor_do_construct() outputs a warning with some patterns after nilfs2 detects metadata corruption and degrades to read-only mode.
After such read-only degeneration, page cache data may be cleared through nilfs_clear_dirty_page() which may also clear the uptodate flag for their buffer heads. However, even after the degeneration, log writes are still performed by unmount processing etc., which causes mark_buffer_dirty() to be called for buffer heads without the "uptodate" flag and causes the warning.
Since any writes should not be done to a read-only file system in the first place, this fixes the warning in mark_buffer_dirty() by letting nilfs_segctor_do_construct() abort early if in read-only mode.
This also changes the retry check of nilfs_segctor_write_out() to avoid unnecessary log write retries if it detects -EROFS that nilfs_segctor_do_construct() returned.
Link: https://lkml.kernel.org/r/20230427011526.13457-1-konishi.ryusuke@gmail.com Signed-off-by: Ryusuke Konishi konishi.ryusuke@gmail.com Tested-by: Ryusuke Konishi konishi.ryusuke@gmail.com Reported-by: syzbot+2af3bc9585be7f23f290@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=2af3bc9585be7f23f290 Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/nilfs2/segment.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -2044,6 +2044,9 @@ static int nilfs_segctor_do_construct(st struct the_nilfs *nilfs = sci->sc_super->s_fs_info; int err;
+ if (sb_rdonly(sci->sc_super)) + return -EROFS; + nilfs_sc_cstage_set(sci, NILFS_ST_INIT); sci->sc_cno = nilfs->ns_cno;
@@ -2729,7 +2732,7 @@ static void nilfs_segctor_write_out(stru
flush_work(&sci->sc_iput_work);
- } while (ret && retrycount-- > 0); + } while (ret && ret != -EROFS && retrycount-- > 0); }
/**
From: Ryusuke Konishi konishi.ryusuke@gmail.com
commit a6a491c048882e7e424d407d32cba0b52d9ef2bf upstream.
If the disk image that nilfs2 mounts is corrupted and a virtual block address obtained by block lookup for a metadata file is invalid, nilfs_bmap_lookup_at_level() may return the same internal return code as -ENOENT, meaning the block does not exist in the metadata file.
This duplication of return codes confuses nilfs_mdt_get_block(), causing it to read and create a metadata block indefinitely.
In particular, if this happens to the inode metadata file, ifile, semaphore i_rwsem can be left held, causing task hangs in lock_mount.
Fix this issue by making nilfs_bmap_lookup_at_level() treat virtual block address translation failures with -ENOENT as metadata corruption instead of returning the error code.
Link: https://lkml.kernel.org/r/20230430193046.6769-1-konishi.ryusuke@gmail.com Signed-off-by: Ryusuke Konishi konishi.ryusuke@gmail.com Tested-by: Ryusuke Konishi konishi.ryusuke@gmail.com Reported-by: syzbot+221d75710bde87fa0e97@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=221d75710bde87fa0e97 Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/nilfs2/bmap.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
--- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c @@ -67,20 +67,28 @@ int nilfs_bmap_lookup_at_level(struct ni
down_read(&bmap->b_sem); ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp); - if (ret < 0) { - ret = nilfs_bmap_convert_error(bmap, __func__, ret); + if (ret < 0) goto out; - } + if (NILFS_BMAP_USE_VBN(bmap)) { ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp, &blocknr); if (!ret) *ptrp = blocknr; + else if (ret == -ENOENT) { + /* + * If there was no valid entry in DAT for the block + * address obtained by b_ops->bop_lookup, then pass + * internal code -EINVAL to nilfs_bmap_convert_error + * to treat it as metadata corruption. + */ + ret = -EINVAL; + } }
out: up_read(&bmap->b_sem); - return ret; + return nilfs_bmap_convert_error(bmap, __func__, ret); }
int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp,
From: Li Nan linan122@huawei.com
commit a405c6f0229526160aa3f177f65e20c86fce84c5 upstream.
init_resync() inits mempool and sets conf->have_replacemnt at the beginning of sync, close_sync() frees the mempool when sync is completed.
After [1] recovery might be skipped and init_resync() is called but close_sync() is not. null-ptr-deref occurs with r10bio->dev[i].repl_bio.
The following is one way to reproduce the issue.
1) create a array, wait for resync to complete, mddev->recovery_cp is set to MaxSector. 2) recovery is woken and it is skipped. conf->have_replacement is set to 0 in init_resync(). close_sync() not called. 3) some io errors and rdev A is set to WantReplacement. 4) a new device is added and set to A's replacement. 5) recovery is woken, A have replacement, but conf->have_replacemnt is 0. r10bio->dev[i].repl_bio will not be alloced and null-ptr-deref occurs.
Fix it by not calling init_resync() if recovery skipped.
[1] commit 7e83ccbecd60 ("md/raid10: Allow skipping recovery when clean arrays are assembled") Fixes: 7e83ccbecd60 ("md/raid10: Allow skipping recovery when clean arrays are assembled") Cc: stable@vger.kernel.org Signed-off-by: Li Nan linan122@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230222041000.3341651-3-linan666@huaweicloud.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/raid10.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2900,10 +2900,6 @@ static sector_t raid10_sync_request(stru sector_t chunk_mask = conf->geo.chunk_mask; int page_idx = 0;
- if (!mempool_initialized(&conf->r10buf_pool)) - if (init_resync(conf)) - return 0; - /* * Allow skipping a full rebuild for incremental assembly * of a clean array, like RAID1 does. @@ -2919,6 +2915,10 @@ static sector_t raid10_sync_request(stru return mddev->dev_sectors - sector_nr; }
+ if (!mempool_initialized(&conf->r10buf_pool)) + if (init_resync(conf)) + return 0; + skipped: max_sector = mddev->dev_sectors; if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ||
From: Tanmay Shah tanmay.shah@amd.com
commit 74ad37a30ffee3643bc34f9ca7225b20a66abaaf upstream.
Multiple IPI channels are mapped to same interrupt handler. Current isr implementation handles only one channel per isr. Fix this behavior by checking isr status bit of all child mailbox nodes.
Fixes: 4981b82ba2ff ("mailbox: ZynqMP IPI mailbox controller") Signed-off-by: Tanmay Shah tanmay.shah@amd.com Acked-by: Michal Simek michal.simek@amd.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230311012407.1292118-3-tanmay.shah@amd.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mailbox/zynqmp-ipi-mailbox.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/mailbox/zynqmp-ipi-mailbox.c +++ b/drivers/mailbox/zynqmp-ipi-mailbox.c @@ -152,7 +152,7 @@ static irqreturn_t zynqmp_ipi_interrupt( struct zynqmp_ipi_message *msg; u64 arg0, arg3; struct arm_smccc_res res; - int ret, i; + int ret, i, status = IRQ_NONE;
(void)irq; arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY; @@ -170,11 +170,11 @@ static irqreturn_t zynqmp_ipi_interrupt( memcpy_fromio(msg->data, mchan->req_buf, msg->len); mbox_chan_received_data(chan, (void *)msg); - return IRQ_HANDLED; + status = IRQ_HANDLED; } } } - return IRQ_NONE; + return status; }
/**
From: Tanmay Shah tanmay.shah@amd.com
commit 79963fbfc233759bd8a43462f120d15a1bd4f4fa upstream.
Xilinx IPI message buffers allows 32-byte data transfer. Fix documentation that says 12 bytes
Fixes: 4981b82ba2ff ("mailbox: ZynqMP IPI mailbox controller") Signed-off-by: Tanmay Shah tanmay.shah@amd.com Acked-by: Michal Simek michal.simek@amd.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230311012407.1292118-4-tanmay.shah@amd.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/mailbox/zynqmp-ipi-message.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/include/linux/mailbox/zynqmp-ipi-message.h +++ b/include/linux/mailbox/zynqmp-ipi-message.h @@ -9,7 +9,7 @@ * @data: message payload * * This is the structure for data used in mbox_send_message - * the maximum length of data buffer is fixed to 12 bytes. + * the maximum length of data buffer is fixed to 32 bytes. * Client is supposed to be aware of this. */ struct zynqmp_ipi_message {
From: Bitterblue Smith rtl8821cerfe2@gmail.com
commit d46e04ccd40457a0119b76e11ab64a2ad403e138 upstream.
Always run the entire init sequence (rtl8xxxu_init_device()) for RTL8192EU. It's what the vendor driver does too.
This fixes a bug where the device is unable to connect after rebooting:
wlp3s0f3u2: send auth to ... (try 1/3) wlp3s0f3u2: send auth to ... (try 2/3) wlp3s0f3u2: send auth to ... (try 3/3) wlp3s0f3u2: authentication with ... timed out
Rebooting leaves the device powered on (partially? at least the firmware is still running), but not really in a working state.
Cc: stable@vger.kernel.org Signed-off-by: Bitterblue Smith rtl8821cerfe2@gmail.com Acked-by: Jes Sorensen jes@trained-monkey.org Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/4eb111a9-d4c4-37d0-b376-4e202de7153c@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c @@ -1702,6 +1702,7 @@ struct rtl8xxxu_fileops rtl8192eu_fops = .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24), .has_s0s1 = 0, .gen2_thermal_meter = 1, + .needs_full_init = 1, .adda_1t_init = 0x0fc01616, .adda_1t_path_on = 0x0fc01616, .adda_2t_path_on_a = 0x0fc01616,
From: Quentin Schulz quentin.schulz@theobroma-systems.com
commit 933bf364e152cd60902cf9585c2ba310d593e69f upstream.
clk_cifout is derived from clk_cifout_src through an integer divider limited to 32. clk_cifout_src is a child of either cpll, gpll or npll without any possibility of a divider of any sort. The default clock parent is cpll.
Let's allow clk_cifout to ask its parent clk_cifout_src to reparent in order to find the real closest possible rate for clk_cifout and not one derived from cpll only.
Cc: stable@vger.kernel.org # 4.10+ Fixes: fd8bc829336a ("clk: rockchip: fix the rk3399 cifout clock") Signed-off-by: Quentin Schulz quentin.schulz@theobroma-systems.com Link: https://lore.kernel.org/r/20221117-rk3399-cifout-set-rate-parent-v1-0-432548... Signed-off-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/clk/rockchip/clk-rk3399.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/clk/rockchip/clk-rk3399.c +++ b/drivers/clk/rockchip/clk-rk3399.c @@ -1261,7 +1261,7 @@ static struct rockchip_clk_branch rk3399 RK3399_CLKSEL_CON(56), 6, 2, MFLAGS, RK3399_CLKGATE_CON(10), 7, GFLAGS),
- COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, 0, + COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, CLK_SET_RATE_PARENT, RK3399_CLKSEL_CON(56), 5, 1, MFLAGS, 0, 5, DFLAGS),
/* gic */
From: Zqiang qiang1.zhang@intel.com
[ Upstream commit db7b464df9d820186e98a65aa6a10f0d51fbf8ce ]
This commit adds checks for the TICK_DEP_MASK_RCU_EXP bit, thus enabling RCU expedited grace periods to actually force-enable scheduling-clock interrupts on holdout CPUs.
Fixes: df1e849ae455 ("rcu: Enable tick for nohz_full CPUs slow to provide expedited QS") Signed-off-by: Zqiang qiang1.zhang@intel.com Cc: Steven Rostedt rostedt@goodmis.org Cc: Masami Hiramatsu mhiramat@kernel.org Cc: Frederic Weisbecker fweisbec@gmail.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Ingo Molnar mingo@kernel.org Cc: Anna-Maria Behnsen anna-maria@linutronix.de Acked-by: Frederic Weisbecker frederic@kernel.org Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Joel Fernandes (Google) joel@joelfernandes.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/trace/events/timer.h | 3 ++- kernel/time/tick-sched.c | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h index 19abb6c3eb73f..40e9b5a12732d 100644 --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h @@ -368,7 +368,8 @@ TRACE_EVENT(itimer_expire, tick_dep_name(PERF_EVENTS) \ tick_dep_name(SCHED) \ tick_dep_name(CLOCK_UNSTABLE) \ - tick_dep_name_end(RCU) + tick_dep_name(RCU) \ + tick_dep_name_end(RCU_EXP)
#undef tick_dep_name #undef tick_dep_mask_name diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index e4e0d032126bc..378096fc8c560 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -213,6 +213,11 @@ static bool check_tick_dependency(atomic_t *dep) return true; }
+ if (val & TICK_DEP_MASK_RCU_EXP) { + trace_tick_stop(0, TICK_DEP_MASK_RCU_EXP); + return true; + } + return false; }
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
[ Upstream commit 22a8be280383812235131dda18a8212a59fadd2d ]
malloc_and_init_memory() in fill_buf isn't checking if memalign() successfully allocated memory or not before accessing the memory.
Check the return value of memalign() and return NULL if allocating aligned memory fails.
Fixes: a2561b12fe39 ("selftests/resctrl: Add built in benchmark") Co-developed-by: Fenghua Yu fenghua.yu@intel.com Signed-off-by: Fenghua Yu fenghua.yu@intel.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Reviewed-by: Reinette Chatre reinette.chatre@intel.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/resctrl/fill_buf.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/tools/testing/selftests/resctrl/fill_buf.c b/tools/testing/selftests/resctrl/fill_buf.c index 56ccbeae0638d..c20d0a7ecbe63 100644 --- a/tools/testing/selftests/resctrl/fill_buf.c +++ b/tools/testing/selftests/resctrl/fill_buf.c @@ -68,6 +68,8 @@ static void *malloc_and_init_memory(size_t s) size_t s64;
void *p = memalign(PAGE_SIZE, s); + if (!p) + return NULL;
p64 = (uint64_t *)p; s64 = s / sizeof(uint64_t);
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
[ Upstream commit 0d45c83b95da414e98ad333e723141a94f6e2c64 ]
MBA test case writes schemata but it does not check if the write is successful or not.
Add the error check and return error properly.
Fixes: 01fee6b4d1f9 ("selftests/resctrl: Add MBA test") Co-developed-by: Fenghua Yu fenghua.yu@intel.com Signed-off-by: Fenghua Yu fenghua.yu@intel.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Reviewed-by: Reinette Chatre reinette.chatre@intel.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/resctrl/mba_test.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c index 6449fbd96096a..6cfddd1d43558 100644 --- a/tools/testing/selftests/resctrl/mba_test.c +++ b/tools/testing/selftests/resctrl/mba_test.c @@ -28,6 +28,7 @@ static int mba_setup(int num, ...) struct resctrl_val_param *p; char allocation_str[64]; va_list param; + int ret;
va_start(param, num); p = va_arg(param, struct resctrl_val_param *); @@ -45,7 +46,11 @@ static int mba_setup(int num, ...)
sprintf(allocation_str, "%d", allocation);
- write_schemata(p->ctrlgrp, allocation_str, p->cpu_no, p->resctrl_val); + ret = write_schemata(p->ctrlgrp, allocation_str, p->cpu_no, + p->resctrl_val); + if (ret < 0) + return ret; + allocation -= ALLOCATION_STEP;
return 0;
From: Ondrej Mosnacek omosnace@redhat.com
[ Upstream commit bcab1adeaad4b39a1e04cb98979a367d08253f03 ]
Make the flask.h target depend on the genheaders binary instead of classmap.h to ensure that it is rebuilt if any of the dependencies of genheaders are changed.
Notably this fixes flask.h not being rebuilt when initial_sid_to_string.h is modified.
Fixes: 8753f6bec352 ("selinux: generate flask headers during kernel build") Signed-off-by: Ondrej Mosnacek omosnace@redhat.com Acked-by: Stephen Smalley stephen.smalley.work@gmail.com Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/selinux/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/security/selinux/Makefile b/security/selinux/Makefile index 4d8e0e8adf0b1..47e4aba3a868d 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -21,8 +21,8 @@ ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include $(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h
quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h - cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h + cmd_flask = $< $(obj)/flask.h $(obj)/av_permissions.h
targets += flask.h av_permissions.h -$(obj)/flask.h: $(src)/include/classmap.h FORCE +$(obj)/flask.h: scripts/selinux/genheaders/genheaders FORCE $(call if_changed,flask)
From: Paul Moore paul@paul-moore.com
[ Upstream commit 4ce1f694eb5d8ca607fed8542d32a33b4f1217a5 ]
The Makefile rule responsible for building flask.h and av_permissions.h only lists flask.h as a target which means that av_permissions.h is only generated when flask.h needs to be generated. This patch fixes this by adding av_permissions.h as a target to the rule.
Fixes: 8753f6bec352 ("selinux: generate flask headers during kernel build") Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/selinux/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/selinux/Makefile b/security/selinux/Makefile index 47e4aba3a868d..ee1ddda964478 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -24,5 +24,5 @@ quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h cmd_flask = $< $(obj)/flask.h $(obj)/av_permissions.h
targets += flask.h av_permissions.h -$(obj)/flask.h: scripts/selinux/genheaders/genheaders FORCE +$(obj)/flask.h $(obj)/av_permissions.h &: scripts/selinux/genheaders/genheaders FORCE $(call if_changed,flask)
From: Lino Sanfilippo l.sanfilippo@kunbus.com
[ Upstream commit ed9be0e6c892a783800d77a41ca4c7255c6af8c5 ]
If in tpm_tis_probe_irq_single() an error occurs after the original interrupt vector has been read, restore the interrupts before the error is returned.
Since the caller does not check the error value, return -1 in any case that the TPM_CHIP_FLAG_IRQ flag is not set. Since the return value of function tpm_tis_gen_interrupt() is not longer used, make it a void function.
Fixes: 1107d065fdf1 ("tpm_tis: Introduce intermediate layer for TPM access") Signed-off-by: Lino Sanfilippo l.sanfilippo@kunbus.com Tested-by: Jarkko Sakkinen jarkko@kernel.org Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/tpm/tpm_tis_core.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index dc56b976d8162..ae0c773a6041a 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -714,7 +714,7 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id) return IRQ_HANDLED; }
-static int tpm_tis_gen_interrupt(struct tpm_chip *chip) +static void tpm_tis_gen_interrupt(struct tpm_chip *chip) { const char *desc = "attempting to generate an interrupt"; u32 cap2; @@ -723,7 +723,7 @@ static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
ret = request_locality(chip, 0); if (ret < 0) - return ret; + return;
if (chip->flags & TPM_CHIP_FLAG_TPM2) ret = tpm2_get_tpm_pt(chip, 0x100, &cap2, desc); @@ -731,8 +731,6 @@ static int tpm_tis_gen_interrupt(struct tpm_chip *chip) ret = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, 0);
release_locality(chip, 0); - - return ret; }
/* Register the IRQ and issue a command that will cause an interrupt. If an @@ -762,42 +760,37 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,
rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), irq); if (rc < 0) - return rc; + goto restore_irqs;
rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status); if (rc < 0) - return rc; + goto restore_irqs;
/* Clear all existing */ rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status); if (rc < 0) - return rc; - + goto restore_irqs; /* Turn on */ rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask | TPM_GLOBAL_INT_ENABLE); if (rc < 0) - return rc; + goto restore_irqs;
priv->irq_tested = false;
/* Generate an interrupt by having the core call through to * tpm_tis_send */ - rc = tpm_tis_gen_interrupt(chip); - if (rc < 0) - return rc; + tpm_tis_gen_interrupt(chip);
+restore_irqs: /* tpm_tis_send will either confirm the interrupt is working or it * will call disable_irq which undoes all of the above. */ if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) { - rc = tpm_tis_write8(priv, original_int_vec, - TPM_INT_VECTOR(priv->locality)); - if (rc < 0) - return rc; - - return 1; + tpm_tis_write8(priv, original_int_vec, + TPM_INT_VECTOR(priv->locality)); + return -1; }
return 0;
From: Lino Sanfilippo l.sanfilippo@kunbus.com
[ Upstream commit 282657a8bd7fddcf511b834f43705001668b33a7 ]
In disable_interrupts() the TPM_GLOBAL_INT_ENABLE bit is unset in the TPM_INT_ENABLE register to shut the interrupts off. However modifying the register is only possible with a held locality. So claim the locality before disable_interrupts() is called.
Signed-off-by: Lino Sanfilippo l.sanfilippo@kunbus.com Tested-by: Michael Niewöhner linux@mniewoehner.de Tested-by: Jarkko Sakkinen jarkko@kernel.org Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Stable-dep-of: 955df4f87760 ("tpm, tpm_tis: Claim locality when interrupts are reenabled on resume") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/tpm/tpm_tis_core.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index ae0c773a6041a..274096fece3fa 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -1076,7 +1076,11 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, dev_err(&chip->dev, FW_BUG "TPM interrupt not working, polling instead\n");
+ rc = request_locality(chip, 0); + if (rc < 0) + goto out_err; disable_interrupts(chip); + release_locality(chip, 0); } } else { tpm_tis_probe_irq(chip, intmask);
From: Lino Sanfilippo l.sanfilippo@kunbus.com
[ Upstream commit 6d789ad726950e612a7f31044260337237c5b490 ]
Both functions tpm_tis_probe_irq_single() and tpm_tis_probe_irq() may setup the interrupts and then return with an error. This case is indicated by a missing TPM_CHIP_FLAG_IRQ flag in chip->flags. Currently the interrupt setup is only undone if tpm_tis_probe_irq_single() fails. Undo the setup also if tpm_tis_probe_irq() fails.
Signed-off-by: Lino Sanfilippo l.sanfilippo@kunbus.com Tested-by: Michael Niewöhner linux@mniewoehner.de Tested-by: Jarkko Sakkinen jarkko@kernel.org Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Stable-dep-of: 955df4f87760 ("tpm, tpm_tis: Claim locality when interrupts are reenabled on resume") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/tpm/tpm_tis_core.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 274096fece3fa..99cbf6fb062ce 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -1069,21 +1069,21 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, goto out_err; }
- if (irq) { + if (irq) tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED, irq); - if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) { - dev_err(&chip->dev, FW_BUG + else + tpm_tis_probe_irq(chip, intmask); + + if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) { + dev_err(&chip->dev, FW_BUG "TPM interrupt not working, polling instead\n");
- rc = request_locality(chip, 0); - if (rc < 0) - goto out_err; - disable_interrupts(chip); - release_locality(chip, 0); - } - } else { - tpm_tis_probe_irq(chip, intmask); + rc = request_locality(chip, 0); + if (rc < 0) + goto out_err; + disable_interrupts(chip); + release_locality(chip, 0); } }
From: Lino Sanfilippo l.sanfilippo@kunbus.com
[ Upstream commit 15d7aa4e46eba87242a320f39773aa16faddadee ]
In tpm_tis_probe_single_irq() interrupt registers TPM_INT_VECTOR, TPM_INT_STATUS and TPM_INT_ENABLE are modified to setup the interrupts. Currently these modifications are done without holding a locality thus they have no effect. Fix this by claiming the (default) locality before the registers are written.
Since now tpm_tis_gen_interrupt() is called with the locality already claimed remove locality request and release from this function.
Signed-off-by: Lino Sanfilippo l.sanfilippo@kunbus.com Tested-by: Jarkko Sakkinen jarkko@kernel.org Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Stable-dep-of: 955df4f87760 ("tpm, tpm_tis: Claim locality when interrupts are reenabled on resume") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/tpm/tpm_tis_core.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 99cbf6fb062ce..52826a7edf800 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -721,16 +721,10 @@ static void tpm_tis_gen_interrupt(struct tpm_chip *chip) cap_t cap; int ret;
- ret = request_locality(chip, 0); - if (ret < 0) - return; - if (chip->flags & TPM_CHIP_FLAG_TPM2) ret = tpm2_get_tpm_pt(chip, 0x100, &cap2, desc); else ret = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, 0); - - release_locality(chip, 0); }
/* Register the IRQ and issue a command that will cause an interrupt. If an @@ -753,10 +747,16 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, } priv->irq = irq;
+ rc = request_locality(chip, 0); + if (rc < 0) + return rc; + rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality), &original_int_vec); - if (rc < 0) + if (rc < 0) { + release_locality(chip, priv->locality); return rc; + }
rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), irq); if (rc < 0) @@ -790,10 +790,12 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) { tpm_tis_write8(priv, original_int_vec, TPM_INT_VECTOR(priv->locality)); - return -1; + rc = -1; }
- return 0; + release_locality(chip, priv->locality); + + return rc; }
/* Try to find the IRQ the TPM is using. This is for legacy x86 systems that
From: Lino Sanfilippo l.sanfilippo@kunbus.com
[ Upstream commit 7a2f55d0be296c4e81fd782f3d6c43ed4ec7e265 ]
Implement a usage counter for the (default) locality used by the TPM TIS driver: Request the locality from the TPM if it has not been claimed yet, otherwise only increment the counter. Also release the locality if the counter is 0 otherwise only decrement the counter. Since in case of SPI the register accesses are locked by means of the SPI bus mutex use a sleepable lock (i.e. also a mutex) to ensure thread-safety of the counter which may be accessed by both a userspace thread and the interrupt handler.
By doing this refactor the names of the amended functions to use a more appropriate prefix.
Signed-off-by: Lino Sanfilippo l.sanfilippo@kunbus.com Tested-by: Michael Niewöhner linux@mniewoehner.de Tested-by: Jarkko Sakkinen jarkko@kernel.org Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Stable-dep-of: 955df4f87760 ("tpm, tpm_tis: Claim locality when interrupts are reenabled on resume") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/tpm/tpm_tis_core.c | 63 +++++++++++++++++++++++---------- drivers/char/tpm/tpm_tis_core.h | 2 ++ 2 files changed, 47 insertions(+), 18 deletions(-)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 52826a7edf800..3ea0fff30273e 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -136,16 +136,27 @@ static bool check_locality(struct tpm_chip *chip, int l) return false; }
-static int release_locality(struct tpm_chip *chip, int l) +static int __tpm_tis_relinquish_locality(struct tpm_tis_data *priv, int l) +{ + tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY); + + return 0; +} + +static int tpm_tis_relinquish_locality(struct tpm_chip *chip, int l) { struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
- tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY); + mutex_lock(&priv->locality_count_mutex); + priv->locality_count--; + if (priv->locality_count == 0) + __tpm_tis_relinquish_locality(priv, l); + mutex_unlock(&priv->locality_count_mutex);
return 0; }
-static int request_locality(struct tpm_chip *chip, int l) +static int __tpm_tis_request_locality(struct tpm_chip *chip, int l) { struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); unsigned long stop, timeout; @@ -186,6 +197,20 @@ static int request_locality(struct tpm_chip *chip, int l) return -1; }
+static int tpm_tis_request_locality(struct tpm_chip *chip, int l) +{ + struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); + int ret = 0; + + mutex_lock(&priv->locality_count_mutex); + if (priv->locality_count == 0) + ret = __tpm_tis_request_locality(chip, l); + if (!ret) + priv->locality_count++; + mutex_unlock(&priv->locality_count_mutex); + return ret; +} + static u8 tpm_tis_status(struct tpm_chip *chip) { struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); @@ -638,7 +663,7 @@ static int probe_itpm(struct tpm_chip *chip) if (vendor != TPM_VID_INTEL) return 0;
- if (request_locality(chip, 0) != 0) + if (tpm_tis_request_locality(chip, 0) != 0) return -EBUSY;
rc = tpm_tis_send_data(chip, cmd_getticks, len); @@ -659,7 +684,7 @@ static int probe_itpm(struct tpm_chip *chip)
out: tpm_tis_ready(chip); - release_locality(chip, priv->locality); + tpm_tis_relinquish_locality(chip, priv->locality);
return rc; } @@ -747,14 +772,14 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, } priv->irq = irq;
- rc = request_locality(chip, 0); + rc = tpm_tis_request_locality(chip, 0); if (rc < 0) return rc;
rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality), &original_int_vec); if (rc < 0) { - release_locality(chip, priv->locality); + tpm_tis_relinquish_locality(chip, priv->locality); return rc; }
@@ -793,7 +818,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, rc = -1; }
- release_locality(chip, priv->locality); + tpm_tis_relinquish_locality(chip, priv->locality);
return rc; } @@ -909,8 +934,8 @@ static const struct tpm_class_ops tpm_tis = { .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, .req_canceled = tpm_tis_req_canceled, - .request_locality = request_locality, - .relinquish_locality = release_locality, + .request_locality = tpm_tis_request_locality, + .relinquish_locality = tpm_tis_relinquish_locality, .clk_enable = tpm_tis_clkrun_enable, };
@@ -944,6 +969,8 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, priv->timeout_min = TPM_TIMEOUT_USECS_MIN; priv->timeout_max = TPM_TIMEOUT_USECS_MAX; priv->phy_ops = phy_ops; + priv->locality_count = 0; + mutex_init(&priv->locality_count_mutex);
dev_set_drvdata(&chip->dev, priv);
@@ -990,14 +1017,14 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; intmask &= ~TPM_GLOBAL_INT_ENABLE;
- rc = request_locality(chip, 0); + rc = tpm_tis_request_locality(chip, 0); if (rc < 0) { rc = -ENODEV; goto out_err; }
tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); - release_locality(chip, 0); + tpm_tis_relinquish_locality(chip, 0);
rc = tpm_chip_start(chip); if (rc) @@ -1057,13 +1084,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, * proper timeouts for the driver. */
- rc = request_locality(chip, 0); + rc = tpm_tis_request_locality(chip, 0); if (rc < 0) goto out_err;
rc = tpm_get_timeouts(chip);
- release_locality(chip, 0); + tpm_tis_relinquish_locality(chip, 0);
if (rc) { dev_err(dev, "Could not get TPM timeouts and durations\n"); @@ -1081,11 +1108,11 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, dev_err(&chip->dev, FW_BUG "TPM interrupt not working, polling instead\n");
- rc = request_locality(chip, 0); + rc = tpm_tis_request_locality(chip, 0); if (rc < 0) goto out_err; disable_interrupts(chip); - release_locality(chip, 0); + tpm_tis_relinquish_locality(chip, 0); } }
@@ -1158,13 +1185,13 @@ int tpm_tis_resume(struct device *dev) * an error code but for unknown reason it isn't handled. */ if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { - ret = request_locality(chip, 0); + ret = tpm_tis_request_locality(chip, 0); if (ret < 0) return ret;
tpm1_do_selftest(chip);
- release_locality(chip, 0); + tpm_tis_relinquish_locality(chip, 0); }
return 0; diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index 3be24f221e32a..464ed352ab2e8 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h @@ -90,6 +90,8 @@ enum tpm_tis_flags {
struct tpm_tis_data { u16 manufacturer_id; + struct mutex locality_count_mutex; + unsigned int locality_count; int locality; int irq; bool irq_tested;
From: Lino Sanfilippo l.sanfilippo@kunbus.com
[ Upstream commit 955df4f87760b3bb2af253d3fbb12fb712b3ffa6 ]
In tpm_tis_resume() make sure that the locality has been claimed when tpm_tis_reenable_interrupts() is called. Otherwise the writings to the register might not have any effect.
Fixes: 45baa1d1fa39 ("tpm_tis: Re-enable interrupts upon (S3) resume") Signed-off-by: Lino Sanfilippo l.sanfilippo@kunbus.com Tested-by: Jarkko Sakkinen jarkko@kernel.org Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/tpm/tpm_tis_core.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 3ea0fff30273e..d65fff4e2ebe9 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -1173,28 +1173,27 @@ int tpm_tis_resume(struct device *dev) struct tpm_chip *chip = dev_get_drvdata(dev); int ret;
+ ret = tpm_tis_request_locality(chip, 0); + if (ret < 0) + return ret; + if (chip->flags & TPM_CHIP_FLAG_IRQ) tpm_tis_reenable_interrupts(chip);
ret = tpm_pm_resume(dev); if (ret) - return ret; + goto out;
/* * TPM 1.2 requires self-test on resume. This function actually returns * an error code but for unknown reason it isn't handled. */ - if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { - ret = tpm_tis_request_locality(chip, 0); - if (ret < 0) - return ret; - + if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) tpm1_do_selftest(chip); +out: + tpm_tis_relinquish_locality(chip, 0);
- tpm_tis_relinquish_locality(chip, 0); - } - - return 0; + return ret; } EXPORT_SYMBOL_GPL(tpm_tis_resume); #endif
From: Gao Xiang hsiangkao@linux.alibaba.com
[ Upstream commit cc4efd3dd2ac9f89143e5d881609747ecff04164 ]
Syzbot generated a crafted image [1] with a non-compact HEAD index of clusterofs 33024 while valid numbers should be 0 ~ lclustersize-1, which causes the following unexpected behavior as below:
BUG: unable to handle page fault for address: fffff52101a3fff9 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 23ffed067 P4D 23ffed067 PUD 0 Oops: 0000 [#1] PREEMPT SMP KASAN CPU: 1 PID: 4398 Comm: kworker/u5:1 Not tainted 6.3.0-rc6-syzkaller-g09a9639e56c0 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/30/2023 Workqueue: erofs_worker z_erofs_decompressqueue_work RIP: 0010:z_erofs_decompress_queue+0xb7e/0x2b40 ... Call Trace: <TASK> z_erofs_decompressqueue_work+0x99/0xe0 process_one_work+0x8f6/0x1170 worker_thread+0xa63/0x1210 kthread+0x270/0x300 ret_from_fork+0x1f/0x30
Note that normal images or images using compact indexes are not impacted. Let's fix this now.
[1] https://lore.kernel.org/r/000000000000ec75b005ee97fbaa@google.com
Reported-and-tested-by: syzbot+aafb3f37cfeb6534c4ac@syzkaller.appspotmail.com Fixes: 02827e1796b3 ("staging: erofs: add erofs_map_blocks_iter") Fixes: 152a333a5895 ("staging: erofs: add compacted compression indexes support") Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Reviewed-by: Chao Yu chao@kernel.org Link: https://lore.kernel.org/r/20230410173714.104604-1-hsiangkao@linux.alibaba.co... Signed-off-by: Sasha Levin sashal@kernel.org --- fs/erofs/zmap.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index 14d2de35110cc..f18194fd8d770 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -179,6 +179,10 @@ static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m, case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: case Z_EROFS_VLE_CLUSTER_TYPE_HEAD: m->clusterofs = le16_to_cpu(di->di_clusterofs); + if (m->clusterofs >= 1 << vi->z_logical_clusterbits) { + DBG_BUGON(1); + return -EFSCORRUPTED; + } m->pblk = le32_to_cpu(di->di_u.blkaddr); break; default:
From: Jingbo Xu jefflexu@linux.alibaba.com
[ Upstream commit 1b3567a1969b26f709d82a874498c0754ea841c3 ]
Given on-disk i_xattr_icount is 16 bits and xattr_isize is calculated from i_xattr_icount multiplying 4, xattr_isize has a theoretical maximum of 256K (64K * 4).
Thus declare xattr_isize as unsigned int to avoid the potential overflow.
Fixes: bfb8674dc044 ("staging: erofs: add erofs in-memory stuffs") Signed-off-by: Jingbo Xu jefflexu@linux.alibaba.com Reviewed-by: Gao Xiang hsiangkao@linux.alibaba.com Reviewed-by: Chao Yu chao@kernel.org Link: https://lore.kernel.org/r/20230414061810.6479-1-jefflexu@linux.alibaba.com Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/erofs/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 67a7ec9456866..ce52f708a403d 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -232,7 +232,7 @@ struct erofs_inode {
unsigned char datalayout; unsigned char inode_isize; - unsigned short xattr_isize; + unsigned int xattr_isize;
unsigned int xattr_shared_count; unsigned int *xattr_shared_xattrs;
From: Rob Clark robdclark@chromium.org
[ Upstream commit 8ee3b0e85f6ccd9e6c527bc50eaba774c3bb18d0 ]
In the error path, rockchip_drm_gem_object_mmap() is dropping an obj reference that it doesn't own.
Fixes: 41315b793e13 ("drm/rockchip: use drm_gem_mmap helpers") Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Heiko Stuebner heiko@sntech.de Link: https://patchwork.freedesktop.org/patch/msgid/20230119231734.2884543-1-robdc... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index 62e5d0970525e..22ff4a5929768 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -250,9 +250,6 @@ static int rockchip_drm_gem_object_mmap(struct drm_gem_object *obj, else ret = rockchip_drm_gem_object_mmap_dma(obj, vma);
- if (ret) - drm_gem_vm_close(vma); - return ret; }
From: Maíra Canal mcanal@igalia.com
[ Upstream commit 7c18189b14b33c1fbf76480b1bd217877c086e67 ]
vgem_fence_open() instantiates a mutex for a particular fence instance, but never destroys it by calling mutex_destroy() in vgem_fence_close().
So, add the missing mutex_destroy() to guarantee proper resource destruction.
Fixes: 407779848445 ("drm/vgem: Attach sw fences to exported vGEM dma-buf (ioctl)") Signed-off-by: Maíra Canal mcanal@igalia.com Reviewed-by: Stanislaw Gruszka stanislaw.gruszka@linux.intel.com Signed-off-by: Maíra Canal mairacanal@riseup.net Link: https://patchwork.freedesktop.org/patch/msgid/20230202125517.427976-1-mcanal... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vgem/vgem_fence.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c index 17f32f550dd99..575bc331716e8 100644 --- a/drivers/gpu/drm/vgem/vgem_fence.c +++ b/drivers/gpu/drm/vgem/vgem_fence.c @@ -249,4 +249,5 @@ void vgem_fence_close(struct vgem_file *vfile) { idr_for_each(&vfile->fence_idr, __vgem_fence_idr_fini, vfile); idr_destroy(&vfile->fence_idr); + mutex_destroy(&vfile->fence_mutex); }
From: Dom Cobley popcornmix@gmail.com
[ Upstream commit a8e47884f1906cd7440fafa056adc8817568e73e ]
Currently we schedule a call to output_poll_execute from drm_kms_helper_poll_enable for 10s in future. Later we try to replace that in drm_helper_probe_single_connector_modes with a 0s schedule with delayed_event set.
But as there is already a job in the queue this fails, and the immediate job we wanted with delayed_event set doesn't occur until 10s later.
And that call acts as if connector state has changed, reprobing modes. This has a side effect of waking up a display that has been blanked.
Make sure we cancel the old job before submitting the immediate one.
Fixes: 162b6a57ac50 ("drm/probe-helper: don't lose hotplug event") Acked-by: Daniel Vetter daniel@ffwll.ch Signed-off-by: Dom Cobley popcornmix@gmail.com [Maxime: Switched to mod_delayed_work] Signed-off-by: Maxime Ripard maxime@cerno.tech Link: https://patchwork.freedesktop.org/patch/msgid/20230127154052.452524-1-maxime... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_probe_helper.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index e5432dcf69996..d3f0d048594e7 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -488,8 +488,9 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, */ dev->mode_config.delayed_event = true; if (dev->mode_config.poll_enabled) - schedule_delayed_work(&dev->mode_config.output_poll_work, - 0); + mod_delayed_work(system_wq, + &dev->mode_config.output_poll_work, + 0); }
/* Re-enable polling in case the global poll config changed. */
From: Tony Lindgren tony@atomide.com
[ Upstream commit 74033131d2467fda6b76ba10bc80a75fb47e03d1 ]
To prepare for moving to use genpd, let's enable basic PM runtime support.
Cc: Dave Gerlach d-gerlach@ti.com Cc: Santosh Shilimkar ssantosh@kernel.org Cc: Suman Anna s-anna@ti.com Signed-off-by: Tony Lindgren tony@atomide.com Stable-dep-of: 8f3c307b580a ("soc: ti: pm33xx: Fix refcount leak in am33xx_pm_probe") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/ti/pm33xx.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/ti/pm33xx.c b/drivers/soc/ti/pm33xx.c index dc21aa855a458..332588de22f3f 100644 --- a/drivers/soc/ti/pm33xx.c +++ b/drivers/soc/ti/pm33xx.c @@ -19,6 +19,7 @@ #include <linux/of_address.h> #include <linux/platform_data/pm33xx.h> #include <linux/platform_device.h> +#include <linux/pm_runtime.h> #include <linux/rtc.h> #include <linux/rtc/rtc-omap.h> #include <linux/sizes.h> @@ -555,16 +556,26 @@ static int am33xx_pm_probe(struct platform_device *pdev) suspend_wfi_flags |= WFI_FLAG_WAKE_M3; #endif /* CONFIG_SUSPEND */
+ pm_runtime_enable(dev); + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + goto err_pm_runtime_disable; + } + ret = pm_ops->init(am33xx_do_sram_idle); if (ret) { dev_err(dev, "Unable to call core pm init!\n"); ret = -ENODEV; - goto err_put_wkup_m3_ipc; + goto err_pm_runtime_put; }
return 0;
-err_put_wkup_m3_ipc: +err_pm_runtime_put: + pm_runtime_put_sync(dev); +err_pm_runtime_disable: + pm_runtime_disable(dev); wkup_m3_ipc_put(m3_ipc); err_unsetup_rtc: iounmap(rtc_base_virt); @@ -577,6 +588,8 @@ static int am33xx_pm_probe(struct platform_device *pdev)
static int am33xx_pm_remove(struct platform_device *pdev) { + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); if (pm_ops->deinit) pm_ops->deinit(); suspend_set_ops(NULL);
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 8f3c307b580a4a6425896007325bddefc36e8d91 ]
wkup_m3_ipc_get() takes refcount, which should be freed by wkup_m3_ipc_put(). Add missing refcount release in the error paths.
Fixes: 5a99ae0092fe ("soc: ti: pm33xx: AM437X: Add rtc_only with ddr in self-refresh support") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20230106054022.947529-1-linmq006@gmail.com Signed-off-by: Nishanth Menon nm@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/ti/pm33xx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/ti/pm33xx.c b/drivers/soc/ti/pm33xx.c index 332588de22f3f..44ec0048911cd 100644 --- a/drivers/soc/ti/pm33xx.c +++ b/drivers/soc/ti/pm33xx.c @@ -529,7 +529,7 @@ static int am33xx_pm_probe(struct platform_device *pdev)
ret = am33xx_pm_alloc_sram(); if (ret) - return ret; + goto err_wkup_m3_ipc_put;
ret = am33xx_pm_rtc_setup(); if (ret) @@ -576,13 +576,14 @@ static int am33xx_pm_probe(struct platform_device *pdev) pm_runtime_put_sync(dev); err_pm_runtime_disable: pm_runtime_disable(dev); - wkup_m3_ipc_put(m3_ipc); err_unsetup_rtc: iounmap(rtc_base_virt); clk_put(rtc_fck); err_free_sram: am33xx_pm_free_sram(); pm33xx_dev = NULL; +err_wkup_m3_ipc_put: + wkup_m3_ipc_put(m3_ipc); return ret; }
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit fb76b0fae3ca880363214e1dcd6513ab8bd529e7 ]
According to the R-Car Series, 3rd Generation Hardware User’s Manual Rev. 2.30, the System CPU cores on R-Car E3 do not have their own power supply, but use the common internal power supply (typical 1.03V).
Hence remove the "opp-microvolt" properties from the Operating Performance Points table. They are optional, and unused, when none of the CPU nodes is tied to a regulator using the "cpu-supply" property.
Fixes: dd7188eb4ed128dc ("arm64: dts: renesas: r8a77990: Add OPPs table for cpu devices") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/9232578d9d395d529f64db3333a371e31327f459.167656085... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/renesas/r8a77990.dtsi | 3 --- 1 file changed, 3 deletions(-)
diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index 37159b9408e8a..e91d197a4c0b4 100644 --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi @@ -60,17 +60,14 @@ opp-shared; opp-800000000 { opp-hz = /bits/ 64 <800000000>; - opp-microvolt = <820000>; clock-latency-ns = <300000>; }; opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; - opp-microvolt = <820000>; clock-latency-ns = <300000>; }; opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; - opp-microvolt = <820000>; clock-latency-ns = <300000>; opp-suspend; };
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 554edc3e9239bb81e61be9f0f5dbbeb528a69e72 ]
According to the RZ/G Series, 2nd Generation Hardware User’s Manual Rev. 1.11, the System CPU cores on RZ/G2E do not have their own power supply, but use the common internal power supply (typical 1.03V).
Hence remove the "opp-microvolt" properties from the Operating Performance Points table. They are optional, and unused, when none of the CPU nodes is tied to a regulator using the "cpu-supply" property.
Fixes: 231d8908a66fa98f ("arm64: dts: renesas: r8a774c0: Add OPPs table for cpu devices") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/8348e18a011ded94e35919cd8e17c0be1f9acf2f.167656085... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/renesas/r8a774c0.dtsi | 3 --- 1 file changed, 3 deletions(-)
diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi index 4c7d7e8f8e289..c4a6dfae93aad 100644 --- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi @@ -49,17 +49,14 @@ opp-shared; opp-800000000 { opp-hz = /bits/ 64 <800000000>; - opp-microvolt = <820000>; clock-latency-ns = <300000>; }; opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; - opp-microvolt = <820000>; clock-latency-ns = <300000>; }; opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; - opp-microvolt = <820000>; clock-latency-ns = <300000>; opp-suspend; };
From: Vinod Polimera quic_vpolimer@quicinc.com
[ Upstream commit b6975693846b562c4d3e0e60cc884affc5bdac00 ]
According to KMS documentation, The driver must not release any shared resources if active is set to false but enable still true.
Fixes: ccc862b957c6 ("drm/msm/dpu: Fix reservation failures in modeset") Signed-off-by: Vinod Polimera quic_vpolimer@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/524726/ Link: https://lore.kernel.org/r/1677774797-31063-5-git-send-email-quic_vpolimer@qu... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index a0274fcfe9c9d..408fc6c8a6df8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -634,7 +634,7 @@ static int dpu_encoder_virt_atomic_check( if (drm_atomic_crtc_needs_modeset(crtc_state)) { dpu_rm_release(global_state, drm_enc);
- if (!crtc_state->active_changed || crtc_state->active) + if (!crtc_state->active_changed || crtc_state->enable) ret = dpu_rm_reserve(&dpu_kms->rm, global_state, drm_enc, crtc_state, topology); }
From: Qiuxu Zhuo qiuxu.zhuo@intel.com
[ Upstream commit 71b1e3ba3fed5a34c5fac6d3a15c2634b04c1eb7 ]
The current DRAM row address mapping arrays skx_{open,close}_row[] only support ranks with sizes up to 16G. Decoding a rank address to a DRAM row address for a 32G rank by using either one of the above arrays by the skx_edac driver, will result in an overflow on the array.
For a 32G rank, the most significant DRAM row address bit (the bit17) is mapped from the bit34 of the rank address. Add this new mapping item to both arrays to fix the overflow issue.
Fixes: 4ec656bdf43a ("EDAC, skx_edac: Add EDAC driver for Skylake") Reported-by: Feng Xu feng.f.xu@intel.com Tested-by: Feng Xu feng.f.xu@intel.com Signed-off-by: Qiuxu Zhuo qiuxu.zhuo@intel.com Signed-off-by: Tony Luck tony.luck@intel.com Link: https://lore.kernel.org/all/20230211011728.71764-1-qiuxu.zhuo@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/edac/skx_base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/edac/skx_base.c b/drivers/edac/skx_base.c index f887e31666510..ba3e83313938b 100644 --- a/drivers/edac/skx_base.c +++ b/drivers/edac/skx_base.c @@ -509,7 +509,7 @@ static bool skx_rir_decode(struct decoded_addr *res) }
static u8 skx_close_row[] = { - 15, 16, 17, 18, 20, 21, 22, 28, 10, 11, 12, 13, 29, 30, 31, 32, 33 + 15, 16, 17, 18, 20, 21, 22, 28, 10, 11, 12, 13, 29, 30, 31, 32, 33, 34 };
static u8 skx_close_column[] = { @@ -517,7 +517,7 @@ static u8 skx_close_column[] = { };
static u8 skx_open_row[] = { - 14, 15, 16, 20, 28, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33 + 14, 15, 16, 20, 28, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34 };
static u8 skx_open_column[] = {
From: Konrad Dybcio konrad.dybcio@linaro.org
[ Upstream commit b5d08f08377218b1d2ab4026e427a7788b271c8e ]
The name stm-data-base comes from ancient (msm-3.10 or older) downstream kernels. Upstream uses stm-stimulus-base instead. Fix it.
Fixes: 783abfa2249a ("arm64: dts: qcom: msm8998: Add Coresight support") Signed-off-by: Konrad Dybcio konrad.dybcio@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230213210331.2106877-1-konrad.dybcio@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8998.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi index 9e04ac3f596d0..0ea4c9e7e1800 100644 --- a/arch/arm64/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi @@ -1187,7 +1187,7 @@ compatible = "arm,coresight-stm", "arm,primecell"; reg = <0x06002000 0x1000>, <0x16280000 0x180000>; - reg-names = "stm-base", "stm-data-base"; + reg-names = "stm-base", "stm-stimulus-base"; status = "disabled";
clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 0e0a8e35d72533b3eef3365e900baacd7cede8e2 ]
Following sm8150/sm8250 update sdm845 capacity-dmips-mhz and dynamic-power-coefficient based on the measurements [1], [2].
The energy model dynamic-power-coefficient values were calculated with DPC = µW / MHz / V^2 for each OPP, and averaged across all OPPs within each cluster for the final coefficient. Voltages were obtained from the qcom-cpufreq-hw driver that reads voltages from the OSM LUT programmed into the SoC.
Normalized DMIPS/MHz capacity scale values for each CPU were calculated from CoreMarks/MHz (CoreMark iterations per second per MHz), which serves the same purpose. For each CPU, the final capacity-dmips-mhz value is the C/MHz value of its maximum frequency normalized to SCHED_CAPACITY_SCALE (1024) for the fastest CPU in the system.
For more details on measurement process see the commit message for the commit 6aabed5526ee ("arm64: dts: qcom: sm8250: Add CPU capacities and energy model").
[1] https://github.com/kdrag0n/freqbench [2] https://github.com/kdrag0n/freqbench/tree/master/results/sdm845/main
Cc: Danny Lin danny@kdrag0n.dev Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220315141104.730235-1-dmitry.baryshkov@linaro.or... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 9beb3c34fcdb5..076b6949a0eed 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -196,8 +196,8 @@ cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - capacity-dmips-mhz = <607>; - dynamic-power-coefficient = <100>; + capacity-dmips-mhz = <611>; + dynamic-power-coefficient = <290>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, @@ -221,8 +221,8 @@ cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - capacity-dmips-mhz = <607>; - dynamic-power-coefficient = <100>; + capacity-dmips-mhz = <611>; + dynamic-power-coefficient = <290>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, @@ -243,8 +243,8 @@ cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - capacity-dmips-mhz = <607>; - dynamic-power-coefficient = <100>; + capacity-dmips-mhz = <611>; + dynamic-power-coefficient = <290>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, @@ -265,8 +265,8 @@ cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - capacity-dmips-mhz = <607>; - dynamic-power-coefficient = <100>; + capacity-dmips-mhz = <611>; + dynamic-power-coefficient = <290>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, @@ -288,7 +288,7 @@ cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - dynamic-power-coefficient = <396>; + dynamic-power-coefficient = <442>; qcom,freq-domain = <&cpufreq_hw 1>; operating-points-v2 = <&cpu4_opp_table>; interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, @@ -310,7 +310,7 @@ cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - dynamic-power-coefficient = <396>; + dynamic-power-coefficient = <442>; qcom,freq-domain = <&cpufreq_hw 1>; operating-points-v2 = <&cpu4_opp_table>; interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, @@ -332,7 +332,7 @@ cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - dynamic-power-coefficient = <396>; + dynamic-power-coefficient = <442>; qcom,freq-domain = <&cpufreq_hw 1>; operating-points-v2 = <&cpu4_opp_table>; interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, @@ -354,7 +354,7 @@ cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - dynamic-power-coefficient = <396>; + dynamic-power-coefficient = <442>; qcom,freq-domain = <&cpufreq_hw 1>; operating-points-v2 = <&cpu4_opp_table>; interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
From: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
[ Upstream commit 67aa109eee654c76dcc100554e637fa64d5aa099 ]
For 1MiB of the I/O region, the I/O ports of the legacy PCI devices are located in the range of 0x0 to 0x100000. Hence, fix the bogus PCI addresses (0x60200000, 0x40200000) specified in the ranges property for I/O region.
While at it, let's use the missing 0x prefix for the addresses.
Fixes: 42ad231338c1 ("arm64: dts: qcom: sdm845: Add second PCIe PHY and controller") Fixes: 5c538e09cb19 ("arm64: dts: qcom: sdm845: Add first PCIe controller and PHY") Reported-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/linux-arm-msm/7c5dfa87-41df-4ba7-b0e4-72c8386402a8@a... Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230228164752.55682-2-manivannan.sadhasivam@linar... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 076b6949a0eed..28fbd728304d3 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -1816,8 +1816,8 @@ #address-cells = <3>; #size-cells = <2>;
- ranges = <0x01000000 0x0 0x60200000 0 0x60200000 0x0 0x100000>, - <0x02000000 0x0 0x60300000 0 0x60300000 0x0 0xd00000>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>, + <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0xd00000>;
interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "msi"; @@ -1920,7 +1920,7 @@ #address-cells = <3>; #size-cells = <2>;
- ranges = <0x01000000 0x0 0x40200000 0x0 0x40200000 0x0 0x100000>, + ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>, <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
interrupts = <GIC_SPI 307 IRQ_TYPE_EDGE_RISING>;
From: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
[ Upstream commit c30a27dcfe4545edbda1578b3a63ed6147519cdd ]
For 1MiB of the I/O region, the I/O ports of the legacy PCI devices are located in the range of 0x0 to 0x100000. Hence, fix the bogus PCI address (0x1b200000) specified in the ranges property for I/O region.
Fixes: b84dfd175c09 ("arm64: dts: qcom: msm8998: Add PCIe PHY and RC nodes") Reported-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/linux-arm-msm/7c5dfa87-41df-4ba7-b0e4-72c8386402a8@a... Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230228164752.55682-3-manivannan.sadhasivam@linar... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8998.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi index 0ea4c9e7e1800..7c8d69ca91cf4 100644 --- a/arch/arm64/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi @@ -942,7 +942,7 @@ phys = <&pciephy>; phy-names = "pciephy";
- ranges = <0x01000000 0x0 0x1b200000 0x1b200000 0x0 0x100000>, + ranges = <0x01000000 0x0 0x00000000 0x1b200000 0x0 0x100000>, <0x02000000 0x0 0x1b300000 0x1b300000 0x0 0xd00000>;
#interrupt-cells = <1>;
From: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
[ Upstream commit e49eafefe5ab325e38dd074f2005076ffc271e54 ]
For 64KiB of the I/O region, the I/O ports of the legacy PCI devices are located in the range of 0x0 to 0x10000. Hence, fix the bogus PCI addresses (0x10200000, 0x20200000) specified in the ranges property for I/O region.
While at it, let's use the missing 0x prefix for the addresses and align them in a single line.
Fixes: 33057e1672fe ("ARM: dts: ipq8074: Add pcie nodes") Reported-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/linux-arm-msm/7c5dfa87-41df-4ba7-b0e4-72c8386402a8@a... Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230228164752.55682-6-manivannan.sadhasivam@linar... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index e191a7bc532be..f85fcc7c8676b 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -609,10 +609,8 @@ phys = <&pcie_phy1>; phy-names = "pciephy";
- ranges = <0x81000000 0 0x10200000 0x10200000 - 0 0x10000>, /* downstream I/O */ - <0x82000000 0 0x10220000 0x10220000 - 0 0xfde0000>; /* non-prefetchable memory */ + ranges = <0x81000000 0x0 0x00000000 0x10200000 0x0 0x10000>, /* I/O */ + <0x82000000 0x0 0x10220000 0x10220000 0x0 0xfde0000>; /* MEM */
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "msi"; @@ -673,10 +671,8 @@ phys = <&pcie_phy0>; phy-names = "pciephy";
- ranges = <0x81000000 0 0x20200000 0x20200000 - 0 0x10000>, /* downstream I/O */ - <0x82000000 0 0x20220000 0x20220000 - 0 0xfde0000>; /* non-prefetchable memory */ + ranges = <0x81000000 0x0 0x00000000 0x20200000 0x0 0x10000>, /* I/O */ + <0x82000000 0x0 0x20220000 0x20220000 0x0 0xfde0000>; /* MEM */
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "msi";
From: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
[ Upstream commit cf0ac10feb17661987d0018eb9475dc03e2a2253 ]
For 1MiB of the I/O region, the I/O ports of the legacy PCI devices are located in the range of 0x0 to 0x100000. Hence, fix the bogus PCI addresses (0x0c200000, 0x0d200000, 0x0e200000) specified in the ranges property for I/O region.
While at it, let's also align the entries.
Fixes: ed965ef89227 ("arm64: dts: qcom: msm8996: add support to pcie") Reported-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/linux-arm-msm/7c5dfa87-41df-4ba7-b0e4-72c8386402a8@a... Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230228164752.55682-8-manivannan.sadhasivam@linar... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index bc140269e4cc5..02b5f6f1d331e 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -744,8 +744,8 @@
#address-cells = <3>; #size-cells = <2>; - ranges = <0x01000000 0x0 0x0c200000 0x0c200000 0x0 0x100000>, - <0x02000000 0x0 0x0c300000 0x0c300000 0x0 0xd00000>; + ranges = <0x01000000 0x0 0x00000000 0x0c200000 0x0 0x100000>, + <0x02000000 0x0 0x0c300000 0x0c300000 0x0 0xd00000>;
interrupts = <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "msi"; @@ -796,8 +796,8 @@
#address-cells = <3>; #size-cells = <2>; - ranges = <0x01000000 0x0 0x0d200000 0x0d200000 0x0 0x100000>, - <0x02000000 0x0 0x0d300000 0x0d300000 0x0 0xd00000>; + ranges = <0x01000000 0x0 0x00000000 0x0d200000 0x0 0x100000>, + <0x02000000 0x0 0x0d300000 0x0d300000 0x0 0xd00000>;
interrupts = <GIC_SPI 413 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "msi"; @@ -845,8 +845,8 @@
#address-cells = <3>; #size-cells = <2>; - ranges = <0x01000000 0x0 0x0e200000 0x0e200000 0x0 0x100000>, - <0x02000000 0x0 0x0e300000 0x0e300000 0x0 0x1d00000>; + ranges = <0x01000000 0x0 0x00000000 0x0e200000 0x0 0x100000>, + <0x02000000 0x0 0x0e300000 0x0e300000 0x0 0x1d00000>;
device_type = "pci";
From: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
[ Upstream commit 2540279e9a9e74fc880d1e4c83754ecfcbe290a0 ]
For 1MiB of the I/O region, the I/O ports of the legacy PCI devices are located in the range of 0x0 to 0x100000. Hence, fix the bogus PCI address (0x40200000) specified in the ranges property for I/O region.
While at it, let's use the missing 0x prefix for the addresses.
Fixes: 187519403273 ("ARM: dts: ipq4019: Add a few peripheral nodes") Reported-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/linux-arm-msm/7c5dfa87-41df-4ba7-b0e4-72c8386402a8@a... Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230228164752.55682-16-manivannan.sadhasivam@lina... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-ipq4019.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi index 3defd47fd8fab..037bb8a9b01ec 100644 --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi @@ -414,8 +414,8 @@ #address-cells = <3>; #size-cells = <2>;
- ranges = <0x81000000 0 0x40200000 0x40200000 0 0x00100000>, - <0x82000000 0 0x40300000 0x40300000 0 0x00d00000>; + ranges = <0x81000000 0x0 0x00000000 0x40200000 0x0 0x00100000>, + <0x82000000 0x0 0x40300000 0x40300000 0x0 0x00d00000>;
interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "msi";
From: Christian Marangi ansuelsmth@gmail.com
[ Upstream commit 8fafb7e5c041814876266259e5e439f93571dcef ]
The current value for pci IO is problematic for ath10k wifi card commonly connected to ipq8064 SoC. The current value is probably a typo and is actually uncommon to find 1MB IO space even on a x86 arch. Also with recent changes to the pci driver, pci1 and pci2 now fails to function as any connected device fails any reg read/write. Reduce this to 64K as it should be more than enough and 3 * 64K of total IO space doesn't exceed the IO_SPACE_LIMIT hardcoded for the ARM arch.
Signed-off-by: Christian Marangi ansuelsmth@gmail.com Tested-by: Jonathan McDowell noodles@earth.li Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220707010943.20857-7-ansuelsmth@gmail.com Stable-dep-of: 0b16b34e4916 ("ARM: dts: qcom: ipq8064: Fix the PCI I/O port range") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-ipq8064.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi index c51481405e7f8..f7ed87a35e34d 100644 --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi @@ -465,7 +465,7 @@ #address-cells = <3>; #size-cells = <2>;
- ranges = <0x81000000 0 0x0fe00000 0x0fe00000 0 0x00100000 /* downstream I/O */ + ranges = <0x81000000 0 0x0fe00000 0x0fe00000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x08000000 0x08000000 0 0x07e00000>; /* non-prefetchable memory */
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; @@ -516,7 +516,7 @@ #address-cells = <3>; #size-cells = <2>;
- ranges = <0x81000000 0 0x31e00000 0x31e00000 0 0x00100000 /* downstream I/O */ + ranges = <0x81000000 0 0x31e00000 0x31e00000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x2e000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */
interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; @@ -567,7 +567,7 @@ #address-cells = <3>; #size-cells = <2>;
- ranges = <0x81000000 0 0x35e00000 0x35e00000 0 0x00100000 /* downstream I/O */ + ranges = <0x81000000 0 0x35e00000 0x35e00000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x32000000 0x32000000 0 0x03e00000>; /* non-prefetchable memory */
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
From: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
[ Upstream commit 0b16b34e491629016109e56747ad64588074194b ]
For 64KiB of the I/O region, the I/O ports of the legacy PCI devices are located in the range of 0x0 to 0x10000. Hence, fix the bogus PCI addresses (0x0fe00000, 0x31e00000, 0x35e00000) specified in the ranges property for I/O region.
While at it, let's use the missing 0x prefix for the addresses.
Fixes: 93241840b664 ("ARM: dts: qcom: Add pcie nodes for ipq8064") Reported-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/linux-arm-msm/7c5dfa87-41df-4ba7-b0e4-72c8386402a8@a... Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230228164752.55682-17-manivannan.sadhasivam@lina... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-ipq8064.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi index f7ed87a35e34d..dca0ed6c8c8de 100644 --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi @@ -465,8 +465,8 @@ #address-cells = <3>; #size-cells = <2>;
- ranges = <0x81000000 0 0x0fe00000 0x0fe00000 0 0x00010000 /* downstream I/O */ - 0x82000000 0 0x08000000 0x08000000 0 0x07e00000>; /* non-prefetchable memory */ + ranges = <0x81000000 0x0 0x00000000 0x0fe00000 0x0 0x00010000 /* I/O */ + 0x82000000 0x0 0x08000000 0x08000000 0x0 0x07e00000>; /* MEM */
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "msi"; @@ -516,8 +516,8 @@ #address-cells = <3>; #size-cells = <2>;
- ranges = <0x81000000 0 0x31e00000 0x31e00000 0 0x00010000 /* downstream I/O */ - 0x82000000 0 0x2e000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */ + ranges = <0x81000000 0x0 0x00000000 0x31e00000 0x0 0x00010000 /* I/O */ + 0x82000000 0x0 0x2e000000 0x2e000000 0x0 0x03e00000>; /* MEM */
interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "msi"; @@ -567,8 +567,8 @@ #address-cells = <3>; #size-cells = <2>;
- ranges = <0x81000000 0 0x35e00000 0x35e00000 0 0x00010000 /* downstream I/O */ - 0x82000000 0 0x32000000 0x32000000 0 0x03e00000>; /* non-prefetchable memory */ + ranges = <0x81000000 0x0 0x00000000 0x35e00000 0x0 0x00010000 /* I/O */ + 0x82000000 0x0 0x32000000 0x32000000 0x0 0x03e00000>; /* MEM */
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "msi";
From: Muralidhara M K muralimk@amd.com
[ Upstream commit 4c1cdec319b9aadb65737c3eb1f5cb74bd6aa156 ]
Thee maximum number of MCA banks is 64 (MAX_NR_BANKS), see
a0bc32b3cacf ("x86/mce: Increase maximum number of banks to 64").
However, the bank_map which contains a bitfield of which banks to initialize is of type unsigned int and that overflows when those bit numbers are >= 32, leading to UBSAN complaining correctly:
UBSAN: shift-out-of-bounds in arch/x86/kernel/cpu/mce/amd.c:1365:38 shift exponent 32 is too large for 32-bit type 'int'
Change the bank_map to a u64 and use the proper BIT_ULL() macro when modifying bits in there.
[ bp: Rewrite commit message. ]
Fixes: a0bc32b3cacf ("x86/mce: Increase maximum number of banks to 64") Signed-off-by: Muralidhara M K muralimk@amd.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Link: https://lore.kernel.org/r/20230127151601.1068324-1-muralimk@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/mce/amd.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c index 4f9b7c1cfc36f..cd8db6b9ca2f5 100644 --- a/arch/x86/kernel/cpu/mce/amd.c +++ b/arch/x86/kernel/cpu/mce/amd.c @@ -197,10 +197,10 @@ static DEFINE_PER_CPU(struct threshold_bank **, threshold_banks); * A list of the banks enabled on each logical CPU. Controls which respective * descriptors to initialize later in mce_threshold_create_device(). */ -static DEFINE_PER_CPU(unsigned int, bank_map); +static DEFINE_PER_CPU(u64, bank_map);
/* Map of banks that have more than MCA_MISC0 available. */ -static DEFINE_PER_CPU(u32, smca_misc_banks_map); +static DEFINE_PER_CPU(u64, smca_misc_banks_map);
static void amd_threshold_interrupt(void); static void amd_deferred_error_interrupt(void); @@ -229,7 +229,7 @@ static void smca_set_misc_banks_map(unsigned int bank, unsigned int cpu) return;
if (low & MASK_BLKPTR_LO) - per_cpu(smca_misc_banks_map, cpu) |= BIT(bank); + per_cpu(smca_misc_banks_map, cpu) |= BIT_ULL(bank);
}
@@ -492,7 +492,7 @@ static u32 smca_get_block_address(unsigned int bank, unsigned int block, if (!block) return MSR_AMD64_SMCA_MCx_MISC(bank);
- if (!(per_cpu(smca_misc_banks_map, cpu) & BIT(bank))) + if (!(per_cpu(smca_misc_banks_map, cpu) & BIT_ULL(bank))) return 0;
return MSR_AMD64_SMCA_MCx_MISCy(bank, block - 1); @@ -536,7 +536,7 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr, int new;
if (!block) - per_cpu(bank_map, cpu) |= (1 << bank); + per_cpu(bank_map, cpu) |= BIT_ULL(bank);
memset(&b, 0, sizeof(b)); b.cpu = cpu; @@ -1048,7 +1048,7 @@ static void amd_threshold_interrupt(void) return;
for (bank = 0; bank < this_cpu_read(mce_num_banks); ++bank) { - if (!(per_cpu(bank_map, cpu) & (1 << bank))) + if (!(per_cpu(bank_map, cpu) & BIT_ULL(bank))) continue;
first_block = bp[bank]->blocks; @@ -1525,7 +1525,7 @@ int mce_threshold_create_device(unsigned int cpu) return -ENOMEM;
for (bank = 0; bank < numbanks; ++bank) { - if (!(this_cpu_read(bank_map) & (1 << bank))) + if (!(this_cpu_read(bank_map) & BIT_ULL(bank))) continue; err = threshold_create_bank(bp, cpu, bank); if (err) {
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit 2371adeab717d8fe32144a84f3491a03c5838cfb ]
Add the check for the return value of the create_workqueue in order to avoid NULL pointer dereference.
Fixes: 28ffeebbb7bd ("[media] bdisp: 2D blitter driver using v4l2 mem2mem framework") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 85288da9d2ae6..182e5a4aeb171 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -1310,6 +1310,8 @@ static int bdisp_probe(struct platform_device *pdev) init_waitqueue_head(&bdisp->irq_queue); INIT_DELAYED_WORK(&bdisp->timeout_work, bdisp_irq_timeout); bdisp->work_queue = create_workqueue(BDISP_NAME); + if (!bdisp->work_queue) + return -ENOMEM;
spin_lock_init(&bdisp->slock); mutex_init(&bdisp->lock);
From: Mukesh Ojha quic_mojha@quicinc.com
[ Upstream commit 781d32d1c9709fd25655c4e3e3e15370ae4ae4db ]
During normal restart of a system download bit should be cleared irrespective of whether download mode is set or not.
Fixes: 8c1b7dc9ba22 ("firmware: qcom: scm: Expose download-mode control") Signed-off-by: Mukesh Ojha quic_mojha@quicinc.com Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/1678979666-551-1-git-send-email-quic_mojha@quicinc... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/qcom_scm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index d417199f8fe94..96086e7df9100 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -1256,8 +1256,7 @@ static int qcom_scm_probe(struct platform_device *pdev) static void qcom_scm_shutdown(struct platform_device *pdev) { /* Clean shutdown, disable download mode to allow normal restart */ - if (download_mode) - qcom_scm_set_download_mode(false); + qcom_scm_set_download_mode(false); }
static const struct of_device_id qcom_scm_dt_match[] = {
From: Adam Ford aford173@gmail.com
[ Upstream commit ee0285e13455fdbce5de315bdbe91b5f198a2a06 ]
When dynamically switching lanes was removed, the intent of the code was to check to make sure that higher speed items used 4 lanes, but it had the unintended consequence of removing the slower speeds for 4-lane users.
This attempts to remedy this by doing a check to see that the max frequency doesn't exceed the chip limit, and a second check to make sure that the max bit-rate doesn't exceed the number of lanes * max bit rate / lane.
Fixes: 9a0cdcd6649b ("drm/bridge: adv7533: remove dynamic lane switching from adv7533 bridge") Reviewed-by: Robert Foss rfoss@kernel.org Signed-off-by: Adam Ford aford173@gmail.com Signed-off-by: Robert Foss rfoss@kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20230319125524.58803-1-aford17... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/adv7511/adv7533.c | 25 +++++++++++------------- 1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index f304a5ff8e596..e0bdedf22390c 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -103,22 +103,19 @@ void adv7533_dsi_power_off(struct adv7511 *adv) enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, const struct drm_display_mode *mode) { - int lanes; + unsigned long max_lane_freq; struct mipi_dsi_device *dsi = adv->dsi; + u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
- if (mode->clock > 80000) - lanes = 4; - else - lanes = 3; - - /* - * TODO: add support for dynamic switching of lanes - * by using the bridge pre_enable() op . Till then filter - * out the modes which shall need different number of lanes - * than what was configured in the device tree. - */ - if (lanes != dsi->lanes) - return MODE_BAD; + /* Check max clock for either 7533 or 7535 */ + if (mode->clock > (adv->type == ADV7533 ? 80000 : 148500)) + return MODE_CLOCK_HIGH; + + /* Check max clock for each lane */ + max_lane_freq = (adv->type == ADV7533 ? 800000 : 891000); + + if (mode->clock * bpp > max_lane_freq * adv->num_dsi_lanes) + return MODE_CLOCK_HIGH;
return MODE_OK; }
From: Laurent Pinchart laurent.pinchart@ideasonboard.com
[ Upstream commit bfce6a12e5ba1edde95126aa06778027f16115d4 ]
The control handler is leaked in some probe-time error paths, as well as in the remove path. Fix it.
Fixes: 66d8c9d2422d ("media: i2c: Add MAX9286 driver") Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Reviewed-by: Niklas Söderlund niklas.soderlund+renesas@ragnatech.se Reviewed-by: Jacopo Mondi jacopo.mondi@ideasonboard.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/max9286.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index 79a11c0184c65..62ce27552dd3c 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -899,6 +899,7 @@ static int max9286_v4l2_register(struct max9286_priv *priv) static void max9286_v4l2_unregister(struct max9286_priv *priv) { fwnode_handle_put(priv->sd.fwnode); + v4l2_ctrl_handler_free(&priv->ctrls); v4l2_async_unregister_subdev(&priv->sd); max9286_v4l2_notifier_unregister(priv); }
From: Rob Clark robdclark@chromium.org
[ Upstream commit 4b18299b33655fa9672b774b6df774dc03d6aee8 ]
To avoid preventing the display from coming up before the rootfs is mounted, without resorting to packing fw in the initrd, the GPU has this limbo state where the device is probed, but we aren't ready to start sending commands to it. This is particularly problematic for a6xx, since the GMU (which requires fw to be loaded) is the one that is controlling the power/clk/icc votes.
So defer enabling runpm until we are ready to call gpu->hw_init(), as that is a point where we know we have all the needed fw and are ready to start sending commands to the coproc's.
Signed-off-by: Rob Clark robdclark@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/489337/ Link: https://lore.kernel.org/r/20220613182036.2567963-1-robdclark@gmail.com Stable-dep-of: db7662d076c9 ("drm/msm/adreno: drop bogus pm_runtime_set_active()") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/adreno_device.c | 6 ++++++ drivers/gpu/drm/msm/adreno/adreno_gpu.c | 1 - 2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 58e03b20e1c7a..c06202b9243c4 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -301,6 +301,12 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) if (ret) return NULL;
+ /* + * Now that we have firmware loaded, and are ready to begin + * booting the gpu, go ahead and enable runpm: + */ + pm_runtime_enable(&pdev->dev); + /* Make sure pm runtime is active and reset any previous errors */ pm_runtime_set_active(&pdev->dev);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 78181e2d78a97..11a6a41b4910f 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -916,7 +916,6 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, pm_runtime_set_autosuspend_delay(dev, adreno_gpu->info->inactive_period); pm_runtime_use_autosuspend(dev); - pm_runtime_enable(dev);
ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, adreno_gpu->info->name, &adreno_gpu_config);
From: Johan Hovold johan+linaro@kernel.org
[ Upstream commit db7662d076c973072d788bd0e8130e04430307a1 ]
The runtime PM status can only be updated while runtime PM is disabled.
Drop the bogus pm_runtime_set_active() call that was made after enabling runtime PM and which (incidentally but correctly) left the runtime PM status set to 'suspended'.
Fixes: 2c087a336676 ("drm/msm/adreno: Load the firmware before bringing up the hardware") Signed-off-by: Johan Hovold johan+linaro@kernel.org Patchwork: https://patchwork.freedesktop.org/patch/524972/ Link: https://lore.kernel.org/r/20230303164807.13124-4-johan+linaro@kernel.org Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/adreno_device.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index c06202b9243c4..760687f66ae5b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -307,9 +307,6 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) */ pm_runtime_enable(&pdev->dev);
- /* Make sure pm runtime is active and reset any previous errors */ - pm_runtime_set_active(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) { pm_runtime_put_sync(&pdev->dev);
From: Adam Skladowski a39.skl@gmail.com
[ Upstream commit 010c8bbad2cb8c33c47963e29f051f1e917e45a5 ]
Downstream driver appears to not support preemption on A510 target, trying to use one make device slow and fill log with rings related errors. Set num_rings to 1 to disable preemption.
Suggested-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Fixes: e20c9284c8f2 ("drm/msm/adreno: Add support for Adreno 510 GPU") Signed-off-by: Adam Skladowski a39.skl@gmail.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/526898/ Link: https://lore.kernel.org/r/20230314221757.13096-1-a39.skl@gmail.com Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 6f84db97e20e8..0fcba2bc26b8e 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1569,6 +1569,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) struct a5xx_gpu *a5xx_gpu = NULL; struct adreno_gpu *adreno_gpu; struct msm_gpu *gpu; + unsigned int nr_rings; int ret;
if (!pdev) { @@ -1589,7 +1590,12 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
check_speed_bin(&pdev->dev);
- ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); + nr_rings = 4; + + if (adreno_is_a510(adreno_gpu)) + nr_rings = 1; + + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, nr_rings); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); return ERR_PTR(ret);
From: Roger Pau Monne roger.pau@citrix.com
[ Upstream commit 073828e954459b883f23e53999d31e4c55ab9654 ]
In ACPI systems, the OS can direct power management, as opposed to the firmware. This OS-directed Power Management is called OSPM. Part of telling the firmware that the OS going to direct power management is making ACPI "_PDC" (Processor Driver Capabilities) calls. These _PDC methods must be evaluated for every processor object. If these _PDC calls are not completed for every processor it can lead to inconsistency and later failures in things like the CPU frequency driver.
In a Xen system, the dom0 kernel is responsible for system-wide power management. The dom0 kernel is in charge of OSPM. However, the number of CPUs available to dom0 can be different than the number of CPUs physically present on the system.
This leads to a problem: the dom0 kernel needs to evaluate _PDC for all the processors, but it can't always see them.
In dom0 kernels, ignore the existing ACPI method for determining if a processor is physically present because it might not be accurate. Instead, ask the hypervisor for this information.
Fix this by introducing a custom function to use when running as Xen dom0 in order to check whether a processor object matches a CPU that's online. Such checking is done using the existing information fetched by the Xen pCPU subsystem, extending it to also store the ACPI ID.
This ensures that _PDC method gets evaluated for all physically online CPUs, regardless of the number of CPUs made available to dom0.
Fixes: 5d554a7bb064 ("ACPI: processor: add internal processor_physically_present()") Signed-off-by: Roger Pau Monné roger.pau@citrix.com Reviewed-by: Juergen Gross jgross@suse.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/processor_pdc.c | 11 +++++++++++ drivers/xen/pcpu.c | 20 ++++++++++++++++++++ include/xen/xen.h | 11 +++++++++++ 3 files changed, 42 insertions(+)
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 813f1b78c16a9..c0d2d9a2c0d58 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -14,6 +14,8 @@ #include <linux/acpi.h> #include <acpi/processor.h>
+#include <xen/xen.h> + #include "internal.h"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT @@ -50,6 +52,15 @@ static bool __init processor_physically_present(acpi_handle handle) return false; }
+ if (xen_initial_domain()) + /* + * When running as a Xen dom0 the number of processors Linux + * sees can be different from the real number of processors on + * the system, and we still need to execute _PDC for all of + * them. + */ + return xen_processor_present(acpi_id); + type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; cpuid = acpi_get_cpuid(handle, type, acpi_id);
diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c index 9cf7085a260b4..4581217e31fea 100644 --- a/drivers/xen/pcpu.c +++ b/drivers/xen/pcpu.c @@ -58,6 +58,7 @@ struct pcpu { struct list_head list; struct device dev; uint32_t cpu_id; + uint32_t acpi_id; uint32_t flags; };
@@ -249,6 +250,7 @@ static struct pcpu *create_and_register_pcpu(struct xenpf_pcpuinfo *info)
INIT_LIST_HEAD(&pcpu->list); pcpu->cpu_id = info->xen_cpuid; + pcpu->acpi_id = info->acpi_id; pcpu->flags = info->flags;
/* Need hold on xen_pcpu_lock before pcpu list manipulations */ @@ -416,3 +418,21 @@ static int __init xen_pcpu_init(void) return ret; } arch_initcall(xen_pcpu_init); + +#ifdef CONFIG_ACPI +bool __init xen_processor_present(uint32_t acpi_id) +{ + const struct pcpu *pcpu; + bool online = false; + + mutex_lock(&xen_pcpu_lock); + list_for_each_entry(pcpu, &xen_pcpus, list) + if (pcpu->acpi_id == acpi_id) { + online = pcpu->flags & XEN_PCPU_FLAGS_ONLINE; + break; + } + mutex_unlock(&xen_pcpu_lock); + + return online; +} +#endif diff --git a/include/xen/xen.h b/include/xen/xen.h index 43efba045acc7..5a6a2ab675bed 100644 --- a/include/xen/xen.h +++ b/include/xen/xen.h @@ -61,4 +61,15 @@ void xen_free_unpopulated_pages(unsigned int nr_pages, struct page **pages); #include <xen/balloon.h> #endif
+#if defined(CONFIG_XEN_DOM0) && defined(CONFIG_ACPI) && defined(CONFIG_X86) +bool __init xen_processor_present(uint32_t acpi_id); +#else +#include <linux/bug.h> +static inline bool xen_processor_present(uint32_t acpi_id) +{ + BUG(); + return false; +} +#endif + #endif /* _XEN_XEN_H */
From: Georgii Kruglov georgy.kruglov@yandex.ru
[ Upstream commit 0dd8316037a2a6d85b2be208bef9991de7b42170 ]
If spec_reg is equal to 'SDHCI_PRESENT_STATE', esdhc_readl_fixup() fixes up register value and returns it immediately. As a result, the further block (spec_reg == SDHCI_PRESENT_STATE) &&(esdhc->quirk_ignore_data_inhibit == true), is never executed.
The patch merges the second block into the first one.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 1f1929f3f2fa ("mmc: sdhci-of-esdhc: add quirk to ignore command inhibit for data") Signed-off-by: Georgii Kruglov georgy.kruglov@yandex.ru Acked-by: Adrian Hunter adrian.hunter@intel.com Link: https://lore.kernel.org/r/20230321203715.3975-1-georgy.kruglov@yandex.ru Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-of-esdhc.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index d53374991e137..5b853f651b389 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -126,6 +126,7 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host, return ret; } } + /* * The DAT[3:0] line signal levels and the CMD line signal level are * not compatible with standard SDHC register. The line signal levels @@ -137,6 +138,16 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host, ret = value & 0x000fffff; ret |= (value >> 4) & SDHCI_DATA_LVL_MASK; ret |= (value << 1) & SDHCI_CMD_LVL; + + /* + * Some controllers have unreliable Data Line Active + * bit for commands with busy signal. This affects + * Command Inhibit (data) bit. Just ignore it since + * MMC core driver has already polled card status + * with CMD13 after any command with busy siganl. + */ + if (esdhc->quirk_ignore_data_inhibit) + ret &= ~SDHCI_DATA_INHIBIT; return ret; }
@@ -151,19 +162,6 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host, return ret; }
- /* - * Some controllers have unreliable Data Line Active - * bit for commands with busy signal. This affects - * Command Inhibit (data) bit. Just ignore it since - * MMC core driver has already polled card status - * with CMD13 after any command with busy siganl. - */ - if ((spec_reg == SDHCI_PRESENT_STATE) && - (esdhc->quirk_ignore_data_inhibit == true)) { - ret = value & ~SDHCI_DATA_INHIBIT; - return ret; - } - ret = value; return ret; }
From: H. Nikolaus Schaller hns@goldelico.com
[ Upstream commit a622310f7f0185da02e42cdb06475f533efaae60 ]
OMAP processors support 32 channels but there is no check or inspect this except booting a device and looking at dmesg reports of not available channels.
Recently some more subsystems with DMA (aes1+2) were added filling the list of dma channels beyond the limit of 32 (even if other parameters indicate 96 or 128 channels). This leads to random subsystem failures i(e.g. mcbsp for audio) after boot or boot messages that DMA can not be initialized.
Another symptom is that
/sys/kernel/debug/dmaengine/summary
has 32 entries and does not show all required channels.
Fix by disabling unused (on the GTA04 hardware) mcspi1...4. Each SPI channel allocates 4 DMA channels rapidly filling the available ones.
Disabling unused SPI modules on the OMAP3 SoC may also save some energy (has not been checked).
Fixes: c312f066314e ("ARM: dts: omap3: Migrate AES from hwmods to sysc-omap2") Signed-off-by: H. Nikolaus Schaller hns@goldelico.com [re-enabled aes2, improved commit subject line] Signed-off-by: Andreas Kemnade andreas@kemnade.info Message-Id: 20230113211151.2314874-1-andreas@kemnade.info Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/omap3-gta04.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi index cc8a378dd076e..e61e5ddbf2027 100644 --- a/arch/arm/boot/dts/omap3-gta04.dtsi +++ b/arch/arm/boot/dts/omap3-gta04.dtsi @@ -609,6 +609,22 @@ clock-frequency = <100000>; };
+&mcspi1 { + status = "disabled"; +}; + +&mcspi2 { + status = "disabled"; +}; + +&mcspi3 { + status = "disabled"; +}; + +&mcspi4 { + status = "disabled"; +}; + &usb_otg_hs { interface-type = <0>; usb-phy = <&usb2_phy>;
From: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
[ Upstream commit c5647cae2704e58d1c4e5fedbf63f11bca6376c9 ]
Smatch reports: drivers/gpu/drm/lima/lima_drv.c:396 lima_pdev_probe() warn: missing unwind goto?
Store return value in err and goto 'err_out0' which has lima_sched_slab_fini() before returning.
Fixes: a1d2a6339961 ("drm/lima: driver for ARM Mali4xx GPUs") Signed-off-by: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com Signed-off-by: Qiang Yu yuq825@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20230314052711.4061652-1-harsh... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/lima/lima_drv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c index ab460121fd52c..65dc0dc2c119a 100644 --- a/drivers/gpu/drm/lima/lima_drv.c +++ b/drivers/gpu/drm/lima/lima_drv.c @@ -392,8 +392,10 @@ static int lima_pdev_probe(struct platform_device *pdev)
/* Allocate and initialize the DRM device. */ ddev = drm_dev_alloc(&lima_drm_driver, &pdev->dev); - if (IS_ERR(ddev)) - return PTR_ERR(ddev); + if (IS_ERR(ddev)) { + err = PTR_ERR(ddev); + goto err_out0; + }
ddev->dev_private = ldev; ldev->ddev = ddev;
From: Douglas Anderson dianders@chromium.org
[ Upstream commit b83a1772be854f87602de14726737d3e5b06e1f4 ]
When a codepath locks a rdev using ww_mutex_lock_slow() directly then that codepath is responsible for incrementing the "ref_cnt" and also setting the "mutex_owner" to "current".
The regulator core consistently got that right for "ref_cnt" but didn't always get it right for "mutex_owner". Let's fix this.
It's unlikely that this truly matters because the "mutex_owner" is only needed if we're going to do subsequent locking of the same rdev. However, even though it's not truly needed it seems less surprising if we consistently set "mutex_owner" properly.
Fixes: f8702f9e4aa7 ("regulator: core: Use ww_mutex for regulators locking") Signed-off-by: Douglas Anderson dianders@chromium.org Link: https://lore.kernel.org/r/20230329143317.RFC.v2.1.I4e9d433ea26360c06dd1381d0... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/core.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 6dd698b2d0af3..bd2a3f44dd6ea 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -343,6 +343,7 @@ static void regulator_lock_dependent(struct regulator_dev *rdev, ww_mutex_lock_slow(&new_contended_rdev->mutex, ww_ctx); old_contended_rdev = new_contended_rdev; old_contended_rdev->ref_cnt++; + old_contended_rdev->mutex_owner = current; }
err = regulator_lock_recursive(rdev, @@ -5800,6 +5801,7 @@ static void regulator_summary_lock(struct ww_acquire_ctx *ww_ctx) ww_mutex_lock_slow(&new_contended_rdev->mutex, ww_ctx); old_contended_rdev = new_contended_rdev; old_contended_rdev->ref_cnt++; + old_contended_rdev->mutex_owner = current; }
err = regulator_summary_lock_all(ww_ctx,
From: Douglas Anderson dianders@chromium.org
[ Upstream commit cba6cfdc7c3f1516f0d08ddfb24e689af0932573 ]
An automated bot told me that there was a potential lockdep problem with regulators. This was on the chromeos-5.15 kernel, but I see nothing that would be different downstream compared to upstream. The bot said: ============================================ WARNING: possible recursive locking detected 5.15.104-lockdep-17461-gc1e499ed6604 #1 Not tainted -------------------------------------------- kworker/u16:4/115 is trying to acquire lock: ffffff8083110170 (regulator_ww_class_mutex){+.+.}-{3:3}, at: create_regulator+0x398/0x7ec
but task is already holding lock: ffffff808378e170 (regulator_ww_class_mutex){+.+.}-{3:3}, at: ww_mutex_trylock+0x3c/0x7b8
other info that might help us debug this: Possible unsafe locking scenario:
CPU0 ---- lock(regulator_ww_class_mutex); lock(regulator_ww_class_mutex);
*** DEADLOCK ***
May be due to missing lock nesting notation
4 locks held by kworker/u16:4/115: #0: ffffff808006a948 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_one_work+0x520/0x1348 #1: ffffffc00e0a7cc0 ((work_completion)(&entry->work)){+.+.}-{0:0}, at: process_one_work+0x55c/0x1348 #2: ffffff80828a2260 (&dev->mutex){....}-{3:3}, at: __device_attach_async_helper+0xd0/0x2a4 #3: ffffff808378e170 (regulator_ww_class_mutex){+.+.}-{3:3}, at: ww_mutex_trylock+0x3c/0x7b8
stack backtrace: CPU: 2 PID: 115 Comm: kworker/u16:4 Not tainted 5.15.104-lockdep-17461-gc1e499ed6604 #1 9292e52fa83c0e23762b2b3aa1bacf5787a4d5da Hardware name: Google Quackingstick (rev0+) (DT) Workqueue: events_unbound async_run_entry_fn Call trace: dump_backtrace+0x0/0x4ec show_stack+0x34/0x50 dump_stack_lvl+0xdc/0x11c dump_stack+0x1c/0x48 __lock_acquire+0x16d4/0x6c74 lock_acquire+0x208/0x750 __mutex_lock_common+0x11c/0x11f8 ww_mutex_lock+0xc0/0x440 create_regulator+0x398/0x7ec regulator_resolve_supply+0x654/0x7c4 regulator_register_resolve_supply+0x30/0x120 class_for_each_device+0x1b8/0x230 regulator_register+0x17a4/0x1f40 devm_regulator_register+0x60/0xd0 reg_fixed_voltage_probe+0x728/0xaec platform_probe+0x150/0x1c8 really_probe+0x274/0xa20 __driver_probe_device+0x1dc/0x3f4 driver_probe_device+0x78/0x1c0 __device_attach_driver+0x1ac/0x2c8 bus_for_each_drv+0x11c/0x190 __device_attach_async_helper+0x1e4/0x2a4 async_run_entry_fn+0xa0/0x3ac process_one_work+0x638/0x1348 worker_thread+0x4a8/0x9c4 kthread+0x2e4/0x3a0 ret_from_fork+0x10/0x20
The problem was first reported soon after we made many of the regulators probe asynchronously, though nothing I've seen implies that the problems couldn't have also happened even without that.
I haven't personally been able to reproduce the lockdep issue, but the issue does look somewhat legitimate. Specifically, it looks like in regulator_resolve_supply() we are holding a "rdev" lock while calling set_supply() -> create_regulator() which grabs the lock of a _different_ "rdev" (the one for our supply). This is not necessarily safe from a lockdep perspective since there is no documented ordering between these two locks.
In reality, we should always be locking a regulator before the supplying regulator, so I don't expect there to be any real deadlocks in practice. However, the regulator framework in general doesn't express this to lockdep.
Let's fix the issue by simply grabbing the two locks involved in the same way we grab multiple locks elsewhere in the regulator framework: using the "wound/wait" mechanisms.
Fixes: eaa7995c529b ("regulator: core: avoid regulator_resolve_supply() race condition") Signed-off-by: Douglas Anderson dianders@chromium.org Link: https://lore.kernel.org/r/20230329143317.RFC.v2.2.I30d8e1ca10cfbe5403884cdd1... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/core.c | 91 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 83 insertions(+), 8 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index bd2a3f44dd6ea..47a04c5f7a9b8 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -216,6 +216,78 @@ static void regulator_unlock(struct regulator_dev *rdev) mutex_unlock(®ulator_nesting_mutex); }
+/** + * regulator_lock_two - lock two regulators + * @rdev1: first regulator + * @rdev2: second regulator + * @ww_ctx: w/w mutex acquire context + * + * Locks both rdevs using the regulator_ww_class. + */ +static void regulator_lock_two(struct regulator_dev *rdev1, + struct regulator_dev *rdev2, + struct ww_acquire_ctx *ww_ctx) +{ + struct regulator_dev *tmp; + int ret; + + ww_acquire_init(ww_ctx, ®ulator_ww_class); + + /* Try to just grab both of them */ + ret = regulator_lock_nested(rdev1, ww_ctx); + WARN_ON(ret); + ret = regulator_lock_nested(rdev2, ww_ctx); + if (ret != -EDEADLOCK) { + WARN_ON(ret); + goto exit; + } + + while (true) { + /* + * Start of loop: rdev1 was locked and rdev2 was contended. + * Need to unlock rdev1, slowly lock rdev2, then try rdev1 + * again. + */ + regulator_unlock(rdev1); + + ww_mutex_lock_slow(&rdev2->mutex, ww_ctx); + rdev2->ref_cnt++; + rdev2->mutex_owner = current; + ret = regulator_lock_nested(rdev1, ww_ctx); + + if (ret == -EDEADLOCK) { + /* More contention; swap which needs to be slow */ + tmp = rdev1; + rdev1 = rdev2; + rdev2 = tmp; + } else { + WARN_ON(ret); + break; + } + } + +exit: + ww_acquire_done(ww_ctx); +} + +/** + * regulator_unlock_two - unlock two regulators + * @rdev1: first regulator + * @rdev2: second regulator + * @ww_ctx: w/w mutex acquire context + * + * The inverse of regulator_lock_two(). + */ + +static void regulator_unlock_two(struct regulator_dev *rdev1, + struct regulator_dev *rdev2, + struct ww_acquire_ctx *ww_ctx) +{ + regulator_unlock(rdev2); + regulator_unlock(rdev1); + ww_acquire_fini(ww_ctx); +} + static bool regulator_supply_is_couple(struct regulator_dev *rdev) { struct regulator_dev *c_rdev; @@ -1460,8 +1532,8 @@ static int set_machine_constraints(struct regulator_dev *rdev)
/** * set_supply - set regulator supply regulator - * @rdev: regulator name - * @supply_rdev: supply regulator name + * @rdev: regulator (locked) + * @supply_rdev: supply regulator (locked)) * * Called by platform initialisation code to set the supply regulator for this * regulator. This ensures that a regulators supply will also be enabled by the @@ -1633,6 +1705,8 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, struct regulator *regulator; int err = 0;
+ lockdep_assert_held_once(&rdev->mutex.base); + if (dev) { char buf[REG_STR_SIZE]; int size; @@ -1660,9 +1734,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, regulator->rdev = rdev; regulator->supply_name = supply_name;
- regulator_lock(rdev); list_add(®ulator->list, &rdev->consumer_list); - regulator_unlock(rdev);
if (dev) { regulator->dev = dev; @@ -1828,6 +1900,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) { struct regulator_dev *r; struct device *dev = rdev->dev.parent; + struct ww_acquire_ctx ww_ctx; int ret = 0;
/* No supply to resolve? */ @@ -1894,23 +1967,23 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) * between rdev->supply null check and setting rdev->supply in * set_supply() from concurrent tasks. */ - regulator_lock(rdev); + regulator_lock_two(rdev, r, &ww_ctx);
/* Supply just resolved by a concurrent task? */ if (rdev->supply) { - regulator_unlock(rdev); + regulator_unlock_two(rdev, r, &ww_ctx); put_device(&r->dev); goto out; }
ret = set_supply(rdev, r); if (ret < 0) { - regulator_unlock(rdev); + regulator_unlock_two(rdev, r, &ww_ctx); put_device(&r->dev); goto out; }
- regulator_unlock(rdev); + regulator_unlock_two(rdev, r, &ww_ctx);
/* * In set_machine_constraints() we may have turned this regulator on @@ -2023,7 +2096,9 @@ struct regulator *_regulator_get(struct device *dev, const char *id, return regulator; }
+ regulator_lock(rdev); regulator = create_regulator(rdev, dev, id); + regulator_unlock(rdev); if (regulator == NULL) { regulator = ERR_PTR(-ENOMEM); module_put(rdev->owner);
From: Uros Bizjak ubizjak@gmail.com
[ Upstream commit f96fb2df3eb31ede1b34b0521560967310267750 ]
The detection of atomic update failure in reserve_eilvt_offset() is not correct. The value returned by atomic_cmpxchg() should be compared to the old value from the location to be updated.
If these two are the same, then atomic update succeeded and "eilvt_offsets[offset]" location is updated to "new" in an atomic way.
Otherwise, the atomic update failed and it should be retried with the value from "eilvt_offsets[offset]" - exactly what atomic_try_cmpxchg() does in a correct and more optimal way.
Fixes: a68c439b1966c ("apic, x86: Check if EILVT APIC registers are available (AMD only)") Signed-off-by: Uros Bizjak ubizjak@gmail.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Link: https://lore.kernel.org/r/20230227160917.107820-1-ubizjak@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/apic/apic.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 1c96f2425eafd..25eb69f26e039 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -410,10 +410,9 @@ static unsigned int reserve_eilvt_offset(int offset, unsigned int new) if (vector && !eilvt_entry_is_changeable(vector, new)) /* may not change if vectors are different */ return rsvd; - rsvd = atomic_cmpxchg(&eilvt_offsets[offset], rsvd, new); - } while (rsvd != new); + } while (!atomic_try_cmpxchg(&eilvt_offsets[offset], &rsvd, new));
- rsvd &= ~APIC_EILVT_MASKED; + rsvd = new & ~APIC_EILVT_MASKED; if (rsvd && rsvd != vector) pr_info("LVT offset %d assigned for vector 0x%02x\n", offset, rsvd);
From: Zheng Wang zyytlz.wz@163.com
[ Upstream commit 3228cec23b8b29215e18090c6ba635840190993d ]
In rkvdec_probe, rkvdec->watchdog_work is bound with rkvdec_watchdog_func. Then rkvdec_vp9_run may be called to start the work.
If we remove the module which will call rkvdec_remove to make cleanup, there may be a unfinished work. The possible sequence is as follows, which will cause a typical UAF bug.
Fix it by canceling the work before cleanup in rkvdec_remove.
CPU0 CPU1
|rkvdec_watchdog_func rkvdec_remove | rkvdec_v4l2_cleanup| v4l2_m2m_release | kfree(m2m_dev); | | | v4l2_m2m_get_curr_priv | m2m_dev->curr_ctx //use
Fixes: cd33c830448b ("media: rkvdec: Add the rkvdec driver") Signed-off-by: Zheng Wang zyytlz.wz@163.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/rkvdec/rkvdec.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c index e384ea8d72801..f6a29a7078625 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -1077,6 +1077,8 @@ static int rkvdec_remove(struct platform_device *pdev) { struct rkvdec_dev *rkvdec = platform_get_drvdata(pdev);
+ cancel_delayed_work_sync(&rkvdec->watchdog_work); + rkvdec_v4l2_cleanup(rkvdec); pm_runtime_disable(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev);
From: Zheng Wang zyytlz.wz@163.com
[ Upstream commit 5abda7a16698d4d1f47af1168d8fa2c640116b4a ]
In dm1105_probe, it called dm1105_ir_init and bound &dm1105->ir.work with dm1105_emit_key. When it handles IRQ request with dm1105_irq, it may call schedule_work to start the work.
When we call dm1105_remove to remove the driver, there may be a sequence as follows:
Fix it by finishing the work before cleanup in dm1105_remove
CPU0 CPU1
|dm1105_emit_key dm1105_remove | dm1105_ir_exit | rc_unregister_device | rc_free_device | rc_dev_release | kfree(dev); | | | rc_keydown | //use
Fixes: 34d2f9bf189c ("V4L/DVB: dm1105: use dm1105_dev & dev instead of dm1105dvb") Signed-off-by: Zheng Wang zyytlz.wz@163.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/dm1105/dm1105.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c index 9dce31d2b525b..d2e194a24e7e7 100644 --- a/drivers/media/pci/dm1105/dm1105.c +++ b/drivers/media/pci/dm1105/dm1105.c @@ -1178,6 +1178,7 @@ static void dm1105_remove(struct pci_dev *pdev) struct dvb_demux *dvbdemux = &dev->demux; struct dmx_demux *dmx = &dvbdemux->dmx;
+ cancel_work_sync(&dev->ir.work); dm1105_ir_exit(dev); dmx->close(dmx); dvb_net_release(&dev->dvbnet);
From: Zheng Wang zyytlz.wz@163.com
[ Upstream commit 30cf57da176cca80f11df0d9b7f71581fe601389 ]
In saa7134_initdev, it will call saa7134_hwinit1. There are three function invoking here: saa7134_video_init1, saa7134_ts_init1 and saa7134_vbi_init1.
All of them will init a timer with same function. Take saa7134_video_init1 as an example. It'll bound &dev->video_q.timeout with saa7134_buffer_timeout.
In buffer_activate, the timer funtcion is started.
If we remove the module or device which will call saa7134_finidev to make cleanup, there may be a unfinished work. The possible sequence is as follows, which will cause a typical UAF bug.
Fix it by canceling the timer works accordingly before cleanup in saa7134_finidev.
CPU0 CPU1
|saa7134_buffer_timeout saa7134_finidev | kfree(dev); | | | saa7134_buffer_next | //use dev
Fixes: 1e7126b4a86a ("media: saa7134: Convert timers to use timer_setup()") Signed-off-by: Zheng Wang zyytlz.wz@163.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/saa7134/saa7134-ts.c | 1 + drivers/media/pci/saa7134/saa7134-vbi.c | 1 + drivers/media/pci/saa7134/saa7134-video.c | 1 + 3 files changed, 3 insertions(+)
diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c index 6a5053126237f..437dbe5e75e29 100644 --- a/drivers/media/pci/saa7134/saa7134-ts.c +++ b/drivers/media/pci/saa7134/saa7134-ts.c @@ -300,6 +300,7 @@ int saa7134_ts_start(struct saa7134_dev *dev)
int saa7134_ts_fini(struct saa7134_dev *dev) { + del_timer_sync(&dev->ts_q.timeout); saa7134_pgtable_free(dev->pci, &dev->ts_q.pt); return 0; } diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c index 3f0b0933eed69..3e773690468bd 100644 --- a/drivers/media/pci/saa7134/saa7134-vbi.c +++ b/drivers/media/pci/saa7134/saa7134-vbi.c @@ -185,6 +185,7 @@ int saa7134_vbi_init1(struct saa7134_dev *dev) int saa7134_vbi_fini(struct saa7134_dev *dev) { /* nothing */ + del_timer_sync(&dev->vbi_q.timeout); return 0; }
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 85d082baaadc5..df9e3293015a2 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -2153,6 +2153,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
void saa7134_video_fini(struct saa7134_dev *dev) { + del_timer_sync(&dev->video_q.timeout); /* free stuff */ saa7134_pgtable_free(dev->pci, &dev->video_q.pt); saa7134_pgtable_free(dev->pci, &dev->vbi_q.pt);
From: Mauro Carvalho Chehab mchehab+huawei@kernel.org
[ Upstream commit fa9f443f7c962d072d150472e2bb77de39817a9a ]
Avoid some code duplication by moving the common error path logic at fdp_open().
Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Stable-dep-of: c766c90faf93 ("media: rcar_fdp1: Fix refcount leak in probe and remove function") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/rcar_fdp1.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index c9448de885b62..ac2e7b2c60829 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -2121,9 +2121,7 @@ static int fdp1_open(struct file *file)
if (ctx->hdl.error) { ret = ctx->hdl.error; - v4l2_ctrl_handler_free(&ctx->hdl); - kfree(ctx); - goto done; + goto error_ctx; }
ctx->fh.ctrl_handler = &ctx->hdl; @@ -2137,10 +2135,7 @@ static int fdp1_open(struct file *file)
if (IS_ERR(ctx->fh.m2m_ctx)) { ret = PTR_ERR(ctx->fh.m2m_ctx); - - v4l2_ctrl_handler_free(&ctx->hdl); - kfree(ctx); - goto done; + goto error_ctx; }
/* Perform any power management required */ @@ -2151,6 +2146,12 @@ static int fdp1_open(struct file *file) dprintk(fdp1, "Created instance: %p, m2m_ctx: %p\n", ctx, ctx->fh.m2m_ctx);
+ mutex_unlock(&fdp1->dev_mutex); + return 0; + +error_ctx: + v4l2_ctrl_handler_free(&ctx->hdl); + kfree(ctx); done: mutex_unlock(&fdp1->dev_mutex); return ret;
From: Mauro Carvalho Chehab mchehab+huawei@kernel.org
[ Upstream commit 45e75a8c6fa455a5909ac04db76a4b15d6bb8368 ]
The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. Replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter, avoiding a potential PM usage counter leak.
Also, right now, the driver is ignoring any troubles when trying to do PM resume. So, add the proper error handling for the code.
Reviewed-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Stable-dep-of: c766c90faf93 ("media: rcar_fdp1: Fix refcount leak in probe and remove function") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/rcar_fdp1.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index ac2e7b2c60829..cedae184c6ad4 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -2139,7 +2139,9 @@ static int fdp1_open(struct file *file) }
/* Perform any power management required */ - pm_runtime_get_sync(fdp1->dev); + ret = pm_runtime_resume_and_get(fdp1->dev); + if (ret < 0) + goto error_pm;
v4l2_fh_add(&ctx->fh);
@@ -2149,6 +2151,8 @@ static int fdp1_open(struct file *file) mutex_unlock(&fdp1->dev_mutex); return 0;
+error_pm: + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); error_ctx: v4l2_ctrl_handler_free(&ctx->hdl); kfree(ctx); @@ -2356,7 +2360,9 @@ static int fdp1_probe(struct platform_device *pdev)
/* Power up the cells to read HW */ pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(fdp1->dev); + ret = pm_runtime_resume_and_get(fdp1->dev); + if (ret < 0) + goto disable_pm;
hw_version = fdp1_read(fdp1, FD1_IP_INTDATA); switch (hw_version) { @@ -2385,6 +2391,9 @@ static int fdp1_probe(struct platform_device *pdev)
return 0;
+disable_pm: + pm_runtime_disable(fdp1->dev); + release_m2m: v4l2_m2m_release(fdp1->m2m_dev);
From: Cai Huoqing caihuoqing@baidu.com
[ Upstream commit 736cce12fa630e28705de06570d74f0513d948d5 ]
Use the devm_platform_ioremap_resource() helper instead of calling platform_get_resource() and devm_ioremap_resource() separately
Signed-off-by: Cai Huoqing caihuoqing@baidu.com Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Stable-dep-of: c766c90faf93 ("media: rcar_fdp1: Fix refcount leak in probe and remove function") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/rcar_fdp1.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index cedae184c6ad4..782e805b85da2 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -2260,7 +2260,6 @@ static int fdp1_probe(struct platform_device *pdev) struct fdp1_dev *fdp1; struct video_device *vfd; struct device_node *fcp_node; - struct resource *res; struct clk *clk; unsigned int i;
@@ -2287,8 +2286,7 @@ static int fdp1_probe(struct platform_device *pdev) platform_set_drvdata(pdev, fdp1);
/* Memory-mapped registers */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - fdp1->regs = devm_ioremap_resource(&pdev->dev, res); + fdp1->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(fdp1->regs)) return PTR_ERR(fdp1->regs);
From: Tang Bin tangbin@cmss.chinamobile.com
[ Upstream commit af88c2adbb72a09ab1bb5c37ba388c98fecca69b ]
In the function fdp1_probe(), when get irq failed, the function platform_get_irq() log an error message, so remove redundant message here. And the variable type of "ret" is int, the "fdp1->irq" is unsigned int, when irq failed, this place maybe wrong, thus fix it.
Signed-off-by: Tang Bin tangbin@cmss.chinamobile.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Stable-dep-of: c766c90faf93 ("media: rcar_fdp1: Fix refcount leak in probe and remove function") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/rcar_fdp1.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index 782e805b85da2..1dd8bebb66f53 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -2291,11 +2291,10 @@ static int fdp1_probe(struct platform_device *pdev) return PTR_ERR(fdp1->regs);
/* Interrupt service routine registration */ - fdp1->irq = ret = platform_get_irq(pdev, 0); - if (ret < 0) { - dev_err(&pdev->dev, "cannot find IRQ\n"); + ret = platform_get_irq(pdev, 0); + if (ret < 0) return ret; - } + fdp1->irq = ret;
ret = devm_request_irq(&pdev->dev, fdp1->irq, fdp1_irq_handler, 0, dev_name(&pdev->dev), fdp1);
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit c766c90faf93897b77c9c5daa603cffab85ba907 ]
rcar_fcp_get() take reference, which should be balanced with rcar_fcp_put(). Add missing rcar_fcp_put() in fdp1_remove and the error paths of fdp1_probe() to fix this.
Fixes: 4710b752e029 ("[media] v4l: Add Renesas R-Car FDP1 Driver") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com [hverkuil: resolve merge conflict, remove() is now void] Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/rcar_fdp1.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index 1dd8bebb66f53..44a57fa06e74a 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -2317,8 +2317,10 @@ static int fdp1_probe(struct platform_device *pdev)
/* Determine our clock rate */ clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) - return PTR_ERR(clk); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto put_dev; + }
fdp1->clk_rate = clk_get_rate(clk); clk_put(clk); @@ -2327,7 +2329,7 @@ static int fdp1_probe(struct platform_device *pdev) ret = v4l2_device_register(&pdev->dev, &fdp1->v4l2_dev); if (ret) { v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n"); - return ret; + goto put_dev; }
/* M2M registration */ @@ -2397,6 +2399,8 @@ static int fdp1_probe(struct platform_device *pdev) unreg_dev: v4l2_device_unregister(&fdp1->v4l2_dev);
+put_dev: + rcar_fcp_put(fdp1->fcp); return ret; }
@@ -2408,6 +2412,7 @@ static int fdp1_remove(struct platform_device *pdev) video_unregister_device(&fdp1->vfd); v4l2_device_unregister(&fdp1->v4l2_dev); pm_runtime_disable(&pdev->dev); + rcar_fcp_put(fdp1->fcp);
return 0; }
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit 9c592f8ab114875fdb3b2040f01818e53de44991 ]
The driver was intended from the start to be a wake-up source for the system, however due to the absence of a suitable call to device_set_wakeup_capable(), the device_may_wakeup() call used to decide whether to enable the GPIO interrupt as a wake-up source would never happen. Lookup the DT standard "wakeup-source" property and call device_init_wakeup() to ensure the device is flagged as being wakeup capable.
Reported-by: Matthew Lear matthew.lear@broadcom.com Fixes: fd0f6851eb46 ("[media] rc: Add support for GPIO based IR Receiver driver") Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sean Young sean@mess.org Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/rc/gpio-ir-recv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index a56c844d7f816..16795e07dc103 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -107,6 +107,8 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) rcdev->map_name = RC_MAP_EMPTY;
gpio_dev->rcdev = rcdev; + if (of_property_read_bool(np, "wakeup-source")) + device_init_wakeup(dev, true);
rc = devm_rc_register_device(dev, rcdev); if (rc < 0) {
From: Stanimir Varbanov stanimir.varbanov@linaro.org
[ Upstream commit acf8a57d8caf5ceabbe50774953fe04745ad1a50 ]
In real use of dynamic-resolution-change it is observed that the LAST buffer flag (which marks the last decoded buffer with the resolution before the resolution-change event) is not reliably set.
Fix this by set the LAST buffer flag on next queued capture buffer after the resolution-change event.
Signed-off-by: Stanimir Varbanov stanimir.varbanov@linaro.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Stable-dep-of: 50248ad9f190 ("media: venus: dec: Fix handling of the start cmd") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/qcom/venus/core.h | 5 +-- drivers/media/platform/qcom/venus/helpers.c | 6 +++ drivers/media/platform/qcom/venus/vdec.c | 45 ++++++++++++--------- 3 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index f2a0ef9ee884e..f78eed2c243a8 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -283,7 +283,6 @@ enum venus_dec_state { VENUS_DEC_STATE_DRAIN = 5, VENUS_DEC_STATE_DECODING = 6, VENUS_DEC_STATE_DRC = 7, - VENUS_DEC_STATE_DRC_FLUSH_DONE = 8, };
struct venus_ts_metadata { @@ -348,7 +347,7 @@ struct venus_ts_metadata { * @priv: a private for HFI operations callbacks * @session_type: the type of the session (decoder or encoder) * @hprop: a union used as a holder by get property - * @last_buf: last capture buffer for dynamic-resoluton-change + * @next_buf_last: a flag to mark next queued capture buffer as last */ struct venus_inst { struct list_head list; @@ -410,7 +409,7 @@ struct venus_inst { union hfi_get_property hprop; unsigned int core_acquired: 1; unsigned int bit_depth; - struct vb2_buffer *last_buf; + bool next_buf_last; };
#define IS_V1(core) ((core)->res->hfi_version == HFI_VERSION_1XX) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 50439eb1ffeaa..5ca3920237c5a 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -1347,6 +1347,12 @@ void venus_helper_vb2_buf_queue(struct vb2_buffer *vb)
v4l2_m2m_buf_queue(m2m_ctx, vbuf);
+ /* Skip processing queued capture buffers after LAST flag */ + if (inst->session_type == VIDC_SESSION_TYPE_DEC && + V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && + inst->codec_state == VENUS_DEC_STATE_DRC) + goto unlock; + cache_payload(inst, vb);
if (inst->session_type == VIDC_SESSION_TYPE_ENC && diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index de34a87d1130e..b6b5ae0a457bb 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -916,10 +916,6 @@ static int vdec_start_capture(struct venus_inst *inst) return 0;
reconfigure: - ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, true); - if (ret) - return ret; - ret = vdec_output_conf(inst); if (ret) return ret; @@ -947,6 +943,8 @@ static int vdec_start_capture(struct venus_inst *inst)
venus_pm_load_scale(inst);
+ inst->next_buf_last = false; + ret = hfi_session_continue(inst); if (ret) goto free_dpb_bufs; @@ -987,6 +985,7 @@ static int vdec_start_output(struct venus_inst *inst) venus_helper_init_instance(inst); inst->sequence_out = 0; inst->reconfig = false; + inst->next_buf_last = false;
ret = vdec_set_properties(inst); if (ret) @@ -1080,9 +1079,7 @@ static int vdec_stop_capture(struct venus_inst *inst) inst->codec_state = VENUS_DEC_STATE_STOPPED; break; case VENUS_DEC_STATE_DRC: - WARN_ON(1); - fallthrough; - case VENUS_DEC_STATE_DRC_FLUSH_DONE: + ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, true); inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP; venus_helper_free_dpb_bufs(inst); break; @@ -1206,9 +1203,28 @@ static void vdec_buf_cleanup(struct vb2_buffer *vb) static void vdec_vb2_buf_queue(struct vb2_buffer *vb) { struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + static const struct v4l2_event eos = { .type = V4L2_EVENT_EOS };
vdec_pm_get_put(inst);
+ mutex_lock(&inst->lock); + + if (inst->next_buf_last && V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && + inst->codec_state == VENUS_DEC_STATE_DRC) { + vbuf->flags |= V4L2_BUF_FLAG_LAST; + vbuf->sequence = inst->sequence_cap++; + vbuf->field = V4L2_FIELD_NONE; + vb2_set_plane_payload(vb, 0, 0); + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); + v4l2_event_queue_fh(&inst->fh, &eos); + inst->next_buf_last = false; + mutex_unlock(&inst->lock); + return; + } + + mutex_unlock(&inst->lock); + venus_helper_vb2_buf_queue(vb); }
@@ -1252,13 +1268,6 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type, vb->timestamp = timestamp_us * NSEC_PER_USEC; vbuf->sequence = inst->sequence_cap++;
- if (inst->last_buf == vb) { - inst->last_buf = NULL; - vbuf->flags |= V4L2_BUF_FLAG_LAST; - vb2_set_plane_payload(vb, 0, 0); - vb->timestamp = 0; - } - if (vbuf->flags & V4L2_BUF_FLAG_LAST) { const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
@@ -1343,12 +1352,9 @@ static void vdec_event_change(struct venus_inst *inst, */
if (!sufficient && inst->codec_state == VENUS_DEC_STATE_DRC) { - struct vb2_v4l2_buffer *last; int ret;
- last = v4l2_m2m_last_dst_buf(inst->m2m_ctx); - if (last) - inst->last_buf = &last->vb2_buf; + inst->next_buf_last = true;
ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, false); if (ret) @@ -1397,8 +1403,7 @@ static void vdec_event_notify(struct venus_inst *inst, u32 event,
static void vdec_flush_done(struct venus_inst *inst) { - if (inst->codec_state == VENUS_DEC_STATE_DRC) - inst->codec_state = VENUS_DEC_STATE_DRC_FLUSH_DONE; + dev_dbg(inst->core->dev_dec, VDBGH "flush done\n"); }
static const struct hfi_inst_ops vdec_hfi_ops = {
From: Stanimir Varbanov stanimir.varbanov@linaro.org
[ Upstream commit a4ca67af8b831a781ac53060c5d5c3dccaf7676e ]
This makes the decoder to behaives equally for sufficient and insufficient events. After this change the LAST buffer flag will be set when the new resolution (in dynamic-resolution-change state) is smaller then the old bitstream resolution.
Signed-off-by: Stanimir Varbanov stanimir.varbanov@linaro.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Stable-dep-of: 50248ad9f190 ("media: venus: dec: Fix handling of the start cmd") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/qcom/venus/vdec.c | 42 ++++++++++++++++-------- 1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index b6b5ae0a457bb..3adff10fce6a7 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -636,6 +636,7 @@ static int vdec_output_conf(struct venus_inst *inst) { struct venus_core *core = inst->core; struct hfi_enable en = { .enable = 1 }; + struct hfi_buffer_requirements bufreq; u32 width = inst->out_width; u32 height = inst->out_height; u32 out_fmt, out2_fmt; @@ -711,6 +712,23 @@ static int vdec_output_conf(struct venus_inst *inst) }
if (IS_V3(core) || IS_V4(core)) { + ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); + if (ret) + return ret; + + if (bufreq.size > inst->output_buf_size) + return -EINVAL; + + if (inst->dpb_fmt) { + ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT2, + &bufreq); + if (ret) + return ret; + + if (bufreq.size > inst->output2_buf_size) + return -EINVAL; + } + if (inst->output2_buf_size) { ret = venus_helper_set_bufsize(inst, inst->output2_buf_size, @@ -1330,19 +1348,15 @@ static void vdec_event_change(struct venus_inst *inst, dev_dbg(dev, VDBGM "event %s sufficient resources (%ux%u)\n", sufficient ? "" : "not", ev_data->width, ev_data->height);
- if (sufficient) { - hfi_session_continue(inst); - } else { - switch (inst->codec_state) { - case VENUS_DEC_STATE_INIT: - inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP; - break; - case VENUS_DEC_STATE_DECODING: - inst->codec_state = VENUS_DEC_STATE_DRC; - break; - default: - break; - } + switch (inst->codec_state) { + case VENUS_DEC_STATE_INIT: + inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP; + break; + case VENUS_DEC_STATE_DECODING: + inst->codec_state = VENUS_DEC_STATE_DRC; + break; + default: + break; }
/* @@ -1351,7 +1365,7 @@ static void vdec_event_change(struct venus_inst *inst, * itself doesn't mark the last decoder output buffer with HFI EOS flag. */
- if (!sufficient && inst->codec_state == VENUS_DEC_STATE_DRC) { + if (inst->codec_state == VENUS_DEC_STATE_DRC) { int ret;
inst->next_buf_last = true;
From: Alexandre Courbot acourbot@chromium.org
[ Upstream commit d5ee32d7e5929592ad9b6e7a919dcdf89d05221b ]
DRC events can happen virtually at anytime, including when we are starting a seek. Should this happen, we must make sure to return to the DRC state, otherwise the firmware will expect buffers of the new resolution whereas userspace will still work with the old one.
Returning to the DRC state upon resume for seeking makes sure that the client will get the DRC event and will reallocate the buffers to fit the firmware's expectations.
Signed-off-by: Alexandre Courbot acourbot@chromium.org Signed-off-by: Stanimir Varbanov stanimir.varbanov@linaro.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Stable-dep-of: 50248ad9f190 ("media: venus: dec: Fix handling of the start cmd") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/qcom/venus/vdec.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 3adff10fce6a7..1bb2350408cf2 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -987,7 +987,10 @@ static int vdec_start_output(struct venus_inst *inst)
if (inst->codec_state == VENUS_DEC_STATE_SEEK) { ret = venus_helper_process_initial_out_bufs(inst); - inst->codec_state = VENUS_DEC_STATE_DECODING; + if (inst->next_buf_last) + inst->codec_state = VENUS_DEC_STATE_DRC; + else + inst->codec_state = VENUS_DEC_STATE_DECODING; goto done; }
@@ -1093,8 +1096,10 @@ static int vdec_stop_capture(struct venus_inst *inst) ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true); fallthrough; case VENUS_DEC_STATE_DRAIN: - vdec_cancel_dst_buffers(inst); inst->codec_state = VENUS_DEC_STATE_STOPPED; + fallthrough; + case VENUS_DEC_STATE_SEEK: + vdec_cancel_dst_buffers(inst); break; case VENUS_DEC_STATE_DRC: ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, true); @@ -1116,6 +1121,7 @@ static int vdec_stop_output(struct venus_inst *inst) case VENUS_DEC_STATE_DECODING: case VENUS_DEC_STATE_DRAIN: case VENUS_DEC_STATE_STOPPED: + case VENUS_DEC_STATE_DRC: ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true); inst->codec_state = VENUS_DEC_STATE_SEEK; break; @@ -1375,6 +1381,7 @@ static void vdec_event_change(struct venus_inst *inst, dev_dbg(dev, VDBGH "flush output error %d\n", ret); }
+ inst->next_buf_last = true; inst->reconfig = true; v4l2_event_queue_fh(&inst->fh, &ev); wake_up(&inst->reconf_wait);
From: Fritz Koenig frkoenig@chromium.org
[ Upstream commit c8e8dabcd1a8c7aaedc514052d383a8152119084 ]
If the DRC is near the end of the stream the client may send a V4L2_DEC_CMD_STOP before the DRC occurs. V4L2_DEC_CMD_STOP puts the driver into the VENUS_DEC_STATE_DRAIN state. DRC must be aware so that after the DRC event the state can be restored correctly.
Signed-off-by: Fritz Koenig frkoenig@chromium.org Signed-off-by: Stanimir Varbanov stanimir.varbanov@linaro.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Stable-dep-of: 50248ad9f190 ("media: venus: dec: Fix handling of the start cmd") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/qcom/venus/core.h | 1 + drivers/media/platform/qcom/venus/vdec.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index f78eed2c243a8..aebd4c664bfa1 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -410,6 +410,7 @@ struct venus_inst { unsigned int core_acquired: 1; unsigned int bit_depth; bool next_buf_last; + bool drain_active; };
#define IS_V1(core) ((core)->res->hfi_version == HFI_VERSION_1XX) diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 1bb2350408cf2..766c292915272 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -518,8 +518,10 @@ vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
ret = hfi_session_process_buf(inst, &fdata);
- if (!ret && inst->codec_state == VENUS_DEC_STATE_DECODING) + if (!ret && inst->codec_state == VENUS_DEC_STATE_DECODING) { inst->codec_state = VENUS_DEC_STATE_DRAIN; + inst->drain_active = true; + } }
unlock: @@ -969,9 +971,13 @@ static int vdec_start_capture(struct venus_inst *inst)
inst->codec_state = VENUS_DEC_STATE_DECODING;
+ if (inst->drain_active) + inst->codec_state = VENUS_DEC_STATE_DRAIN; + inst->streamon_cap = 1; inst->sequence_cap = 0; inst->reconfig = false; + inst->drain_active = false;
return 0;
@@ -1097,6 +1103,7 @@ static int vdec_stop_capture(struct venus_inst *inst) fallthrough; case VENUS_DEC_STATE_DRAIN: inst->codec_state = VENUS_DEC_STATE_STOPPED; + inst->drain_active = false; fallthrough; case VENUS_DEC_STATE_SEEK: vdec_cancel_dst_buffers(inst); @@ -1297,8 +1304,10 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
v4l2_event_queue_fh(&inst->fh, &ev);
- if (inst->codec_state == VENUS_DEC_STATE_DRAIN) + if (inst->codec_state == VENUS_DEC_STATE_DRAIN) { + inst->drain_active = false; inst->codec_state = VENUS_DEC_STATE_STOPPED; + } }
if (!bytesused) @@ -1359,6 +1368,7 @@ static void vdec_event_change(struct venus_inst *inst, inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP; break; case VENUS_DEC_STATE_DECODING: + case VENUS_DEC_STATE_DRAIN: inst->codec_state = VENUS_DEC_STATE_DRC; break; default:
From: Michał Krawczyk mk@semihalf.com
[ Upstream commit 50248ad9f190d527cbd578190ca769729518b703 ]
The decoder driver should clear the last_buffer_dequeued flag of the capture queue upon receiving V4L2_DEC_CMD_START.
The last_buffer_dequeued flag is set upon receiving EOS (which always happens upon receiving V4L2_DEC_CMD_STOP).
Without this patch, after issuing the V4L2_DEC_CMD_STOP and V4L2_DEC_CMD_START, the vb2_dqbuf() function will always fail, even if the buffers are completed by the hardware.
Fixes: beac82904a87 ("media: venus: make decoder compliant with stateful codec API")
Signed-off-by: Michał Krawczyk mk@semihalf.com Signed-off-by: Stanimir Varbanov stanimir.k.varbanov@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/qcom/venus/vdec.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 766c292915272..c437a929a5451 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -495,6 +495,7 @@ static int vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) { struct venus_inst *inst = to_inst(file); + struct vb2_queue *dst_vq; struct hfi_frame_data fdata = {0}; int ret;
@@ -522,6 +523,13 @@ vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) inst->codec_state = VENUS_DEC_STATE_DRAIN; inst->drain_active = true; } + } else if (cmd->cmd == V4L2_DEC_CMD_START && + inst->codec_state == VENUS_DEC_STATE_STOPPED) { + dst_vq = v4l2_m2m_get_vq(inst->fh.m2m_ctx, + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + vb2_clear_last_buffer_dequeued(dst_vq); + + inst->codec_state = VENUS_DEC_STATE_DECODING; }
unlock:
From: YAN SHI m202071378@hust.edu.cn
[ Upstream commit c4a413e56d16a2ae84e6d8992f215c4dcc7fac20 ]
Smatch reports: drivers/regulator/stm32-pwr.c:166 stm32_pwr_regulator_probe() warn: 'base' from of_iomap() not released on lines: 151,166.
In stm32_pwr_regulator_probe(), base is not released when devm_kzalloc() fails to allocate memory or devm_regulator_register() fails to register a new regulator device, which may cause a leak.
To fix this issue, replace of_iomap() with devm_platform_ioremap_resource(). devm_platform_ioremap_resource() is a specialized function for platform devices. It allows 'base' to be automatically released whether the probe function succeeds or fails.
Besides, use IS_ERR(base) instead of !base as the return value of devm_platform_ioremap_resource() can either be a pointer to the remapped memory or an ERR_PTR() encoded error code if the operation fails.
Fixes: dc62f951a6a8 ("regulator: stm32-pwr: Fix return value check in stm32_pwr_regulator_probe()") Signed-off-by: YAN SHI m202071378@hust.edu.cn Reported-by: kernel test robot lkp@intel.com Link: https://lore.kernel.org/oe-kbuild-all/202304111750.o2643eJN-lkp@intel.com/ Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Link: https://lore.kernel.org/r/20230412033529.18890-1-m202071378@hust.edu.cn Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/stm32-pwr.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/regulator/stm32-pwr.c b/drivers/regulator/stm32-pwr.c index 2a42acb7c24e9..e5dd4db6403b2 100644 --- a/drivers/regulator/stm32-pwr.c +++ b/drivers/regulator/stm32-pwr.c @@ -129,17 +129,16 @@ static const struct regulator_desc stm32_pwr_desc[] = {
static int stm32_pwr_regulator_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; struct stm32_pwr_reg *priv; void __iomem *base; struct regulator_dev *rdev; struct regulator_config config = { }; int i, ret = 0;
- base = of_iomap(np, 0); - if (!base) { + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) { dev_err(&pdev->dev, "Unable to map IO memory\n"); - return -ENOMEM; + return PTR_ERR(base); }
config.dev = &pdev->dev;
From: Saurabh Sengar ssengar@linux.microsoft.com
[ Upstream commit 5af507bef93c09a94fb8f058213b489178f4cbe5 ]
arch_dynirq_lower_bound() is invoked by the core interrupt code to retrieve the lowest possible Linux interrupt number for dynamically allocated interrupts like MSI.
The x86 implementation uses this to exclude the IO/APIC GSI space. This works correctly as long as there is an IO/APIC registered, but returns 0 if not. This has been observed in VMs where the BIOS does not advertise an IO/APIC.
0 is an invalid interrupt number except for the legacy timer interrupt on x86. The return value is unchecked in the core code, so it ends up to allocate interrupt number 0 which is subsequently considered to be invalid by the caller, e.g. the MSI allocation code.
The function has already a check for 0 in the case that an IO/APIC is registered, as ioapic_dynirq_base is 0 in case of device tree setups.
Consolidate this and zero check for both ioapic_dynirq_base and gsi_top, which is used in the case that no IO/APIC is registered.
Fixes: 3e5bedc2c258 ("x86/apic: Fix arch_dynirq_lower_bound() bug for DT enabled machines") Signed-off-by: Saurabh Sengar ssengar@linux.microsoft.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lore.kernel.org/r/1679988604-20308-1-git-send-email-ssengar@linux.mi... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/apic/io_apic.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 25b1d5c6af969..74794387bf59d 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2442,17 +2442,21 @@ static int io_apic_get_redir_entries(int ioapic)
unsigned int arch_dynirq_lower_bound(unsigned int from) { + unsigned int ret; + /* * dmar_alloc_hwirq() may be called before setup_IO_APIC(), so use * gsi_top if ioapic_dynirq_base hasn't been initialized yet. */ - if (!ioapic_initialized) - return gsi_top; + ret = ioapic_dynirq_base ? : gsi_top; + /* - * For DT enabled machines ioapic_dynirq_base is irrelevant and not - * updated. So simply return @from if ioapic_dynirq_base == 0. + * For DT enabled machines ioapic_dynirq_base is irrelevant and + * always 0. gsi_top can be 0 if there is no IO/APIC registered. + * 0 is an invalid interrupt number for dynamic allocations. Return + * @from instead. */ - return ioapic_dynirq_base ? : from; + return ret ? : from; }
#ifdef CONFIG_X86_32
From: Sumit Garg sumit.garg@linaro.org
[ Upstream commit af6c0bd59f4f3ad5daad2f7b777954b1954551d5 ]
Currently only the first attempt to single-step has any effect. After that all further stepping remains "stuck" at the same program counter value.
Refer to the ARM Architecture Reference Manual (ARM DDI 0487E.a) D2.12, PSTATE.SS=1 should be set at each step before transferring the PE to the 'Active-not-pending' state. The problem here is PSTATE.SS=1 is not set since the second single-step.
After the first single-step, the PE transferes to the 'Inactive' state, with PSTATE.SS=0 and MDSCR.SS=1, thus PSTATE.SS won't be set to 1 due to kernel_active_single_step()=true. Then the PE transferes to the 'Active-pending' state when ERET and returns to the debugger by step exception.
Before this patch: ================== Entering kdb (current=0xffff3376039f0000, pid 1) on processor 0 due to Keyboard Entry [0]kdb>
[0]kdb> [0]kdb> bp write_sysrq_trigger Instruction(i) BP #0 at 0xffffa45c13d09290 (write_sysrq_trigger) is enabled addr at ffffa45c13d09290, hardtype=0 installed=0
[0]kdb> go $ echo h > /proc/sysrq-trigger
Entering kdb (current=0xffff4f7e453f8000, pid 175) on processor 1 due to Breakpoint @ 0xffffad651a309290 [1]kdb> ss
Entering kdb (current=0xffff4f7e453f8000, pid 175) on processor 1 due to SS trap @ 0xffffad651a309294 [1]kdb> ss
Entering kdb (current=0xffff4f7e453f8000, pid 175) on processor 1 due to SS trap @ 0xffffad651a309294 [1]kdb>
After this patch: ================= Entering kdb (current=0xffff6851c39f0000, pid 1) on processor 0 due to Keyboard Entry [0]kdb> bp write_sysrq_trigger Instruction(i) BP #0 at 0xffffc02d2dd09290 (write_sysrq_trigger) is enabled addr at ffffc02d2dd09290, hardtype=0 installed=0
[0]kdb> go $ echo h > /proc/sysrq-trigger
Entering kdb (current=0xffff6851c53c1840, pid 174) on processor 1 due to Breakpoint @ 0xffffc02d2dd09290 [1]kdb> ss
Entering kdb (current=0xffff6851c53c1840, pid 174) on processor 1 due to SS trap @ 0xffffc02d2dd09294 [1]kdb> ss
Entering kdb (current=0xffff6851c53c1840, pid 174) on processor 1 due to SS trap @ 0xffffc02d2dd09298 [1]kdb> ss
Entering kdb (current=0xffff6851c53c1840, pid 174) on processor 1 due to SS trap @ 0xffffc02d2dd0929c [1]kdb>
Fixes: 44679a4f142b ("arm64: KGDB: Add step debugging support") Co-developed-by: Wei Li liwei391@huawei.com Signed-off-by: Wei Li liwei391@huawei.com Signed-off-by: Sumit Garg sumit.garg@linaro.org Tested-by: Douglas Anderson dianders@chromium.org Acked-by: Daniel Thompson daniel.thompson@linaro.org Tested-by: Daniel Thompson daniel.thompson@linaro.org Link: https://lore.kernel.org/r/20230202073148.657746-3-sumit.garg@linaro.org Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/include/asm/debug-monitors.h | 1 + arch/arm64/kernel/debug-monitors.c | 5 +++++ arch/arm64/kernel/kgdb.c | 2 ++ 3 files changed, 8 insertions(+)
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h index 657c921fd784a..c16ed5b68768e 100644 --- a/arch/arm64/include/asm/debug-monitors.h +++ b/arch/arm64/include/asm/debug-monitors.h @@ -116,6 +116,7 @@ void user_regs_reset_single_step(struct user_pt_regs *regs, void kernel_enable_single_step(struct pt_regs *regs); void kernel_disable_single_step(void); int kernel_active_single_step(void); +void kernel_rewind_single_step(struct pt_regs *regs);
#ifdef CONFIG_HAVE_HW_BREAKPOINT int reinstall_suspended_bps(struct pt_regs *regs); diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index fa76151de6ff1..38a0213fdbeee 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -439,6 +439,11 @@ int kernel_active_single_step(void) } NOKPROBE_SYMBOL(kernel_active_single_step);
+void kernel_rewind_single_step(struct pt_regs *regs) +{ + set_regs_spsr_ss(regs); +} + /* ptrace API */ void user_enable_single_step(struct task_struct *task) { diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c index 1a157ca33262d..e4e95821b1f6c 100644 --- a/arch/arm64/kernel/kgdb.c +++ b/arch/arm64/kernel/kgdb.c @@ -223,6 +223,8 @@ int kgdb_arch_handle_exception(int exception_vector, int signo, */ if (!kernel_active_single_step()) kernel_enable_single_step(linux_regs); + else + kernel_rewind_single_step(linux_regs); err = 0; break; default:
From: Thomas Gleixner tglx@linutronix.de
[ Upstream commit 63a759694eed61025713b3e14dd827c8548daadc ]
Statically initialized objects are usually not initialized via the init() function of the subsystem. They are special cased and the subsystem provides a function to validate whether an object which is not yet tracked by debugobjects is statically initialized. This means the object is started to be tracked on first use, e.g. activation.
This works perfectly fine, unless there are two concurrent operations on that object. Schspa decoded the problem:
T0 T1
debug_object_assert_init(addr) lock_hash_bucket() obj = lookup_object(addr); if (!obj) { unlock_hash_bucket(); - > preemption lock_subsytem_object(addr); activate_object(addr) lock_hash_bucket(); obj = lookup_object(addr); if (!obj) { unlock_hash_bucket(); if (is_static_object(addr)) init_and_track(addr); lock_hash_bucket(); obj = lookup_object(addr); obj->state = ACTIVATED; unlock_hash_bucket();
subsys function modifies content of addr, so static object detection does not longer work.
unlock_subsytem_object(addr);
if (is_static_object(addr)) <- Fails
debugobject emits a warning and invokes the fixup function which reinitializes the already active object in the worst case.
This race exists forever, but was never observed until mod_timer() got a debug_object_assert_init() added which is outside of the timer base lock held section right at the beginning of the function to cover the lockless early exit points too.
Rework the code so that the lookup, the static object check and the tracking object association happens atomically under the hash bucket lock. This prevents the issue completely as all callers are serialized on the hash bucket lock and therefore cannot observe inconsistent state.
Fixes: 3ac7fe5a4aab ("infrastructure to debug (dynamic) objects") Reported-by: syzbot+5093ba19745994288b53@syzkaller.appspotmail.com Debugged-by: Schspa Shi schspa@gmail.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Stephen Boyd swboyd@chromium.org Link: https://syzkaller.appspot.com/bug?id=22c8a5938eab640d1c6bcc0e3dc7be519d87846... Link: https://lore.kernel.org/lkml/20230303161906.831686-1-schspa@gmail.com Link: https://lore.kernel.org/r/87zg7dzgao.ffs@tglx Signed-off-by: Sasha Levin sashal@kernel.org --- lib/debugobjects.c | 125 ++++++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 59 deletions(-)
diff --git a/lib/debugobjects.c b/lib/debugobjects.c index 71bdc167a9ee7..8282ae37db4ef 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -219,10 +219,6 @@ static struct debug_obj *__alloc_object(struct hlist_head *list) return obj; }
-/* - * Allocate a new object. If the pool is empty, switch off the debugger. - * Must be called with interrupts disabled. - */ static struct debug_obj * alloc_object(void *addr, struct debug_bucket *b, const struct debug_obj_descr *descr) { @@ -555,11 +551,49 @@ static void debug_object_is_on_stack(void *addr, int onstack) WARN_ON(1); }
+static struct debug_obj *lookup_object_or_alloc(void *addr, struct debug_bucket *b, + const struct debug_obj_descr *descr, + bool onstack, bool alloc_ifstatic) +{ + struct debug_obj *obj = lookup_object(addr, b); + enum debug_obj_state state = ODEBUG_STATE_NONE; + + if (likely(obj)) + return obj; + + /* + * debug_object_init() unconditionally allocates untracked + * objects. It does not matter whether it is a static object or + * not. + * + * debug_object_assert_init() and debug_object_activate() allow + * allocation only if the descriptor callback confirms that the + * object is static and considered initialized. For non-static + * objects the allocation needs to be done from the fixup callback. + */ + if (unlikely(alloc_ifstatic)) { + if (!descr->is_static_object || !descr->is_static_object(addr)) + return ERR_PTR(-ENOENT); + /* Statically allocated objects are considered initialized */ + state = ODEBUG_STATE_INIT; + } + + obj = alloc_object(addr, b, descr); + if (likely(obj)) { + obj->state = state; + debug_object_is_on_stack(addr, onstack); + return obj; + } + + /* Out of memory. Do the cleanup outside of the locked region */ + debug_objects_enabled = 0; + return NULL; +} + static void __debug_object_init(void *addr, const struct debug_obj_descr *descr, int onstack) { enum debug_obj_state state; - bool check_stack = false; struct debug_bucket *db; struct debug_obj *obj; unsigned long flags; @@ -570,16 +604,11 @@ __debug_object_init(void *addr, const struct debug_obj_descr *descr, int onstack
raw_spin_lock_irqsave(&db->lock, flags);
- obj = lookup_object(addr, db); - if (!obj) { - obj = alloc_object(addr, db, descr); - if (!obj) { - debug_objects_enabled = 0; - raw_spin_unlock_irqrestore(&db->lock, flags); - debug_objects_oom(); - return; - } - check_stack = true; + obj = lookup_object_or_alloc(addr, db, descr, onstack, false); + if (unlikely(!obj)) { + raw_spin_unlock_irqrestore(&db->lock, flags); + debug_objects_oom(); + return; }
switch (obj->state) { @@ -605,8 +634,6 @@ __debug_object_init(void *addr, const struct debug_obj_descr *descr, int onstack }
raw_spin_unlock_irqrestore(&db->lock, flags); - if (check_stack) - debug_object_is_on_stack(addr, onstack); }
/** @@ -646,14 +673,12 @@ EXPORT_SYMBOL_GPL(debug_object_init_on_stack); */ int debug_object_activate(void *addr, const struct debug_obj_descr *descr) { + struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr }; enum debug_obj_state state; struct debug_bucket *db; struct debug_obj *obj; unsigned long flags; int ret; - struct debug_obj o = { .object = addr, - .state = ODEBUG_STATE_NOTAVAILABLE, - .descr = descr };
if (!debug_objects_enabled) return 0; @@ -662,8 +687,8 @@ int debug_object_activate(void *addr, const struct debug_obj_descr *descr)
raw_spin_lock_irqsave(&db->lock, flags);
- obj = lookup_object(addr, db); - if (obj) { + obj = lookup_object_or_alloc(addr, db, descr, false, true); + if (likely(!IS_ERR_OR_NULL(obj))) { bool print_object = false;
switch (obj->state) { @@ -696,24 +721,16 @@ int debug_object_activate(void *addr, const struct debug_obj_descr *descr)
raw_spin_unlock_irqrestore(&db->lock, flags);
- /* - * We are here when a static object is activated. We - * let the type specific code confirm whether this is - * true or not. if true, we just make sure that the - * static object is tracked in the object tracker. If - * not, this must be a bug, so we try to fix it up. - */ - if (descr->is_static_object && descr->is_static_object(addr)) { - /* track this static object */ - debug_object_init(addr, descr); - debug_object_activate(addr, descr); - } else { - debug_print_object(&o, "activate"); - ret = debug_object_fixup(descr->fixup_activate, addr, - ODEBUG_STATE_NOTAVAILABLE); - return ret ? 0 : -EINVAL; + /* If NULL the allocation has hit OOM */ + if (!obj) { + debug_objects_oom(); + return 0; } - return 0; + + /* Object is neither static nor tracked. It's not initialized */ + debug_print_object(&o, "activate"); + ret = debug_object_fixup(descr->fixup_activate, addr, ODEBUG_STATE_NOTAVAILABLE); + return ret ? 0 : -EINVAL; } EXPORT_SYMBOL_GPL(debug_object_activate);
@@ -867,6 +884,7 @@ EXPORT_SYMBOL_GPL(debug_object_free); */ void debug_object_assert_init(void *addr, const struct debug_obj_descr *descr) { + struct debug_obj o = { .object = addr, .state = ODEBUG_STATE_NOTAVAILABLE, .descr = descr }; struct debug_bucket *db; struct debug_obj *obj; unsigned long flags; @@ -877,31 +895,20 @@ void debug_object_assert_init(void *addr, const struct debug_obj_descr *descr) db = get_bucket((unsigned long) addr);
raw_spin_lock_irqsave(&db->lock, flags); + obj = lookup_object_or_alloc(addr, db, descr, false, true); + raw_spin_unlock_irqrestore(&db->lock, flags); + if (likely(!IS_ERR_OR_NULL(obj))) + return;
- obj = lookup_object(addr, db); + /* If NULL the allocation has hit OOM */ if (!obj) { - struct debug_obj o = { .object = addr, - .state = ODEBUG_STATE_NOTAVAILABLE, - .descr = descr }; - - raw_spin_unlock_irqrestore(&db->lock, flags); - /* - * Maybe the object is static, and we let the type specific - * code confirm. Track this static object if true, else invoke - * fixup. - */ - if (descr->is_static_object && descr->is_static_object(addr)) { - /* Track this static object */ - debug_object_init(addr, descr); - } else { - debug_print_object(&o, "assert_init"); - debug_object_fixup(descr->fixup_assert_init, addr, - ODEBUG_STATE_NOTAVAILABLE); - } + debug_objects_oom(); return; }
- raw_spin_unlock_irqrestore(&db->lock, flags); + /* Object is neither tracked nor static. It's not initialized. */ + debug_print_object(&o, "assert_init"); + debug_object_fixup(descr->fixup_assert_init, addr, ODEBUG_STATE_NOTAVAILABLE); } EXPORT_SYMBOL_GPL(debug_object_assert_init);
From: Ville Syrjälä ville.syrjala@linux.intel.com
[ Upstream commit 631420b06597a33c72b6dcef78d1c2dea17f452d ]
The point of the WARN was to print something, not oops straight up. Currently that is precisely what happens if we can't find the connector for the crtc in the atomic state. Get the dev pointer from the atomic state instead of the potentially NULL encoder to avoid that.
Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230413200602.6037-2-ville.sy... Fixes: 3a47ae201e07 ("drm/i915/display: Make WARN* drm specific where encoder ptr is available") Reviewed-by: Jani Nikula jani.nikula@intel.com (cherry picked from commit 3b6692357f70498f617ea1b31a0378070a0acf1c) Signed-off-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d46011f7a8380..9a06bd8cb200b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5844,7 +5844,7 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state, num_encoders++; }
- drm_WARN(encoder->base.dev, num_encoders != 1, + drm_WARN(state->base.dev, num_encoders != 1, "%d encoders for pipe %c\n", num_encoders, pipe_name(crtc->pipe));
From: Thomas Gleixner tglx@linutronix.de
[ Upstream commit 372acbbaa80940189593f9d69c7c069955f24f7a ]
No point in doing calculations.
tick_next_period = last_jiffies_update + tick_period
Just check whether now is before tick_next_period to figure out whether jiffies need an update.
Add a comment why the intentional data race in the quick check is safe or not so safe in a 32bit corner case and why we don't worry about it.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lore.kernel.org/r/20201117132006.337366695@linutronix.de Stable-dep-of: e9523a0d8189 ("tick/common: Align tick period with the HZ tick.") Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/time/tick-sched.c | 46 ++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-)
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 378096fc8c560..4f1b6170b3a20 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -57,11 +57,29 @@ static void tick_do_update_jiffies64(ktime_t now) ktime_t delta;
/* - * Do a quick check without holding jiffies_lock: - * The READ_ONCE() pairs with two updates done later in this function. + * Do a quick check without holding jiffies_lock. The READ_ONCE() + * pairs with the update done later in this function. + * + * This is also an intentional data race which is even safe on + * 32bit in theory. If there is a concurrent update then the check + * might give a random answer. It does not matter because if it + * returns then the concurrent update is already taking care, if it + * falls through then it will pointlessly contend on jiffies_lock. + * + * Though there is one nasty case on 32bit due to store tearing of + * the 64bit value. If the first 32bit store makes the quick check + * return on all other CPUs and the writing CPU context gets + * delayed to complete the second store (scheduled out on virt) + * then jiffies can become stale for up to ~2^32 nanoseconds + * without noticing. After that point all CPUs will wait for + * jiffies lock. + * + * OTOH, this is not any different than the situation with NOHZ=off + * where one CPU is responsible for updating jiffies and + * timekeeping. If that CPU goes out for lunch then all other CPUs + * will operate on stale jiffies until it decides to come back. */ - delta = ktime_sub(now, READ_ONCE(last_jiffies_update)); - if (delta < tick_period) + if (ktime_before(now, READ_ONCE(tick_next_period))) return;
/* Reevaluate with jiffies_lock held */ @@ -72,9 +90,8 @@ static void tick_do_update_jiffies64(ktime_t now) if (delta >= tick_period) {
delta = ktime_sub(delta, tick_period); - /* Pairs with the lockless read in this function. */ - WRITE_ONCE(last_jiffies_update, - ktime_add(last_jiffies_update, tick_period)); + last_jiffies_update = ktime_add(last_jiffies_update, + tick_period);
/* Slow path for long timeouts */ if (unlikely(delta >= tick_period)) { @@ -82,15 +99,18 @@ static void tick_do_update_jiffies64(ktime_t now)
ticks = ktime_divns(delta, incr);
- /* Pairs with the lockless read in this function. */ - WRITE_ONCE(last_jiffies_update, - ktime_add_ns(last_jiffies_update, - incr * ticks)); + last_jiffies_update = ktime_add_ns(last_jiffies_update, + incr * ticks); } do_timer(++ticks);
- /* Keep the tick_next_period variable up to date */ - tick_next_period = ktime_add(last_jiffies_update, tick_period); + /* + * Keep the tick_next_period variable up to date. + * WRITE_ONCE() pairs with the READ_ONCE() in the lockless + * quick check above. + */ + WRITE_ONCE(tick_next_period, + ktime_add(last_jiffies_update, tick_period)); } else { write_seqcount_end(&jiffies_seq); raw_spin_unlock(&jiffies_lock);
From: Yunfeng Ye yeyunfeng@huawei.com
[ Upstream commit 94ad2e3cedb82af034f6d97c58022f162b669f9b ]
If jiffies are up to date already (caller lost the race against another CPU) there is no point to change the sequence count. Doing that just forces other CPUs into the seqcount retry loop in tick_nohz_next_event() for nothing.
Just bail out early.
[ tglx: Rewrote most of it ]
Signed-off-by: Yunfeng Ye yeyunfeng@huawei.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lore.kernel.org/r/20201117132006.462195901@linutronix.de Stable-dep-of: e9523a0d8189 ("tick/common: Align tick period with the HZ tick.") Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/time/tick-sched.c | 47 +++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 25 deletions(-)
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 4f1b6170b3a20..ac9953f6f92ce 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -84,38 +84,35 @@ static void tick_do_update_jiffies64(ktime_t now)
/* Reevaluate with jiffies_lock held */ raw_spin_lock(&jiffies_lock); + if (ktime_before(now, tick_next_period)) { + raw_spin_unlock(&jiffies_lock); + return; + } + write_seqcount_begin(&jiffies_seq);
- delta = ktime_sub(now, last_jiffies_update); - if (delta >= tick_period) { + last_jiffies_update = ktime_add(last_jiffies_update, tick_period);
- delta = ktime_sub(delta, tick_period); - last_jiffies_update = ktime_add(last_jiffies_update, - tick_period); + delta = ktime_sub(now, tick_next_period); + if (unlikely(delta >= tick_period)) { + /* Slow path for long idle sleep times */ + s64 incr = ktime_to_ns(tick_period);
- /* Slow path for long timeouts */ - if (unlikely(delta >= tick_period)) { - s64 incr = ktime_to_ns(tick_period); + ticks = ktime_divns(delta, incr);
- ticks = ktime_divns(delta, incr); + last_jiffies_update = ktime_add_ns(last_jiffies_update, + incr * ticks); + }
- last_jiffies_update = ktime_add_ns(last_jiffies_update, - incr * ticks); - } - do_timer(++ticks); + do_timer(++ticks); + + /* + * Keep the tick_next_period variable up to date. WRITE_ONCE() + * pairs with the READ_ONCE() in the lockless quick check above. + */ + WRITE_ONCE(tick_next_period, + ktime_add(last_jiffies_update, tick_period));
- /* - * Keep the tick_next_period variable up to date. - * WRITE_ONCE() pairs with the READ_ONCE() in the lockless - * quick check above. - */ - WRITE_ONCE(tick_next_period, - ktime_add(last_jiffies_update, tick_period)); - } else { - write_seqcount_end(&jiffies_seq); - raw_spin_unlock(&jiffies_lock); - return; - } write_seqcount_end(&jiffies_seq); raw_spin_unlock(&jiffies_lock); update_wall_time();
From: Thomas Gleixner tglx@linutronix.de
[ Upstream commit 7a35bf2a6a871cd0252cd371d741e7d070b53af9 ]
Now that it's clear that there is always one tick to account, simplify the calculations some more.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lore.kernel.org/r/20201117132006.565663056@linutronix.de Stable-dep-of: e9523a0d8189 ("tick/common: Align tick period with the HZ tick.") Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/time/tick-sched.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index ac9953f6f92ce..5c3d4355266db 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -53,7 +53,7 @@ static ktime_t last_jiffies_update; */ static void tick_do_update_jiffies64(ktime_t now) { - unsigned long ticks = 0; + unsigned long ticks = 1; ktime_t delta;
/* @@ -91,20 +91,21 @@ static void tick_do_update_jiffies64(ktime_t now)
write_seqcount_begin(&jiffies_seq);
- last_jiffies_update = ktime_add(last_jiffies_update, tick_period); - delta = ktime_sub(now, tick_next_period); if (unlikely(delta >= tick_period)) { /* Slow path for long idle sleep times */ s64 incr = ktime_to_ns(tick_period);
- ticks = ktime_divns(delta, incr); + ticks += ktime_divns(delta, incr);
last_jiffies_update = ktime_add_ns(last_jiffies_update, incr * ticks); + } else { + last_jiffies_update = ktime_add(last_jiffies_update, + tick_period); }
- do_timer(++ticks); + do_timer(ticks);
/* * Keep the tick_next_period variable up to date. WRITE_ONCE()
From: Thomas Gleixner tglx@linutronix.de
[ Upstream commit b996544916429946bf4934c1c01a306d1690972c ]
The variable tick_period is initialized to NSEC_PER_TICK / HZ during boot and never updated again.
If NSEC_PER_TICK is not an integer multiple of HZ this computation is less accurate than TICK_NSEC which has proper rounding in place.
Aside of the inaccuracy there is no reason for having this variable at all. It's just a pointless indirection and all usage sites can just use the TICK_NSEC constant.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lore.kernel.org/r/20201117132006.766643526@linutronix.de Stable-dep-of: e9523a0d8189 ("tick/common: Align tick period with the HZ tick.") Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/time/tick-broadcast.c | 2 +- kernel/time/tick-common.c | 8 +++----- kernel/time/tick-internal.h | 1 - kernel/time/tick-sched.c | 22 +++++++++++----------- 4 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 36d7464c89625..a9530e866e5f1 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -331,7 +331,7 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev) bc_local = tick_do_periodic_broadcast();
if (clockevent_state_oneshot(dev)) { - ktime_t next = ktime_add(dev->next_event, tick_period); + ktime_t next = ktime_add_ns(dev->next_event, TICK_NSEC);
clockevents_program_event(dev, next, true); } diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 6c9c342dd0e53..92bf99d558b48 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -30,7 +30,6 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device); * Tick next event: keeps track of the tick time */ ktime_t tick_next_period; -ktime_t tick_period;
/* * tick_do_timer_cpu is a timer core internal variable which holds the CPU NR @@ -88,7 +87,7 @@ static void tick_periodic(int cpu) write_seqcount_begin(&jiffies_seq);
/* Keep track of the next tick event */ - tick_next_period = ktime_add(tick_next_period, tick_period); + tick_next_period = ktime_add_ns(tick_next_period, TICK_NSEC);
do_timer(1); write_seqcount_end(&jiffies_seq); @@ -127,7 +126,7 @@ void tick_handle_periodic(struct clock_event_device *dev) * Setup the next period for devices, which do not have * periodic mode: */ - next = ktime_add(next, tick_period); + next = ktime_add_ns(next, TICK_NSEC);
if (!clockevents_program_event(dev, next, false)) return; @@ -173,7 +172,7 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast) for (;;) { if (!clockevents_program_event(dev, next, false)) return; - next = ktime_add(next, tick_period); + next = ktime_add_ns(next, TICK_NSEC); } } } @@ -220,7 +219,6 @@ static void tick_setup_device(struct tick_device *td, tick_do_timer_cpu = cpu;
tick_next_period = ktime_get(); - tick_period = NSEC_PER_SEC / HZ; #ifdef CONFIG_NO_HZ_FULL /* * The boot CPU may be nohz_full, in which case set diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index 5294f5b1f9550..e61c1244e7d46 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h @@ -15,7 +15,6 @@
DECLARE_PER_CPU(struct tick_device, tick_cpu_device); extern ktime_t tick_next_period; -extern ktime_t tick_period; extern int tick_do_timer_cpu __read_mostly;
extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast); diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 5c3d4355266db..17dc3f53efef8 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -92,17 +92,17 @@ static void tick_do_update_jiffies64(ktime_t now) write_seqcount_begin(&jiffies_seq);
delta = ktime_sub(now, tick_next_period); - if (unlikely(delta >= tick_period)) { + if (unlikely(delta >= TICK_NSEC)) { /* Slow path for long idle sleep times */ - s64 incr = ktime_to_ns(tick_period); + s64 incr = TICK_NSEC;
ticks += ktime_divns(delta, incr);
last_jiffies_update = ktime_add_ns(last_jiffies_update, incr * ticks); } else { - last_jiffies_update = ktime_add(last_jiffies_update, - tick_period); + last_jiffies_update = ktime_add_ns(last_jiffies_update, + TICK_NSEC); }
do_timer(ticks); @@ -112,7 +112,7 @@ static void tick_do_update_jiffies64(ktime_t now) * pairs with the READ_ONCE() in the lockless quick check above. */ WRITE_ONCE(tick_next_period, - ktime_add(last_jiffies_update, tick_period)); + ktime_add_ns(last_jiffies_update, TICK_NSEC));
write_seqcount_end(&jiffies_seq); raw_spin_unlock(&jiffies_lock); @@ -688,7 +688,7 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) hrtimer_set_expires(&ts->sched_timer, ts->last_tick);
/* Forward the time to expire in the future */ - hrtimer_forward(&ts->sched_timer, now, tick_period); + hrtimer_forward(&ts->sched_timer, now, TICK_NSEC);
if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { hrtimer_start_expires(&ts->sched_timer, @@ -1250,7 +1250,7 @@ static void tick_nohz_handler(struct clock_event_device *dev) if (unlikely(ts->tick_stopped)) return;
- hrtimer_forward(&ts->sched_timer, now, tick_period); + hrtimer_forward(&ts->sched_timer, now, TICK_NSEC); tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1); }
@@ -1287,7 +1287,7 @@ static void tick_nohz_switch_to_nohz(void) next = tick_init_jiffy_update();
hrtimer_set_expires(&ts->sched_timer, next); - hrtimer_forward_now(&ts->sched_timer, tick_period); + hrtimer_forward_now(&ts->sched_timer, TICK_NSEC); tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1); tick_nohz_activate(ts, NOHZ_MODE_LOWRES); } @@ -1353,7 +1353,7 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) if (unlikely(ts->tick_stopped)) return HRTIMER_NORESTART;
- hrtimer_forward(timer, now, tick_period); + hrtimer_forward(timer, now, TICK_NSEC);
return HRTIMER_RESTART; } @@ -1387,13 +1387,13 @@ void tick_setup_sched_timer(void)
/* Offset the tick to avert jiffies_lock contention. */ if (sched_skew_tick) { - u64 offset = ktime_to_ns(tick_period) >> 1; + u64 offset = TICK_NSEC >> 1; do_div(offset, num_possible_cpus()); offset *= smp_processor_id(); hrtimer_add_expires_ns(&ts->sched_timer, offset); }
- hrtimer_forward(&ts->sched_timer, now, tick_period); + hrtimer_forward(&ts->sched_timer, now, TICK_NSEC); hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS_PINNED_HARD); tick_nohz_activate(ts, NOHZ_MODE_HIGHRES); }
From: Sebastian Andrzej Siewior bigeasy@linutronix.de
[ Upstream commit e9523a0d81899361214d118ad60ef76f0e92f71d ]
With HIGHRES enabled tick_sched_timer() is programmed every jiffy to expire the timer_list timers. This timer is programmed accurate in respect to CLOCK_MONOTONIC so that 0 seconds and nanoseconds is the first tick and the next one is 1000/CONFIG_HZ ms later. For HZ=250 it is every 4 ms and so based on the current time the next tick can be computed.
This accuracy broke since the commit mentioned below because the jiffy based clocksource is initialized with higher accuracy in read_persistent_wall_and_boot_offset(). This higher accuracy is inherited during the setup in tick_setup_device(). The timer still fires every 4ms with HZ=250 but timer is no longer aligned with CLOCK_MONOTONIC with 0 as it origin but has an offset in the us/ns part of the timestamp. The offset differs with every boot and makes it impossible for user land to align with the tick.
Align the tick period with CLOCK_MONOTONIC ensuring that it is always a multiple of 1000/CONFIG_HZ ms.
Fixes: 857baa87b6422 ("sched/clock: Enable sched clock early") Reported-by: Gusenleitner Klaus gus@keba.com Signed-off-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lore.kernel.org/20230406095735.0_14edn3@linutronix.de Link: https://lore.kernel.org/r/20230418122639.ikgfvu3f@linutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/time/tick-common.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 92bf99d558b48..2b7448ae5b478 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -216,9 +216,19 @@ static void tick_setup_device(struct tick_device *td, * this cpu: */ if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) { + ktime_t next_p; + u32 rem; + tick_do_timer_cpu = cpu;
- tick_next_period = ktime_get(); + next_p = ktime_get(); + div_u64_rem(next_p, TICK_NSEC, &rem); + if (rem) { + next_p -= rem; + next_p += TICK_NSEC; + } + + tick_next_period = next_p; #ifdef CONFIG_NO_HZ_FULL /* * The boot CPU may be nohz_full, in which case set
From: Alexey V. Vissarionov gremlin@altlinux.org
[ Upstream commit 778f83f889e7fca37780d9640fcbd0229ae38eaa ]
Although the "param" pointer occupies more or equal space compared to "*param", the allocation size should use the size of variable itself.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: bdcd81707973cf8a ("Add ath6kl cleaned up driver") Signed-off-by: Alexey V. Vissarionov gremlin@altlinux.org Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230117110414.GC12547@altlinux.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath6kl/bmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c index bde5a10d470c8..af98e871199d3 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/drivers/net/wireless/ath/ath6kl/bmi.c @@ -246,7 +246,7 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param) return -EACCES; }
- size = sizeof(cid) + sizeof(addr) + sizeof(param); + size = sizeof(cid) + sizeof(addr) + sizeof(*param); if (size > ar->bmi.max_cmd_size) { WARN_ON(1); return -EINVAL;
From: Fedor Pchelkin pchelkin@ispras.ru
[ Upstream commit 7654cc03eb699297130b693ec34e25f77b17c947 ]
hif_dev->remain_skb is allocated and used exclusively in ath9k_hif_usb_rx_stream(). It is implied that an allocated remain_skb is processed and subsequently freed (in error paths) only during the next call of ath9k_hif_usb_rx_stream().
So, if the urbs are deallocated between those two calls due to the device deinitialization or suspend, it is possible that ath9k_hif_usb_rx_stream() is not called next time and the allocated remain_skb is leaked. Our local Syzkaller instance was able to trigger that.
remain_skb makes sense when receiving two consecutive urbs which are logically linked together, i.e. a specific data field from the first skb indicates a cached skb to be allocated, memcpy'd with some data and subsequently processed in the next call to ath9k_hif_usb_rx_stream(). Urbs deallocation supposedly makes that link irrelevant so we need to free the cached skb in those cases.
Fix the leak by introducing a function to explicitly free remain_skb (if it is not NULL) when the rx urbs have been deallocated. remain_skb is NULL when it has not been allocated at all (hif_dev struct is kzalloced) or when it has been processed in next call to ath9k_hif_usb_rx_stream().
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.") Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru Signed-off-by: Alexey Khoroshilov khoroshilov@ispras.ru Acked-by: Toke Høiland-Jørgensen toke@toke.dk Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230216192301.171225-1-pchelkin@ispras.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/hif_usb.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index f521dfa2f1945..e0130beb304df 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -534,6 +534,24 @@ static struct ath9k_htc_hif hif_usb = { .send = hif_usb_send, };
+/* Need to free remain_skb allocated in ath9k_hif_usb_rx_stream + * in case ath9k_hif_usb_rx_stream wasn't called next time to + * process the buffer and subsequently free it. + */ +static void ath9k_hif_usb_free_rx_remain_skb(struct hif_device_usb *hif_dev) +{ + unsigned long flags; + + spin_lock_irqsave(&hif_dev->rx_lock, flags); + if (hif_dev->remain_skb) { + dev_kfree_skb_any(hif_dev->remain_skb); + hif_dev->remain_skb = NULL; + hif_dev->rx_remain_len = 0; + RX_STAT_INC(hif_dev, skb_dropped); + } + spin_unlock_irqrestore(&hif_dev->rx_lock, flags); +} + static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, struct sk_buff *skb) { @@ -868,6 +886,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev) { usb_kill_anchored_urbs(&hif_dev->rx_submitted); + ath9k_hif_usb_free_rx_remain_skb(hif_dev); }
static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
From: Dan Carpenter error27@gmail.com
[ Upstream commit 4c856ee12df85aabd437c3836ed9f68d94268358 ]
This loop checks that i < max at the start of loop but then it does i++ which could put it past the end of the array. It's harmless to check again and prevent a potential out of bounds.
Fixes: 1048643ea94d ("ath5k: Clean up eeprom parsing and add missing calibration data") Signed-off-by: Dan Carpenter error27@gmail.com Reviewed-by: Luis Chamberlain mcgrof@kernel.org Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/Y+D9hPQrHfWBJhXz@kili Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath5k/eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index d444b3d70ba2e..58d3e86f6256d 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -529,7 +529,7 @@ ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, ee->ee_n_piers[mode]++;
freq2 = (val >> 8) & 0xff; - if (!freq2) + if (!freq2 || i >= max) break;
pc[i++].freq = ath5k_eeprom_bin2freq(ee,
From: Fedor Pchelkin pchelkin@ispras.ru
[ Upstream commit 75c4a8154cb6c7239fb55d5550f481f6765fb83c ]
The warn is triggered on a known race condition, documented in the code above the test, that is correctly handled. Using WARN() hinders automated testing. Reducing severity.
Fixes: de2070fc4aa7 ("ath6kl: Fix kernel panic on continuous driver load/unload") Reported-and-tested-by: syzbot+555908813b2ea35dae9a@syzkaller.appspotmail.com Signed-off-by: Oliver Neukum oneukum@suse.com Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru Signed-off-by: Alexey Khoroshilov khoroshilov@ispras.ru Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20230126182431.867984-1-pchelkin@ispras.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath6kl/htc_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c index c68848819a52d..9b88d96bfe96c 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c @@ -960,8 +960,8 @@ static int ath6kl_htc_pipe_rx_complete(struct ath6kl *ar, struct sk_buff *skb, * Thus the possibility of ar->htc_target being NULL * via ath6kl_recv_complete -> ath6kl_usb_io_comp_work. */ - if (WARN_ON_ONCE(!target)) { - ath6kl_err("Target not yet initialized\n"); + if (!target) { + ath6kl_dbg(ATH6KL_DBG_HTC, "Target not yet initialized\n"); status = -EINVAL; goto free_skb; }
From: Luis Gerhorst gerhorst@cs.fau.de
[ Upstream commit c679bbd611c08b0559ffae079330bc4e5574696a ]
RFC8259 ("The JavaScript Object Notation (JSON) Data Interchange Format") only specifies ", \, /, \b, \f, \n, \r, and \r as valid two-character escape sequences. This does not include ', which is not required in JSON because it exclusively uses double quotes as string separators.
Solidus (/) may be escaped, but does not have to. Only reverse solidus (), double quotes ("), and the control characters have to be escaped. Therefore, with this fix, bpftool correctly supports all valid two-character escape sequences (but still does not support characters that require multi-character escape sequences).
Witout this fix, attempting to load a JSON file generated by bpftool using Python 3.10.6's default json.load() may fail with the error "Invalid \escape" if the file contains the invalid escaped single quote (').
Fixes: b66e907cfee2 ("tools: bpftool: copy JSON writer from iproute2 repository") Signed-off-by: Luis Gerhorst gerhorst@cs.fau.de Signed-off-by: Andrii Nakryiko andrii@kernel.org Reviewed-by: Quentin Monnet quentin@isovalent.com Link: https://lore.kernel.org/bpf/20230227150853.16863-1-gerhorst@cs.fau.de Signed-off-by: Sasha Levin sashal@kernel.org --- tools/bpf/bpftool/json_writer.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/tools/bpf/bpftool/json_writer.c b/tools/bpf/bpftool/json_writer.c index 7fea83bedf488..bca5dd0a59e34 100644 --- a/tools/bpf/bpftool/json_writer.c +++ b/tools/bpf/bpftool/json_writer.c @@ -80,9 +80,6 @@ static void jsonw_puts(json_writer_t *self, const char *str) case '"': fputs("\"", self->out); break; - case ''': - fputs("\'", self->out); - break; default: putc(*str, self->out); }
From: Martin Blumenstingl martin.blumenstingl@googlemail.com
[ Upstream commit b7ed9fa2cb76ca7a3c3cd4a6d35748fe1fbda9f6 ]
rtw_pwr_seq_parser() calls rtw_sub_pwr_seq_parser() which can either return -EBUSY, -EINVAL or 0. Propagate the original error code instead of unconditionally returning -EBUSY in case of an error.
Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver") Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Reviewed-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230226221004.138331-2-martin.blumenstingl@google... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw88/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c index 59028b121b00e..fd427c606fa2d 100644 --- a/drivers/net/wireless/realtek/rtw88/mac.c +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -233,7 +233,7 @@ static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
ret = rtw_sub_pwr_seq_parser(rtwdev, intf_mask, cut_mask, cmd); if (ret) - return -EBUSY; + return ret;
idx++; } while (1);
From: Martin Blumenstingl martin.blumenstingl@googlemail.com
[ Upstream commit 15c8e267dfa62f207ee1db666c822324e3362b84 ]
rtw_mac_power_switch() calls rtw_pwr_seq_parser() which can return -EINVAL, -EBUSY or 0. Propagate the original error code instead of unconditionally returning -EINVAL in case of an error.
Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver") Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Reviewed-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230226221004.138331-3-martin.blumenstingl@google... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw88/mac.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c index fd427c606fa2d..a6d554a9dd995 100644 --- a/drivers/net/wireless/realtek/rtw88/mac.c +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -247,6 +247,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) const struct rtw_pwr_seq_cmd **pwr_seq; u8 rpwm; bool cur_pwr; + int ret;
if (rtw_chip_wcpu_11ac(rtwdev)) { rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); @@ -270,8 +271,9 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) return -EALREADY;
pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq; - if (rtw_pwr_seq_parser(rtwdev, pwr_seq)) - return -EINVAL; + ret = rtw_pwr_seq_parser(rtwdev, pwr_seq); + if (ret) + return ret;
return 0; }
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit 52c2b005a3c18c565fc70cfd0ca49375f301e952 ]
When doing state comparison, if old state has register that is not marked as REG_LIVE_READ, then we just skip comparison, regardless what's the state of corresponing register in current state. This is because not REG_LIVE_READ register is irrelevant for further program execution and correctness. All good here.
But when we get to precision propagation, after two states were declared equivalent, we don't take into account old register's liveness, and thus attempt to propagate precision for register in current state even if that register in old state was not REG_LIVE_READ anymore. This is bad, because register in current state could be anything at all and this could cause -EFAULT due to internal logic bugs.
Fix by taking into account REG_LIVE_READ liveness mark to keep the logic in state comparison in sync with precision propagation.
Fixes: a3ce685dd01a ("bpf: fix precision tracking") Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/r/20230309224131.57449-1-andrii@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/verifier.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 5a96a9dd51e4c..e2488a00efc5a 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -9550,7 +9550,8 @@ static int propagate_precision(struct bpf_verifier_env *env, state_reg = state->regs; for (i = 0; i < BPF_REG_FP; i++, state_reg++) { if (state_reg->type != SCALAR_VALUE || - !state_reg->precise) + !state_reg->precise || + !(state_reg->live & REG_LIVE_READ)) continue; if (env->log.level & BPF_LOG_LEVEL2) verbose(env, "frame %d: propagating r%d\n", i, fr); @@ -9564,7 +9565,8 @@ static int propagate_precision(struct bpf_verifier_env *env, continue; state_reg = &state->stack[i].spilled_ptr; if (state_reg->type != SCALAR_VALUE || - !state_reg->precise) + !state_reg->precise || + !(state_reg->live & REG_LIVE_READ)) continue; if (env->log.level & BPF_LOG_LEVEL2) verbose(env, "frame %d: propagating fp%d\n",
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit 34f0677e7afd3a292bc1aadda7ce8e35faedb204 ]
Fix wrong order of frame index vs register/slot index in precision propagation verbose (level 2) output. It's wrong and very confusing as is.
Fixes: 529409ea92d5 ("bpf: propagate precision across all frames, not just the last one") Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/r/20230313184017.4083374-1-andrii@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/verifier.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index e2488a00efc5a..232f720104cdf 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -9554,7 +9554,7 @@ static int propagate_precision(struct bpf_verifier_env *env, !(state_reg->live & REG_LIVE_READ)) continue; if (env->log.level & BPF_LOG_LEVEL2) - verbose(env, "frame %d: propagating r%d\n", i, fr); + verbose(env, "frame %d: propagating r%d\n", fr, i); err = mark_chain_precision_frame(env, fr, i); if (err < 0) return err; @@ -9570,7 +9570,7 @@ static int propagate_precision(struct bpf_verifier_env *env, continue; if (env->log.level & BPF_LOG_LEVEL2) verbose(env, "frame %d: propagating fp%d\n", - (-i - 1) * BPF_REG_SIZE, fr); + fr, (-i - 1) * BPF_REG_SIZE); err = mark_chain_precision_stack_frame(env, fr, i); if (err < 0) return err;
From: Alexander Mikhalitsyn aleksandr.mikhalitsyn@canonical.com
[ Upstream commit a02d83f9947d8f71904eda4de046630c3eb6802c ]
Currently, kernel would set MSG_CTRUNC flag if msg_control buffer wasn't provided and SO_PASSCRED was set or if there was pending SCM_RIGHTS.
For some reason we have no corresponding check for SO_PASSSEC.
In the recvmsg(2) doc we have: MSG_CTRUNC indicates that some control data was discarded due to lack of space in the buffer for ancillary data.
So, we need to set MSG_CTRUNC flag for all types of SCM.
This change can break applications those don't check MSG_CTRUNC flag.
Cc: "David S. Miller" davem@davemloft.net Cc: Eric Dumazet edumazet@google.com Cc: Jakub Kicinski kuba@kernel.org Cc: Paolo Abeni pabeni@redhat.com Cc: Leon Romanovsky leon@kernel.org Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Alexander Mikhalitsyn aleksandr.mikhalitsyn@canonical.com
v2: - commit message was rewritten according to Eric's suggestion Acked-by: Paul Moore paul@paul-moore.com
Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/scm.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/include/net/scm.h b/include/net/scm.h index 1ce365f4c2560..585adc1346bd0 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -105,16 +105,27 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc } } } + +static inline bool scm_has_secdata(struct socket *sock) +{ + return test_bit(SOCK_PASSSEC, &sock->flags); +} #else static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { } + +static inline bool scm_has_secdata(struct socket *sock) +{ + return false; +} #endif /* CONFIG_SECURITY_NETWORK */
static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm, int flags) { if (!msg->msg_control) { - if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp) + if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp || + scm_has_secdata(sock)) msg->msg_flags |= MSG_CTRUNC; scm_destroy(scm); return;
From: Luis Gerhorst gerhorst@cs.fau.de
[ Upstream commit 082cdc69a4651dd2a77539d69416a359ed1214f5 ]
For every BPF_ADD/SUB involving a pointer, adjust_ptr_min_max_vals() ensures that the resulting pointer has a constant offset if bypass_spec_v1 is false. This is ensured by calling sanitize_check_bounds() which in turn calls check_stack_access_for_ptr_arithmetic(). There, -EACCESS is returned if the register's offset is not constant, thereby rejecting the program.
In summary, an unprivileged user must never be able to create stack pointers with a variable offset. That is also the case, because a respective check in check_stack_write() is missing. If they were able to create a variable-offset pointer, users could still use it in a stack-write operation to trigger unsafe speculative behavior [1].
Because unprivileged users must already be prevented from creating variable-offset stack pointers, viable options are to either remove this check (replacing it with a clarifying comment), or to turn it into a "verifier BUG"-message, also adding a similar check in check_stack_write() (for consistency, as a second-level defense). This patch implements the first option to reduce verifier bloat.
This check was introduced by commit 01f810ace9ed ("bpf: Allow variable-offset stack access") which correctly notes that "variable-offset reads and writes are disallowed (they were already disallowed for the indirect access case) because the speculative execution checking code doesn't support them". However, it does not further discuss why the check in check_stack_read() is necessary. The code which made this check obsolete was also introduced in this commit.
I have compiled ~650 programs from the Linux selftests, Linux samples, Cilium, and libbpf/examples projects and confirmed that none of these trigger the check in check_stack_read() [2]. Instead, all of these programs are, as expected, already rejected when constructing the variable-offset pointers. Note that the check in check_stack_access_for_ptr_arithmetic() also prints "off=%d" while the code removed by this patch does not (the error removed does not appear in the "verification_error" values). For reproducibility, the repository linked includes the raw data and scripts used to create the plot.
[1] https://arxiv.org/pdf/1807.03757.pdf [2] https://gitlab.cs.fau.de/un65esoq/bpf-spectre/-/raw/53dc19fcf459c186613b1156...
Fixes: 01f810ace9ed ("bpf: Allow variable-offset stack access") Signed-off-by: Luis Gerhorst gerhorst@cs.fau.de Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20230315165358.23701-1-gerhorst@cs.fau.de Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/verifier.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 232f720104cdf..6876796a8de0c 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2775,17 +2775,13 @@ static int check_stack_read(struct bpf_verifier_env *env, } /* Variable offset is prohibited for unprivileged mode for simplicity * since it requires corresponding support in Spectre masking for stack - * ALU. See also retrieve_ptr_limit(). + * ALU. See also retrieve_ptr_limit(). The check in + * check_stack_access_for_ptr_arithmetic() called by + * adjust_ptr_min_max_vals() prevents users from creating stack pointers + * with variable offsets, therefore no check is required here. Further, + * just checking it here would be insufficient as speculative stack + * writes could still lead to unsafe speculative behaviour. */ - if (!env->bypass_spec_v1 && var_off) { - char tn_buf[48]; - - tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); - verbose(env, "R%d variable offset stack access prohibited for !root, var_off=%s\n", - ptr_regno, tn_buf); - return -EACCES; - } - if (!var_off) { off += reg->var_off.value; err = check_stack_read_fixed_off(env, state, off, size,
From: Vadim Fedorenko vadim.fedorenko@linux.dev
[ Upstream commit 731b73dba359e3ff00517c13aa0daa82b34ff466 ]
Setting timestamp filter was explicitly disabled on vlan devices in containers because it might affect other processes on the host. But it's absolutely legit in case when real device is in the same namespace.
Fixes: 873017af7784 ("vlan: disable SIOCSHWTSTAMP in container") Signed-off-by: Vadim Fedorenko vadim.fedorenko@linux.dev Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/8021q/vlan_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 86a1c99025ea0..929f85c6cf112 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -365,7 +365,7 @@ static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
switch (cmd) { case SIOCSHWTSTAMP: - if (!net_eq(dev_net(dev), &init_net)) + if (!net_eq(dev_net(dev), dev_net(real_dev))) break; fallthrough; case SIOCGMIIPHY:
From: Eric Dumazet edumazet@google.com
[ Upstream commit b9d83ab8a708f23a4001d60e9d8d0b3be3d9f607 ]
po->xmit can be set from setsockopt(PACKET_QDISC_BYPASS), while read locklessly.
Use READ_ONCE()/WRITE_ONCE() to avoid potential load/store tearing issues.
Fixes: d346a3fae3ff ("packet: introduce PACKET_QDISC_BYPASS socket option") Signed-off-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/packet/af_packet.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 3716797c55643..2b435d9916e64 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -269,7 +269,8 @@ static void packet_cached_dev_reset(struct packet_sock *po)
static bool packet_use_direct_xmit(const struct packet_sock *po) { - return po->xmit == packet_direct_xmit; + /* Paired with WRITE_ONCE() in packet_setsockopt() */ + return READ_ONCE(po->xmit) == packet_direct_xmit; }
static u16 packet_pick_tx_queue(struct sk_buff *skb) @@ -2825,7 +2826,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) packet_inc_pending(&po->tx_ring);
status = TP_STATUS_SEND_REQUEST; - err = po->xmit(skb); + /* Paired with WRITE_ONCE() in packet_setsockopt() */ + err = READ_ONCE(po->xmit)(skb); if (unlikely(err != 0)) { if (err > 0) err = net_xmit_errno(err); @@ -3028,7 +3030,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) virtio_net_hdr_set_proto(skb, &vnet_hdr); }
- err = po->xmit(skb); + /* Paired with WRITE_ONCE() in packet_setsockopt() */ + err = READ_ONCE(po->xmit)(skb); if (unlikely(err != 0)) { if (err > 0) err = net_xmit_errno(err); @@ -3979,7 +3982,8 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval, if (copy_from_sockptr(&val, optval, sizeof(val))) return -EFAULT;
- po->xmit = val ? packet_direct_xmit : dev_queue_xmit; + /* Paired with all lockless reads of po->xmit */ + WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit); return 0; } default:
From: Eric Dumazet edumazet@google.com
[ Upstream commit ee5675ecdf7a4e713ed21d98a70c2871d6ebed01 ]
syzbot/KCAN reported that po->origdev can be read while another thread is changing its value.
We can avoid this splat by converting this field to an actual bit.
Following patches will convert remaining 1bit fields.
Fixes: 80feaacb8a64 ("[AF_PACKET]: Add option to return orig_dev to userspace.") Signed-off-by: Eric Dumazet edumazet@google.com Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/packet/af_packet.c | 10 ++++------ net/packet/diag.c | 2 +- net/packet/internal.h | 22 +++++++++++++++++++++- 3 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 2b435d9916e64..df93f4b09ab9e 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -2146,7 +2146,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, sll = &PACKET_SKB_CB(skb)->sa.ll; sll->sll_hatype = dev->type; sll->sll_pkttype = skb->pkt_type; - if (unlikely(po->origdev)) + if (unlikely(packet_sock_flag(po, PACKET_SOCK_ORIGDEV))) sll->sll_ifindex = orig_dev->ifindex; else sll->sll_ifindex = dev->ifindex; @@ -2419,7 +2419,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, sll->sll_hatype = dev->type; sll->sll_protocol = skb->protocol; sll->sll_pkttype = skb->pkt_type; - if (unlikely(po->origdev)) + if (unlikely(packet_sock_flag(po, PACKET_SOCK_ORIGDEV))) sll->sll_ifindex = orig_dev->ifindex; else sll->sll_ifindex = dev->ifindex; @@ -3883,9 +3883,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval, if (copy_from_sockptr(&val, optval, sizeof(val))) return -EFAULT;
- lock_sock(sk); - po->origdev = !!val; - release_sock(sk); + packet_sock_flag_set(po, PACKET_SOCK_ORIGDEV, val); return 0; } case PACKET_VNET_HDR: @@ -4037,7 +4035,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, val = po->auxdata; break; case PACKET_ORIGDEV: - val = po->origdev; + val = packet_sock_flag(po, PACKET_SOCK_ORIGDEV); break; case PACKET_VNET_HDR: val = po->has_vnet_hdr; diff --git a/net/packet/diag.c b/net/packet/diag.c index 07812ae5ca073..e1ac9bb375b31 100644 --- a/net/packet/diag.c +++ b/net/packet/diag.c @@ -25,7 +25,7 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb) pinfo.pdi_flags |= PDI_RUNNING; if (po->auxdata) pinfo.pdi_flags |= PDI_AUXDATA; - if (po->origdev) + if (packet_sock_flag(po, PACKET_SOCK_ORIGDEV)) pinfo.pdi_flags |= PDI_ORIGDEV; if (po->has_vnet_hdr) pinfo.pdi_flags |= PDI_VNETHDR; diff --git a/net/packet/internal.h b/net/packet/internal.h index 7af1e9179385f..7fea453dc7215 100644 --- a/net/packet/internal.h +++ b/net/packet/internal.h @@ -116,9 +116,9 @@ struct packet_sock { int copy_thresh; spinlock_t bind_lock; struct mutex pg_vec_lock; + unsigned long flags; unsigned int running; /* bind_lock must be held */ unsigned int auxdata:1, /* writer must hold sock lock */ - origdev:1, has_vnet_hdr:1, tp_loss:1, tp_tx_has_off:1; @@ -144,4 +144,24 @@ static struct packet_sock *pkt_sk(struct sock *sk) return (struct packet_sock *)sk; }
+enum packet_sock_flags { + PACKET_SOCK_ORIGDEV, +}; + +static inline void packet_sock_flag_set(struct packet_sock *po, + enum packet_sock_flags flag, + bool val) +{ + if (val) + set_bit(flag, &po->flags); + else + clear_bit(flag, &po->flags); +} + +static inline bool packet_sock_flag(const struct packet_sock *po, + enum packet_sock_flags flag) +{ + return test_bit(flag, &po->flags); +} + #endif
From: Eric Dumazet edumazet@google.com
[ Upstream commit fd53c297aa7b077ae98a3d3d2d3aa278a1686ba6 ]
po->auxdata can be read while another thread is changing its value, potentially raising KCSAN splat.
Convert it to PACKET_SOCK_AUXDATA flag.
Fixes: 8dc419447415 ("[PACKET]: Add optional checksum computation for recvmsg") Signed-off-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/packet/af_packet.c | 8 +++----- net/packet/diag.c | 2 +- net/packet/internal.h | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index df93f4b09ab9e..9b6f6a5e0b147 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -3485,7 +3485,7 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, copy_len); }
- if (pkt_sk(sk)->auxdata) { + if (packet_sock_flag(pkt_sk(sk), PACKET_SOCK_AUXDATA)) { struct tpacket_auxdata aux;
aux.tp_status = TP_STATUS_USER; @@ -3869,9 +3869,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval, if (copy_from_sockptr(&val, optval, sizeof(val))) return -EFAULT;
- lock_sock(sk); - po->auxdata = !!val; - release_sock(sk); + packet_sock_flag_set(po, PACKET_SOCK_AUXDATA, val); return 0; } case PACKET_ORIGDEV: @@ -4032,7 +4030,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
break; case PACKET_AUXDATA: - val = po->auxdata; + val = packet_sock_flag(po, PACKET_SOCK_AUXDATA); break; case PACKET_ORIGDEV: val = packet_sock_flag(po, PACKET_SOCK_ORIGDEV); diff --git a/net/packet/diag.c b/net/packet/diag.c index e1ac9bb375b31..d704c7bf51b20 100644 --- a/net/packet/diag.c +++ b/net/packet/diag.c @@ -23,7 +23,7 @@ static int pdiag_put_info(const struct packet_sock *po, struct sk_buff *nlskb) pinfo.pdi_flags = 0; if (po->running) pinfo.pdi_flags |= PDI_RUNNING; - if (po->auxdata) + if (packet_sock_flag(po, PACKET_SOCK_AUXDATA)) pinfo.pdi_flags |= PDI_AUXDATA; if (packet_sock_flag(po, PACKET_SOCK_ORIGDEV)) pinfo.pdi_flags |= PDI_ORIGDEV; diff --git a/net/packet/internal.h b/net/packet/internal.h index 7fea453dc7215..3938cb413d5d3 100644 --- a/net/packet/internal.h +++ b/net/packet/internal.h @@ -118,8 +118,7 @@ struct packet_sock { struct mutex pg_vec_lock; unsigned long flags; unsigned int running; /* bind_lock must be held */ - unsigned int auxdata:1, /* writer must hold sock lock */ - has_vnet_hdr:1, + unsigned int has_vnet_hdr:1, /* writer must hold sock lock */ tp_loss:1, tp_tx_has_off:1; int pressure; @@ -146,6 +145,7 @@ static struct packet_sock *pkt_sk(struct sock *sk)
enum packet_sock_flags { PACKET_SOCK_ORIGDEV, + PACKET_SOCK_AUXDATA, };
static inline void packet_sock_flag_set(struct packet_sock *po,
From: David Disseldorp ddiss@suse.de
[ Upstream commit b455233dcc403e3eb955a642dd69b6676e12b245 ]
This helps distinguish it from the SCSI sense INFORMATION field.
Link: https://lore.kernel.org/r/20201031233211.5207-2-ddiss@suse.de Reviewed-by: Mike Christie michael.christie@oracle.com Signed-off-by: David Disseldorp ddiss@suse.de Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Stable-dep-of: 673db054d7a2 ("scsi: target: Fix multiple LUN_RESET handling") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_transport.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index bca3a32a4bfb7..ce521d3d30470 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -3131,14 +3131,14 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) } EXPORT_SYMBOL(transport_wait_for_tasks);
-struct sense_info { +struct sense_detail { u8 key; u8 asc; u8 ascq; bool add_sector_info; };
-static const struct sense_info sense_info_table[] = { +static const struct sense_detail sense_detail_table[] = { [TCM_NO_SENSE] = { .key = NOT_READY }, @@ -3298,39 +3298,39 @@ static const struct sense_info sense_info_table[] = { */ static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason) { - const struct sense_info *si; + const struct sense_detail *sd; u8 *buffer = cmd->sense_buffer; int r = (__force int)reason; u8 key, asc, ascq; bool desc_format = target_sense_desc_format(cmd->se_dev);
- if (r < ARRAY_SIZE(sense_info_table) && sense_info_table[r].key) - si = &sense_info_table[r]; + if (r < ARRAY_SIZE(sense_detail_table) && sense_detail_table[r].key) + sd = &sense_detail_table[r]; else - si = &sense_info_table[(__force int) + sd = &sense_detail_table[(__force int) TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE];
- key = si->key; + key = sd->key; if (reason == TCM_CHECK_CONDITION_UNIT_ATTENTION) { if (!core_scsi3_ua_for_check_condition(cmd, &key, &asc, &ascq)) { cmd->scsi_status = SAM_STAT_BUSY; return; } - } else if (si->asc == 0) { + } else if (sd->asc == 0) { WARN_ON_ONCE(cmd->scsi_asc == 0); asc = cmd->scsi_asc; ascq = cmd->scsi_ascq; } else { - asc = si->asc; - ascq = si->ascq; + asc = sd->asc; + ascq = sd->ascq; }
cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE; cmd->scsi_status = SAM_STAT_CHECK_CONDITION; cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; scsi_build_sense_buffer(desc_format, buffer, key, asc, ascq); - if (si->add_sector_info) + if (sd->add_sector_info) WARN_ON_ONCE(scsi_set_sense_information(buffer, cmd->scsi_sense_length, cmd->bad_sector) < 0);
From: David Disseldorp ddiss@suse.de
[ Upstream commit 8dd992fb67f33a0777fb4bee1e22a5ee5530f024 ]
cmd.bad_sector currently gets packed into the sense INFORMATION field for TCM_LOGICAL_BLOCK_{GUARD,APP_TAG,REF_TAG}_CHECK_FAILED errors, which carry an .add_sector_info flag in the sense_detail_table to ensure this.
In preparation for propagating a byte offset on COMPARE AND WRITE TCM_MISCOMPARE_VERIFY error, rename cmd.bad_sector to cmd.sense_info and sense_detail.add_sector_info to sense_detail.add_sense_info so that it better reflects the sense INFORMATION field destination.
[ddiss: update previously overlooked ib_isert]
Link: https://lore.kernel.org/r/20201031233211.5207-3-ddiss@suse.de Reviewed-by: Mike Christie michael.christie@oracle.com Signed-off-by: David Disseldorp ddiss@suse.de Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Stable-dep-of: 673db054d7a2 ("scsi: target: Fix multiple LUN_RESET handling") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/isert/ib_isert.c | 4 ++-- drivers/target/target_core_sbc.c | 2 +- drivers/target/target_core_transport.c | 12 ++++++------ include/target/target_core_base.h | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index edea37da8a5bd..2d0d966fba2c8 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -1553,12 +1553,12 @@ isert_check_pi_status(struct se_cmd *se_cmd, struct ib_mr *sig_mr) } sec_offset_err = mr_status.sig_err.sig_err_offset; do_div(sec_offset_err, block_size); - se_cmd->bad_sector = sec_offset_err + se_cmd->t_task_lba; + se_cmd->sense_info = sec_offset_err + se_cmd->t_task_lba;
isert_err("PI error found type %d at sector 0x%llx " "expected 0x%x vs actual 0x%x\n", mr_status.sig_err.err_type, - (unsigned long long)se_cmd->bad_sector, + (unsigned long long)se_cmd->sense_info, mr_status.sig_err.expected, mr_status.sig_err.actual); ret = 1; diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index eaf8551ebc612..47c5f26e6012d 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -1438,7 +1438,7 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors, if (rc) { kunmap_atomic(daddr - dsg->offset); kunmap_atomic(paddr - psg->offset); - cmd->bad_sector = sector; + cmd->sense_info = sector; return rc; } next: diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index ce521d3d30470..84d654c14917c 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -3135,7 +3135,7 @@ struct sense_detail { u8 key; u8 asc; u8 ascq; - bool add_sector_info; + bool add_sense_info; };
static const struct sense_detail sense_detail_table[] = { @@ -3238,19 +3238,19 @@ static const struct sense_detail sense_detail_table[] = { .key = ABORTED_COMMAND, .asc = 0x10, .ascq = 0x01, /* LOGICAL BLOCK GUARD CHECK FAILED */ - .add_sector_info = true, + .add_sense_info = true, }, [TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED] = { .key = ABORTED_COMMAND, .asc = 0x10, .ascq = 0x02, /* LOGICAL BLOCK APPLICATION TAG CHECK FAILED */ - .add_sector_info = true, + .add_sense_info = true, }, [TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED] = { .key = ABORTED_COMMAND, .asc = 0x10, .ascq = 0x03, /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */ - .add_sector_info = true, + .add_sense_info = true, }, [TCM_COPY_TARGET_DEVICE_NOT_REACHABLE] = { .key = COPY_ABORTED, @@ -3330,10 +3330,10 @@ static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason) cmd->scsi_status = SAM_STAT_CHECK_CONDITION; cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; scsi_build_sense_buffer(desc_format, buffer, key, asc, ascq); - if (sd->add_sector_info) + if (sd->add_sense_info) WARN_ON_ONCE(scsi_set_sense_information(buffer, cmd->scsi_sense_length, - cmd->bad_sector) < 0); + cmd->sense_info) < 0); }
int diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 18a5dcd275f88..16992ba455deb 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -540,7 +540,7 @@ struct se_cmd { struct scatterlist *t_prot_sg; unsigned int t_prot_nents; sense_reason_t pi_err; - sector_t bad_sector; + u64 sense_info; int cpuid; };
From: Mike Christie michael.christie@oracle.com
[ Upstream commit 1526d9f10c6184031e42afad0adbdde1213e8ad1 ]
Do a state_list/execute_task_lock per CPU, so we can do submissions from different CPUs without contention with each other.
Note: tcm_fc was passing TARGET_SCF_USE_CPUID, but never set cpuid. The assumption is that it wanted to set the cpuid to the CPU it was submitting from so it will get this behavior with this patch.
[mkp: s/printk/pr_err/ + resolve COMPARE AND WRITE patch conflict]
Link: https://lore.kernel.org/r/1604257174-4524-8-git-send-email-michael.christie@... Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Mike Christie michael.christie@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Stable-dep-of: 673db054d7a2 ("scsi: target: Fix multiple LUN_RESET handling") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_device.c | 16 ++- drivers/target/target_core_tmr.c | 166 +++++++++++++------------ drivers/target/target_core_transport.c | 27 ++-- drivers/target/tcm_fc/tfc_cmd.c | 2 +- include/target/target_core_base.h | 13 +- 5 files changed, 126 insertions(+), 98 deletions(-)
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 1eded5c4ebda6..bd3f1192c75a1 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -724,11 +724,24 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) { struct se_device *dev; struct se_lun *xcopy_lun; + int i;
dev = hba->backend->ops->alloc_device(hba, name); if (!dev) return NULL;
+ dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL); + if (!dev->queues) { + dev->transport->free_device(dev); + return NULL; + } + + dev->queue_cnt = nr_cpu_ids; + for (i = 0; i < dev->queue_cnt; i++) { + INIT_LIST_HEAD(&dev->queues[i].state_list); + spin_lock_init(&dev->queues[i].lock); + } + dev->se_hba = hba; dev->transport = hba->backend->ops; dev->transport_flags = dev->transport->transport_flags_default; @@ -738,9 +751,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) INIT_LIST_HEAD(&dev->dev_sep_list); INIT_LIST_HEAD(&dev->dev_tmr_list); INIT_LIST_HEAD(&dev->delayed_cmd_list); - INIT_LIST_HEAD(&dev->state_list); INIT_LIST_HEAD(&dev->qf_cmd_list); - spin_lock_init(&dev->execute_task_lock); spin_lock_init(&dev->delayed_cmd_lock); spin_lock_init(&dev->dev_reservation_lock); spin_lock_init(&dev->se_port_lock); @@ -1014,6 +1025,7 @@ void target_free_device(struct se_device *dev) if (dev->transport->free_prot) dev->transport->free_prot(dev);
+ kfree(dev->queues); dev->transport->free_device(dev); }
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 3efd5a3bd69d1..5da384bb88c82 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -121,57 +121,61 @@ void core_tmr_abort_task( unsigned long flags; bool rc; u64 ref_tag; - - spin_lock_irqsave(&dev->execute_task_lock, flags); - list_for_each_entry_safe(se_cmd, next, &dev->state_list, state_list) { - - if (se_sess != se_cmd->se_sess) - continue; - - /* skip task management functions, including tmr->task_cmd */ - if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) - continue; - - ref_tag = se_cmd->tag; - if (tmr->ref_task_tag != ref_tag) - continue; - - printk("ABORT_TASK: Found referenced %s task_tag: %llu\n", - se_cmd->se_tfo->fabric_name, ref_tag); - - spin_lock(&se_sess->sess_cmd_lock); - rc = __target_check_io_state(se_cmd, se_sess, 0); - spin_unlock(&se_sess->sess_cmd_lock); - if (!rc) - continue; - - list_move_tail(&se_cmd->state_list, &aborted_list); - se_cmd->state_active = false; - - spin_unlock_irqrestore(&dev->execute_task_lock, flags); - - /* - * Ensure that this ABORT request is visible to the LU RESET - * code. - */ - if (!tmr->tmr_dev) - WARN_ON_ONCE(transport_lookup_tmr_lun(tmr->task_cmd) < - 0); - - if (dev->transport->tmr_notify) - dev->transport->tmr_notify(dev, TMR_ABORT_TASK, - &aborted_list); - - list_del_init(&se_cmd->state_list); - target_put_cmd_and_wait(se_cmd); - - printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for" - " ref_tag: %llu\n", ref_tag); - tmr->response = TMR_FUNCTION_COMPLETE; - atomic_long_inc(&dev->aborts_complete); - return; + int i; + + for (i = 0; i < dev->queue_cnt; i++) { + spin_lock_irqsave(&dev->queues[i].lock, flags); + list_for_each_entry_safe(se_cmd, next, &dev->queues[i].state_list, + state_list) { + if (se_sess != se_cmd->se_sess) + continue; + + /* + * skip task management functions, including + * tmr->task_cmd + */ + if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) + continue; + + ref_tag = se_cmd->tag; + if (tmr->ref_task_tag != ref_tag) + continue; + + pr_err("ABORT_TASK: Found referenced %s task_tag: %llu\n", + se_cmd->se_tfo->fabric_name, ref_tag); + + spin_lock(&se_sess->sess_cmd_lock); + rc = __target_check_io_state(se_cmd, se_sess, 0); + spin_unlock(&se_sess->sess_cmd_lock); + if (!rc) + continue; + + list_move_tail(&se_cmd->state_list, &aborted_list); + se_cmd->state_active = false; + spin_unlock_irqrestore(&dev->queues[i].lock, flags); + + /* + * Ensure that this ABORT request is visible to the LU + * RESET code. + */ + if (!tmr->tmr_dev) + WARN_ON_ONCE(transport_lookup_tmr_lun(tmr->task_cmd) < 0); + + if (dev->transport->tmr_notify) + dev->transport->tmr_notify(dev, TMR_ABORT_TASK, + &aborted_list); + + list_del_init(&se_cmd->state_list); + target_put_cmd_and_wait(se_cmd); + + pr_err("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for ref_tag: %llu\n", + ref_tag); + tmr->response = TMR_FUNCTION_COMPLETE; + atomic_long_inc(&dev->aborts_complete); + return; + } + spin_unlock_irqrestore(&dev->queues[i].lock, flags); } - spin_unlock_irqrestore(&dev->execute_task_lock, flags);
if (dev->transport->tmr_notify) dev->transport->tmr_notify(dev, TMR_ABORT_TASK, &aborted_list); @@ -273,7 +277,7 @@ static void core_tmr_drain_state_list( struct se_session *sess; struct se_cmd *cmd, *next; unsigned long flags; - int rc; + int rc, i;
/* * Complete outstanding commands with TASK_ABORTED SAM status. @@ -297,35 +301,39 @@ static void core_tmr_drain_state_list( * Note that this seems to be independent of TAS (Task Aborted Status) * in the Control Mode Page. */ - spin_lock_irqsave(&dev->execute_task_lock, flags); - list_for_each_entry_safe(cmd, next, &dev->state_list, state_list) { - /* - * For PREEMPT_AND_ABORT usage, only process commands - * with a matching reservation key. - */ - if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd)) - continue; - - /* - * Not aborting PROUT PREEMPT_AND_ABORT CDB.. - */ - if (prout_cmd == cmd) - continue; - - sess = cmd->se_sess; - if (WARN_ON_ONCE(!sess)) - continue; - - spin_lock(&sess->sess_cmd_lock); - rc = __target_check_io_state(cmd, tmr_sess, tas); - spin_unlock(&sess->sess_cmd_lock); - if (!rc) - continue; - - list_move_tail(&cmd->state_list, &drain_task_list); - cmd->state_active = false; + for (i = 0; i < dev->queue_cnt; i++) { + spin_lock_irqsave(&dev->queues[i].lock, flags); + list_for_each_entry_safe(cmd, next, &dev->queues[i].state_list, + state_list) { + /* + * For PREEMPT_AND_ABORT usage, only process commands + * with a matching reservation key. + */ + if (target_check_cdb_and_preempt(preempt_and_abort_list, + cmd)) + continue; + + /* + * Not aborting PROUT PREEMPT_AND_ABORT CDB.. + */ + if (prout_cmd == cmd) + continue; + + sess = cmd->se_sess; + if (WARN_ON_ONCE(!sess)) + continue; + + spin_lock(&sess->sess_cmd_lock); + rc = __target_check_io_state(cmd, tmr_sess, tas); + spin_unlock(&sess->sess_cmd_lock); + if (!rc) + continue; + + list_move_tail(&cmd->state_list, &drain_task_list); + cmd->state_active = false; + } + spin_unlock_irqrestore(&dev->queues[i].lock, flags); } - spin_unlock_irqrestore(&dev->execute_task_lock, flags);
if (dev->transport->tmr_notify) dev->transport->tmr_notify(dev, preempt_and_abort_list ? diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 84d654c14917c..230fffa993c00 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -650,12 +650,12 @@ static void target_remove_from_state_list(struct se_cmd *cmd) if (!dev) return;
- spin_lock_irqsave(&dev->execute_task_lock, flags); + spin_lock_irqsave(&dev->queues[cmd->cpuid].lock, flags); if (cmd->state_active) { list_del(&cmd->state_list); cmd->state_active = false; } - spin_unlock_irqrestore(&dev->execute_task_lock, flags); + spin_unlock_irqrestore(&dev->queues[cmd->cpuid].lock, flags); }
/* @@ -866,10 +866,7 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
INIT_WORK(&cmd->work, success ? target_complete_ok_work : target_complete_failure_work); - if (cmd->se_cmd_flags & SCF_USE_CPUID) - queue_work_on(cmd->cpuid, target_completion_wq, &cmd->work); - else - queue_work(target_completion_wq, &cmd->work); + queue_work_on(cmd->cpuid, target_completion_wq, &cmd->work); } EXPORT_SYMBOL(target_complete_cmd);
@@ -904,12 +901,13 @@ static void target_add_to_state_list(struct se_cmd *cmd) struct se_device *dev = cmd->se_dev; unsigned long flags;
- spin_lock_irqsave(&dev->execute_task_lock, flags); + spin_lock_irqsave(&dev->queues[cmd->cpuid].lock, flags); if (!cmd->state_active) { - list_add_tail(&cmd->state_list, &dev->state_list); + list_add_tail(&cmd->state_list, + &dev->queues[cmd->cpuid].state_list); cmd->state_active = true; } - spin_unlock_irqrestore(&dev->execute_task_lock, flags); + spin_unlock_irqrestore(&dev->queues[cmd->cpuid].lock, flags); }
/* @@ -1397,6 +1395,9 @@ void transport_init_se_cmd( cmd->sense_buffer = sense_buffer; cmd->orig_fe_lun = unpacked_lun;
+ if (!(cmd->se_cmd_flags & SCF_USE_CPUID)) + cmd->cpuid = smp_processor_id(); + cmd->state_active = false; } EXPORT_SYMBOL(transport_init_se_cmd); @@ -1614,6 +1615,9 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess BUG_ON(!se_tpg); BUG_ON(se_cmd->se_tfo || se_cmd->se_sess); BUG_ON(in_interrupt()); + + if (flags & TARGET_SCF_USE_CPUID) + se_cmd->se_cmd_flags |= SCF_USE_CPUID; /* * Initialize se_cmd for target operation. From this point * exceptions are handled by sending exception status via @@ -1623,11 +1627,6 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess data_length, data_dir, task_attr, sense, unpacked_lun);
- if (flags & TARGET_SCF_USE_CPUID) - se_cmd->se_cmd_flags |= SCF_USE_CPUID; - else - se_cmd->cpuid = WORK_CPU_UNBOUND; - if (flags & TARGET_SCF_UNKNOWN_SIZE) se_cmd->unknown_data_length = 1; /* diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index a7ed56602c6cd..8936a094f8461 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -551,7 +551,7 @@ static void ft_send_work(struct work_struct *work) if (target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, fcp->fc_cdb, &cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun), ntohl(fcp->fc_dl), task_attr, data_dir, - TARGET_SCF_ACK_KREF | TARGET_SCF_USE_CPUID)) + TARGET_SCF_ACK_KREF)) goto err;
pr_debug("r_ctl %x target_submit_cmd %p\n", fh->fh_r_ctl, cmd); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 16992ba455deb..0109adcdfa0b4 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -541,6 +541,10 @@ struct se_cmd { unsigned int t_prot_nents; sense_reason_t pi_err; u64 sense_info; + /* + * CPU LIO will execute the cmd on. Defaults to the CPU the cmd is + * initialized on. Drivers can override. + */ int cpuid; };
@@ -761,6 +765,11 @@ struct se_dev_stat_grps { struct config_group scsi_lu_group; };
+struct se_device_queue { + struct list_head state_list; + spinlock_t lock; +}; + struct se_device { /* RELATIVE TARGET PORT IDENTIFER Counter */ u16 dev_rpti_counter; @@ -794,7 +803,6 @@ struct se_device { atomic_t dev_qf_count; u32 export_count; spinlock_t delayed_cmd_lock; - spinlock_t execute_task_lock; spinlock_t dev_reservation_lock; unsigned int dev_reservation_flags; #define DRF_SPC2_RESERVATIONS 0x00000001 @@ -814,7 +822,6 @@ struct se_device { struct work_struct qf_work_queue; struct work_struct delayed_cmd_work; struct list_head delayed_cmd_list; - struct list_head state_list; struct list_head qf_cmd_list; /* Pointer to associated SE HBA */ struct se_hba *se_hba; @@ -841,6 +848,8 @@ struct se_device { /* For se_lun->lun_se_dev RCU read-side critical access */ u32 hba_index; struct rcu_head rcu_head; + int queue_cnt; + struct se_device_queue *queues; };
struct se_hba {
From: Mike Christie michael.christie@oracle.com
[ Upstream commit 673db054d7a2b5a470d7a25baf65956d005ad729 ]
This fixes a bug where an initiator thinks a LUN_RESET has cleaned up running commands when it hasn't. The bug was added in commit 51ec502a3266 ("target: Delete tmr from list before processing").
The problem occurs when:
1. We have N I/O cmds running in the target layer spread over 2 sessions.
2. The initiator sends a LUN_RESET for each session.
3. session1's LUN_RESET loops over all the running commands from both sessions and moves them to its local drain_task_list.
4. session2's LUN_RESET does not see the LUN_RESET from session1 because the commit above has it remove itself. session2 also does not see any commands since the other reset moved them off the state lists.
5. sessions2's LUN_RESET will then complete with a successful response.
6. sessions2's inititor believes the running commands on its session are now cleaned up due to the successful response and cleans up the running commands from its side. It then restarts them.
7. The commands do eventually complete on the backend and the target starts to return aborted task statuses for them. The initiator will either throw a invalid ITT error or might accidentally lookup a new task if the ITT has been reallocated already.
Fix the bug by reverting the patch, and serialize the execution of LUN_RESETs and Preempt and Aborts.
Also prevent us from waiting on LUN_RESETs in core_tmr_drain_tmr_list, because it turns out the original patch fixed a bug that was not mentioned. For LUN_RESET1 core_tmr_drain_tmr_list can see a second LUN_RESET and wait on it. Then the second reset will run core_tmr_drain_tmr_list and see the first reset and wait on it resulting in a deadlock.
Fixes: 51ec502a3266 ("target: Delete tmr from list before processing") Signed-off-by: Mike Christie michael.christie@oracle.com Link: https://lore.kernel.org/r/20230319015620.96006-8-michael.christie@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_device.c | 1 + drivers/target/target_core_tmr.c | 26 +++++++++++++++++++++++--- include/target/target_core_base.h | 1 + 3 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index bd3f1192c75a1..4664330fb55dd 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -770,6 +770,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) spin_lock_init(&dev->t10_alua.lba_map_lock);
INIT_WORK(&dev->delayed_cmd_work, target_do_delayed_work); + mutex_init(&dev->lun_reset_mutex);
dev->t10_wwn.t10_dev = dev; dev->t10_alua.t10_dev = dev; diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 5da384bb88c82..a2b18a98d6718 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -202,14 +202,23 @@ static void core_tmr_drain_tmr_list( * LUN_RESET tmr.. */ spin_lock_irqsave(&dev->se_tmr_lock, flags); - if (tmr) - list_del_init(&tmr->tmr_list); list_for_each_entry_safe(tmr_p, tmr_pp, &dev->dev_tmr_list, tmr_list) { + if (tmr_p == tmr) + continue; + cmd = tmr_p->task_cmd; if (!cmd) { pr_err("Unable to locate struct se_cmd for TMR\n"); continue; } + + /* + * We only execute one LUN_RESET at a time so we can't wait + * on them below. + */ + if (tmr_p->function == TMR_LUN_RESET) + continue; + /* * If this function was called with a valid pr_res_key * parameter (eg: for PROUT PREEMPT_AND_ABORT service action @@ -390,14 +399,25 @@ int core_tmr_lun_reset( tmr_nacl->initiatorname); } } + + + /* + * We only allow one reset or preempt and abort to execute at a time + * to prevent one call from claiming all the cmds causing a second + * call from returning while cmds it should have waited on are still + * running. + */ + mutex_lock(&dev->lun_reset_mutex); + pr_debug("LUN_RESET: %s starting for [%s], tas: %d\n", (preempt_and_abort_list) ? "Preempt" : "TMR", dev->transport->name, tas); - core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list); core_tmr_drain_state_list(dev, prout_cmd, tmr_sess, tas, preempt_and_abort_list);
+ mutex_unlock(&dev->lun_reset_mutex); + /* * Clear any legacy SPC-2 reservation when called during * LOGICAL UNIT RESET diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 0109adcdfa0b4..e681c712fcca2 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -850,6 +850,7 @@ struct se_device { struct rcu_head rcu_head; int queue_cnt; struct se_device_queue *queues; + struct mutex lun_reset_mutex; };
struct se_hba {
From: Mike Christie michael.christie@oracle.com
[ Upstream commit cc79da306ebb2edb700c3816b90219223182ac3c ]
Fix a bug added in commit f36199355c64 ("scsi: target: iscsi: Fix cmd abort fabric stop race").
If CMD_T_TAS is set on the se_cmd we must call iscsit_free_cmd() to do the last put on the cmd and free it, because the connection is down and we will not up sending the response and doing the put from the normal I/O path.
Add a check for CMD_T_TAS in iscsit_release_commands_from_conn() so we now detect this case and run iscsit_free_cmd().
Fixes: f36199355c64 ("scsi: target: iscsi: Fix cmd abort fabric stop race") Signed-off-by: Mike Christie michael.christie@oracle.com Link: https://lore.kernel.org/r/20230319015620.96006-9-michael.christie@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/iscsi/iscsi_target.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index a237f1cf9bd60..6bb8403580729 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -4084,9 +4084,12 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) { struct se_cmd *se_cmd = &cmd->se_cmd;
- if (se_cmd->se_tfo != NULL) { - spin_lock_irq(&se_cmd->t_state_lock); - if (se_cmd->transport_state & CMD_T_ABORTED) { + if (!se_cmd->se_tfo) + continue; + + spin_lock_irq(&se_cmd->t_state_lock); + if (se_cmd->transport_state & CMD_T_ABORTED) { + if (!(se_cmd->transport_state & CMD_T_TAS)) /* * LIO's abort path owns the cleanup for this, * so put it back on the list and let @@ -4094,11 +4097,10 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) */ list_move_tail(&cmd->i_conn_node, &conn->conn_cmd_list); - } else { - se_cmd->transport_state |= CMD_T_FABRIC_STOP; - } - spin_unlock_irq(&se_cmd->t_state_lock); + } else { + se_cmd->transport_state |= CMD_T_FABRIC_STOP; } + spin_unlock_irq(&se_cmd->t_state_lock); } spin_unlock_bh(&conn->cmd_lock);
From: Danila Chernetsov listdansp@mail.ru
[ Upstream commit 75cb113cd43f06aaf4f1bda0069cfd5b98e909eb ]
When cmdid == CMDID_INT_CMDS, the 'cmds' pointer is NULL but is dereferenced below.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 0f2bb84d2a68 ("[SCSI] megaraid: simplify internal command handling") Signed-off-by: Danila Chernetsov listdansp@mail.ru Link: https://lore.kernel.org/r/20230317175109.18585-1-listdansp@mail.ru Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/megaraid.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index daffa36988aee..810d803406761 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -1443,6 +1443,7 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status) */ if (cmdid == CMDID_INT_CMDS) { scb = &adapter->int_scb; + cmd = scb->cmd;
list_del_init(&scb->list); scb->state = SCB_FREE;
From: Yangtao Li frank.li@vivo.com
[ Upstream commit 8051692f5f23260215bfe9a72e712d93606acc5f ]
We should set the error code when dqget() failed.
Fixes: 2c1d03056991 ("f2fs: support F2FS_IOC_FS{GET,SET}XATTR") Signed-off-by: Yangtao Li frank.li@vivo.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/file.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index d56fcace18211..a0d8aa52b696b 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3013,15 +3013,16 @@ int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid) struct dquot *transfer_to[MAXQUOTAS] = {}; struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct super_block *sb = sbi->sb; - int err = 0; + int err;
transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid)); - if (!IS_ERR(transfer_to[PRJQUOTA])) { - err = __dquot_transfer(inode, transfer_to); - if (err) - set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); - dqput(transfer_to[PRJQUOTA]); - } + if (IS_ERR(transfer_to[PRJQUOTA])) + return PTR_ERR(transfer_to[PRJQUOTA]); + + err = __dquot_transfer(inode, transfer_to); + if (err) + set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); + dqput(transfer_to[PRJQUOTA]); return err; }
From: Jaegeuk Kim jaegeuk@kernel.org
[ Upstream commit b771aadc6e4c221a468fe4a2dfcfffec01a06722 ]
In order to simplify the complicated per-zone capacity, let's support only one capacity for entire zoned device.
Reviewed-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Stable-dep-of: 0b37ed21e336 ("f2fs: apply zone capacity to all zone type") Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/f2fs.h | 2 +- fs/f2fs/segment.c | 19 ++++++------------- fs/f2fs/segment.h | 3 +++ fs/f2fs/super.c | 33 ++++++++++++--------------------- 4 files changed, 22 insertions(+), 35 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index c03fdda1bddf6..62b7848f1f71e 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1153,7 +1153,6 @@ struct f2fs_dev_info { #ifdef CONFIG_BLK_DEV_ZONED unsigned int nr_blkz; /* Total number of zones */ unsigned long *blkz_seq; /* Bitmap indicating sequential zones */ - block_t *zone_capacity_blocks; /* Array of zone capacity in blks */ #endif };
@@ -1422,6 +1421,7 @@ struct f2fs_sb_info { unsigned int meta_ino_num; /* meta inode number*/ unsigned int log_blocks_per_seg; /* log2 blocks per segment */ unsigned int blocks_per_seg; /* blocks per segment */ + unsigned int unusable_blocks_per_sec; /* unusable blocks per section */ unsigned int segs_per_sec; /* segments per section */ unsigned int secs_per_zone; /* sections per zone */ unsigned int total_sections; /* total section count */ diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 7c90d93f4e435..5305913fe0d58 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -4982,7 +4982,7 @@ static unsigned int get_zone_idx(struct f2fs_sb_info *sbi, unsigned int secno, static inline unsigned int f2fs_usable_zone_segs_in_sec( struct f2fs_sb_info *sbi, unsigned int segno) { - unsigned int dev_idx, zone_idx, unusable_segs_in_sec; + unsigned int dev_idx, zone_idx;
dev_idx = f2fs_target_device_index(sbi, START_BLOCK(sbi, segno)); zone_idx = get_zone_idx(sbi, GET_SEC_FROM_SEG(sbi, segno), dev_idx); @@ -4991,18 +4991,12 @@ static inline unsigned int f2fs_usable_zone_segs_in_sec( if (is_conv_zone(sbi, zone_idx, dev_idx)) return sbi->segs_per_sec;
- /* - * If the zone_capacity_blocks array is NULL, then zone capacity - * is equal to the zone size for all zones - */ - if (!FDEV(dev_idx).zone_capacity_blocks) + if (!sbi->unusable_blocks_per_sec) return sbi->segs_per_sec;
/* Get the segment count beyond zone capacity block */ - unusable_segs_in_sec = (sbi->blocks_per_blkz - - FDEV(dev_idx).zone_capacity_blocks[zone_idx]) >> - sbi->log_blocks_per_seg; - return sbi->segs_per_sec - unusable_segs_in_sec; + return sbi->segs_per_sec - (sbi->unusable_blocks_per_sec >> + sbi->log_blocks_per_seg); }
/* @@ -5031,12 +5025,11 @@ static inline unsigned int f2fs_usable_zone_blks_in_seg( if (is_conv_zone(sbi, zone_idx, dev_idx)) return sbi->blocks_per_seg;
- if (!FDEV(dev_idx).zone_capacity_blocks) + if (!sbi->unusable_blocks_per_sec) return sbi->blocks_per_seg;
sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno)); - sec_cap_blkaddr = sec_start_blkaddr + - FDEV(dev_idx).zone_capacity_blocks[zone_idx]; + sec_cap_blkaddr = sec_start_blkaddr + CAP_BLKS_PER_SEC(sbi);
/* * If segment starts before zone capacity and spans beyond diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index eafd89f0c77e8..aca6c9a3aad0b 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -101,6 +101,9 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi, GET_SEGNO_FROM_SEG0(sbi, blk_addr))) #define BLKS_PER_SEC(sbi) \ ((sbi)->segs_per_sec * (sbi)->blocks_per_seg) +#define CAP_BLKS_PER_SEC(sbi) \ + ((sbi)->segs_per_sec * (sbi)->blocks_per_seg - \ + (sbi)->unusable_blocks_per_sec) #define GET_SEC_FROM_SEG(sbi, segno) \ (((segno) == -1) ? -1: (segno) / (sbi)->segs_per_sec) #define GET_SEG_FROM_SEC(sbi, secno) \ diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 0bba5c72fc77e..9a74d60f61dba 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1242,7 +1242,6 @@ static void destroy_device_list(struct f2fs_sb_info *sbi) blkdev_put(FDEV(i).bdev, FMODE_EXCL); #ifdef CONFIG_BLK_DEV_ZONED kvfree(FDEV(i).blkz_seq); - kfree(FDEV(i).zone_capacity_blocks); #endif } kvfree(sbi->devs); @@ -3199,24 +3198,29 @@ static int init_percpu_info(struct f2fs_sb_info *sbi) #ifdef CONFIG_BLK_DEV_ZONED
struct f2fs_report_zones_args { + struct f2fs_sb_info *sbi; struct f2fs_dev_info *dev; - bool zone_cap_mismatch; };
static int f2fs_report_zone_cb(struct blk_zone *zone, unsigned int idx, void *data) { struct f2fs_report_zones_args *rz_args = data; + block_t unusable_blocks = (zone->len - zone->capacity) >> + F2FS_LOG_SECTORS_PER_BLOCK;
if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL) return 0;
set_bit(idx, rz_args->dev->blkz_seq); - rz_args->dev->zone_capacity_blocks[idx] = zone->capacity >> - F2FS_LOG_SECTORS_PER_BLOCK; - if (zone->len != zone->capacity && !rz_args->zone_cap_mismatch) - rz_args->zone_cap_mismatch = true; - + if (!rz_args->sbi->unusable_blocks_per_sec) { + rz_args->sbi->unusable_blocks_per_sec = unusable_blocks; + return 0; + } + if (rz_args->sbi->unusable_blocks_per_sec != unusable_blocks) { + f2fs_err(rz_args->sbi, "F2FS supports single zone capacity\n"); + return -EINVAL; + } return 0; }
@@ -3250,26 +3254,13 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi) if (!FDEV(devi).blkz_seq) return -ENOMEM;
- /* Get block zones type and zone-capacity */ - FDEV(devi).zone_capacity_blocks = f2fs_kzalloc(sbi, - FDEV(devi).nr_blkz * sizeof(block_t), - GFP_KERNEL); - if (!FDEV(devi).zone_capacity_blocks) - return -ENOMEM; - + rep_zone_arg.sbi = sbi; rep_zone_arg.dev = &FDEV(devi); - rep_zone_arg.zone_cap_mismatch = false;
ret = blkdev_report_zones(bdev, 0, BLK_ALL_ZONES, f2fs_report_zone_cb, &rep_zone_arg); if (ret < 0) return ret; - - if (!rep_zone_arg.zone_cap_mismatch) { - kfree(FDEV(devi).zone_capacity_blocks); - FDEV(devi).zone_capacity_blocks = NULL; - } - return 0; } #endif
From: Jaegeuk Kim jaegeuk@kernel.org
[ Upstream commit 0b37ed21e3367539b79284e0b0af2246ffcf0dca ]
If we manage the zone capacity per zone type, it'll break the GC assumption. And, the current logic complains valid block count mismatch. Let's apply zone capacity to all zone type, if specified.
Fixes: de881df97768 ("f2fs: support zone capacity less than zone size") Reviewed-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/segment.c | 65 +++-------------------------------------------- fs/f2fs/segment.h | 3 +++ 2 files changed, 7 insertions(+), 61 deletions(-)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 5305913fe0d58..a27a934292715 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -4957,48 +4957,6 @@ int f2fs_check_write_pointer(struct f2fs_sb_info *sbi) return 0; }
-static bool is_conv_zone(struct f2fs_sb_info *sbi, unsigned int zone_idx, - unsigned int dev_idx) -{ - if (!bdev_is_zoned(FDEV(dev_idx).bdev)) - return true; - return !test_bit(zone_idx, FDEV(dev_idx).blkz_seq); -} - -/* Return the zone index in the given device */ -static unsigned int get_zone_idx(struct f2fs_sb_info *sbi, unsigned int secno, - int dev_idx) -{ - block_t sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno)); - - return (sec_start_blkaddr - FDEV(dev_idx).start_blk) >> - sbi->log_blocks_per_blkz; -} - -/* - * Return the usable segments in a section based on the zone's - * corresponding zone capacity. Zone is equal to a section. - */ -static inline unsigned int f2fs_usable_zone_segs_in_sec( - struct f2fs_sb_info *sbi, unsigned int segno) -{ - unsigned int dev_idx, zone_idx; - - dev_idx = f2fs_target_device_index(sbi, START_BLOCK(sbi, segno)); - zone_idx = get_zone_idx(sbi, GET_SEC_FROM_SEG(sbi, segno), dev_idx); - - /* Conventional zone's capacity is always equal to zone size */ - if (is_conv_zone(sbi, zone_idx, dev_idx)) - return sbi->segs_per_sec; - - if (!sbi->unusable_blocks_per_sec) - return sbi->segs_per_sec; - - /* Get the segment count beyond zone capacity block */ - return sbi->segs_per_sec - (sbi->unusable_blocks_per_sec >> - sbi->log_blocks_per_seg); -} - /* * Return the number of usable blocks in a segment. The number of blocks * returned is always equal to the number of blocks in a segment for @@ -5011,23 +4969,13 @@ static inline unsigned int f2fs_usable_zone_blks_in_seg( struct f2fs_sb_info *sbi, unsigned int segno) { block_t seg_start, sec_start_blkaddr, sec_cap_blkaddr; - unsigned int zone_idx, dev_idx, secno; - - secno = GET_SEC_FROM_SEG(sbi, segno); - seg_start = START_BLOCK(sbi, segno); - dev_idx = f2fs_target_device_index(sbi, seg_start); - zone_idx = get_zone_idx(sbi, secno, dev_idx); - - /* - * Conventional zone's capacity is always equal to zone size, - * so, blocks per segment is unchanged. - */ - if (is_conv_zone(sbi, zone_idx, dev_idx)) - return sbi->blocks_per_seg; + unsigned int secno;
if (!sbi->unusable_blocks_per_sec) return sbi->blocks_per_seg;
+ secno = GET_SEC_FROM_SEG(sbi, segno); + seg_start = START_BLOCK(sbi, segno); sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno)); sec_cap_blkaddr = sec_start_blkaddr + CAP_BLKS_PER_SEC(sbi);
@@ -5061,11 +5009,6 @@ static inline unsigned int f2fs_usable_zone_blks_in_seg(struct f2fs_sb_info *sbi return 0; }
-static inline unsigned int f2fs_usable_zone_segs_in_sec(struct f2fs_sb_info *sbi, - unsigned int segno) -{ - return 0; -} #endif unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi, unsigned int segno) @@ -5080,7 +5023,7 @@ unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi, unsigned int segno) { if (f2fs_sb_has_blkzoned(sbi)) - return f2fs_usable_zone_segs_in_sec(sbi, segno); + return CAP_SEGS_PER_SEC(sbi);
return sbi->segs_per_sec; } diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index aca6c9a3aad0b..979296b835b5a 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -104,6 +104,9 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi, #define CAP_BLKS_PER_SEC(sbi) \ ((sbi)->segs_per_sec * (sbi)->blocks_per_seg - \ (sbi)->unusable_blocks_per_sec) +#define CAP_SEGS_PER_SEC(sbi) \ + ((sbi)->segs_per_sec - ((sbi)->unusable_blocks_per_sec >>\ + (sbi)->log_blocks_per_seg)) #define GET_SEC_FROM_SEG(sbi, segno) \ (((segno) == -1) ? -1: (segno) / (sbi)->segs_per_sec) #define GET_SEG_FROM_SEC(sbi, secno) \
From: Yangtao Li frank.li@vivo.com
[ Upstream commit babedcbac164cec970872b8097401ca913a80e61 ]
BUG_ON() will be triggered when writing files concurrently, because the same page is writtenback multiple times.
1597 void folio_end_writeback(struct folio *folio) 1598 { ...... 1618 if (!__folio_end_writeback(folio)) 1619 BUG(); ...... 1625 }
kernel BUG at mm/filemap.c:1619! Call Trace: <TASK> f2fs_write_end_io+0x1a0/0x370 blk_update_request+0x6c/0x410 blk_mq_end_request+0x15/0x130 blk_complete_reqs+0x3c/0x50 __do_softirq+0xb8/0x29b ? sort_range+0x20/0x20 run_ksoftirqd+0x19/0x20 smpboot_thread_fn+0x10b/0x1d0 kthread+0xde/0x110 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x22/0x30 </TASK>
Below is the concurrency scenario:
[Process A] [Process B] [Process C] f2fs_write_raw_pages() - redirty_page_for_writepage() - unlock page() f2fs_do_write_data_page() - lock_page() - clear_page_dirty_for_io() - set_page_writeback() [1st writeback] ..... - unlock page()
generic_perform_write() - f2fs_write_begin() - wait_for_stable_page()
- f2fs_write_end() - set_page_dirty()
- lock_page() - f2fs_do_write_data_page() - set_page_writeback() [2st writeback]
This problem was introduced by the previous commit 7377e853967b ("f2fs: compress: fix potential deadlock of compress file"). All pagelocks were released in f2fs_write_raw_pages(), but whether the page was in the writeback state was ignored in the subsequent writing process. Let's fix it by waiting for the page to writeback before writing.
Cc: Christoph Hellwig hch@lst.de Fixes: 4c8ff7095bef ("f2fs: support data compression") Fixes: 7377e853967b ("f2fs: compress: fix potential deadlock of compress file") Signed-off-by: Qi Han hanqi@vivo.com Signed-off-by: Yangtao Li frank.li@vivo.com Reviewed-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/compress.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 1541da5ace85e..1be9de40f0b5a 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1391,6 +1391,12 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, if (!PageDirty(cc->rpages[i])) goto continue_unlock;
+ if (PageWriteback(cc->rpages[i])) { + if (wbc->sync_mode == WB_SYNC_NONE) + goto continue_unlock; + f2fs_wait_on_page_writeback(cc->rpages[i], DATA, true, true); + } + if (!clear_page_dirty_for_io(cc->rpages[i])) goto continue_unlock;
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 9c19fb86a8cb2ee82a832c95e139f29ea05c4d08 ]
According to the comment at the end of the 'for' loop just a few lines below, it looks needed to clear 'desc'.
So it should also be cleared for the first iteration.
Move the memset() to the beginning of the loop to be safe.
Fixes: 281922a1d4f5 ("crypto: caam - add support for SEC v5.x RNG4") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Gaurav Jain gaurav.jain@nxp.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/caam/ctrl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index f87aa2169e5f5..f9a1ec3c84851 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -284,6 +284,10 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask, const u32 rdsta_if = RDSTA_IF0 << sh_idx; const u32 rdsta_pr = RDSTA_PR0 << sh_idx; const u32 rdsta_mask = rdsta_if | rdsta_pr; + + /* Clear the contents before using the descriptor */ + memset(desc, 0x00, CAAM_CMD_SZ * 7); + /* * If the corresponding bit is set, this state handle * was initialized by somebody else, so it's left alone. @@ -327,8 +331,6 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask, }
dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx); - /* Clear the contents before recreating the descriptor */ - memset(desc, 0x00, CAAM_CMD_SZ * 7); }
kfree(desc);
From: Suman Anna s-anna@ti.com
[ Upstream commit 8832023efd20966e29944dac92118dfbf1fa1bc0 ]
The SA2UL Crypto driver provides support for couple of DES3 algos "cbc(des3_ede)" and "ecb(des3_ede)", and enabling the crypto selftest throws the following errors (as seen on K3 J721E SoCs): saul-crypto 4e00000.crypto: Error allocating fallback algo cbc(des3_ede) alg: skcipher: failed to allocate transform for cbc-des3-sa2ul: -2 saul-crypto 4e00000.crypto: Error allocating fallback algo ecb(des3_ede) alg: skcipher: failed to allocate transform for ecb-des3-sa2ul: -2
Fix this by selecting CRYPTO_DES which was missed while adding base driver support.
Fixes: 7694b6ca649f ("crypto: sa2ul - Add crypto driver") Signed-off-by: Suman Anna s-anna@ti.com Signed-off-by: Jayesh Choudhary j-choudhary@ti.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 0a3dd0793f30e..dbdee43c6ffcf 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -897,6 +897,7 @@ config CRYPTO_DEV_SA2UL select CRYPTO_AES_ARM64 select CRYPTO_ALGAPI select CRYPTO_AUTHENC + select CRYPTO_DES select CRYPTO_SHA1 select CRYPTO_SHA256 select CRYPTO_SHA512
From: Wei Chen harperchen1110@gmail.com
[ Upstream commit 905a9241e4e8c15d2c084fee916280514848fe35 ]
If there is a failure during copy_from_user or user-provided data buffer is invalid, rtl_debugfs_set_write_rfreg should return negative error code instead of a positive value count.
Fix this bug by returning correct error code. Moreover, the check of buffer against null is removed since it will be handled by copy_from_user.
Fixes: 610247f46feb ("rtlwifi: Improve debugging by using debugfs") Signed-off-by: Wei Chen harperchen1110@gmail.com Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230326053138.91338-1-harperchen1110@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtlwifi/debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c index 0b1bc04cb6adb..602717928887d 100644 --- a/drivers/net/wireless/realtek/rtlwifi/debug.c +++ b/drivers/net/wireless/realtek/rtlwifi/debug.c @@ -375,8 +375,8 @@ static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp,
tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
- if (!buffer || copy_from_user(tmp, buffer, tmp_len)) - return count; + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT;
tmp[tmp_len] = '\0';
@@ -386,7 +386,7 @@ static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp, if (num != 4) { rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, "Format is <path> <addr> <mask> <data>\n"); - return count; + return -EINVAL; }
rtl_set_rfreg(hw, path, addr, bitmask, data);
From: Wei Chen harperchen1110@gmail.com
[ Upstream commit 5dbe1f8eb8c5ac69394400a5b86fd81775e96c43 ]
If there is a failure during copy_from_user or user-provided data buffer is invalid, rtl_debugfs_set_write_reg should return negative error code instead of a positive value count.
Fix this bug by returning correct error code. Moreover, the check of buffer against null is removed since it will be handled by copy_from_user.
Fixes: 610247f46feb ("rtlwifi: Improve debugging by using debugfs") Signed-off-by: Wei Chen harperchen1110@gmail.com Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20230326054217.93492-1-harperchen1110@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtlwifi/debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c index 602717928887d..9eb26dfe4ca92 100644 --- a/drivers/net/wireless/realtek/rtlwifi/debug.c +++ b/drivers/net/wireless/realtek/rtlwifi/debug.c @@ -278,8 +278,8 @@ static ssize_t rtl_debugfs_set_write_reg(struct file *filp,
tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
- if (!buffer || copy_from_user(tmp, buffer, tmp_len)) - return count; + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT;
tmp[tmp_len] = '\0';
@@ -287,7 +287,7 @@ static ssize_t rtl_debugfs_set_write_reg(struct file *filp, num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
if (num != 3) - return count; + return -EINVAL;
switch (len) { case 1:
From: Simon Horman horms@kernel.org
[ Upstream commit 054fbf7ff8143d35ca7d3bb5414bb44ee1574194 ]
The arguments passed to the trace events are of type unsigned int, however the signature of the events used __le32 parameters.
I may be missing the point here, but sparse flagged this and it does seem incorrect to me.
net/qrtr/ns.c: note: in included file (through include/trace/trace_events.h, include/trace/define_trace.h, include/trace/events/qrtr.h): ./include/trace/events/qrtr.h:11:1: warning: cast to restricted __le32 ./include/trace/events/qrtr.h:11:1: warning: restricted __le32 degrades to integer ./include/trace/events/qrtr.h:11:1: warning: restricted __le32 degrades to integer ... (a lot more similar warnings) net/qrtr/ns.c:115:47: expected restricted __le32 [usertype] service net/qrtr/ns.c:115:47: got unsigned int service net/qrtr/ns.c:115:61: warning: incorrect type in argument 2 (different base types) ... (a lot more similar warnings)
Fixes: dfddb54043f0 ("net: qrtr: Add tracepoint support") Reviewed-by: Manivannan Sadhasivam mani@kernel.org Signed-off-by: Simon Horman horms@kernel.org Link: https://lore.kernel.org/r/20230402-qrtr-trace-types-v1-1-92ad55008dd3@kernel... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/trace/events/qrtr.h | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/include/trace/events/qrtr.h b/include/trace/events/qrtr.h index b1de14c3bb934..441132c67133f 100644 --- a/include/trace/events/qrtr.h +++ b/include/trace/events/qrtr.h @@ -10,15 +10,16 @@
TRACE_EVENT(qrtr_ns_service_announce_new,
- TP_PROTO(__le32 service, __le32 instance, __le32 node, __le32 port), + TP_PROTO(unsigned int service, unsigned int instance, + unsigned int node, unsigned int port),
TP_ARGS(service, instance, node, port),
TP_STRUCT__entry( - __field(__le32, service) - __field(__le32, instance) - __field(__le32, node) - __field(__le32, port) + __field(unsigned int, service) + __field(unsigned int, instance) + __field(unsigned int, node) + __field(unsigned int, port) ),
TP_fast_assign( @@ -36,15 +37,16 @@ TRACE_EVENT(qrtr_ns_service_announce_new,
TRACE_EVENT(qrtr_ns_service_announce_del,
- TP_PROTO(__le32 service, __le32 instance, __le32 node, __le32 port), + TP_PROTO(unsigned int service, unsigned int instance, + unsigned int node, unsigned int port),
TP_ARGS(service, instance, node, port),
TP_STRUCT__entry( - __field(__le32, service) - __field(__le32, instance) - __field(__le32, node) - __field(__le32, port) + __field(unsigned int, service) + __field(unsigned int, instance) + __field(unsigned int, node) + __field(unsigned int, port) ),
TP_fast_assign( @@ -62,15 +64,16 @@ TRACE_EVENT(qrtr_ns_service_announce_del,
TRACE_EVENT(qrtr_ns_server_add,
- TP_PROTO(__le32 service, __le32 instance, __le32 node, __le32 port), + TP_PROTO(unsigned int service, unsigned int instance, + unsigned int node, unsigned int port),
TP_ARGS(service, instance, node, port),
TP_STRUCT__entry( - __field(__le32, service) - __field(__le32, instance) - __field(__le32, node) - __field(__le32, port) + __field(unsigned int, service) + __field(unsigned int, instance) + __field(unsigned int, node) + __field(unsigned int, port) ),
TP_fast_assign(
From: YiFei Zhu zhuyifei@google.com
[ Upstream commit 5af607a861d43ffff830fc1890033e579ec44799 ]
In some cases the loopback latency might be large enough, causing the assertion on invocations to be run before ingress prog getting executed. The assertion would fail and the test would flake.
This can be reliably reproduced by arbitrarily increasing the loopback latency (thanks to [1]): tc qdisc add dev lo root handle 1: htb default 12 tc class add dev lo parent 1:1 classid 1:12 htb rate 20kbps ceil 20kbps tc qdisc add dev lo parent 1:12 netem delay 100ms
Fix this by waiting on the receive end, instead of instantly returning to the assert. The call to read() will wait for the default SO_RCVTIMEO timeout of 3 seconds provided by start_server().
[1] https://gist.github.com/kstevens715/4598301
Reported-by: Martin KaFai Lau martin.lau@linux.dev Link: https://lore.kernel.org/bpf/9c5c8b7e-1d89-a3af-5400-14fde81f4429@linux.dev/ Fixes: 3573f384014f ("selftests/bpf: Test CGROUP_STORAGE behavior on shared egress + ingress") Acked-by: Stanislav Fomichev sdf@google.com Signed-off-by: YiFei Zhu zhuyifei@google.com Link: https://lore.kernel.org/r/20230405193354.1956209-1-zhuyifei@google.com Signed-off-by: Martin KaFai Lau martin.lau@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c b/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c index 643dfa35419c1..48dc5827daa7f 100644 --- a/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c +++ b/tools/testing/selftests/bpf/prog_tests/cg_storage_multi.c @@ -56,8 +56,9 @@ static bool assert_storage_noexist(struct bpf_map *map, const void *key)
static bool connect_send(const char *cgroup_path) { - bool res = true; int server_fd = -1, client_fd = -1; + char message[] = "message"; + bool res = true;
if (join_cgroup(cgroup_path)) goto out_clean; @@ -70,7 +71,10 @@ static bool connect_send(const char *cgroup_path) if (client_fd < 0) goto out_clean;
- if (send(client_fd, "message", strlen("message"), 0) < 0) + if (send(client_fd, &message, sizeof(message), 0) < 0) + goto out_clean; + + if (read(server_fd, &message, sizeof(message)) < 0) goto out_clean;
res = false;
From: Quentin Monnet quentin@isovalent.com
[ Upstream commit 67cf52cdb6c8fa6365d29106555dacf95c9fd374 ]
When dumping the control flow graphs for programs using the 16-byte long load instruction, we need to skip the second part of this instruction when looking for the next instruction to process. Otherwise, we end up printing "BUG_ld_00" from the kernel disassembler in the CFG.
Fixes: efcef17a6d65 ("tools: bpftool: generate .dot graph from CFG information") Signed-off-by: Quentin Monnet quentin@isovalent.com Link: https://lore.kernel.org/r/20230405132120.59886-3-quentin@isovalent.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/bpf/bpftool/xlated_dumper.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c index 8608cd68cdd07..13d614b16f6c2 100644 --- a/tools/bpf/bpftool/xlated_dumper.c +++ b/tools/bpf/bpftool/xlated_dumper.c @@ -363,8 +363,15 @@ void dump_xlated_for_graph(struct dump_data *dd, void *buf_start, void *buf_end, struct bpf_insn *insn_start = buf_start; struct bpf_insn *insn_end = buf_end; struct bpf_insn *cur = insn_start; + bool double_insn = false;
for (; cur <= insn_end; cur++) { + if (double_insn) { + double_insn = false; + continue; + } + double_insn = cur->code == (BPF_LD | BPF_IMM | BPF_DW); + printf("% 4d: ", (int)(cur - insn_start + start_idx)); print_bpf_insn(&cbs, cur, true); if (cur != insn_end)
From: Nicolai Stange nstange@suse.de
[ Upstream commit 559edd47cce4cc407d606b4d7f376822816fd4b8 ]
Now that drbg_prepare_hrng() doesn't do anything but to instantiate a jitterentropy crypto_rng instance, it looks a little odd to have the related error handling at its only caller, drbg_instantiate().
Move the handling of jitterentropy allocation failures from drbg_instantiate() close to the allocation itself in drbg_prepare_hrng().
There is no change in behaviour.
Signed-off-by: Nicolai Stange nstange@suse.de Reviewed-by: Stephan Müller smueller@chronox.de Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Stable-dep-of: 686cd976b6dd ("crypto: drbg - Only fail when jent is unavailable in FIPS mode") Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/drbg.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/crypto/drbg.c b/crypto/drbg.c index a4b5d6dbe99d3..ecc6b167b89e2 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -1515,6 +1515,14 @@ static int drbg_prepare_hrng(struct drbg_state *drbg) return 0;
drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0); + if (IS_ERR(drbg->jent)) { + const int err = PTR_ERR(drbg->jent); + + drbg->jent = NULL; + if (fips_enabled || err != -ENOENT) + return err; + pr_info("DRBG: Continuing without Jitter RNG\n"); + }
return 0; } @@ -1570,14 +1578,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers, if (ret) goto free_everything;
- if (IS_ERR(drbg->jent)) { - ret = PTR_ERR(drbg->jent); - drbg->jent = NULL; - if (fips_enabled || ret != -ENOENT) - goto free_everything; - pr_info("DRBG: Continuing without Jitter RNG\n"); - } - reseed = false; }
From: Herbert Xu herbert@gondor.apana.org.au
[ Upstream commit 686cd976b6ddedeeb1a1fb09ba53a891d3cc9a03 ]
When jent initialisation fails for any reason other than ENOENT, the entire drbg fails to initialise, even when we're not in FIPS mode. This is wrong because we can still use the kernel RNG when we're not in FIPS mode.
Change it so that it only fails when we are in FIPS mode.
Fixes: 57225e679788 ("crypto: drbg - Use callback API for random readiness") Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Reviewed-by: Stephan Mueller smueller@chronox.de Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/drbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crypto/drbg.c b/crypto/drbg.c index ecc6b167b89e2..ba1fa5cdd90ac 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -1519,7 +1519,7 @@ static int drbg_prepare_hrng(struct drbg_state *drbg) const int err = PTR_ERR(drbg->jent);
drbg->jent = NULL; - if (fips_enabled || err != -ENOENT) + if (fips_enabled) return err; pr_info("DRBG: Continuing without Jitter RNG\n"); }
From: Kal Conley kal.conley@dectris.com
[ Upstream commit d769ccaf957fe7391f357c0a923de71f594b8a2b ]
Make sure unaligned descriptors that straddle the end of the UMEM are considered invalid. Currently, descriptor validation is broken for zero-copy mode which only checks descriptors at page granularity. For example, descriptors in zero-copy mode that overrun the end of the UMEM but not a page boundary are (incorrectly) considered valid. The UMEM boundary check needs to happen before the page boundary and contiguity checks in xp_desc_crosses_non_contig_pg(). Do this check in xp_unaligned_validate_desc() instead like xp_check_unaligned() already does.
Fixes: 2b43470add8c ("xsk: Introduce AF_XDP buffer allocation API") Signed-off-by: Kal Conley kal.conley@dectris.com Acked-by: Magnus Karlsson magnus.karlsson@intel.com Link: https://lore.kernel.org/r/20230405235920.7305-2-kal.conley@dectris.com Signed-off-by: Martin KaFai Lau martin.lau@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/xsk_buff_pool.h | 9 ++------- net/xdp/xsk_queue.h | 1 + 2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h index c9a47d3d8f503..5a63e3b12335a 100644 --- a/include/net/xsk_buff_pool.h +++ b/include/net/xsk_buff_pool.h @@ -150,13 +150,8 @@ static inline bool xp_desc_crosses_non_contig_pg(struct xsk_buff_pool *pool, if (likely(!cross_pg)) return false;
- if (pool->dma_pages_cnt) { - return !(pool->dma_pages[addr >> PAGE_SHIFT] & - XSK_NEXT_PG_CONTIG_MASK); - } - - /* skb path */ - return addr + len > pool->addrs_cnt; + return pool->dma_pages_cnt && + !(pool->dma_pages[addr >> PAGE_SHIFT] & XSK_NEXT_PG_CONTIG_MASK); }
static inline u64 xp_aligned_extract_addr(struct xsk_buff_pool *pool, u64 addr) diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h index 3c7ce60fe9a5a..a76d43787549f 100644 --- a/net/xdp/xsk_queue.h +++ b/net/xdp/xsk_queue.h @@ -155,6 +155,7 @@ static inline bool xp_unaligned_validate_desc(struct xsk_buff_pool *pool, return false;
if (base_addr >= pool->addrs_cnt || addr >= pool->addrs_cnt || + addr + desc->len > pool->addrs_cnt || xp_desc_crosses_non_contig_pg(pool, addr, desc->len)) return false;
From: Chao Yu chao@kernel.org
[ Upstream commit 5cdb422c839134273866208dad5360835ddb9794 ]
xfstest generic/019 reports a bug:
kernel BUG at mm/filemap.c:1619! RIP: 0010:folio_end_writeback+0x8a/0x90 Call Trace: end_page_writeback+0x1c/0x60 f2fs_write_end_io+0x199/0x420 bio_endio+0x104/0x180 submit_bio_noacct+0xa5/0x510 submit_bio+0x48/0x80 f2fs_submit_write_bio+0x35/0x300 f2fs_submit_merged_ipu_write+0x2a0/0x2b0 f2fs_write_single_data_page+0x838/0x8b0 f2fs_write_cache_pages+0x379/0xa30 f2fs_write_data_pages+0x30c/0x340 do_writepages+0xd8/0x1b0 __writeback_single_inode+0x44/0x370 writeback_sb_inodes+0x233/0x4d0 __writeback_inodes_wb+0x56/0xf0 wb_writeback+0x1dd/0x2d0 wb_workfn+0x367/0x4a0 process_one_work+0x21d/0x430 worker_thread+0x4e/0x3c0 kthread+0x103/0x130 ret_from_fork+0x2c/0x50
The root cause is: after cp_error is set, f2fs_submit_merged_ipu_write() in f2fs_write_single_data_page() tries to flush IPU bio in cache, however f2fs_submit_merged_ipu_write() missed to check validity of @bio parameter, result in submitting random cached bio which belong to other IO context, then it will cause use-after-free issue, fix it by adding additional validity check.
Fixes: 0b20fcec8651 ("f2fs: cache global IPU bio") Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/data.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index db26e87b8f0dd..e9481c940895c 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -849,6 +849,8 @@ void f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi, bool found = false; struct bio *target = bio ? *bio : NULL;
+ f2fs_bug_on(sbi, !target && !page); + for (temp = HOT; temp < NR_TEMP_TYPE && !found; temp++) { struct f2fs_bio_info *io = sbi->write_io[DATA] + temp; struct list_head *head = &io->bio_list; @@ -2917,7 +2919,8 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
if (unlikely(f2fs_cp_error(sbi))) { f2fs_submit_merged_write(sbi, DATA); - f2fs_submit_merged_ipu_write(sbi, bio, NULL); + if (bio && *bio) + f2fs_submit_merged_ipu_write(sbi, bio, NULL); submitted = NULL; }
From: Shuchang Li lishuchang@hust.edu.cn
[ Upstream commit 91a0c0c1413239d0548b5aac4c82f38f6d53a91e ]
When if_type equals zero and pci_resource_start(pdev, PCI_64BIT_BAR4) returns false, drbl_regs_memmap_p is not remapped. This passes a NULL pointer to iounmap(), which can trigger a WARN() on certain arches.
When if_type equals six and pci_resource_start(pdev, PCI_64BIT_BAR4) returns true, drbl_regs_memmap_p may has been remapped and ctrl_regs_memmap_p is not remapped. This is a resource leak and passes a NULL pointer to iounmap().
To fix these issues, we need to add null checks before iounmap(), and change some goto labels.
Fixes: 1351e69fc6db ("scsi: lpfc: Add push-to-adapter support to sli4") Signed-off-by: Shuchang Li lishuchang@hust.edu.cn Link: https://lore.kernel.org/r/20230404072133.1022-1-lishuchang@hust.edu.cn Reviewed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_init.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 17200b453cbbb..1bb3c96a04bd6 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -10477,7 +10477,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) goto out_iounmap_all; } else { error = -ENOMEM; - goto out_iounmap_all; + goto out_iounmap_ctrl; } }
@@ -10495,7 +10495,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) dev_err(&pdev->dev, "ioremap failed for SLI4 HBA dpp registers.\n"); error = -ENOMEM; - goto out_iounmap_ctrl; + goto out_iounmap_all; } phba->pci_bar4_memmap_p = phba->sli4_hba.dpp_regs_memmap_p; } @@ -10520,9 +10520,11 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) return 0;
out_iounmap_all: - iounmap(phba->sli4_hba.drbl_regs_memmap_p); + if (phba->sli4_hba.drbl_regs_memmap_p) + iounmap(phba->sli4_hba.drbl_regs_memmap_p); out_iounmap_ctrl: - iounmap(phba->sli4_hba.ctrl_regs_memmap_p); + if (phba->sli4_hba.ctrl_regs_memmap_p) + iounmap(phba->sli4_hba.ctrl_regs_memmap_p); out_iounmap_conf: iounmap(phba->sli4_hba.conf_regs_memmap_p);
From: Sebastian Reichel sebastian.reichel@collabora.com
[ Upstream commit db21973263f8c56750cb610f1d5e8bee00a513b9 ]
The usual devm_regulator_get() call already handles "optional" regulators by returning a valid dummy and printing a warning that the dummy regulator should be described properly. This code open coded the same behaviour, but masked any errors that are not -EPROBE_DEFER and is quite noisy.
This change effectively unmasks and propagates regulators errors not involving -ENODEV, downgrades the error print to warning level if no regulator is specified and captures the probe defer message for /sys/kernel/debug/devices_deferred.
Fixes: 2e12f536635f ("net: stmmac: dwmac-rk: Use standard devicetree property for phy regulator") Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index e7fbc9b30bf96..d0d47d91b460c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -1194,9 +1194,6 @@ static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) int ret; struct device *dev = &bsp_priv->pdev->dev;
- if (!ldo) - return 0; - if (enable) { ret = regulator_enable(ldo); if (ret) @@ -1227,14 +1224,11 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface); bsp_priv->ops = ops;
- bsp_priv->regulator = devm_regulator_get_optional(dev, "phy"); + bsp_priv->regulator = devm_regulator_get(dev, "phy"); if (IS_ERR(bsp_priv->regulator)) { - if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) { - dev_err(dev, "phy regulator is not available yet, deferred probing\n"); - return ERR_PTR(-EPROBE_DEFER); - } - dev_err(dev, "no regulator found\n"); - bsp_priv->regulator = NULL; + ret = PTR_ERR(bsp_priv->regulator); + dev_err_probe(dev, ret, "failed to get phy regulator\n"); + return ERR_PTR(ret); }
ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
From: Xin Liu liuxin350@huawei.com
[ Upstream commit ed17aa92dc56b6d8883e4b7a8f1c6fbf5ed6cd29 ]
When huang uses sched_switch tracepoint, the tracepoint does only one thing in the mounted ebpf program, which deletes the fixed elements in sockhash ([0])
It seems that elements in sockhash are rarely actively deleted by users or ebpf program. Therefore, we do not pay much attention to their deletion. Compared with hash maps, sockhash only provides spin_lock_bh protection. This causes it to appear to have self-locking behavior in the interrupt context.
[0]:https://lore.kernel.org/all/CABcoxUayum5oOqFMMqAeWuS8+EzojquSOSyDA3J_2omY=2E...
Reported-by: Hsin-Wei Hung hsinweih@uci.edu Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface") Signed-off-by: Xin Liu liuxin350@huawei.com Acked-by: John Fastabend john.fastabend@gmail.com Link: https://lore.kernel.org/r/20230406122622.109978-1-liuxin350@huawei.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/sock_map.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/core/sock_map.c b/net/core/sock_map.c index ee5d3f49b0b5b..e21adbbb7461c 100644 --- a/net/core/sock_map.c +++ b/net/core/sock_map.c @@ -423,8 +423,9 @@ static int __sock_map_delete(struct bpf_stab *stab, struct sock *sk_test, { struct sock *sk; int err = 0; + unsigned long flags;
- raw_spin_lock_bh(&stab->lock); + raw_spin_lock_irqsave(&stab->lock, flags); sk = *psk; if (!sk_test || sk_test == sk) sk = xchg(psk, NULL); @@ -434,7 +435,7 @@ static int __sock_map_delete(struct bpf_stab *stab, struct sock *sk_test, else err = -EINVAL;
- raw_spin_unlock_bh(&stab->lock); + raw_spin_unlock_irqrestore(&stab->lock, flags); return err; }
@@ -956,11 +957,12 @@ static int sock_hash_delete_elem(struct bpf_map *map, void *key) struct bpf_shtab_bucket *bucket; struct bpf_shtab_elem *elem; int ret = -ENOENT; + unsigned long flags;
hash = sock_hash_bucket_hash(key, key_size); bucket = sock_hash_select_bucket(htab, hash);
- raw_spin_lock_bh(&bucket->lock); + raw_spin_lock_irqsave(&bucket->lock, flags); elem = sock_hash_lookup_elem_raw(&bucket->head, hash, key, key_size); if (elem) { hlist_del_rcu(&elem->node); @@ -968,7 +970,7 @@ static int sock_hash_delete_elem(struct bpf_map *map, void *key) sock_hash_free_elem(htab, elem); ret = 0; } - raw_spin_unlock_bh(&bucket->lock); + raw_spin_unlock_irqrestore(&bucket->lock, flags); return ret; }
From: Michael Kelley mikelley@microsoft.com
[ Upstream commit 2c61c97fb12b806e1c8eb15f04c277ad097ec95e ]
In the NVM Express Revision 1.4 spec, Figure 145 describes possible values for an AER with event type "Error" (value 000b). For a Persistent Internal Error (value 03h), the host should perform a controller reset.
Add support for this error using code that already exists for doing a controller reset. As part of this support, introduce two utility functions for parsing the AER type and subtype.
This new support was tested in a lab environment where we can generate the persistent internal error on demand, and observe both the Linux side and NVMe controller side to see that the controller reset has been done.
Signed-off-by: Michael Kelley mikelley@microsoft.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Stable-dep-of: 6622b76fe922 ("nvme: fix async event trace event") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 31 +++++++++++++++++++++++++++++-- include/linux/nvme.h | 4 ++++ 2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index a4b6aa932a8fe..cb3f807ede1b8 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4416,9 +4416,19 @@ static void nvme_fw_act_work(struct work_struct *work) nvme_get_fw_slot_info(ctrl); }
+static u32 nvme_aer_type(u32 result) +{ + return result & 0x7; +} + +static u32 nvme_aer_subtype(u32 result) +{ + return (result & 0xff00) >> 8; +} + static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result) { - u32 aer_notice_type = (result & 0xff00) >> 8; + u32 aer_notice_type = nvme_aer_subtype(result);
trace_nvme_async_event(ctrl, aer_notice_type);
@@ -4451,11 +4461,19 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result) } }
+static void nvme_handle_aer_persistent_error(struct nvme_ctrl *ctrl) +{ + trace_nvme_async_event(ctrl, NVME_AER_ERROR); + dev_warn(ctrl->device, "resetting controller due to AER\n"); + nvme_reset_ctrl(ctrl); +} + void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status, volatile union nvme_result *res) { u32 result = le32_to_cpu(res->u32); - u32 aer_type = result & 0x07; + u32 aer_type = nvme_aer_type(result); + u32 aer_subtype = nvme_aer_subtype(result);
if (le16_to_cpu(status) >> 1 != NVME_SC_SUCCESS) return; @@ -4465,6 +4483,15 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status, nvme_handle_aen_notice(ctrl, result); break; case NVME_AER_ERROR: + /* + * For a persistent internal error, don't run async_event_work + * to submit a new AER. The controller reset will do it. + */ + if (aer_subtype == NVME_AER_ERROR_PERSIST_INT_ERR) { + nvme_handle_aer_persistent_error(ctrl); + return; + } + fallthrough; case NVME_AER_SMART: case NVME_AER_CSS: case NVME_AER_VS: diff --git a/include/linux/nvme.h b/include/linux/nvme.h index fe39ed9e9303e..f454dd1003347 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -602,6 +602,10 @@ enum { NVME_AER_VS = 7, };
+enum { + NVME_AER_ERROR_PERSIST_INT_ERR = 0x03, +}; + enum { NVME_AER_NOTICE_NS_CHANGED = 0x00, NVME_AER_NOTICE_FW_ACT_STARTING = 0x01,
From: Keith Busch kbusch@kernel.org
[ Upstream commit 6622b76fe922b94189499a90ccdb714a4a8d0773 ]
Mixing AER Event Type and Event Info has masking clashes. Just print the event type, but also include the event info of the AER result in the trace.
Fixes: 09bd1ff4b15143b ("nvme-core: add async event trace helper") Reported-by: Nate Thornton nate.thornton@samsung.com Reviewed-by: Sagi Grimberg sagi@grimberg.me Reviewed-by: Minwoo Im minwoo.im@samsung.com Reviewed-by: Chaitanya Kulkarni kch@nvidia.com Signed-off-by: Keith Busch kbusch@kernel.org Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 5 +---- drivers/nvme/host/trace.h | 15 ++++++--------- 2 files changed, 7 insertions(+), 13 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index cb3f807ede1b8..07c41a149328a 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4430,8 +4430,6 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result) { u32 aer_notice_type = nvme_aer_subtype(result);
- trace_nvme_async_event(ctrl, aer_notice_type); - switch (aer_notice_type) { case NVME_AER_NOTICE_NS_CHANGED: set_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events); @@ -4463,7 +4461,6 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
static void nvme_handle_aer_persistent_error(struct nvme_ctrl *ctrl) { - trace_nvme_async_event(ctrl, NVME_AER_ERROR); dev_warn(ctrl->device, "resetting controller due to AER\n"); nvme_reset_ctrl(ctrl); } @@ -4478,6 +4475,7 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status, if (le16_to_cpu(status) >> 1 != NVME_SC_SUCCESS) return;
+ trace_nvme_async_event(ctrl, result); switch (aer_type) { case NVME_AER_NOTICE: nvme_handle_aen_notice(ctrl, result); @@ -4495,7 +4493,6 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status, case NVME_AER_SMART: case NVME_AER_CSS: case NVME_AER_VS: - trace_nvme_async_event(ctrl, aer_type); ctrl->aen_result = result; break; default: diff --git a/drivers/nvme/host/trace.h b/drivers/nvme/host/trace.h index aa8b0f86b2be1..b258f7b8788e1 100644 --- a/drivers/nvme/host/trace.h +++ b/drivers/nvme/host/trace.h @@ -127,15 +127,12 @@ TRACE_EVENT(nvme_async_event, ), TP_printk("nvme%d: NVME_AEN=%#08x [%s]", __entry->ctrl_id, __entry->result, - __print_symbolic(__entry->result, - aer_name(NVME_AER_NOTICE_NS_CHANGED), - aer_name(NVME_AER_NOTICE_ANA), - aer_name(NVME_AER_NOTICE_FW_ACT_STARTING), - aer_name(NVME_AER_NOTICE_DISC_CHANGED), - aer_name(NVME_AER_ERROR), - aer_name(NVME_AER_SMART), - aer_name(NVME_AER_CSS), - aer_name(NVME_AER_VS)) + __print_symbolic(__entry->result & 0x7, + aer_name(NVME_AER_ERROR), + aer_name(NVME_AER_SMART), + aer_name(NVME_AER_NOTICE), + aer_name(NVME_AER_CSS), + aer_name(NVME_AER_VS)) ) );
From: Ming Lei ming.lei@redhat.com
[ Upstream commit 4f86a6ff6fbd891232dda3ca97fd1b9630b59809 ]
fcloop_fcp_op() could be called from flush request's ->end_io(flush_end_io) in which the spinlock of fq->mq_flush_lock is grabbed with irq saved/disabled.
So fcloop_fcp_op() can't call spin_unlock_irq(&tfcp_req->reqlock) simply which enables irq unconditionally.
Fixes the warning by switching to spin_lock_irqsave()/spin_unlock_irqrestore()
Fixes: c38dbbfab1bc ("nvme-fcloop: fix inconsistent lock state warnings") Reported-by: Yi Zhang yi.zhang@redhat.com Signed-off-by: Ming Lei ming.lei@redhat.com Reviewed-by: Ewan D. Milne emilne@redhat.com Tested-by: Yi Zhang yi.zhang@redhat.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/target/fcloop.c | 48 ++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 21 deletions(-)
diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c index 3da067a8311e5..80a208fb34f52 100644 --- a/drivers/nvme/target/fcloop.c +++ b/drivers/nvme/target/fcloop.c @@ -570,10 +570,11 @@ fcloop_fcp_recv_work(struct work_struct *work) struct fcloop_fcpreq *tfcp_req = container_of(work, struct fcloop_fcpreq, fcp_rcv_work); struct nvmefc_fcp_req *fcpreq = tfcp_req->fcpreq; + unsigned long flags; int ret = 0; bool aborted = false;
- spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); switch (tfcp_req->inistate) { case INI_IO_START: tfcp_req->inistate = INI_IO_ACTIVE; @@ -582,11 +583,11 @@ fcloop_fcp_recv_work(struct work_struct *work) aborted = true; break; default: - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); WARN_ON(1); return; } - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
if (unlikely(aborted)) ret = -ECANCELED; @@ -607,8 +608,9 @@ fcloop_fcp_abort_recv_work(struct work_struct *work) container_of(work, struct fcloop_fcpreq, abort_rcv_work); struct nvmefc_fcp_req *fcpreq; bool completed = false; + unsigned long flags;
- spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); fcpreq = tfcp_req->fcpreq; switch (tfcp_req->inistate) { case INI_IO_ABORTED: @@ -617,11 +619,11 @@ fcloop_fcp_abort_recv_work(struct work_struct *work) completed = true; break; default: - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); WARN_ON(1); return; } - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
if (unlikely(completed)) { /* remove reference taken in original abort downcall */ @@ -633,9 +635,9 @@ fcloop_fcp_abort_recv_work(struct work_struct *work) nvmet_fc_rcv_fcp_abort(tfcp_req->tport->targetport, &tfcp_req->tgt_fcp_req);
- spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); tfcp_req->fcpreq = NULL; - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
fcloop_call_host_done(fcpreq, tfcp_req, -ECANCELED); /* call_host_done releases reference for abort downcall */ @@ -651,11 +653,12 @@ fcloop_tgt_fcprqst_done_work(struct work_struct *work) struct fcloop_fcpreq *tfcp_req = container_of(work, struct fcloop_fcpreq, tio_done_work); struct nvmefc_fcp_req *fcpreq; + unsigned long flags;
- spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); fcpreq = tfcp_req->fcpreq; tfcp_req->inistate = INI_IO_COMPLETED; - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
fcloop_call_host_done(fcpreq, tfcp_req, tfcp_req->status); } @@ -759,13 +762,14 @@ fcloop_fcp_op(struct nvmet_fc_target_port *tgtport, u32 rsplen = 0, xfrlen = 0; int fcp_err = 0, active, aborted; u8 op = tgt_fcpreq->op; + unsigned long flags;
- spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); fcpreq = tfcp_req->fcpreq; active = tfcp_req->active; aborted = tfcp_req->aborted; tfcp_req->active = true; - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
if (unlikely(active)) /* illegal - call while i/o active */ @@ -773,9 +777,9 @@ fcloop_fcp_op(struct nvmet_fc_target_port *tgtport,
if (unlikely(aborted)) { /* target transport has aborted i/o prior */ - spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); tfcp_req->active = false; - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); tgt_fcpreq->transferred_length = 0; tgt_fcpreq->fcp_error = -ECANCELED; tgt_fcpreq->done(tgt_fcpreq); @@ -832,9 +836,9 @@ fcloop_fcp_op(struct nvmet_fc_target_port *tgtport, break; }
- spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); tfcp_req->active = false; - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
tgt_fcpreq->transferred_length = xfrlen; tgt_fcpreq->fcp_error = fcp_err; @@ -848,15 +852,16 @@ fcloop_tgt_fcp_abort(struct nvmet_fc_target_port *tgtport, struct nvmefc_tgt_fcp_req *tgt_fcpreq) { struct fcloop_fcpreq *tfcp_req = tgt_fcp_req_to_fcpreq(tgt_fcpreq); + unsigned long flags;
/* * mark aborted only in case there were 2 threads in transport * (one doing io, other doing abort) and only kills ops posted * after the abort request */ - spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); tfcp_req->aborted = true; - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
tfcp_req->status = NVME_SC_INTERNAL;
@@ -898,6 +903,7 @@ fcloop_fcp_abort(struct nvme_fc_local_port *localport, struct fcloop_ini_fcpreq *inireq = fcpreq->private; struct fcloop_fcpreq *tfcp_req; bool abortio = true; + unsigned long flags;
spin_lock(&inireq->inilock); tfcp_req = inireq->tfcp_req; @@ -910,7 +916,7 @@ fcloop_fcp_abort(struct nvme_fc_local_port *localport, return;
/* break initiator/target relationship for io */ - spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); switch (tfcp_req->inistate) { case INI_IO_START: case INI_IO_ACTIVE: @@ -920,11 +926,11 @@ fcloop_fcp_abort(struct nvme_fc_local_port *localport, abortio = false; break; default: - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); WARN_ON(1); return; } - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
if (abortio) /* leave the reference while the work item is scheduled */
From: Daniel Borkmann daniel@iogearbox.net
[ Upstream commit 8c5c2a4898e3d6bad86e29d471e023c8a19ba799 ]
syzbot reported a splat and bisected it to recent commit ed17aa92dc56 ("bpf, sockmap: fix deadlocks in the sockhash and sockmap"):
[...] WARNING: CPU: 1 PID: 9280 at kernel/softirq.c:376 __local_bh_enable_ip+0xbe/0x130 kernel/softirq.c:376 Modules linked in: CPU: 1 PID: 9280 Comm: syz-executor.1 Not tainted 6.2.0-syzkaller-13249-gd319f344561d #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/30/2023 RIP: 0010:__local_bh_enable_ip+0xbe/0x130 kernel/softirq.c:376 [...] Call Trace: <TASK> spin_unlock_bh include/linux/spinlock.h:395 [inline] sock_map_del_link+0x2ea/0x510 net/core/sock_map.c:165 sock_map_unref+0xb0/0x1d0 net/core/sock_map.c:184 sock_hash_delete_elem+0x1ec/0x2a0 net/core/sock_map.c:945 map_delete_elem kernel/bpf/syscall.c:1536 [inline] __sys_bpf+0x2edc/0x53e0 kernel/bpf/syscall.c:5053 __do_sys_bpf kernel/bpf/syscall.c:5166 [inline] __se_sys_bpf kernel/bpf/syscall.c:5164 [inline] __x64_sys_bpf+0x79/0xc0 kernel/bpf/syscall.c:5164 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7fe8f7c8c169 </TASK> [...]
Revert for now until we have a proper solution.
Fixes: ed17aa92dc56 ("bpf, sockmap: fix deadlocks in the sockhash and sockmap") Reported-by: syzbot+49f6cef45247ff249498@syzkaller.appspotmail.com Cc: Hsin-Wei Hung hsinweih@uci.edu Cc: Xin Liu liuxin350@huawei.com Cc: John Fastabend john.fastabend@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/000000000000f1db9605f939720e@google.com/ Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/sock_map.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/net/core/sock_map.c b/net/core/sock_map.c index e21adbbb7461c..ee5d3f49b0b5b 100644 --- a/net/core/sock_map.c +++ b/net/core/sock_map.c @@ -423,9 +423,8 @@ static int __sock_map_delete(struct bpf_stab *stab, struct sock *sk_test, { struct sock *sk; int err = 0; - unsigned long flags;
- raw_spin_lock_irqsave(&stab->lock, flags); + raw_spin_lock_bh(&stab->lock); sk = *psk; if (!sk_test || sk_test == sk) sk = xchg(psk, NULL); @@ -435,7 +434,7 @@ static int __sock_map_delete(struct bpf_stab *stab, struct sock *sk_test, else err = -EINVAL;
- raw_spin_unlock_irqrestore(&stab->lock, flags); + raw_spin_unlock_bh(&stab->lock); return err; }
@@ -957,12 +956,11 @@ static int sock_hash_delete_elem(struct bpf_map *map, void *key) struct bpf_shtab_bucket *bucket; struct bpf_shtab_elem *elem; int ret = -ENOENT; - unsigned long flags;
hash = sock_hash_bucket_hash(key, key_size); bucket = sock_hash_select_bucket(htab, hash);
- raw_spin_lock_irqsave(&bucket->lock, flags); + raw_spin_lock_bh(&bucket->lock); elem = sock_hash_lookup_elem_raw(&bucket->head, hash, key, key_size); if (elem) { hlist_del_rcu(&elem->node); @@ -970,7 +968,7 @@ static int sock_hash_delete_elem(struct bpf_map *map, void *key) sock_hash_free_elem(htab, elem); ret = 0; } - raw_spin_unlock_irqrestore(&bucket->lock, flags); + raw_spin_unlock_bh(&bucket->lock); return ret; }
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit 26208a7cffd0c7cbf14237ccd20c7270b3ffeb7e ]
raid10_sync_request() will add 'r10bio->remaining' for both rdev and replacement rdev. However, if the read io fails, recovery_request_write() returns without issuing the write io, in this case, end_sync_request() is only called once and 'remaining' is leaked, cause an io hang.
Fix the problem by decreasing 'remaining' according to if 'bio' and 'repl_bio' is valid.
Fixes: 24afd80d99f8 ("md/raid10: handle recovery of replacement devices.") Signed-off-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230310073855.1337560-5-yukuai1@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/raid10.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 0e741a8d278df..ea0351fa1b549 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2212,11 +2212,22 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio) { struct r10conf *conf = mddev->private; int d; - struct bio *wbio, *wbio2; + struct bio *wbio = r10_bio->devs[1].bio; + struct bio *wbio2 = r10_bio->devs[1].repl_bio; + + /* Need to test wbio2->bi_end_io before we call + * submit_bio_noacct as if the former is NULL, + * the latter is free to free wbio2. + */ + if (wbio2 && !wbio2->bi_end_io) + wbio2 = NULL;
if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) { fix_recovery_read_error(r10_bio); - end_sync_request(r10_bio); + if (wbio->bi_end_io) + end_sync_request(r10_bio); + if (wbio2) + end_sync_request(r10_bio); return; }
@@ -2225,14 +2236,6 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio) * and submit the write request */ d = r10_bio->devs[1].devnum; - wbio = r10_bio->devs[1].bio; - wbio2 = r10_bio->devs[1].repl_bio; - /* Need to test wbio2->bi_end_io before we call - * submit_bio_noacct as if the former is NULL, - * the latter is free to free wbio2. - */ - if (wbio2 && !wbio2->bi_end_io) - wbio2 = NULL; if (wbio->bi_end_io) { atomic_inc(&conf->mirrors[d].rdev->nr_pending); md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio));
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit c9ac2acde53f5385de185bccf6aaa91cf9ac1541 ]
In the error path of raid10_run(), 'conf' need be freed, however, 'conf->bio_split' is missed and memory will be leaked.
Since there are 3 places to free 'conf', factor out a helper to fix the problem.
Fixes: fc9977dd069e ("md/raid10: simplify the splitting of requests.") Signed-off-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230310073855.1337560-6-yukuai1@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/raid10.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index ea0351fa1b549..51f122db9668e 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3618,6 +3618,20 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new) return nc*fc; }
+static void raid10_free_conf(struct r10conf *conf) +{ + if (!conf) + return; + + mempool_exit(&conf->r10bio_pool); + kfree(conf->mirrors); + kfree(conf->mirrors_old); + kfree(conf->mirrors_new); + safe_put_page(conf->tmppage); + bioset_exit(&conf->bio_split); + kfree(conf); +} + static struct r10conf *setup_conf(struct mddev *mddev) { struct r10conf *conf = NULL; @@ -3700,13 +3714,7 @@ static struct r10conf *setup_conf(struct mddev *mddev) return conf;
out: - if (conf) { - mempool_exit(&conf->r10bio_pool); - kfree(conf->mirrors); - safe_put_page(conf->tmppage); - bioset_exit(&conf->bio_split); - kfree(conf); - } + raid10_free_conf(conf); return ERR_PTR(err); }
@@ -3912,10 +3920,7 @@ static int raid10_run(struct mddev *mddev)
out_free_conf: md_unregister_thread(&mddev->thread); - mempool_exit(&conf->r10bio_pool); - safe_put_page(conf->tmppage); - kfree(conf->mirrors); - kfree(conf); + raid10_free_conf(conf); mddev->private = NULL; out: return -EIO; @@ -3923,15 +3928,7 @@ static int raid10_run(struct mddev *mddev)
static void raid10_free(struct mddev *mddev, void *priv) { - struct r10conf *conf = priv; - - mempool_exit(&conf->r10bio_pool); - safe_put_page(conf->tmppage); - kfree(conf->mirrors); - kfree(conf->mirrors_old); - kfree(conf->mirrors_new); - bioset_exit(&conf->bio_split); - kfree(conf); + raid10_free_conf(priv); }
static void raid10_quiesce(struct mddev *mddev, int quiesce)
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit f0ddb83da3cbbf8a1f9087a642c448ff52ee9abd ]
In raid10_run(), if setup_conf() succeed and raid10_run() failed before setting 'mddev->thread', then in the error path 'conf->thread' is not freed.
Fix the problem by setting 'mddev->thread' right after setup_conf().
Fixes: 43a521238aca ("md-cluster: choose correct label when clustered layout is not supported") Signed-off-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/r/20230310073855.1337560-7-yukuai1@huaweicloud.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/raid10.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 51f122db9668e..c6a196a10f894 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3752,6 +3752,9 @@ static int raid10_run(struct mddev *mddev) if (!conf) goto out;
+ mddev->thread = conf->thread; + conf->thread = NULL; + if (mddev_is_clustered(conf->mddev)) { int fc, fo;
@@ -3764,9 +3767,6 @@ static int raid10_run(struct mddev *mddev) } }
- mddev->thread = conf->thread; - conf->thread = NULL; - if (mddev->queue) { blk_queue_max_discard_sectors(mddev->queue, mddev->chunk_sectors);
From: Daniel Gabay daniel.gabay@intel.com
[ Upstream commit ba30415118eee374a08b39a0460a1d1e52c24a25 ]
Don't allow buffer allocation TLV with zero req_size since it leads later to division by zero in iwl_dbg_tlv_alloc_fragments(). Also, NPK/SRAM locations are allowed to have zero buffer req_size, don't discard them.
Fixes: a9248de42464 ("iwlwifi: dbg_ini: add TLV allocation new API support") Signed-off-by: Daniel Gabay daniel.gabay@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230413213309.5d6688ed74d8.I5c2f3a882b50698b708d5... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 3c931b1b2a0bb..fdf2c6ea41d96 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -191,6 +191,12 @@ static int iwl_dbg_tlv_alloc_buf_alloc(struct iwl_trans *trans, alloc_id != IWL_FW_INI_ALLOCATION_ID_INTERNAL) goto err;
+ if (buf_location == IWL_FW_INI_LOCATION_DRAM_PATH && + alloc->req_size == 0) { + IWL_ERR(trans, "WRT: Invalid DRAM buffer allocation requested size (0)\n"); + return -EINVAL; + } + trans->dbg.fw_mon_cfg[alloc_id] = *alloc;
return 0;
From: Tom Rix trix@redhat.com
[ Upstream commit 8ce437dd5b2e4adef13aa4ecce07392f9966b1ab ]
Clang static analysis reports this representative issue dbg.c:1455:6: warning: Branch condition evaluates to a garbage value if (!rxf_data.size) ^~~~~~~~~~~~~~
This check depends on iwl_ini_get_rxf_data() to clear rxf_data but the function can return early without doing the clear. So move the memset before the early return.
Fixes: cc9b6012d34b ("iwlwifi: yoyo: use hweight_long instead of bit manipulating") Signed-off-by: Tom Rix trix@redhat.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230414130637.872a7175f1ff.I33802a77a91998276992b... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 419eaa5cf0b50..79d08e5d9a81c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -1372,13 +1372,13 @@ static void iwl_ini_get_rxf_data(struct iwl_fw_runtime *fwrt, if (!data) return;
+ memset(data, 0, sizeof(*data)); + /* make sure only one bit is set in only one fid */ if (WARN_ONCE(hweight_long(fid1) + hweight_long(fid2) != 1, "fid1=%x, fid2=%x\n", fid1, fid2)) return;
- memset(data, 0, sizeof(*data)); - if (fid1) { fifo_idx = ffs(fid1) - 1; if (WARN_ONCE(fifo_idx >= MAX_NUM_LMAC, "fifo_idx=%d\n",
From: Jan Kara jack@suse.cz
[ Upstream commit bd159398a2d2234de07d310132865706964aaaa7 ]
When invalidating buffers under the partial tail page, jbd2_journal_invalidate_folio() returns -EBUSY if the buffer is part of the committing transaction as we cannot safely modify buffer state. However if the buffer is already invalidated (due to previous invalidation attempts from ext4_wait_for_tail_page_commit()), there's nothing to do and there's no point in returning -EBUSY. This fixes occasional warnings from ext4_journalled_invalidate_folio() triggered by generic/051 fstest when blocksize < pagesize.
Fixes: 53e872681fed ("ext4: fix deadlock in journal_unmap_buffer()") Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20230329154950.19720-1-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org --- fs/jbd2/transaction.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 1923528154b52..1baf2d607268f 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -2378,6 +2378,9 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh, spin_unlock(&jh->b_state_lock); write_unlock(&journal->j_state_lock); jbd2_journal_put_journal_head(jh); + /* Already zapped buffer? Nothing to do... */ + if (!bh->b_bdev) + return 0; return -EBUSY; } /*
From: Emmanuel Grumbach emmanuel.grumbach@intel.com
[ Upstream commit 28965ec0b5d9112585f725660e2ff13218505ace ]
Since we didn't reset t to 0, only the first iteration of the loop did checked the ready bit several times.
From the second iteration and on, we just tested the bit once and
continued to the next iteration.
Reported-and-tested-by: Lorenzo Zolfanelli lorenzo@zolfa.nl Link: https://bugzilla.kernel.org/show_bug.cgi?id=216452 Fixes: 289e5501c314 ("iwlwifi: fix the preparation of the card") Signed-off-by: Emmanuel Grumbach emmanuel.grumbach@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230416154301.615b683ab9c8.Ic52c3229d3345b0064fa3... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index daec61a60fec5..7f8b7f7697cfd 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -620,7 +620,6 @@ static int iwl_pcie_set_hw_ready(struct iwl_trans *trans) int iwl_pcie_prepare_card_hw(struct iwl_trans *trans) { int ret; - int t = 0; int iter;
IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); @@ -635,6 +634,8 @@ int iwl_pcie_prepare_card_hw(struct iwl_trans *trans) usleep_range(1000, 2000);
for (iter = 0; iter < 10; iter++) { + int t = 0; + /* If HW is not ready, prepare the conditions to check again */ iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE);
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 13513cec93ac9902d0b896976d8bab3758a9881c ]
Check the firmware response size for responses to the memory read/write command in debugfs before using it.
Fixes: 2b55f43f8e47 ("iwlwifi: mvm: Add mem debugfs entry") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230417113648.0d56fcaf68ee.I70e9571f3ed7263929b04... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 3395c46759883..36f75d5946304 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1885,6 +1885,11 @@ static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf, if (ret < 0) return ret;
+ if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) { + ret = -EIO; + goto out; + } + rsp = (void *)hcmd.resp_pkt->data; if (le32_to_cpu(rsp->status) != DEBUG_MEM_STATUS_SUCCESS) { ret = -ENXIO; @@ -1962,6 +1967,11 @@ static ssize_t iwl_dbgfs_mem_write(struct file *file, if (ret < 0) return ret;
+ if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) { + ret = -EIO; + goto out; + } + rsp = (void *)hcmd.resp_pkt->data; if (rsp->status != DEBUG_MEM_STATUS_SUCCESS) { ret = -ENXIO;
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 3d90d2f4a018fe8cfd65068bc6350b6222be4852 ]
Fix a memory leak that occurs when reading the fw_info file all the way, since we return NULL indicating no more data, but don't free the status tracking object.
Fixes: 36dfe9ac6e8b ("iwlwifi: dump api version in yaml format") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20230418122405.239e501b3b8d.I4268f87809ef91209cbcd... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/fw/debugfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c index 267ad4eddb5c0..24d6ed3513ce5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c @@ -344,8 +344,10 @@ static void *iwl_dbgfs_fw_info_seq_next(struct seq_file *seq, const struct iwl_fw *fw = priv->fwrt->fw;
*pos = ++state->pos; - if (*pos >= fw->ucode_capa.n_cmd_versions) + if (*pos >= fw->ucode_capa.n_cmd_versions) { + kfree(state); return NULL; + }
return state; }
From: Joe Damato jdamato@fastly.com
[ Upstream commit 4f3ed1293feb9502dc254b05802faf1ad3317ac6 ]
ixgbe currently returns `EINVAL` whenever the flowhash it set by ethtool because the ethtool code in the kernel passes a non-zero value for hfunc that ixgbe should allow.
When ethtool is called with `ETHTOOL_SRXFHINDIR`, `ethtool_set_rxfh_indir` will call ixgbe's set_rxfh function with `ETH_RSS_HASH_NO_CHANGE`. This value should be accepted.
When ethtool is called with `ETHTOOL_SRSSH`, `ethtool_set_rxfh` will call ixgbe's set_rxfh function with `rxfh.hfunc`, which appears to be hardcoded in ixgbe to always be `ETH_RSS_HASH_TOP`. This value should also be accepted.
Before this patch:
$ sudo ethtool -L eth1 combined 10 $ sudo ethtool -X eth1 default Cannot set RX flow hash configuration: Invalid argument
After this patch:
$ sudo ethtool -L eth1 combined 10 $ sudo ethtool -X eth1 default $ sudo ethtool -x eth1 RX flow hash indirection table for eth1 with 10 RX ring(s): 0: 0 1 2 3 4 5 6 7 8: 8 9 0 1 2 3 4 5 16: 6 7 8 9 0 1 2 3 24: 4 5 6 7 8 9 0 1 ...
Fixes: 1c7cf0784e4d ("ixgbe: support for ethtool set_rxfh") Signed-off-by: Joe Damato jdamato@fastly.com Reviewed-by: Sridhar Samudrala sridhar.samudrala@intel.com Tested-by: Pucha Himasekhar Reddy himasekharx.reddy.pucha@intel.com (A Contingent worker at Intel) Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 55983904b6df1..472ea068ea7b0 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -3107,8 +3107,8 @@ static int ixgbe_set_rxfh(struct net_device *netdev, const u32 *indir, int i; u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
- if (hfunc) - return -EINVAL; + if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) + return -EOPNOTSUPP;
/* Fill out the redirection table */ if (indir) {
From: Joe Damato jdamato@fastly.com
[ Upstream commit e85d3d55875f7a1079edfbc4e4e98d6f8aea9ac7 ]
ethtool uses `ETHTOOL_GRXRINGS` to compute how many queues are supported by RSS. The driver should return the smaller of either: - The maximum number of RSS queues the device supports, OR - The number of RX queues configured
Prior to this change, running `ethtool -X $iface default` fails if the number of queues configured is larger than the number supported by RSS, even though changing the queue count correctly resets the flowhash to use all supported queues.
Other drivers (for example, i40e) will succeed but the flow hash will reset to support the maximum number of queues supported by RSS, even if that amount is smaller than the configured amount.
Prior to this change:
$ sudo ethtool -L eth1 combined 20 $ sudo ethtool -x eth1 RX flow hash indirection table for eth1 with 20 RX ring(s): 0: 0 1 2 3 4 5 6 7 8: 8 9 10 11 12 13 14 15 16: 0 1 2 3 4 5 6 7 24: 8 9 10 11 12 13 14 15 32: 0 1 2 3 4 5 6 7 ...
You can see that the flowhash was correctly set to use the maximum number of queues supported by the driver (16).
However, asking the NIC to reset to "default" fails:
$ sudo ethtool -X eth1 default Cannot set RX flow hash configuration: Invalid argument
After this change, the flowhash can be reset to default which will use all of the available RSS queues (16) or the configured queue count, whichever is smaller.
Starting with eth1 which has 10 queues and a flowhash distributing to all 10 queues:
$ sudo ethtool -x eth1 RX flow hash indirection table for eth1 with 10 RX ring(s): 0: 0 1 2 3 4 5 6 7 8: 8 9 0 1 2 3 4 5 16: 6 7 8 9 0 1 2 3 ...
Increasing the queue count to 48 resets the flowhash to distribute to 16 queues, as it did before this patch:
$ sudo ethtool -L eth1 combined 48 $ sudo ethtool -x eth1 RX flow hash indirection table for eth1 with 16 RX ring(s): 0: 0 1 2 3 4 5 6 7 8: 8 9 10 11 12 13 14 15 16: 0 1 2 3 4 5 6 7 ...
Due to the other bugfix in this series, the flowhash can be set to use queues 0-5:
$ sudo ethtool -X eth1 equal 5 $ sudo ethtool -x eth1 RX flow hash indirection table for eth1 with 16 RX ring(s): 0: 0 1 2 3 4 0 1 2 8: 3 4 0 1 2 3 4 0 16: 1 2 3 4 0 1 2 3 ...
Due to this bugfix, the flowhash can be reset to default and use 16 queues:
$ sudo ethtool -X eth1 default $ sudo ethtool -x eth1 RX flow hash indirection table for eth1 with 16 RX ring(s): 0: 0 1 2 3 4 5 6 7 8: 8 9 10 11 12 13 14 15 16: 0 1 2 3 4 5 6 7 ...
Fixes: 91cd94bfe4f0 ("ixgbe: add basic support for setting and getting nfc controls") Signed-off-by: Joe Damato jdamato@fastly.com Reviewed-by: Sridhar Samudrala sridhar.samudrala@intel.com Tested-by: Pucha Himasekhar Reddy himasekharx.reddy.pucha@intel.com (A Contingent worker at Intel) Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 472ea068ea7b0..2eb1331834731 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -2641,6 +2641,14 @@ static int ixgbe_get_rss_hash_opts(struct ixgbe_adapter *adapter, return 0; }
+static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter) +{ + if (adapter->hw.mac.type < ixgbe_mac_X550) + return 16; + else + return 64; +} + static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, u32 *rule_locs) { @@ -2649,7 +2657,8 @@ static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
switch (cmd->cmd) { case ETHTOOL_GRXRINGS: - cmd->data = adapter->num_rx_queues; + cmd->data = min_t(int, adapter->num_rx_queues, + ixgbe_rss_indir_tbl_max(adapter)); ret = 0; break; case ETHTOOL_GRXCLSRLCNT: @@ -3051,14 +3060,6 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) return ret; }
-static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter) -{ - if (adapter->hw.mac.type < ixgbe_mac_X550) - return 16; - else - return 64; -} - static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev) { return IXGBE_RSS_KEY_SIZE;
From: Stanislav Fomichev sdf@google.com
[ Upstream commit 00e74ae0863827d944e36e56a4ce1e77e50edb91 ]
Some socket options do getsockopt with optval=NULL to estimate the size of the final buffer (which is returned via optlen). This breaks BPF getsockopt assumptions about permitted optval buffer size. Let's enforce these assumptions only when non-NULL optval is provided.
Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks") Reported-by: Martin KaFai Lau martin.lau@kernel.org Signed-off-by: Stanislav Fomichev sdf@google.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/ZD7Js4fj5YyI2oLd@google.com/T/#mb68daf700f87a924... Link: https://lore.kernel.org/bpf/20230418225343.553806-2-sdf@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/cgroup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 6d92e393e1bc6..d3593a520bb72 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1516,7 +1516,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, goto out; }
- if (ctx.optlen > max_optlen || ctx.optlen < 0) { + if (optval && (ctx.optlen > max_optlen || ctx.optlen < 0)) { ret = -EFAULT; goto out; } @@ -1530,8 +1530,11 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, }
if (ctx.optlen != 0) { - if (copy_to_user(optval, ctx.optval, ctx.optlen) || - put_user(ctx.optlen, optlen)) { + if (optval && copy_to_user(optval, ctx.optval, ctx.optlen)) { + ret = -EFAULT; + goto out; + } + if (put_user(ctx.optlen, optlen)) { ret = -EFAULT; goto out; }
From: Florian Westphal fw@strlen.de
[ Upstream commit 9a32e9850686599ed194ccdceb6cd3dd56b2d9b9 ]
The ->cleanup callback needs to be removed, this doesn't work anymore as the transaction mutex is already released in the ->abort function.
Just do it after a successful validation pass, this either happens from commit or abort phases where transaction mutex is held.
Fixes: f102d66b335a ("netfilter: nf_tables: use dedicated mutex to guard transactions") Signed-off-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/netfilter/nfnetlink.h | 1 - net/netfilter/nf_tables_api.c | 8 ++------ net/netfilter/nfnetlink.c | 2 -- 3 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index 791d516e1e880..0518ca72b7616 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -39,7 +39,6 @@ struct nfnetlink_subsystem { int (*commit)(struct net *net, struct sk_buff *skb); int (*abort)(struct net *net, struct sk_buff *skb, enum nfnl_abort_action action); - void (*cleanup)(struct net *net); bool (*valid_genid)(struct net *net, u32 genid); };
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 2143edafba772..7bb716df7afce 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -7442,6 +7442,8 @@ static int nf_tables_validate(struct net *net) if (nft_table_validate(net, table) < 0) return -EAGAIN; } + + nft_validate_state_update(net, NFT_VALIDATE_SKIP); break; }
@@ -8273,11 +8275,6 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) return 0; }
-static void nf_tables_cleanup(struct net *net) -{ - nft_validate_state_update(net, NFT_VALIDATE_SKIP); -} - static int nf_tables_abort(struct net *net, struct sk_buff *skb, enum nfnl_abort_action action) { @@ -8309,7 +8306,6 @@ static const struct nfnetlink_subsystem nf_tables_subsys = { .cb = nf_tables_cb, .commit = nf_tables_commit, .abort = nf_tables_abort, - .cleanup = nf_tables_cleanup, .valid_genid = nf_tables_valid_genid, .owner = THIS_MODULE, }; diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index d3df66a39b5e0..edf386a020b9e 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -530,8 +530,6 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh, goto replay_abort; } } - if (ss->cleanup) - ss->cleanup(net);
nfnl_err_deliver(&err_list, oskb); kfree_skb(skb);
From: Davide Caratti dcaratti@redhat.com
[ Upstream commit 7041101ff6c3073fd8f2e99920f535b111c929cb ]
if sch_fq is configured with "initial quantum" having values greater than INT_MAX, the first assignment of "credit" does signed integer overflow to a very negative value. In this situation, the syzkaller script provided by Cristoph triggers the CPU soft-lockup warning even with few sockets. It's not an infinite loop, but "credit" wasn't probably meant to be minus 2Gb for each new flow. Capping "initial quantum" to INT_MAX proved to fix the issue.
v2: validation of "initial quantum" is done in fq_policy, instead of open coding in fq_change() _ suggested by Jakub Kicinski
Reported-by: Christoph Paasch cpaasch@apple.com Link: https://github.com/multipath-tcp/mptcp_net-next/issues/377 Fixes: afe4fd062416 ("pkt_sched: fq: Fair Queue packet scheduler") Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: Davide Caratti dcaratti@redhat.com Link: https://lore.kernel.org/r/7b3a3c7e36d03068707a021760a194a8eb5ad41a.168200230... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/sch_fq.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index 2fb76fc0cc31b..5a1274199fe33 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c @@ -779,13 +779,17 @@ static int fq_resize(struct Qdisc *sch, u32 log) return 0; }
+static struct netlink_range_validation iq_range = { + .max = INT_MAX, +}; + static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = { [TCA_FQ_UNSPEC] = { .strict_start_type = TCA_FQ_TIMER_SLACK },
[TCA_FQ_PLIMIT] = { .type = NLA_U32 }, [TCA_FQ_FLOW_PLIMIT] = { .type = NLA_U32 }, [TCA_FQ_QUANTUM] = { .type = NLA_U32 }, - [TCA_FQ_INITIAL_QUANTUM] = { .type = NLA_U32 }, + [TCA_FQ_INITIAL_QUANTUM] = NLA_POLICY_FULL_RANGE(NLA_U32, &iq_range), [TCA_FQ_RATE_ENABLE] = { .type = NLA_U32 }, [TCA_FQ_FLOW_DEFAULT_RATE] = { .type = NLA_U32 }, [TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 },
From: Ziyang Xuan william.xuanziyang@huawei.com
[ Upstream commit 99e5acae193e369b71217efe6f1dad42f3f18815 ]
Like commit ea30388baebc ("ipv6: Fix an uninit variable access bug in __ip6_make_skb()"). icmphdr does not in skb linear region under the scenario of SOCK_RAW socket. Access icmp_hdr(skb)->type directly will trigger the uninit variable access bug.
Use a local variable icmp_type to carry the correct value in different scenarios.
Fixes: 96793b482540 ("[IPV4]: Add ICMPMsgStats MIB (RFC 4293)") Reviewed-by: Willem de Bruijn willemb@google.com Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/ip_output.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 0dbf950de832f..1e07df2821773 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1564,9 +1564,19 @@ struct sk_buff *__ip_make_skb(struct sock *sk, cork->dst = NULL; skb_dst_set(skb, &rt->dst);
- if (iph->protocol == IPPROTO_ICMP) - icmp_out_count(net, ((struct icmphdr *) - skb_transport_header(skb))->type); + if (iph->protocol == IPPROTO_ICMP) { + u8 icmp_type; + + /* For such sockets, transhdrlen is zero when do ip_append_data(), + * so icmphdr does not in skb linear region and can not get icmp_type + * by icmp_hdr(skb)->type. + */ + if (sk->sk_type == SOCK_RAW && !inet_sk(sk)->hdrincl) + icmp_type = fl4->fl4_icmp_type; + else + icmp_type = icmp_hdr(skb)->type; + icmp_out_count(net, icmp_type); + }
ip_cork_release(cork); out:
From: Liu Jian liujian56@huawei.com
[ Upstream commit db2bf510bd5d57f064d9e1db395ed86a08320c54 ]
This reverts commit 1e9ac114c4428fdb7ff4635b45d4f46017e8916f.
This patch introduces a possible null-ptr-def problem. Revert it. And the fixed bug by this patch have resolved by commit 73f7b171b7c0 ("Bluetooth: btsdio: fix use after free bug in btsdio_remove due to race condition").
Fixes: 1e9ac114c442 ("Bluetooth: btsdio: fix use after free bug in btsdio_remove due to unfinished work") Signed-off-by: Liu Jian liujian56@huawei.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/btsdio.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c index 7050a16e7efeb..199e8f7d426d9 100644 --- a/drivers/bluetooth/btsdio.c +++ b/drivers/bluetooth/btsdio.c @@ -352,7 +352,6 @@ static void btsdio_remove(struct sdio_func *func)
BT_DBG("func %p", func);
- cancel_work_sync(&data->work); if (!data) return;
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit d913d32cc2707e9cd24fe6fa6d7d470e9c728980 ]
Brad Spencer provided a detailed report [0] that when calling getsockopt() for AF_NETLINK, some SOL_NETLINK options set only 1 byte even though such options require at least sizeof(int) as length.
The options return a flag value that fits into 1 byte, but such behaviour confuses users who do not initialise the variable before calling getsockopt() and do not strictly check the returned value as char.
Currently, netlink_getsockopt() uses put_user() to copy data to optlen and optval, but put_user() casts the data based on the pointer, char *optval. As a result, only 1 byte is set to optval.
To avoid this behaviour, we need to use copy_to_user() or cast optval for put_user().
Note that this changes the behaviour on big-endian systems, but we document that the size of optval is int in the man page.
$ man 7 netlink ... Socket options To set or get a netlink socket option, call getsockopt(2) to read or setsockopt(2) to write the option with the option level argument set to SOL_NETLINK. Unless otherwise noted, optval is a pointer to an int.
Fixes: 9a4595bc7e67 ("[NETLINK]: Add set/getsockopt options to support more than 32 groups") Fixes: be0c22a46cfb ("netlink: add NETLINK_BROADCAST_ERROR socket option") Fixes: 38938bfe3489 ("netlink: add NETLINK_NO_ENOBUFS socket flag") Fixes: 0a6a3a23ea6e ("netlink: add NETLINK_CAP_ACK socket option") Fixes: 2d4bc93368f5 ("netlink: extended ACK reporting") Fixes: 89d35528d17d ("netlink: Add new socket option to enable strict checking on dumps") Reported-by: Brad Spencer bspencer@blackberry.com Link: https://lore.kernel.org/netdev/ZD7VkNWFfp22kTDt@datsun.rim.net/ Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Reviewed-by: Johannes Berg johannes@sipsolutions.net Link: https://lore.kernel.org/r/20230421185255.94606-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netlink/af_netlink.c | 75 ++++++++++++---------------------------- 1 file changed, 23 insertions(+), 52 deletions(-)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 2104fbdd63d29..eedb16517f16a 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1744,7 +1744,8 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, { struct sock *sk = sock->sk; struct netlink_sock *nlk = nlk_sk(sk); - int len, val, err; + unsigned int flag; + int len, val;
if (level != SOL_NETLINK) return -ENOPROTOOPT; @@ -1756,39 +1757,17 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
switch (optname) { case NETLINK_PKTINFO: - if (len < sizeof(int)) - return -EINVAL; - len = sizeof(int); - val = nlk->flags & NETLINK_F_RECV_PKTINFO ? 1 : 0; - if (put_user(len, optlen) || - put_user(val, optval)) - return -EFAULT; - err = 0; + flag = NETLINK_F_RECV_PKTINFO; break; case NETLINK_BROADCAST_ERROR: - if (len < sizeof(int)) - return -EINVAL; - len = sizeof(int); - val = nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR ? 1 : 0; - if (put_user(len, optlen) || - put_user(val, optval)) - return -EFAULT; - err = 0; + flag = NETLINK_F_BROADCAST_SEND_ERROR; break; case NETLINK_NO_ENOBUFS: - if (len < sizeof(int)) - return -EINVAL; - len = sizeof(int); - val = nlk->flags & NETLINK_F_RECV_NO_ENOBUFS ? 1 : 0; - if (put_user(len, optlen) || - put_user(val, optval)) - return -EFAULT; - err = 0; + flag = NETLINK_F_RECV_NO_ENOBUFS; break; case NETLINK_LIST_MEMBERSHIPS: { - int pos, idx, shift; + int pos, idx, shift, err = 0;
- err = 0; netlink_lock_table(); for (pos = 0; pos * 8 < nlk->ngroups; pos += sizeof(u32)) { if (len - pos < sizeof(u32)) @@ -1805,40 +1784,32 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname, if (put_user(ALIGN(nlk->ngroups / 8, sizeof(u32)), optlen)) err = -EFAULT; netlink_unlock_table(); - break; + return err; } case NETLINK_CAP_ACK: - if (len < sizeof(int)) - return -EINVAL; - len = sizeof(int); - val = nlk->flags & NETLINK_F_CAP_ACK ? 1 : 0; - if (put_user(len, optlen) || - put_user(val, optval)) - return -EFAULT; - err = 0; + flag = NETLINK_F_CAP_ACK; break; case NETLINK_EXT_ACK: - if (len < sizeof(int)) - return -EINVAL; - len = sizeof(int); - val = nlk->flags & NETLINK_F_EXT_ACK ? 1 : 0; - if (put_user(len, optlen) || put_user(val, optval)) - return -EFAULT; - err = 0; + flag = NETLINK_F_EXT_ACK; break; case NETLINK_GET_STRICT_CHK: - if (len < sizeof(int)) - return -EINVAL; - len = sizeof(int); - val = nlk->flags & NETLINK_F_STRICT_CHK ? 1 : 0; - if (put_user(len, optlen) || put_user(val, optval)) - return -EFAULT; - err = 0; + flag = NETLINK_F_STRICT_CHK; break; default: - err = -ENOPROTOOPT; + return -ENOPROTOOPT; } - return err; + + if (len < sizeof(int)) + return -EINVAL; + + len = sizeof(int); + val = nlk->flags & flag ? 1 : 0; + + if (put_user(len, optlen) || + copy_to_user(optval, &val, len)) + return -EFAULT; + + return 0; }
static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
From: Gencen Gan gangecen@hust.edu.cn
[ Upstream commit d325c34d9e7e38d371c0a299d415e9b07f66a1fb ]
After failing to verify configuration, it returns directly without releasing link, which may cause memory leak.
Paolo Abeni thinks that the whole code of this driver is quite "suboptimal" and looks unmainatained since at least ~15y, so he suggests that we could simply remove the whole driver, please take it into consideration.
Simon Horman suggests that the fix label should be set to "Linux-2.6.12-rc2" considering that the problem has existed since the driver was introduced and the commit above doesn't seem to exist in net/net-next.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Gan Gecen gangecen@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/amd/nmclan_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/amd/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c index 11c0b13edd30f..f34881637505e 100644 --- a/drivers/net/ethernet/amd/nmclan_cs.c +++ b/drivers/net/ethernet/amd/nmclan_cs.c @@ -650,7 +650,7 @@ static int nmclan_config(struct pcmcia_device *link) } else { pr_notice("mace id not found: %x %x should be 0x40 0x?9\n", sig[0], sig[1]); - return -ENODEV; + goto failed; } }
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit 50749f2dd6854a41830996ad302aef2ffaf011d8 ]
syzkaller reported [0] memory leaks of an UDP socket and ZEROCOPY skbs. We can reproduce the problem with these sequences:
sk = socket(AF_INET, SOCK_DGRAM, 0) sk.setsockopt(SOL_SOCKET, SO_TIMESTAMPING, SOF_TIMESTAMPING_TX_SOFTWARE) sk.setsockopt(SOL_SOCKET, SO_ZEROCOPY, 1) sk.sendto(b'', MSG_ZEROCOPY, ('127.0.0.1', 53)) sk.close()
sendmsg() calls msg_zerocopy_alloc(), which allocates a skb, sets skb->cb->ubuf.refcnt to 1, and calls sock_hold(). Here, struct ubuf_info_msgzc indirectly holds a refcnt of the socket. When the skb is sent, __skb_tstamp_tx() clones it and puts the clone into the socket's error queue with the TX timestamp.
When the original skb is received locally, skb_copy_ubufs() calls skb_unclone(), and pskb_expand_head() increments skb->cb->ubuf.refcnt. This additional count is decremented while freeing the skb, but struct ubuf_info_msgzc still has a refcnt, so __msg_zerocopy_callback() is not called.
The last refcnt is not released unless we retrieve the TX timestamped skb by recvmsg(). Since we clear the error queue in inet_sock_destruct() after the socket's refcnt reaches 0, there is a circular dependency. If we close() the socket holding such skbs, we never call sock_put() and leak the count, sk, and skb.
TCP has the same problem, and commit e0c8bccd40fc ("net: stream: purge sk_error_queue in sk_stream_kill_queues()") tried to fix it by calling skb_queue_purge() during close(). However, there is a small chance that skb queued in a qdisc or device could be put into the error queue after the skb_queue_purge() call.
In __skb_tstamp_tx(), the cloned skb should not have a reference to the ubuf to remove the circular dependency, but skb_clone() does not call skb_copy_ubufs() for zerocopy skb. So, we need to call skb_orphan_frags_rx() for the cloned skb to call skb_copy_ubufs().
[0]: BUG: memory leak unreferenced object 0xffff88800c6d2d00 (size 1152): comm "syz-executor392", pid 264, jiffies 4294785440 (age 13.044s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 cd af e8 81 00 00 00 00 ................ 02 00 07 40 00 00 00 00 00 00 00 00 00 00 00 00 ...@............ backtrace: [<0000000055636812>] sk_prot_alloc+0x64/0x2a0 net/core/sock.c:2024 [<0000000054d77b7a>] sk_alloc+0x3b/0x800 net/core/sock.c:2083 [<0000000066f3c7e0>] inet_create net/ipv4/af_inet.c:319 [inline] [<0000000066f3c7e0>] inet_create+0x31e/0xe40 net/ipv4/af_inet.c:245 [<000000009b83af97>] __sock_create+0x2ab/0x550 net/socket.c:1515 [<00000000b9b11231>] sock_create net/socket.c:1566 [inline] [<00000000b9b11231>] __sys_socket_create net/socket.c:1603 [inline] [<00000000b9b11231>] __sys_socket_create net/socket.c:1588 [inline] [<00000000b9b11231>] __sys_socket+0x138/0x250 net/socket.c:1636 [<000000004fb45142>] __do_sys_socket net/socket.c:1649 [inline] [<000000004fb45142>] __se_sys_socket net/socket.c:1647 [inline] [<000000004fb45142>] __x64_sys_socket+0x73/0xb0 net/socket.c:1647 [<0000000066999e0e>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] [<0000000066999e0e>] do_syscall_64+0x38/0x90 arch/x86/entry/common.c:80 [<0000000017f238c1>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
BUG: memory leak unreferenced object 0xffff888017633a00 (size 240): comm "syz-executor392", pid 264, jiffies 4294785440 (age 13.044s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 2d 6d 0c 80 88 ff ff .........-m..... backtrace: [<000000002b1c4368>] __alloc_skb+0x229/0x320 net/core/skbuff.c:497 [<00000000143579a6>] alloc_skb include/linux/skbuff.h:1265 [inline] [<00000000143579a6>] sock_omalloc+0xaa/0x190 net/core/sock.c:2596 [<00000000be626478>] msg_zerocopy_alloc net/core/skbuff.c:1294 [inline] [<00000000be626478>] msg_zerocopy_realloc+0x1ce/0x7f0 net/core/skbuff.c:1370 [<00000000cbfc9870>] __ip_append_data+0x2adf/0x3b30 net/ipv4/ip_output.c:1037 [<0000000089869146>] ip_make_skb+0x26c/0x2e0 net/ipv4/ip_output.c:1652 [<00000000098015c2>] udp_sendmsg+0x1bac/0x2390 net/ipv4/udp.c:1253 [<0000000045e0e95e>] inet_sendmsg+0x10a/0x150 net/ipv4/af_inet.c:819 [<000000008d31bfde>] sock_sendmsg_nosec net/socket.c:714 [inline] [<000000008d31bfde>] sock_sendmsg+0x141/0x190 net/socket.c:734 [<0000000021e21aa4>] __sys_sendto+0x243/0x360 net/socket.c:2117 [<00000000ac0af00c>] __do_sys_sendto net/socket.c:2129 [inline] [<00000000ac0af00c>] __se_sys_sendto net/socket.c:2125 [inline] [<00000000ac0af00c>] __x64_sys_sendto+0xe1/0x1c0 net/socket.c:2125 [<0000000066999e0e>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] [<0000000066999e0e>] do_syscall_64+0x38/0x90 arch/x86/entry/common.c:80 [<0000000017f238c1>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
Fixes: f214f915e7db ("tcp: enable MSG_ZEROCOPY") Fixes: b5947e5d1e71 ("udp: msg_zerocopy") Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Reviewed-by: Willem de Bruijn willemb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/skbuff.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 09cdefe5e1c83..fb6b3f2ae1921 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4750,6 +4750,9 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, skb = alloc_skb(0, GFP_ATOMIC); } else { skb = skb_clone(orig_skb, GFP_ATOMIC); + + if (skb_orphan_frags_rx(skb, GFP_ATOMIC)) + return; } if (!skb) return;
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 2a587b9ad052e7e92e508aea90c1e2ae433c1908 ]
REGMAP is a hidden (not user visible) symbol. Users cannot set it directly thru "make *config", so drivers should select it instead of depending on it if they need it.
Consistently using "select" or "depends on" can also help reduce Kconfig circular dependency issues.
Therefore, change the use of "depends on REGMAP_MMIO" to "select REGMAP_MMIO", which will also set REGMAP.
Fixes: eb994594bc22 ("ipmi: bt-bmc: Use a regmap for register access") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Andrew Jeffery andrew@aj.id.au Cc: Corey Minyard minyard@acm.org Cc: openipmi-developer@lists.sourceforge.net Cc: Arnd Bergmann arnd@arndb.de Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Message-Id: 20230226053953.4681-2-rdunlap@infradead.org Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/ipmi/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index 07847d9a459af..f443186269e1c 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -126,7 +126,8 @@ config NPCM7XX_KCS_IPMI_BMC
config ASPEED_BT_IPMI_BMC depends on ARCH_ASPEED || COMPILE_TEST - depends on REGMAP && REGMAP_MMIO && MFD_SYSCON + depends on MFD_SYSCON + select REGMAP_MMIO tristate "BT IPMI bmc driver" help Provides a driver for the BT (Block Transfer) IPMI interface
From: John Stultz jstultz@google.com
[ Upstream commit 5239a89b06d6b199f133bf0ffea421683187f257 ]
This reverts commit 76d62f24db07f22ccf9bc18ca793c27d4ebef721.
So while priority inversion on the pmsg_lock is an occasional problem that an rt_mutex would help with, in uses where logging is writing to pmsg heavily from multiple threads, the pmsg_lock can be heavily contended.
After this change landed, it was reported that cases where the mutex locking overhead was commonly adding on the order of 10s of usecs delay had suddenly jumped to ~msec delay with rtmutex.
It seems the slight differences in the locks under this level of contention causes the normal mutexes to utilize the spinning optimizations, while the rtmutexes end up in the sleeping slowpath (which allows additional threads to pile on trying to take the lock).
In this case, it devolves to a worse case senerio where the lock acquisition and scheduling overhead dominates, and each thread is waiting on the order of ~ms to do ~us of work.
Obviously, having tons of threads all contending on a single lock for logging is non-optimal, so the proper fix is probably reworking pstore pmsg to have per-cpu buffers so we don't have contention.
Additionally, Steven Rostedt has provided some furhter optimizations for rtmutexes that improves the rtmutex spinning path, but at least in my testing, I still see the test tripping into the sleeping path on rtmutexes while utilizing the spinning path with mutexes.
But in the short term, lets revert the change to the rt_mutex and go back to normal mutexes to avoid a potentially major performance regression. And we can work on optimizations to both rtmutexes and finer-grained locking for pstore pmsg in the future.
Cc: Wei Wang wvw@google.com Cc: Midas Chienmidaschieh@google.com Cc: "Chunhui Li (李春辉)" chunhui.li@mediatek.com Cc: Steven Rostedt rostedt@goodmis.org Cc: Kees Cook keescook@chromium.org Cc: Anton Vorontsov anton@enomsg.org Cc: "Guilherme G. Piccoli" gpiccoli@igalia.com Cc: Tony Luck tony.luck@intel.com Cc: kernel-team@android.com Fixes: 76d62f24db07 ("pstore: Switch pmsg_lock to an rt_mutex to avoid priority inversion") Reported-by: "Chunhui Li (李春辉)" chunhui.li@mediatek.com Signed-off-by: John Stultz jstultz@google.com Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20230308204043.2061631-1-jstultz@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/pstore/pmsg.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c index 18cf94b597e05..d8542ec2f38c6 100644 --- a/fs/pstore/pmsg.c +++ b/fs/pstore/pmsg.c @@ -7,10 +7,9 @@ #include <linux/device.h> #include <linux/fs.h> #include <linux/uaccess.h> -#include <linux/rtmutex.h> #include "internal.h"
-static DEFINE_RT_MUTEX(pmsg_lock); +static DEFINE_MUTEX(pmsg_lock);
static ssize_t write_pmsg(struct file *file, const char __user *buf, size_t count, loff_t *ppos) @@ -29,9 +28,9 @@ static ssize_t write_pmsg(struct file *file, const char __user *buf, if (!access_ok(buf, count)) return -EFAULT;
- rt_mutex_lock(&pmsg_lock); + mutex_lock(&pmsg_lock); ret = psinfo->write_user(&record, buf); - rt_mutex_unlock(&pmsg_lock); + mutex_unlock(&pmsg_lock); return ret ? ret : count; }
From: Wolfram Sang wsa+renesas@sang-engineering.com
[ Upstream commit 5d67f4861884762ebc2bddb5d667444e45f25782 ]
Loading V3 firmware does not need a quirk anymore, remove the leftover code.
Fixes: ed8603e11124 ("usb: host: xhci-rcar: Simplify getting the firmware name for R-Car Gen3") Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Wolfram Sang wsa+renesas@sang-engineering.com Link: https://lore.kernel.org/r/20230307163041.3815-10-wsa+renesas@sang-engineerin... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci-rcar.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index 9888ba7d85b6a..cfafa1c50adea 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -75,7 +75,6 @@ MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V3);
/* For soc_device_attribute */ #define RCAR_XHCI_FIRMWARE_V2 BIT(0) /* FIRMWARE V2 */ -#define RCAR_XHCI_FIRMWARE_V3 BIT(1) /* FIRMWARE V3 */
static const struct soc_device_attribute rcar_quirks_match[] = { { @@ -147,8 +146,6 @@ static int xhci_rcar_download_firmware(struct usb_hcd *hcd)
if (quirks & RCAR_XHCI_FIRMWARE_V2) firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2; - else if (quirks & RCAR_XHCI_FIRMWARE_V3) - firmware_name = XHCI_RCAR_FIRMWARE_NAME_V3; else firmware_name = priv->firmware_name;
From: Prashanth K quic_prashk@quicinc.com
[ Upstream commit 4decf4060ecfee1f7a710999fcd421645ac0c419 ]
Currently we process the suspend interrupt event only if the device is in configured state. Consider a case where device is not configured and got suspend interrupt, in that case our gadget will still use 100mA as composite_suspend didn't happen. But battery charging specification (BC1.2) expects a downstream device to draw less than 2.5mA when unconnected OR suspended.
Fix this by removing the condition for processing suspend event, and thus composite_resume would set vbus draw to 2.
Fixes: 72704f876f50 ("dwc3: gadget: Implement the suspend entry event handler") Signed-off-by: Prashanth K quic_prashk@quicinc.com Acked-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Link: https://lore.kernel.org/r/1677217619-10261-2-git-send-email-quic_prashk@quic... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/gadget.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 01cecde76140b..4e3b451ed749e 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3726,15 +3726,8 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, break; case DWC3_DEVICE_EVENT_EOPF: /* It changed to be suspend event for version 2.30a and above */ - if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) { - /* - * Ignore suspend event until the gadget enters into - * USB_STATE_CONFIGURED state. - */ - if (dwc->gadget->state >= USB_STATE_CONFIGURED) - dwc3_gadget_suspend_interrupt(dwc, - event->event_info); - } + if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) + dwc3_gadget_suspend_interrupt(dwc, event->event_info); break; case DWC3_DEVICE_EVENT_SOF: case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
From: Marco Pagani marpagan@redhat.com
[ Upstream commit 7ef1a2c1c9dffa177ecc3ea50b7f5ee63a621137 ]
Fix the kernel-doc description for the "struct fpga_image_info *info" parameter of the fpga_bridge_get() function.
Fixes: 060ac5c8fa7b ("fpga: bridge: kernel-doc fixes") Signed-off-by: Marco Pagani marpagan@redhat.com Reviewed-by: Tom Rix trix@redhat.com Acked-by: Xu Yilun yilun.xu@intel.com Link: https://lore.kernel.org/r/20230301140309.512578-1-marpagan@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/fpga/fpga-bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c index 2deccacc3aa75..851debe32bf0f 100644 --- a/drivers/fpga/fpga-bridge.c +++ b/drivers/fpga/fpga-bridge.c @@ -115,7 +115,7 @@ static int fpga_bridge_dev_match(struct device *dev, const void *data) /** * fpga_bridge_get - get an exclusive reference to a fpga bridge * @dev: parent device that fpga bridge was registered with - * @info: fpga manager info + * @info: fpga image specific information * * Given a device, get an exclusive reference to a fpga bridge. *
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit b29c49026c3c05a11f845dba17cad0b3ba06836d ]
The driver currently matches only via i2c_device_id, but also has of_device_id table:
drivers/iio/light/max44009.c:545:34: error: ‘max44009_of_match’ defined but not used [-Werror=unused-const-variable=]
Fixes: 6aef699a7d7e ("iio: light: add driver for MAX44009") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20230312153429.371702-2-krzysztof.kozlowski@linaro... Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/light/max44009.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/iio/light/max44009.c b/drivers/iio/light/max44009.c index 801e5a0ad496b..f3648f20ef2c0 100644 --- a/drivers/iio/light/max44009.c +++ b/drivers/iio/light/max44009.c @@ -528,6 +528,12 @@ static int max44009_probe(struct i2c_client *client, return devm_iio_device_register(&client->dev, indio_dev); }
+static const struct of_device_id max44009_of_match[] = { + { .compatible = "maxim,max44009" }, + { } +}; +MODULE_DEVICE_TABLE(of, max44009_of_match); + static const struct i2c_device_id max44009_id[] = { { "max44009", 0 }, { } @@ -537,18 +543,13 @@ MODULE_DEVICE_TABLE(i2c, max44009_id); static struct i2c_driver max44009_driver = { .driver = { .name = MAX44009_DRV_NAME, + .of_match_table = max44009_of_match, }, .probe = max44009_probe, .id_table = max44009_id, }; module_i2c_driver(max44009_driver);
-static const struct of_device_id max44009_of_match[] = { - { .compatible = "maxim,max44009" }, - { } -}; -MODULE_DEVICE_TABLE(of, max44009_of_match); - MODULE_AUTHOR("Robert Eshleman bobbyeshleman@gmail.com"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("MAX44009 ambient light sensor driver");
From: Minghao Chi chi.minghao@zte.com.cn
[ Upstream commit 7d34ff58f35c82207698f43af79817a05e1342e5 ]
Using pm_runtime_resume_and_get() to replace pm_runtime_get_sync and pm_runtime_put_noidle. This change is just to simplify the code, no actual functional changes.
Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Minghao Chi chi.minghao@zte.com.cn Link: https://lore.kernel.org/r/20220414085343.2541608-1-chi.minghao@zte.com.cn Signed-off-by: Mark Brown broonie@kernel.org Stable-dep-of: 11951c9e3f36 ("spi: imx: Don't skip cleanup in remove's error path") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-imx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 74b3b6ca15efb..66b568de96af6 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1554,9 +1554,8 @@ spi_imx_prepare_message(struct spi_master *master, struct spi_message *msg) struct spi_imx_data *spi_imx = spi_master_get_devdata(master); int ret;
- ret = pm_runtime_get_sync(spi_imx->dev); + ret = pm_runtime_resume_and_get(spi_imx->dev); if (ret < 0) { - pm_runtime_put_noidle(spi_imx->dev); dev_err(spi_imx->dev, "failed to enable clock\n"); return ret; } @@ -1765,9 +1764,8 @@ static int spi_imx_remove(struct platform_device *pdev)
spi_bitbang_stop(&spi_imx->bitbang);
- ret = pm_runtime_get_sync(spi_imx->dev); + ret = pm_runtime_resume_and_get(spi_imx->dev); if (ret < 0) { - pm_runtime_put_noidle(spi_imx->dev); dev_err(spi_imx->dev, "failed to enable clock\n"); return ret; }
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 11951c9e3f364d7ae3b568a0e52c8335d43066b5 ]
Returning early in a platform driver's remove callback is wrong. In this case the dma resources are not released in the error path. this is never retried later and so this is a permanent leak. To fix this, only skip hardware disabling if waking the device fails.
Fixes: d593574aff0a ("spi: imx: do not access registers while clocks disabled") Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Link: https://lore.kernel.org/r/20230306065733.2170662-2-u.kleine-koenig@pengutron... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-imx.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 66b568de96af6..bbc420865f0fd 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1764,13 +1764,11 @@ static int spi_imx_remove(struct platform_device *pdev)
spi_bitbang_stop(&spi_imx->bitbang);
- ret = pm_runtime_resume_and_get(spi_imx->dev); - if (ret < 0) { - dev_err(spi_imx->dev, "failed to enable clock\n"); - return ret; - } - - writel(0, spi_imx->base + MXC_CSPICTRL); + ret = pm_runtime_get_sync(spi_imx->dev); + if (ret >= 0) + writel(0, spi_imx->base + MXC_CSPICTRL); + else + dev_warn(spi_imx->dev, "failed to enable clock, skip hw disable\n");
pm_runtime_dont_use_autosuspend(spi_imx->dev); pm_runtime_put_sync(spi_imx->dev);
From: Zheng Wang zyytlz.wz@163.com
[ Upstream commit 2b947f8769be8b8181dc795fd292d3e7120f5204 ]
In renesas_usb3_probe, role_work is bound with renesas_usb3_role_work. renesas_usb3_start will be called to start the work.
If we remove the driver which will call usbhs_remove, there may be an unfinished work. The possible sequence is as follows:
CPU0 CPU1
renesas_usb3_role_work renesas_usb3_remove usb_role_switch_unregister device_unregister kfree(sw) //free usb3->role_sw usb_role_switch_set_role //use usb3->role_sw
The usb3->role_sw could be freed under such circumstance and then used in usb_role_switch_set_role.
This bug was found by static analysis. And note that removing a driver is a root-only operation, and should never happen in normal case. But the root user may directly remove the device which will also trigger the remove function.
Fix it by canceling the work before cleanup in the renesas_usb3_remove.
Fixes: 39facfa01c9f ("usb: gadget: udc: renesas_usb3: Add register of usb role switch") Signed-off-by: Zheng Wang zyytlz.wz@163.com Reviewed-by: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com Link: https://lore.kernel.org/r/20230320062931.505170-1-zyytlz.wz@163.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/udc/renesas_usb3.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 601829a6b4bad..a10f41c4a3f2f 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -2568,6 +2568,7 @@ static int renesas_usb3_remove(struct platform_device *pdev) debugfs_remove_recursive(usb3->dentry); device_remove_file(&pdev->dev, &dev_attr_role);
+ cancel_work_sync(&usb3->role_work); usb_role_switch_unregister(usb3->role_sw);
usb_del_gadget_udc(&usb3->gadget);
From: H. Nikolaus Schaller hns@goldelico.com
[ Upstream commit 5f5ac460dfe7f4e11f99de9870f240e39189cf72 ]
commit bb38919ec56e ("PCI: imx6: Add support for i.MX6 PCIe controller") added a fault hook to this driver in the probe function. So it was only installed if needed.
commit bde4a5a00e76 ("PCI: imx6: Allow probe deferral by reset GPIO") moved it from probe to driver init which installs the hook unconditionally as soon as the driver is compiled into a kernel.
When this driver is compiled as a module, the hook is not registered until after the driver has been matched with a .compatible and loaded.
commit 415b6185c541 ("PCI: imx6: Fix config read timeout handling") extended the fault handling code.
commit 2d8ed461dbc9 ("PCI: imx6: Add support for i.MX8MQ") added some protection for non-ARM architectures, but this does not protect non-i.MX ARM architectures.
Since fault handlers can be triggered on any architecture for different reasons, there is no guarantee that they will be triggered only for the assumed situation, leading to improper error handling (i.MX6-specific imx6q_pcie_abort_handler) on foreign systems.
I had seen strange L3 imprecise external abort messages several times on OMAP4 and OMAP5 devices and couldn't make sense of them until I realized they were related to this unused imx6q driver because I had CONFIG_PCI_IMX6=y.
Note that CONFIG_PCI_IMX6=y is useful for kernel binaries that are designed to run on different ARM SoC and be differentiated only by device tree binaries. So turning off CONFIG_PCI_IMX6 is not a solution.
Therefore we check the compatible in the init function before registering the fault handler.
Link: https://lore.kernel.org/r/e1bcfc3078c82b53aa9b78077a89955abe4ea009.167838099... Fixes: bde4a5a00e76 ("PCI: imx6: Allow probe deferral by reset GPIO") Fixes: 415b6185c541 ("PCI: imx6: Fix config read timeout handling") Fixes: 2d8ed461dbc9 ("PCI: imx6: Add support for i.MX8MQ") Signed-off-by: H. Nikolaus Schaller hns@goldelico.com Signed-off-by: Lorenzo Pieralisi lpieralisi@kernel.org Reviewed-by: Richard Zhu hongxing.zhu@nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pci-imx6.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index ceb4815379cd4..8117f2dad86c4 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -1272,6 +1272,13 @@ DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_SYNOPSYS, 0xabcd, static int __init imx6_pcie_init(void) { #ifdef CONFIG_ARM + struct device_node *np; + + np = of_find_matching_node(NULL, imx6_pcie_of_match); + if (!np) + return -ENODEV; + of_node_put(np); + /* * Since probe() can be deferred we need to make sure that * hook_fault_code is not called after __init memory is freed
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 1cf2aa665901054b140eb71748661ceae99b6b5a ]
Use the new IRQF_NO_AUTOEN flag when requesting the IRQ, rather then disabling it immediately after requesting it.
This fixes a possible race where the IRQ might trigger between requesting and disabling it; and this also leads to a small code cleanup.
Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20211003132255.31743-1-hdegoede@redhat.com Signed-off-by: Mark Brown broonie@kernel.org Stable-dep-of: 39db65a0a17b ("ASoC: es8316: Handle optional IRQ assignment") Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/es8316.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index 609459077f9d9..aa23e4e671897 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -808,12 +808,9 @@ static int es8316_i2c_probe(struct i2c_client *i2c_client, mutex_init(&es8316->lock);
ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN, "es8316", es8316); - if (ret == 0) { - /* Gets re-enabled by es8316_set_jack() */ - disable_irq(es8316->irq); - } else { + if (ret) { dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret); es8316->irq = -ENXIO; }
From: Cristian Ciocaltea cristian.ciocaltea@collabora.com
[ Upstream commit 39db65a0a17b54915b269d3685f253a4731f344c ]
The driver is able to work fine without relying on a mandatory interrupt being assigned to the I2C device. This is only needed when making use of the jack-detect support.
However, the following warning message is always emitted when there is no such interrupt available:
es8316 0-0011: Failed to get IRQ 0: -22
Do not attempt to request an IRQ if it is not available/valid. This also ensures the rather misleading message is not displayed anymore.
Also note the IRQ validation relies on commit dab472eb931bc291 ("i2c / ACPI: Use 0 to indicate that device does not have interrupt assigned").
Fixes: 822257661031 ("ASoC: es8316: Add jack-detect support") Signed-off-by: Cristian Ciocaltea cristian.ciocaltea@collabora.com Reviewed-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230328094901.50763-1-cristian.ciocaltea@collabor... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/es8316.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index aa23e4e671897..bc3d46617a113 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -807,12 +807,14 @@ static int es8316_i2c_probe(struct i2c_client *i2c_client, es8316->irq = i2c_client->irq; mutex_init(&es8316->lock);
- ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN, - "es8316", es8316); - if (ret) { - dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret); - es8316->irq = -ENXIO; + if (es8316->irq > 0) { + ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN, + "es8316", es8316); + if (ret) { + dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret); + es8316->irq = -ENXIO; + } }
return devm_snd_soc_register_component(&i2c_client->dev,
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 2b76ffe81e32afd6d318dc4547e2ba8c46207b77 ]
Fix build errors on ARCH=alpha when CONFIG_MDA_CONSOLE=m. This allows the ARCH macros to be the only ones defined.
In file included from ../drivers/video/console/mdacon.c:37: ../arch/alpha/include/asm/vga.h:17:40: error: expected identifier or '(' before 'volatile' 17 | static inline void scr_writew(u16 val, volatile u16 *addr) | ^~~~~~~~ ../include/linux/vt_buffer.h:24:34: note: in definition of macro 'scr_writew' 24 | #define scr_writew(val, addr) (*(addr) = (val)) | ^~~~ ../include/linux/vt_buffer.h:24:40: error: expected ')' before '=' token 24 | #define scr_writew(val, addr) (*(addr) = (val)) | ^ ../arch/alpha/include/asm/vga.h:17:20: note: in expansion of macro 'scr_writew' 17 | static inline void scr_writew(u16 val, volatile u16 *addr) | ^~~~~~~~~~ ../arch/alpha/include/asm/vga.h:25:29: error: expected identifier or '(' before 'volatile' 25 | static inline u16 scr_readw(volatile const u16 *addr) | ^~~~~~~~
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Jiri Slaby jirislaby@kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-fbdev@vger.kernel.org Link: https://lore.kernel.org/r/20230329021529.16188-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/vt_buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/vt_buffer.h b/include/linux/vt_buffer.h index 848db1b1569ff..919d999a8c1db 100644 --- a/include/linux/vt_buffer.h +++ b/include/linux/vt_buffer.h @@ -16,7 +16,7 @@
#include <linux/string.h>
-#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE) +#if IS_ENABLED(CONFIG_VGA_CONSOLE) || IS_ENABLED(CONFIG_MDA_CONSOLE) #include <asm/vga.h> #endif
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 61f49171a43ab1f80c73c5c88c508770c461e0f2 ]
Returning early in a platform driver's remove callback is wrong. In this case the dma resources are not released in the error path. this is never retried later and so this is a permanent leak. To fix this, only skip hardware disabling if waking the device fails.
Fixes: 64ff247a978f ("spi: Add Qualcomm QUP SPI controller support") Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Link: https://lore.kernel.org/r/20230330210341.2459548-2-u.kleine-koenig@pengutron... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-qup.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index f3877eeb3da65..8bf58510cca6d 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c @@ -1276,18 +1276,22 @@ static int spi_qup_remove(struct platform_device *pdev) struct spi_qup *controller = spi_master_get_devdata(master); int ret;
- ret = pm_runtime_resume_and_get(&pdev->dev); - if (ret < 0) - return ret; + ret = pm_runtime_get_sync(&pdev->dev);
- ret = spi_qup_set_state(controller, QUP_STATE_RESET); - if (ret) - return ret; + if (ret >= 0) { + ret = spi_qup_set_state(controller, QUP_STATE_RESET); + if (ret) + dev_warn(&pdev->dev, "failed to reset controller (%pe)\n", + ERR_PTR(ret));
- spi_qup_release_dma(master); + clk_disable_unprepare(controller->cclk); + clk_disable_unprepare(controller->iclk); + } else { + dev_warn(&pdev->dev, "failed to resume, skip hw disable (%pe)\n", + ERR_PTR(ret)); + }
- clk_disable_unprepare(controller->cclk); - clk_disable_unprepare(controller->iclk); + spi_qup_release_dma(master);
pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev);
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit c20c57d9868d7f9fd1b2904c7801b07e128f6322 ]
CPM has the same problem as QE so for CPM also use the fix added by commit 0398fb70940e ("spi/spi_mpc8xxx: Fix QE mode Litte Endian"):
CPM mode uses Little Endian so words > 8 bits are byte swapped. Workaround this by always enforcing wordsize 8 for 16 and 32 bits words. Unfortunately this will not work for LSB transfers where wordsize is > 8 bits so disable these for now.
Also limit the workaround to 16 and 32 bits words because it can only work for multiples of 8-bits.
Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Cc: Joakim Tjernlund Joakim.Tjernlund@infinera.com Fixes: 0398fb70940e ("spi/spi_mpc8xxx: Fix QE mode Litte Endian") Link: https://lore.kernel.org/r/1b7d3e84b1128f42c1887dd2fb9cdf390f541bc1.168037180... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-fsl-spi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index bdf94cc7be1af..1bad0ceac81b4 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -207,8 +207,8 @@ static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs, struct spi_device *spi, int bits_per_word) { - /* QE uses Little Endian for words > 8 - * so transform all words > 8 into 8 bits + /* CPM/QE uses Little Endian for words > 8 + * so transform 16 and 32 bits words into 8 bits * Unfortnatly that doesn't work for LSB so * reject these for now */ /* Note: 32 bits word, LSB works iff @@ -216,9 +216,11 @@ static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs, if (spi->mode & SPI_LSB_FIRST && bits_per_word > 8) return -EINVAL; - if (bits_per_word > 8) + if (bits_per_word <= 8) + return bits_per_word; + if (bits_per_word == 16 || bits_per_word == 32) return 8; /* pretend its 8 bits */ - return bits_per_word; + return -EINVAL; }
static int fsl_spi_setup_transfer(struct spi_device *spi, @@ -248,7 +250,7 @@ static int fsl_spi_setup_transfer(struct spi_device *spi, bits_per_word = mspi_apply_cpu_mode_quirks(cs, spi, mpc8xxx_spi, bits_per_word); - else if (mpc8xxx_spi->flags & SPI_QE) + else bits_per_word = mspi_apply_qe_mode_quirks(cs, spi, bits_per_word);
From: Dae R. Jeong threeearcat@gmail.com
[ Upstream commit ae13381da5ff0e8e084c0323c3cc0a945e43e9c7 ]
During fuzzing, a general protection fault is observed in vmci_host_poll().
general protection fault, probably for non-canonical address 0xdffffc0000000019: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x00000000000000c8-0x00000000000000cf] RIP: 0010:__lock_acquire+0xf3/0x5e00 kernel/locking/lockdep.c:4926 <- omitting registers -> Call Trace: <TASK> lock_acquire+0x1a4/0x4a0 kernel/locking/lockdep.c:5672 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0xb3/0x100 kernel/locking/spinlock.c:162 add_wait_queue+0x3d/0x260 kernel/sched/wait.c:22 poll_wait include/linux/poll.h:49 [inline] vmci_host_poll+0xf8/0x2b0 drivers/misc/vmw_vmci/vmci_host.c:174 vfs_poll include/linux/poll.h:88 [inline] do_pollfd fs/select.c:873 [inline] do_poll fs/select.c:921 [inline] do_sys_poll+0xc7c/0x1aa0 fs/select.c:1015 __do_sys_ppoll fs/select.c:1121 [inline] __se_sys_ppoll+0x2cc/0x330 fs/select.c:1101 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x4e/0xa0 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x46/0xb0
Example thread interleaving that causes the general protection fault is as follows:
CPU1 (vmci_host_poll) CPU2 (vmci_host_do_init_context) ----- ----- // Read uninitialized context context = vmci_host_dev->context; // Initialize context vmci_host_dev->context = vmci_ctx_create(); vmci_host_dev->ct_type = VMCIOBJ_CONTEXT;
if (vmci_host_dev->ct_type == VMCIOBJ_CONTEXT) { // Dereferencing the wrong pointer poll_wait(..., &context->host_context); }
In this scenario, vmci_host_poll() reads vmci_host_dev->context first, and then reads vmci_host_dev->ct_type to check that vmci_host_dev->context is initialized. However, since these two reads are not atomically executed, there is a chance of a race condition as described above.
To fix this race condition, read vmci_host_dev->context after checking the value of vmci_host_dev->ct_type so that vmci_host_poll() always reads an initialized context.
Reported-by: Dae R. Jeong threeearcat@gmail.com Fixes: 8bf503991f87 ("VMCI: host side driver implementation.") Signed-off-by: Dae R. Jeong threeearcat@gmail.com Link: https://lore.kernel.org/r/ZCGFsdBAU4cYww5l@dragonet Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/misc/vmw_vmci/vmci_host.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c index 2d8328d928d53..4a903770b8e1d 100644 --- a/drivers/misc/vmw_vmci/vmci_host.c +++ b/drivers/misc/vmw_vmci/vmci_host.c @@ -165,10 +165,16 @@ static int vmci_host_close(struct inode *inode, struct file *filp) static __poll_t vmci_host_poll(struct file *filp, poll_table *wait) { struct vmci_host_dev *vmci_host_dev = filp->private_data; - struct vmci_ctx *context = vmci_host_dev->context; + struct vmci_ctx *context; __poll_t mask = 0;
if (vmci_host_dev->ct_type == VMCIOBJ_CONTEXT) { + /* + * Read context only if ct_type == VMCIOBJ_CONTEXT to make + * sure that context is initialized + */ + context = vmci_host_dev->context; + /* Check for VMCI calls to this VM context. */ if (wait) poll_wait(filp, &context->host_context.wait_queue,
From: Miquel Raynal miquel.raynal@bootlin.com
[ Upstream commit b19a4266c52de78496fe40f0b37580a3b762e67d ]
The helper generating an OF based modalias (of_device_get_modalias()) works fine, but due to the use of snprintf() internally it needs a buffer one byte longer than what should be needed just for the entire string (excluding the '\0'). Most users of this helper are sysfs hooks providing the modalias string to users. They all provide a PAGE_SIZE buffer which is way above the number of bytes required to fit the modalias string and hence do not suffer from this issue.
There is another user though, of_device_request_module(), which is only called by drivers/usb/common/ulpi.c. This request module function is faulty, but maybe because in most cases there is an alternative, ULPI driver users have not noticed it.
In this function, of_device_get_modalias() is called twice. The first time without buffer just to get the number of bytes required by the modalias string (excluding the null byte), and a second time, after buffer allocation, to fill the buffer. The allocation asks for an additional byte, in order to store the trailing '\0'. However, the buffer *length* provided to of_device_get_modalias() excludes this extra byte. The internal use of snprintf() with a length that is exactly the number of bytes to be written has the effect of using the last available byte to store a '\0', which then smashes the last character of the modalias string.
Provide the actual size of the buffer to of_device_get_modalias() to fix this issue.
Note: the "str[size - 1] = '\0';" line is not really needed as snprintf will anyway end the string with a null byte, but there is a possibility that this function might be called on a struct device_node without compatible, in this case snprintf() would not be executed. So we keep it just to avoid possible unbounded strings.
Cc: Stephen Boyd sboyd@kernel.org Cc: Peter Chen peter.chen@kernel.org Fixes: 9c829c097f2f ("of: device: Support loading a module with OF based modalias") Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Reviewed-by: Rob Herring robh@kernel.org Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20230404172148.82422-2-srinivas.kandagatla@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/device.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/of/device.c b/drivers/of/device.c index 1122daa8e2736..3a547793135c3 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -264,12 +264,15 @@ int of_device_request_module(struct device *dev) if (size < 0) return size;
- str = kmalloc(size + 1, GFP_KERNEL); + /* Reserve an additional byte for the trailing '\0' */ + size++; + + str = kmalloc(size, GFP_KERNEL); if (!str) return -ENOMEM;
of_device_get_modalias(dev, str, size); - str[size] = '\0'; + str[size - 1] = '\0'; ret = request_module(str); kfree(str);
From: Kuppuswamy Sathyanarayanan sathyanarayanan.kuppuswamy@linux.intel.com
[ Upstream commit c441b1e03da6c680a3e12da59c554f454f2ccf5e ]
During EDR recovery, the OS must clear error status of the port that triggered DPC even if firmware retains control of DPC and AER (see the implementation note in the PCI Firmware spec r3.3, sec 4.6.12).
Prior to 068c29a248b6 ("PCI/ERR: Clear PCIe Device Status errors only if OS owns AER"), the port Device Status was cleared in this path:
edr_handle_event dpc_process_error(dev) # "dev" triggered DPC pcie_do_recovery(dev, dpc_reset_link) dpc_reset_link # exit DPC pcie_clear_device_status(dev) # clear Device Status
After 068c29a248b6, pcie_do_recovery() no longer clears Device Status when firmware controls AER, so the error bit remains set even after recovery.
Per the "Downstream Port Containment configuration control" bit in the returned _OSC Control Field (sec 4.5.1), the OS is allowed to clear error status until it evaluates _OST, so clear Device Status in edr_handle_event() if the error recovery was successful.
[bhelgaas: commit log] Fixes: 068c29a248b6 ("PCI/ERR: Clear PCIe Device Status errors only if OS owns AER") Link: https://lore.kernel.org/r/20230315235449.1279209-1-sathyanarayanan.kuppuswam... Reported-by: Tsaur Erwin erwin.tsaur@intel.com Signed-off-by: Kuppuswamy Sathyanarayanan sathyanarayanan.kuppuswamy@linux.intel.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pcie/edr.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pci/pcie/edr.c b/drivers/pci/pcie/edr.c index a6b9b479b97ad..87734e4c3c204 100644 --- a/drivers/pci/pcie/edr.c +++ b/drivers/pci/pcie/edr.c @@ -193,6 +193,7 @@ static void edr_handle_event(acpi_handle handle, u32 event, void *data) */ if (estate == PCI_ERS_RESULT_RECOVERED) { pci_dbg(edev, "DPC port successfully recovered\n"); + pcie_clear_device_status(edev); acpi_send_edr_status(pdev, edev, EDR_OST_SUCCESS); } else { pci_dbg(edev, "DPC port recovery failed\n");
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 58deeb4ef3b054498747d0929d94ac53ab90981f ]
alloc_per_cpu_data() is called by find_memory(), which is marked as __init. Therefore alloc_per_cpu_data() can also be marked as __init to remedy this modpost problem.
WARNING: modpost: vmlinux.o: section mismatch in reference: alloc_per_cpu_data (section: .text) -> memblock_alloc_try_nid (section: .init.text)
Link: https://lkml.kernel.org/r/20230223034258.12917-1-rdunlap@infradead.org Fixes: 4b9ddc7cf272 ("[IA64] Fix section mismatch in contig.c version of per_cpu_init()") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Christoph Hellwig hch@lst.de Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/ia64/mm/contig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index e30e360beef84..c638e012ad051 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c @@ -79,7 +79,7 @@ void *per_cpu_init(void) return __per_cpu_start + __per_cpu_offset[smp_processor_id()]; }
-static inline void +static inline __init void alloc_per_cpu_data(void) { size_t size = PERCPU_PAGE_SIZE * num_possible_cpus();
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 0de155752b152d6bcd96b5b5bf20af336abd183a ]
When CONFIG_PROC_FS is not set, proc_salinfo_show() is not used. Mark the function as __maybe_unused to quieten the warning message.
../arch/ia64/kernel/salinfo.c:584:12: warning: 'proc_salinfo_show' defined but not used [-Wunused-function] 584 | static int proc_salinfo_show(struct seq_file *m, void *v) | ^~~~~~~~~~~~~~~~~
Link: https://lkml.kernel.org/r/20230223034309.13375-1-rdunlap@infradead.org Fixes: 3f3942aca6da ("proc: introduce proc_create_single{,_data}") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Christoph Hellwig hch@lst.de Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/ia64/kernel/salinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index a25ab9b37953e..bb99b543dc672 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c @@ -581,7 +581,7 @@ static int salinfo_cpu_pre_down(unsigned int cpu) * 'data' contains an integer that corresponds to the feature we're * testing */ -static int proc_salinfo_show(struct seq_file *m, void *v) +static int __maybe_unused proc_salinfo_show(struct seq_file *m, void *v) { unsigned long data = (unsigned long)v; seq_puts(m, (sal_platform_features & data) ? "1\n" : "0\n");
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit 1d7adbc74c009057ed9dc3112f388e91a9c79acc ]
Avoid generating an exception if there are no clocks registered:
(gdb) lx-clk-summary enable prepare protect clock count count count rate ------------------------------------------------------------------------ Python Exception <class 'gdb.error'>: No symbol "clk_root_list" in current context. Error occurred in Python: No symbol "clk_root_list" in current context.
Link: https://lkml.kernel.org/r/20230323225246.3302977-1-f.fainelli@gmail.com Fixes: d1e9710b63d8 ("scripts/gdb: initial clk support: lx-clk-summary") Signed-off-by: Florian Fainelli f.fainelli@gmail.com Cc: Jan Kiszka jan.kiszka@siemens.com Cc: Kieran Bingham kbingham@kernel.org Cc: Leonard Crestez leonard.crestez@nxp.com Cc: Stephen Boyd sboyd@kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/gdb/linux/clk.py | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/scripts/gdb/linux/clk.py b/scripts/gdb/linux/clk.py index 061aecfa294e6..7a01fdc3e8446 100644 --- a/scripts/gdb/linux/clk.py +++ b/scripts/gdb/linux/clk.py @@ -41,6 +41,8 @@ are cached and potentially out of date""" self.show_subtree(child, level + 1)
def invoke(self, arg, from_tty): + if utils.gdb_eval_or_none("clk_root_list") is None: + raise gdb.GdbError("No clocks registered") gdb.write(" enable prepare protect \n") gdb.write(" clock count count count rate \n") gdb.write("------------------------------------------------------------------------\n")
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit f19c3c2959e465209ade1a7a699e6cbf4359ce78 ]
Avoid generating an exception if there are no generic power domain(s) registered:
(gdb) lx-genpd-summary domain status children /device runtime status ---------------------------------------------------------------------- Python Exception <class 'gdb.error'>: No symbol "gpd_list" in current context. Error occurred in Python: No symbol "gpd_list" in current context. (gdb) quit
[f.fainelli@gmail.com: correctly invoke gdb_eval_or_none] Link: https://lkml.kernel.org/r/20230327185746.3856407-1-f.fainelli@gmail.com Link: https://lkml.kernel.org/r/20230323231659.3319941-1-f.fainelli@gmail.com Fixes: 8207d4a88e1e ("scripts/gdb: add lx-genpd-summary command") Signed-off-by: Florian Fainelli f.fainelli@gmail.com Cc: Jan Kiszka jan.kiszka@siemens.com Cc: Kieran Bingham kbingham@kernel.org Cc: Leonard Crestez leonard.crestez@nxp.com Cc: Stephen Boyd sboyd@kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/gdb/linux/genpd.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/scripts/gdb/linux/genpd.py b/scripts/gdb/linux/genpd.py index 39cd1abd85590..b53649c0a77a6 100644 --- a/scripts/gdb/linux/genpd.py +++ b/scripts/gdb/linux/genpd.py @@ -5,7 +5,7 @@ import gdb import sys
-from linux.utils import CachedType +from linux.utils import CachedType, gdb_eval_or_none from linux.lists import list_for_each_entry
generic_pm_domain_type = CachedType('struct generic_pm_domain') @@ -70,6 +70,8 @@ Output is similar to /sys/kernel/debug/pm_genpd/pm_genpd_summary''' gdb.write(' %-50s %s\n' % (kobj_path, rtpm_status_str(dev)))
def invoke(self, arg, from_tty): + if gdb_eval_or_none("&gpd_list") is None: + raise gdb.GdbError("No power domain(s) registered") gdb.write('domain status children\n'); gdb.write(' /device runtime status\n'); gdb.write('----------------------------------------------------------------------\n');
From: Suzuki K Poulose suzuki.poulose@arm.com
[ Upstream commit 18996a113f2567aef3057e300e3193ce2df1684c ]
struct pmu::module must be set to the module owning the PMU driver. Set this for the coresight etm_pmu.
Fixes: 8e264c52e1dab ("coresight: core: Allow the coresight core driver to be built as a module") Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Link: https://lore.kernel.org/r/20230405094922.667834-1-suzuki.poulose@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwtracing/coresight/coresight-etm-perf.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index bdc34ca449f71..c5698c62b6103 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -619,6 +619,7 @@ int __init etm_perf_init(void) etm_pmu.addr_filters_sync = etm_addr_filters_sync; etm_pmu.addr_filters_validate = etm_addr_filters_validate; etm_pmu.nr_addr_filters = ETM_ADDR_CMP_MAX; + etm_pmu.module = THIS_MODULE;
ret = perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1); if (ret == 0)
From: Liliang Ye yll@hust.edu.cn
[ Upstream commit 1c34890273a020d61d6127ade3f68ed1cb21c16a ]
of_node_put() should have been done directly after mqs_priv->regmap = syscon_node_to_regmap(gpr_np); otherwise it creates a reference leak on the success path.
To fix this, of_node_put() is moved to the correct location, and change all the gotos to direct returns.
Fixes: a9d273671440 ("ASoC: fsl_mqs: Fix error handling in probe") Signed-off-by: Liliang Ye yll@hust.edu.cn Reviewed-by: Dan Carpenter error27@gmail.com Link: https://lore.kernel.org/r/20230403152647.17638-1-yll@hust.edu.cn Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/fsl_mqs.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c index 0d4efbed41dab..c33439650823b 100644 --- a/sound/soc/fsl/fsl_mqs.c +++ b/sound/soc/fsl/fsl_mqs.c @@ -204,10 +204,10 @@ static int fsl_mqs_probe(struct platform_device *pdev) }
mqs_priv->regmap = syscon_node_to_regmap(gpr_np); + of_node_put(gpr_np); if (IS_ERR(mqs_priv->regmap)) { dev_err(&pdev->dev, "failed to get gpr regmap\n"); - ret = PTR_ERR(mqs_priv->regmap); - goto err_free_gpr_np; + return PTR_ERR(mqs_priv->regmap); } } else { regs = devm_platform_ioremap_resource(pdev, 0); @@ -236,8 +236,7 @@ static int fsl_mqs_probe(struct platform_device *pdev) if (IS_ERR(mqs_priv->mclk)) { dev_err(&pdev->dev, "failed to get the clock: %ld\n", PTR_ERR(mqs_priv->mclk)); - ret = PTR_ERR(mqs_priv->mclk); - goto err_free_gpr_np; + return PTR_ERR(mqs_priv->mclk); }
dev_set_drvdata(&pdev->dev, mqs_priv); @@ -246,13 +245,9 @@ static int fsl_mqs_probe(struct platform_device *pdev) ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_fsl_mqs, &fsl_mqs_dai, 1); if (ret) - goto err_free_gpr_np; - return 0; - -err_free_gpr_np: - of_node_put(gpr_np); + return ret;
- return ret; + return 0; }
static int fsl_mqs_remove(struct platform_device *pdev)
From: Dhruva Gole d-gole@ti.com
[ Upstream commit 2087e85bb66ee3652dafe732bb9b9b896229eafc ]
The cadence QSPI driver misbehaves after performing a full system suspend resume: ... spi-nor spi0.0: resume() failed ... This results in a flash connected via OSPI interface after system suspend- resume to be unusable. fix these suspend and resume functions.
Fixes: 140623410536 ("mtd: spi-nor: Add driver for Cadence Quad SPI Flash Controller") Signed-off-by: Dhruva Gole d-gole@ti.com Link: https://lore.kernel.org/r/20230417091027.966146-3-d-gole@ti.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-cadence-quadspi.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 2e1255bf1b429..23d50a19ae271 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1355,17 +1355,30 @@ static int cqspi_remove(struct platform_device *pdev) static int cqspi_suspend(struct device *dev) { struct cqspi_st *cqspi = dev_get_drvdata(dev); + struct spi_master *master = dev_get_drvdata(dev); + int ret;
+ ret = spi_master_suspend(master); cqspi_controller_enable(cqspi, 0); - return 0; + + clk_disable_unprepare(cqspi->clk); + + return ret; }
static int cqspi_resume(struct device *dev) { struct cqspi_st *cqspi = dev_get_drvdata(dev); + struct spi_master *master = dev_get_drvdata(dev);
- cqspi_controller_enable(cqspi, 1); - return 0; + clk_prepare_enable(cqspi->clk); + cqspi_wait_idle(cqspi); + cqspi_controller_init(cqspi); + + cqspi->current_cs = -1; + cqspi->sclk = 0; + + return spi_master_resume(master); }
static const struct dev_pm_ops cqspi__dev_pm_ops = {
From: Lars-Peter Clausen lars@metafoo.de
[ Upstream commit ae1664f04f504a998737f5bb563f16b44357bcca ]
The cdns_i2c_master_xfer() function gets a runtime PM reference when the function is entered. This reference is released when the function is exited. There is currently one error path where the function exits directly, which leads to a leak of the runtime PM reference.
Make sure that this error path also releases the runtime PM reference.
Fixes: 1a351b10b967 ("i2c: cadence: Added slave support") Signed-off-by: Lars-Peter Clausen lars@metafoo.de Reviewed-by: Michal Simek michal.simek@amd.com Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-cadence.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 50928216b3f28..24987902ca590 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -792,8 +792,10 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, #if IS_ENABLED(CONFIG_I2C_SLAVE) /* Check i2c operating mode and switch if possible */ if (id->dev_mode == CDNS_I2C_MODE_SLAVE) { - if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE) - return -EAGAIN; + if (id->slave_state != CDNS_I2C_SLAVE_STATE_IDLE) { + ret = -EAGAIN; + goto out; + }
/* Set mode to master */ cdns_i2c_set_mode(CDNS_I2C_MODE_MASTER, id);
From: Kevin Brodsky kevin.brodsky@arm.com
[ Upstream commit 31088f6f7906253ef4577f6a9b84e2d42447dba0 ]
typeof is (still) a GNU extension, which means that it cannot be used when building ISO C (e.g. -std=c99). It should therefore be avoided in uapi headers in favour of the ISO-friendly __typeof__.
Unfortunately this issue could not be detected by CONFIG_UAPI_HEADER_TEST=y as the __ALIGN_KERNEL() macro is not expanded in any uapi header.
This matters from a userspace perspective, not a kernel one. uapi headers and their contents are expected to be usable in a variety of situations, and in particular when building ISO C applications (with -std=c99 or similar).
This particular problem can be reproduced by trying to use the __ALIGN_KERNEL macro directly in application code, say:
#include <linux/const.h>
int align(int x, int a) { return __KERNEL_ALIGN(x, a); }
and trying to build that with -std=c99.
Link: https://lkml.kernel.org/r/20230411092747.3759032-1-kevin.brodsky@arm.com Fixes: a79ff731a1b2 ("netfilter: xtables: make XT_ALIGN() usable in exported headers by exporting __ALIGN_KERNEL()") Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com Reported-by: Ruben Ayrapetyan ruben.ayrapetyan@arm.com Tested-by: Ruben Ayrapetyan ruben.ayrapetyan@arm.com Reviewed-by: Petr Vorel pvorel@suse.cz Tested-by: Petr Vorel pvorel@suse.cz Reviewed-by: Masahiro Yamada masahiroy@kernel.org Cc: Sam Ravnborg sam@ravnborg.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/uapi/linux/const.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/uapi/linux/const.h b/include/uapi/linux/const.h index af2a44c08683d..a429381e7ca50 100644 --- a/include/uapi/linux/const.h +++ b/include/uapi/linux/const.h @@ -28,7 +28,7 @@ #define _BITUL(x) (_UL(1) << (x)) #define _BITULL(x) (_ULL(1) << (x))
-#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) +#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (__typeof__(x))(a) - 1) #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
From: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de
[ Upstream commit 80f746e2bd0e1da3fdb49a53570e54a1a225faac ]
The Store Queue code allocates a bitmap buffer with the size of multiple of sizeof(long) in sq_api_init(). While the buffer size is calculated correctly, the code uses the wrong element size to allocate the buffer which results in the allocated bitmap buffer being too small.
Fix this by allocating the buffer with kcalloc() with element size sizeof(long) instead of kzalloc() whose elements size defaults to sizeof(char).
Fixes: d7c30c682a27 ("sh: Store Queue API rework.") Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Link: https://lore.kernel.org/r/20230419114854.528677-1-glaubitz@physik.fu-berlin.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/sh/kernel/cpu/sh4/sq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index d432164b23b7c..c31ec0fea3003 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -381,7 +381,7 @@ static int __init sq_api_init(void) if (unlikely(!sq_cache)) return ret;
- sq_bitmap = kzalloc(size, GFP_KERNEL); + sq_bitmap = kcalloc(size, sizeof(long), GFP_KERNEL); if (unlikely(!sq_bitmap)) goto out;
From: Jon Hunter jonathanh@nvidia.com
[ Upstream commit 5629d31955297ca47b9283c64fff70f2f34aa528 ]
Commit ac82b56bda5f ("usb: gadget: tegra-xudc: Add vbus_draw support") populated the vbus_draw callback for the Tegra XUDC driver. The function tegra_xudc_gadget_vbus_draw(), that was added by this commit, assumes that the pointer 'curr_usbphy' has been initialised, which is not always the case because this is only initialised when the USB role is updated. Fix this crash, by checking that the 'curr_usbphy' is valid before dereferencing.
Fixes: ac82b56bda5f ("usb: gadget: tegra-xudc: Add vbus_draw support") Reviewed-by: Thierry Reding treding@nvidia.com Signed-off-by: Jon Hunter jonathanh@nvidia.com Link: https://lore.kernel.org/r/20230405181854.42355-1-jonathanh@nvidia.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 3ebc8c5416e30..66d5f6a85c848 100644 --- a/drivers/usb/gadget/udc/tegra-xudc.c +++ b/drivers/usb/gadget/udc/tegra-xudc.c @@ -2154,7 +2154,7 @@ static int tegra_xudc_gadget_vbus_draw(struct usb_gadget *gadget,
dev_dbg(xudc->dev, "%s: %u mA\n", __func__, m_a);
- if (xudc->curr_usbphy->chg_type == SDP_TYPE) + if (xudc->curr_usbphy && xudc->curr_usbphy->chg_type == SDP_TYPE) ret = usb_phy_set_power(xudc->curr_usbphy, m_a);
return ret;
From: Yinhao Hu dddddd@hust.edu.cn
[ Upstream commit d6f712f53b79f5017cdcefafb7a5aea9ec52da5d ]
From the comment of ci_usb_phy_init, it returns an error code if
usb_phy_init has failed, and it should do some clean up, not just return directly.
Fix this by goto the error handling.
Fixes: 74475ede784d ("usb: chipidea: move PHY operation to core") Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Acked-by: Peter Chen peter.chen@kernel.org Signed-off-by: Yinhao Hu dddddd@hust.edu.cn Link: https://lore.kernel.org/r/20230412055852.971991-1-dddddd@hust.edu.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/chipidea/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index f26dd1f054f21..3d18599c5b9e4 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -1090,7 +1090,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) ret = ci_usb_phy_init(ci); if (ret) { dev_err(dev, "unable to init phy: %d\n", ret); - return ret; + goto ulpi_exit; }
ci->hw_bank.phys = res->start;
From: Chunfeng Yun chunfeng.yun@mediatek.com
[ Upstream commit d28f4091ea7ec3510fd6a3c6d433234e7a2bef14 ]
When handle qmu transfer irq, it will unlock @mtu->lock before give back request, if another thread handle disconnect event at the same time, and try to disable ep, it may lock @mtu->lock and free qmu ring, then qmu irq hanlder may get a NULL gpd, avoid the KE by checking gpd's value before handling it.
e.g. qmu done irq on cpu0 thread running on cpu1
qmu_done_tx() handle gpd [0] mtu3_requ_complete() mtu3_gadget_ep_disable() unlock @mtu->lock give back request lock @mtu->lock mtu3_ep_disable() mtu3_gpd_ring_free() unlock @mtu->lock lock @mtu->lock get next gpd [1]
[1]: goto [0] to handle next gpd, and next gpd may be NULL.
Fixes: 48e0d3735aa5 ("usb: mtu3: supports new QMU format") Signed-off-by: Chunfeng Yun chunfeng.yun@mediatek.com Link: https://lore.kernel.org/r/20230417025203.18097-3-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/mtu3/mtu3_qmu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/mtu3/mtu3_qmu.c b/drivers/usb/mtu3/mtu3_qmu.c index 2ea3157ddb6e2..e65586147965d 100644 --- a/drivers/usb/mtu3/mtu3_qmu.c +++ b/drivers/usb/mtu3/mtu3_qmu.c @@ -210,6 +210,7 @@ static struct qmu_gpd *advance_enq_gpd(struct mtu3_gpd_ring *ring) return ring->enqueue; }
+/* @dequeue may be NULL if ring is unallocated or freed */ static struct qmu_gpd *advance_deq_gpd(struct mtu3_gpd_ring *ring) { if (ring->dequeue < ring->end) @@ -484,7 +485,7 @@ static void qmu_done_tx(struct mtu3 *mtu, u8 epnum) dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n", __func__, epnum, gpd, gpd_current, ring->enqueue);
- while (gpd != gpd_current && !GET_GPD_HWO(gpd)) { + while (gpd && gpd != gpd_current && !GET_GPD_HWO(gpd)) {
mreq = next_request(mep);
@@ -523,7 +524,7 @@ static void qmu_done_rx(struct mtu3 *mtu, u8 epnum) dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n", __func__, epnum, gpd, gpd_current, ring->enqueue);
- while (gpd != gpd_current && !GET_GPD_HWO(gpd)) { + while (gpd && gpd != gpd_current && !GET_GPD_HWO(gpd)) {
mreq = next_request(mep);
From: Dan Carpenter dan.carpenter@linaro.org
[ Upstream commit e1d6ca042e62c2a69513235f8629eb6e62ca79c5 ]
The svc_create_memory_pool() function returns error pointers. It never returns NULL. Fix the check.
Fixes: 7ca5ce896524 ("firmware: add Intel Stratix10 service layer driver") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Link: https://lore.kernel.org/r/5f9a8cb4-5a4f-460b-9cdc-2fae6c5b7922@kili.mountain Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/stratix10-svc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c index 7dd0ac1a0cfc7..78a446cb43486 100644 --- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -989,8 +989,8 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) return ret;
genpool = svc_create_memory_pool(pdev, sh_memory); - if (!genpool) - return -ENOMEM; + if (IS_ERR(genpool)) + return PTR_ERR(genpool);
/* allocate service controller and supporting channel */ controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL);
From: Shenwei Wang shenwei.wang@nxp.com
[ Upstream commit f73fd750552524b06b5d77ebfdd106ccc8fcac61 ]
Based on the fls function definition provided below, we should not subtract 1 to obtain the correct buffer length:
fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
Fixes: 5887ad43ee02 ("tty: serial: fsl_lpuart: Use cyclic DMA for Rx") Signed-off-by: Shenwei Wang shenwei.wang@nxp.com Link: https://lore.kernel.org/r/20230410195555.1003900-1-shenwei.wang@nxp.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/fsl_lpuart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index f481c260b7049..a2efa81471f30 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1220,7 +1220,7 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport) * 10ms at any baud rate. */ sport->rx_dma_rng_buf_len = (DMA_RX_TIMEOUT * baud / bits / 1000) * 2; - sport->rx_dma_rng_buf_len = (1 << (fls(sport->rx_dma_rng_buf_len) - 1)); + sport->rx_dma_rng_buf_len = (1 << fls(sport->rx_dma_rng_buf_len)); if (sport->rx_dma_rng_buf_len < 16) sport->rx_dma_rng_buf_len = 16;
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit 0ba9e3a13c6adfa99e32b2576d20820ab10ad48a ]
An 8250 UART configured as a wake-up source would not have reported itself through sysfs as being the source of wake-up, correct that.
Fixes: b3b708fa2780 ("wake up from a serial port") Signed-off-by: Florian Fainelli f.fainelli@gmail.com Link: https://lore.kernel.org/r/20230414170241.2016255-1-f.fainelli@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_port.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 1f231fcda657b..1f9e4b87387b5 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -15,6 +15,7 @@ #include <linux/moduleparam.h> #include <linux/ioport.h> #include <linux/init.h> +#include <linux/irq.h> #include <linux/console.h> #include <linux/gpio/consumer.h> #include <linux/sysrq.h> @@ -1889,6 +1890,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) unsigned char status; unsigned long flags; struct uart_8250_port *up = up_to_u8250p(port); + struct tty_port *tport = &port->state->port; bool skip_rx = false;
if (iir & UART_IIR_NO_INT) @@ -1912,6 +1914,8 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) skip_rx = true;
if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { + if (irqd_is_wakeup_set(irq_get_irq_data(port->irq))) + pm_wakeup_event(tport->tty->dev, 0); if (!up->dma || handle_rx_dma(up, iir)) status = serial8250_rx_chars(up, status); }
From: Philipp Hortmann philipp.g.hortmann@gmail.com
[ Upstream commit 3fac2397f562eb669ddc2f45867a253f3fc26184 ]
When loading the driver for rtl8192e, the W_DISABLE# switch is working as intended. But when the WLAN is turned off in software and then turned on again the W_DISABLE# does not work anymore. Reason for this is that in the function _rtl92e_dm_check_rf_ctrl_gpio() the bfirst_after_down is checked and returned when true. bfirst_after_down is set true when switching the WLAN off in software. But it is not set to false again when WLAN is turned on again.
Add bfirst_after_down = false in _rtl92e_sta_up to reset bit and fix above described bug.
Fixes: 94a799425eee ("From: wlanfae wlanfae@realtek.com [PATCH 1/8] rtl8192e: Import new version of driver from realtek") Signed-off-by: Philipp Hortmann philipp.g.hortmann@gmail.com Link: https://lore.kernel.org/r/20230418200201.GA17398@matrix-ESPRIMO-P710 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 99c27d6b42333..291f98251f7f7 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -770,6 +770,7 @@ static int _rtl92e_sta_up(struct net_device *dev, bool is_silent_reset) else netif_wake_queue(dev);
+ priv->bfirst_after_down = false; return 0; }
From: Jishnu Prakash quic_jprakash@quicinc.com
[ Upstream commit b56eef3e16d888883fefab47425036de80dd38fc ]
When removing a SPMI driver, there can be a crash due to NULL pointer dereference if it does not have a remove callback defined. This is one such call trace observed when removing the QCOM SPMI PMIC driver:
dump_backtrace.cfi_jt+0x0/0x8 dump_stack_lvl+0xd8/0x16c panic+0x188/0x498 __cfi_slowpath+0x0/0x214 __cfi_slowpath+0x1dc/0x214 spmi_drv_remove+0x16c/0x1e0 device_release_driver_internal+0x468/0x79c driver_detach+0x11c/0x1a0 bus_remove_driver+0xc4/0x124 driver_unregister+0x58/0x84 cleanup_module+0x1c/0xc24 [qcom_spmi_pmic] __do_sys_delete_module+0x3ec/0x53c __arm64_sys_delete_module+0x18/0x28 el0_svc_common+0xdc/0x294 el0_svc+0x38/0x9c el0_sync_handler+0x8c/0xf0 el0_sync+0x1b4/0x1c0
If a driver has all its resources allocated through devm_() APIs and does not need any other explicit cleanup, it would not require a remove callback to be defined. Hence, add a check for remove callback presence before calling it when removing a SPMI driver.
Link: https://lore.kernel.org/r/1671601032-18397-2-git-send-email-quic_jprakash@qu... Fixes: 6f00f8c8635f ("mfd: qcom-spmi-pmic: Use devm_of_platform_populate()") Fixes: 5a86bf343976 ("spmi: Linux driver framework for SPMI") Signed-off-by: Jishnu Prakash quic_jprakash@quicinc.com Signed-off-by: Stephen Boyd sboyd@kernel.org Link: https://lore.kernel.org/r/20230413223834.4084793-7-sboyd@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spmi/spmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index c16b60f645a4d..8ca7e004a53dc 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -348,7 +348,8 @@ static int spmi_drv_remove(struct device *dev) const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
pm_runtime_get_sync(dev); - sdrv->remove(to_spmi_device(dev)); + if (sdrv->remove) + sdrv->remove(to_spmi_device(dev)); pm_runtime_put_noidle(dev);
pm_runtime_disable(dev);
From: Liang He windhl@126.com
[ Upstream commit 631cf002826007ab7415258ee647dcaf8845ad5a ]
We call of_node_get() in wf_sat_probe() after sat is created, so we need the of_node_put() before *kfree(sat)*.
Fixes: ac171c46667c ("[PATCH] powerpc: Thermal control for dual core G5s") Signed-off-by: Liang He windhl@126.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230330033558.2562778-1-windhl@126.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/macintosh/windfarm_smu_sat.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index e46e1153a0b43..7d7d6213e32aa 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -171,6 +171,7 @@ static void wf_sat_release(struct kref *ref)
if (sat->nr >= 0) sats[sat->nr] = NULL; + of_node_put(sat->node); kfree(sat); }
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 7538c97e2b80ff6b7a8ea2ecf16a04355461b439 ]
Use "%pa" format specifier for resource_size_t to avoid a compiler printk format warning.
../arch/powerpc/platforms/512x/clock-commonclk.c: In function 'mpc5121_clk_provide_backwards_compat': ../arch/powerpc/platforms/512x/clock-commonclk.c:989:44: error: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=] 989 | snprintf(devname, sizeof(devname), "%08x.%s", res.start, np->name); \ | ^~~~~~~~~ ~~~~~~~~~ | | | resource_size_t {aka long long unsigned int}
Prevents 24 such warnings.
Fixes: 01f25c371658 ("clk: mpc512x: add backwards compat to the CCF code") Signed-off-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230223070116.660-2-rdunlap@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/512x/clock-commonclk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c index 30342b60aa63f..42c3d40355d90 100644 --- a/arch/powerpc/platforms/512x/clock-commonclk.c +++ b/arch/powerpc/platforms/512x/clock-commonclk.c @@ -984,7 +984,7 @@ static void mpc5121_clk_provide_migration_support(void)
#define NODE_PREP do { \ of_address_to_resource(np, 0, &res); \ - snprintf(devname, sizeof(devname), "%08x.%s", res.start, np->name); \ + snprintf(devname, sizeof(devname), "%pa.%s", &res.start, np->name); \ } while (0)
#define NODE_CHK(clkname, clkitem, regnode, regflag) do { \
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 7b69600d4da0049244e9be2f5ef5a2f8e04fcd9a ]
Use "%pa" format specifier for resource_size_t to avoid compiler printk format warnings.
../arch/powerpc/platforms/embedded6xx/flipper-pic.c: In function 'flipper_pic_init': ../include/linux/kern_levels.h:5:25: error: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=] ../arch/powerpc/platforms/embedded6xx/flipper-pic.c:148:9: note: in expansion of macro 'pr_info' 148 | pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base); | ^~~~~~~
../arch/powerpc/platforms/embedded6xx/hlwd-pic.c: In function 'hlwd_pic_init': ../include/linux/kern_levels.h:5:25: error: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=] ../arch/powerpc/platforms/embedded6xx/hlwd-pic.c:174:9: note: in expansion of macro 'pr_info' 174 | pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base); | ^~~~~~~
../arch/powerpc/platforms/embedded6xx/wii.c: In function 'wii_ioremap_hw_regs': ../include/linux/kern_levels.h:5:25: error: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=] ../arch/powerpc/platforms/embedded6xx/wii.c:77:17: note: in expansion of macro 'pr_info' 77 | pr_info("%s at 0x%08x mapped to 0x%p\n", name, | ^~~~~~~
Fixes: 028ee972f032 ("powerpc: gamecube/wii: flipper interrupt controller support") Fixes: 9c21025c7845 ("powerpc: wii: hollywood interrupt controller support") Fixes: 5a7ee3198dfa ("powerpc: wii: platform support") Signed-off-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230223070116.660-3-rdunlap@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/embedded6xx/flipper-pic.c | 2 +- arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 2 +- arch/powerpc/platforms/embedded6xx/wii.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c index d39a9213a3e69..7dd2e2f97aae5 100644 --- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c @@ -144,7 +144,7 @@ static struct irq_domain * __init flipper_pic_init(struct device_node *np) } io_base = ioremap(res.start, resource_size(&res));
- pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base); + pr_info("controller at 0x%pa mapped to 0x%p\n", &res.start, io_base);
__flipper_quiesce(io_base);
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c index de10c13de15c6..c6b492ebb7662 100644 --- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c @@ -173,7 +173,7 @@ static struct irq_domain *hlwd_pic_init(struct device_node *np) return NULL; }
- pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base); + pr_info("controller at 0x%pa mapped to 0x%p\n", &res.start, io_base);
__hlwd_quiesce(io_base);
diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c index a802ef957d63e..458a63a30e803 100644 --- a/arch/powerpc/platforms/embedded6xx/wii.c +++ b/arch/powerpc/platforms/embedded6xx/wii.c @@ -89,8 +89,8 @@ static void __iomem *wii_ioremap_hw_regs(char *name, char *compatible)
hw_regs = ioremap(res.start, resource_size(&res)); if (hw_regs) { - pr_info("%s at 0x%08x mapped to 0x%p\n", name, - res.start, hw_regs); + pr_info("%s at 0x%pa mapped to 0x%p\n", name, + &res.start, hw_regs); }
out_put:
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 55d8bd02cc1b9f1063993b5c42c9cabf4af67dea ]
Use "%pa" format specifier for resource_size_t to avoid a compiler printk format warning.
arch/powerpc/sysdev/tsi108_pci.c: In function 'tsi108_setup_pci': include/linux/kern_levels.h:5:25: error: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'resource_size_t'
Fixes: c4342ff92bed ("[POWERPC] Update mpc7448hpc2 board irq support using device tree") Fixes: 2b9d7467a6db ("[POWERPC] Add tsi108 pci and platform device data register function") Signed-off-by: Randy Dunlap rdunlap@infradead.org [mpe: Use pr_info() and unsplit string] Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230223070116.660-5-rdunlap@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/sysdev/tsi108_pci.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 49f9541954f8d..3664ffcbb313c 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c @@ -216,9 +216,8 @@ int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary)
(hose)->ops = &tsi108_direct_pci_ops;
- printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. " - "Firmware bus number: %d->%d\n", - rsrc.start, hose->first_busno, hose->last_busno); + pr_info("Found tsi108 PCI host bridge at 0x%pa. Firmware bus number: %d->%d\n", + &rsrc.start, hose->first_busno, hose->last_busno);
/* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 05dce4ba125336875cd3eed3c1503fa81cd2f691 ]
LEDS_TRIGGER_DISK depends on ATA, so selecting LEDS_TRIGGER_DISK when ATA is not set/enabled causes a Kconfig warning:
WARNING: unmet direct dependencies detected for LEDS_TRIGGER_DISK Depends on [n]: NEW_LEDS [=y] && LEDS_TRIGGERS [=y] && ATA [=n] Selected by [y]: - ADB_PMU_LED_DISK [=y] && MACINTOSH_DRIVERS [=y] && ADB_PMU_LED [=y] && LEDS_CLASS [=y]
Fix this by making ADB_PMU_LED_DISK depend on ATA.
Seen on both PPC32 and PPC64.
Fixes: 0e865a80c135 ("macintosh: Remove dependency on IDE_GD_ATA if ADB_PMU_LED_DISK is selected") Signed-off-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230223014241.20878-1-rdunlap@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/macintosh/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 539a2ed4e13dc..a0e717a986dcb 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -86,6 +86,7 @@ config ADB_PMU_LED
config ADB_PMU_LED_DISK bool "Use front LED as DISK LED by default" + depends on ATA depends on ADB_PMU_LED depends on LEDS_CLASS select LEDS_TRIGGERS
From: Nathan Lynch nathanl@linux.ibm.com
[ Upstream commit 271208ee5e335cb1ad280d22784940daf7ddf820 ]
Using memcpy() isn't safe when buf is identical to rtas_err_buf, which can happen during boot before slab is up. Full context which may not be obvious from the diff:
if (altbuf) { buf = altbuf; } else { buf = rtas_err_buf; if (slab_is_available()) buf = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC); } if (buf) memcpy(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX);
This was found by inspection and I'm not aware of it causing problems in practice. It appears to have been introduced by commit 033ef338b6e0 ("powerpc: Merge rtas.c into arch/powerpc/kernel"); the old ppc64 version of this code did not have this problem.
Use memmove() instead.
Fixes: 033ef338b6e0 ("powerpc: Merge rtas.c into arch/powerpc/kernel") Signed-off-by: Nathan Lynch nathanl@linux.ibm.com Reviewed-by: Andrew Donnellan ajd@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230220-rtas-queue-for-6-4-v1-2-010e4416f13f@linux.ibm.c... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/rtas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index c2e407a112a28..5976a25c6264d 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -399,7 +399,7 @@ static char *__fetch_rtas_last_error(char *altbuf) buf = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC); } if (buf) - memcpy(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX); + memmove(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX); }
return buf;
From: Yang Jihong yangjihong1@huawei.com
[ Upstream commit 15def34e2635ab7e0e96f1bc32e1b69609f14942 ]
commit e050e3f0a71bf ("perf: Fix broken interrupt rate throttling") introduces a change in throttling threshold judgment. Before this, compare hwc->interrupts and max_samples_per_tick, then increase hwc->interrupts by 1, but this commit reverses order of these two behaviors, causing the semantics of max_samples_per_tick to change. In literal sense of "max_samples_per_tick", if hwc->interrupts == max_samples_per_tick, it should not be throttled, therefore, the judgment condition should be changed to "hwc->interrupts > max_samples_per_tick".
In fact, this may cause the hardlockup to fail, The minimum value of max_samples_per_tick may be 1, in this case, the return value of __perf_event_account_interrupt function is 1. As a result, nmi_watchdog gets throttled, which would stop PMU (Use x86 architecture as an example, see x86_pmu_handle_irq).
Fixes: e050e3f0a71b ("perf: Fix broken interrupt rate throttling") Signed-off-by: Yang Jihong yangjihong1@huawei.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20230227023508.102230-1-yangjihong1@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/events/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/events/core.c b/kernel/events/core.c index f0df3bc0e6415..53f36bbaf0c66 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -8925,8 +8925,8 @@ __perf_event_account_interrupt(struct perf_event *event, int throttle) hwc->interrupts = 1; } else { hwc->interrupts++; - if (unlikely(throttle - && hwc->interrupts >= max_samples_per_tick)) { + if (unlikely(throttle && + hwc->interrupts > max_samples_per_tick)) { __this_cpu_inc(perf_throttled_count); tick_dep_set_cpu(smp_processor_id(), TICK_DEP_BIT_PERF_EVENTS); hwc->interrupts = MAX_INTERRUPTS;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 1bd8e27fd0db0fe7f489213836dcbab92934f8fa ]
sam9x60_frac_pll_compute_mul_frac() can't return zero. Remove the check against zero to reflect this.
Fixes: 43b1bb4a9b3e ("clk: at91: clk-sam9x60-pll: re-factor to support plls with multiple outputs") Reported-by: Dan Carpenter error27@gmail.com Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230227105931.2812412-1-claudiu.beznea@microchip.... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/at91/clk-sam9x60-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c index 5a9daa3643a72..5fe50ba173a80 100644 --- a/drivers/clk/at91/clk-sam9x60-pll.c +++ b/drivers/clk/at91/clk-sam9x60-pll.c @@ -452,7 +452,7 @@ sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
ret = sam9x60_frac_pll_compute_mul_frac(&frac->core, FCORE_MIN, parent_rate, true); - if (ret <= 0) { + if (ret < 0) { hw = ERR_PTR(ret); goto free; }
From: Daniil Dulov d.dulov@aladdin.ru
[ Upstream commit 271bfcfb83a9f77cbae3d6e1a16e3c14132922f0 ]
When seg is equal to MAX_ARRAY, the loop should break, otherwise it will result in out of range access.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: b9be6f18cf9e ("rdma/siw: transmit path") Signed-off-by: Daniil Dulov d.dulov@aladdin.ru Link: https://lore.kernel.org/r/20230227091751.589612-1-d.dulov@aladdin.ru Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/siw/siw_qp_tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c index df8802b4981cf..ccc6d5bb1a276 100644 --- a/drivers/infiniband/sw/siw/siw_qp_tx.c +++ b/drivers/infiniband/sw/siw/siw_qp_tx.c @@ -548,7 +548,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s) data_len -= plen; fp_off = 0;
- if (++seg > (int)MAX_ARRAY) { + if (++seg >= (int)MAX_ARRAY) { siw_dbg_qp(tx_qp(c_tx), "to many fragments\n"); siw_unmap_pages(page_array, kmap_mask); wqe->processed -= c_tx->bytes_unsent;
From: Natalia Petrova n.petrova@fintech.ru
[ Upstream commit b73a0b80c69de77d8d4942abb37066531c0169b2 ]
There is no need to check 'rdi->qp_dev' for NULL. The field 'qp_dev' is created in rvt_register_device() which will fail if the 'qp_dev' allocation fails in rvt_driver_qp_init(). Overwise this pointer doesn't changed and passed to rvt_qp_exit() by the next step.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 0acb0cc7ecc1 ("IB/rdmavt: Initialize and teardown of qpn table") Signed-off-by: Natalia Petrova n.petrova@fintech.ru Link: https://lore.kernel.org/r/20230303124408.16685-1-n.petrova@fintech.ru Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rdmavt/qp.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c index 585a9c76e5183..ddc8825d526e0 100644 --- a/drivers/infiniband/sw/rdmavt/qp.c +++ b/drivers/infiniband/sw/rdmavt/qp.c @@ -505,8 +505,6 @@ void rvt_qp_exit(struct rvt_dev_info *rdi) if (qps_inuse) rvt_pr_err(rdi, "QP memory leak! %u still in use\n", qps_inuse); - if (!rdi->qp_dev) - return;
kfree(rdi->qp_dev->qp_table); free_qpn_table(&rdi->qp_dev->qpn_table);
From: Lai Jiangshan laijs@linux.alibaba.com
[ Upstream commit f97a4a1a3f8769e3452885967955e21c88f3f263 ]
There are two kinds of "delayed" work items in workqueue subsystem.
One is for timer-delayed work items which are visible to workqueue users. The other kind is for work items delayed by active management which can not be directly visible to workqueue users. We mixed the word "delayed" for both kinds and caused somewhat ambiguity.
This patch renames the later one (delayed by active management) to "inactive", because it is used for workqueue active management and most of its related symbols are named with "active" or "activate".
All "delayed" and "DELAYED" are carefully checked and renamed one by one to avoid accidentally changing the name of the other kind for timer-delayed.
No functional change intended.
Signed-off-by: Lai Jiangshan laijs@linux.alibaba.com Signed-off-by: Tejun Heo tj@kernel.org Stable-dep-of: 335a42ebb0ca ("workqueue: Fix hung time report of worker pools") Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/workqueue.h | 4 +-- kernel/workqueue.c | 58 +++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 26de0cae2a0a8..2fa9b311e5663 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -29,7 +29,7 @@ void delayed_work_timer_fn(struct timer_list *t);
enum { WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */ - WORK_STRUCT_DELAYED_BIT = 1, /* work item is delayed */ + WORK_STRUCT_INACTIVE_BIT= 1, /* work item is inactive */ WORK_STRUCT_PWQ_BIT = 2, /* data points to pwq */ WORK_STRUCT_LINKED_BIT = 3, /* next work is linked to this one */ #ifdef CONFIG_DEBUG_OBJECTS_WORK @@ -42,7 +42,7 @@ enum { WORK_STRUCT_COLOR_BITS = 4,
WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT, - WORK_STRUCT_DELAYED = 1 << WORK_STRUCT_DELAYED_BIT, + WORK_STRUCT_INACTIVE = 1 << WORK_STRUCT_INACTIVE_BIT, WORK_STRUCT_PWQ = 1 << WORK_STRUCT_PWQ_BIT, WORK_STRUCT_LINKED = 1 << WORK_STRUCT_LINKED_BIT, #ifdef CONFIG_DEBUG_OBJECTS_WORK diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 0cc2a62e88f9e..7f57fed719957 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -207,7 +207,7 @@ struct pool_workqueue { /* L: nr of in_flight works */ int nr_active; /* L: nr of active works */ int max_active; /* L: max active works */ - struct list_head delayed_works; /* L: delayed works */ + struct list_head inactive_works; /* L: inactive works */ struct list_head pwqs_node; /* WR: node on wq->pwqs */ struct list_head mayday_node; /* MD: node on wq->maydays */
@@ -1145,7 +1145,7 @@ static void put_pwq_unlocked(struct pool_workqueue *pwq) } }
-static void pwq_activate_delayed_work(struct work_struct *work) +static void pwq_activate_inactive_work(struct work_struct *work) { struct pool_workqueue *pwq = get_work_pwq(work);
@@ -1153,16 +1153,16 @@ static void pwq_activate_delayed_work(struct work_struct *work) if (list_empty(&pwq->pool->worklist)) pwq->pool->watchdog_ts = jiffies; move_linked_works(work, &pwq->pool->worklist, NULL); - __clear_bit(WORK_STRUCT_DELAYED_BIT, work_data_bits(work)); + __clear_bit(WORK_STRUCT_INACTIVE_BIT, work_data_bits(work)); pwq->nr_active++; }
-static void pwq_activate_first_delayed(struct pool_workqueue *pwq) +static void pwq_activate_first_inactive(struct pool_workqueue *pwq) { - struct work_struct *work = list_first_entry(&pwq->delayed_works, + struct work_struct *work = list_first_entry(&pwq->inactive_works, struct work_struct, entry);
- pwq_activate_delayed_work(work); + pwq_activate_inactive_work(work); }
/** @@ -1185,10 +1185,10 @@ static void pwq_dec_nr_in_flight(struct pool_workqueue *pwq, int color) pwq->nr_in_flight[color]--;
pwq->nr_active--; - if (!list_empty(&pwq->delayed_works)) { - /* one down, submit a delayed one */ + if (!list_empty(&pwq->inactive_works)) { + /* one down, submit an inactive one */ if (pwq->nr_active < pwq->max_active) - pwq_activate_first_delayed(pwq); + pwq_activate_first_inactive(pwq); }
/* is flush in progress and are we at the flushing tip? */ @@ -1290,14 +1290,14 @@ static int try_to_grab_pending(struct work_struct *work, bool is_dwork, debug_work_deactivate(work);
/* - * A delayed work item cannot be grabbed directly because + * An inactive work item cannot be grabbed directly because * it might have linked NO_COLOR work items which, if left - * on the delayed_list, will confuse pwq->nr_active + * on the inactive_works list, will confuse pwq->nr_active * management later on and cause stall. Make sure the work * item is activated before grabbing. */ - if (*work_data_bits(work) & WORK_STRUCT_DELAYED) - pwq_activate_delayed_work(work); + if (*work_data_bits(work) & WORK_STRUCT_INACTIVE) + pwq_activate_inactive_work(work);
list_del_init(&work->entry); pwq_dec_nr_in_flight(pwq, get_work_color(work)); @@ -1496,8 +1496,8 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, if (list_empty(worklist)) pwq->pool->watchdog_ts = jiffies; } else { - work_flags |= WORK_STRUCT_DELAYED; - worklist = &pwq->delayed_works; + work_flags |= WORK_STRUCT_INACTIVE; + worklist = &pwq->inactive_works; }
debug_work_activate(work); @@ -2534,7 +2534,7 @@ static int rescuer_thread(void *__rescuer) /* * The above execution of rescued work items could * have created more to rescue through - * pwq_activate_first_delayed() or chained + * pwq_activate_first_inactive() or chained * queueing. Let's put @pwq back on mayday list so * that such back-to-back work items, which may be * being used to relieve memory pressure, don't @@ -2960,7 +2960,7 @@ void drain_workqueue(struct workqueue_struct *wq) bool drained;
raw_spin_lock_irq(&pwq->pool->lock); - drained = !pwq->nr_active && list_empty(&pwq->delayed_works); + drained = !pwq->nr_active && list_empty(&pwq->inactive_works); raw_spin_unlock_irq(&pwq->pool->lock);
if (drained) @@ -3714,7 +3714,7 @@ static void pwq_unbound_release_workfn(struct work_struct *work) * @pwq: target pool_workqueue * * If @pwq isn't freezing, set @pwq->max_active to the associated - * workqueue's saved_max_active and activate delayed work items + * workqueue's saved_max_active and activate inactive work items * accordingly. If @pwq is freezing, clear @pwq->max_active to zero. */ static void pwq_adjust_max_active(struct pool_workqueue *pwq) @@ -3743,9 +3743,9 @@ static void pwq_adjust_max_active(struct pool_workqueue *pwq)
pwq->max_active = wq->saved_max_active;
- while (!list_empty(&pwq->delayed_works) && + while (!list_empty(&pwq->inactive_works) && pwq->nr_active < pwq->max_active) { - pwq_activate_first_delayed(pwq); + pwq_activate_first_inactive(pwq); kick = true; }
@@ -3776,7 +3776,7 @@ static void init_pwq(struct pool_workqueue *pwq, struct workqueue_struct *wq, pwq->wq = wq; pwq->flush_color = -1; pwq->refcnt = 1; - INIT_LIST_HEAD(&pwq->delayed_works); + INIT_LIST_HEAD(&pwq->inactive_works); INIT_LIST_HEAD(&pwq->pwqs_node); INIT_LIST_HEAD(&pwq->mayday_node); INIT_WORK(&pwq->unbound_release_work, pwq_unbound_release_workfn); @@ -4363,7 +4363,7 @@ static bool pwq_busy(struct pool_workqueue *pwq)
if ((pwq != pwq->wq->dfl_pwq) && (pwq->refcnt > 1)) return true; - if (pwq->nr_active || !list_empty(&pwq->delayed_works)) + if (pwq->nr_active || !list_empty(&pwq->inactive_works)) return true;
return false; @@ -4559,7 +4559,7 @@ bool workqueue_congested(int cpu, struct workqueue_struct *wq) else pwq = unbound_pwq_by_node(wq, cpu_to_node(cpu));
- ret = !list_empty(&pwq->delayed_works); + ret = !list_empty(&pwq->inactive_works); preempt_enable(); rcu_read_unlock();
@@ -4755,11 +4755,11 @@ static void show_pwq(struct pool_workqueue *pwq) pr_cont("\n"); }
- if (!list_empty(&pwq->delayed_works)) { + if (!list_empty(&pwq->inactive_works)) { bool comma = false;
- pr_info(" delayed:"); - list_for_each_entry(work, &pwq->delayed_works, entry) { + pr_info(" inactive:"); + list_for_each_entry(work, &pwq->inactive_works, entry) { pr_cont_work(comma, work); comma = !(*work_data_bits(work) & WORK_STRUCT_LINKED); } @@ -4789,7 +4789,7 @@ void show_workqueue_state(void) bool idle = true;
for_each_pwq(pwq, wq) { - if (pwq->nr_active || !list_empty(&pwq->delayed_works)) { + if (pwq->nr_active || !list_empty(&pwq->inactive_works)) { idle = false; break; } @@ -4801,7 +4801,7 @@ void show_workqueue_state(void)
for_each_pwq(pwq, wq) { raw_spin_lock_irqsave(&pwq->pool->lock, flags); - if (pwq->nr_active || !list_empty(&pwq->delayed_works)) + if (pwq->nr_active || !list_empty(&pwq->inactive_works)) show_pwq(pwq); raw_spin_unlock_irqrestore(&pwq->pool->lock, flags); /* @@ -5176,7 +5176,7 @@ EXPORT_SYMBOL_GPL(work_on_cpu_safe); * freeze_workqueues_begin - begin freezing workqueues * * Start freezing workqueues. After this function returns, all freezable - * workqueues will queue new works to their delayed_works list instead of + * workqueues will queue new works to their inactive_works list instead of * pool->worklist. * * CONTEXT:
From: Petr Mladek pmladek@suse.com
[ Upstream commit 335a42ebb0ca8ee9997a1731aaaae6dcd704c113 ]
The workqueue watchdog prints a warning when there is no progress in a worker pool. Where the progress means that the pool started processing a pending work item.
Note that it is perfectly fine to process work items much longer. The progress should be guaranteed by waking up or creating idle workers.
show_one_worker_pool() prints state of non-idle worker pool. It shows a delay since the last pool->watchdog_ts.
The timestamp is updated when a first pending work is queued in __queue_work(). Also it is updated when a work is dequeued for processing in worker_thread() and rescuer_thread().
The delay is misleading when there is no pending work item. In this case it shows how long the last work item is being proceed. Show zero instead. There is no stall if there is no pending work.
Fixes: 82607adcf9cdf40fb7b ("workqueue: implement lockup detector") Signed-off-by: Petr Mladek pmladek@suse.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/workqueue.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 7f57fed719957..b9041ab881bc8 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -4816,16 +4816,19 @@ void show_workqueue_state(void) for_each_pool(pool, pi) { struct worker *worker; bool first = true; + unsigned long hung = 0;
raw_spin_lock_irqsave(&pool->lock, flags); if (pool->nr_workers == pool->nr_idle) goto next_pool;
+ /* How long the first pending work is waiting for a worker. */ + if (!list_empty(&pool->worklist)) + hung = jiffies_to_msecs(jiffies - pool->watchdog_ts) / 1000; + pr_info("pool %d:", pool->id); pr_cont_pool_info(pool); - pr_cont(" hung=%us workers=%d", - jiffies_to_msecs(jiffies - pool->watchdog_ts) / 1000, - pool->nr_workers); + pr_cont(" hung=%lus workers=%d", hung, pool->nr_workers); if (pool->manager) pr_cont(" manager: %d", task_pid_nr(pool->manager->task));
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit f69c2b5420497b7a54181ce170d682cbeb1f119f ]
Non-static functions should have a prototype:
drivers/rtc/rtc-omap.c:410:5: error: no previous prototype for ‘omap_rtc_power_off_program’ [-Werror=missing-prototypes]
Fixes: 6256f7f7f217 ("rtc: OMAP: Add support for rtc-only mode") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20230311094021.79730-1-krzysztof.kozlowski@linaro.... Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-omap.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index c20fc7937dfa8..18ae2a4f26eab 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -25,6 +25,7 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/rtc.h> +#include <linux/rtc/rtc-omap.h>
/* * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock
From: Dan Carpenter error27@gmail.com
[ Upstream commit d50b3c73f1ac20dabc53dc6e9d64ce9c79a331eb ]
The ucmd->log_sq_bb_count variable is controlled by the user so this shift can wrap. Fix it by using check_shl_overflow() in the same way that it was done in commit 515f60004ed9 ("RDMA/hns: Prevent undefined behavior in hns_roce_set_user_sq_size()").
Fixes: 839041329fd3 ("IB/mlx4: Sanity check userspace send queue sizes") Signed-off-by: Dan Carpenter error27@gmail.com Link: https://lore.kernel.org/r/a8dfbd1d-c019-4556-930b-bab1ded73b10@kili.mountain Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/mlx4/qp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index c6a815a705fef..255194029e2d8 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -412,9 +412,13 @@ static int set_user_sq_size(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp, struct mlx4_ib_create_qp *ucmd) { + u32 cnt; + /* Sanity check SQ size before proceeding */ - if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes || - ucmd->log_sq_stride > + if (check_shl_overflow(1, ucmd->log_sq_bb_count, &cnt) || + cnt > dev->dev->caps.max_wqes) + return -EINVAL; + if (ucmd->log_sq_stride > ilog2(roundup_pow_of_two(dev->dev->caps.max_sq_desc_sz)) || ucmd->log_sq_stride < MLX4_IB_MIN_SQ_STRIDE) return -EINVAL;
From: Martin Blumenstingl martin.blumenstingl@googlemail.com
[ Upstream commit 0e6255fa3f649170da6bd1a544680589cfae1131 ]
The VRTC alarm register can be programmed with an amount of seconds after which the SoC will be woken up by the VRTC timer again. We are already converting the alarm time from meson_vrtc_set_alarm() to "seconds since 1970". This means we also need to use "seconds since 1970" for the current time.
This fixes a problem where setting the alarm to one minute in the future results in the firmware (which handles wakeup) to output (on the serial console) that the system will be woken up in billions of seconds. ktime_get_raw_ts64() returns the time since boot, not since 1970. Switch to ktime_get_real_ts64() to fix the calculation of the alarm time and to make the SoC wake up at the specified date/time. Also the firmware (which manages suspend) now prints either 59 or 60 seconds until wakeup (depending on how long it takes for the system to enter suspend).
Fixes: 6ef35398e827 ("rtc: Add Amlogic Virtual Wake RTC") Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Reviewed-by: Kevin Hilman khilman@baylibre.com Link: https://lore.kernel.org/r/20230320212142.2355062-1-martin.blumenstingl@googl... Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-meson-vrtc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/rtc-meson-vrtc.c b/drivers/rtc/rtc-meson-vrtc.c index e6bd0808a092b..18ff8439b5bb5 100644 --- a/drivers/rtc/rtc-meson-vrtc.c +++ b/drivers/rtc/rtc-meson-vrtc.c @@ -23,7 +23,7 @@ static int meson_vrtc_read_time(struct device *dev, struct rtc_time *tm) struct timespec64 time;
dev_dbg(dev, "%s\n", __func__); - ktime_get_raw_ts64(&time); + ktime_get_real_ts64(&time); rtc_time64_to_tm(time.tv_sec, tm);
return 0; @@ -96,7 +96,7 @@ static int __maybe_unused meson_vrtc_suspend(struct device *dev) long alarm_secs; struct timespec64 time;
- ktime_get_raw_ts64(&time); + ktime_get_real_ts64(&time); local_time = time.tv_sec;
dev_dbg(dev, "alarm_time = %lus, local_time=%lus\n",
From: Sebastian Reichel sre@kernel.org
[ Upstream commit 44263f50065969f2344808388bd589740f026167 ]
power-supply properties are reported in µV, µA and µW. The IIO API provides mV, mA, mW, so the values need to be multiplied by 1000.
Fixes: e60fea794e6e ("power: battery: Generic battery driver using IIO") Reviewed-by: Linus Walleij linus.walleij@linaro.org Reviewed-by: Matti Vaittinen mazziesaccount@gmail.com Signed-off-by: Sebastian Reichel sre@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/generic-adc-battery.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/power/supply/generic-adc-battery.c b/drivers/power/supply/generic-adc-battery.c index 58f09314741a7..09bb4ff291cb0 100644 --- a/drivers/power/supply/generic-adc-battery.c +++ b/drivers/power/supply/generic-adc-battery.c @@ -138,6 +138,9 @@ static int read_channel(struct gab *adc_bat, enum power_supply_property psp, result); if (ret < 0) pr_err("read channel error\n"); + else + *result *= 1000; + return ret; }
From: Clément Léger clement.leger@bootlin.com
[ Upstream commit 27a6e1b09a782517fddac91259970ac466a3f7b6 ]
When returning from of_parse_phandle_with_args(), the np member of the of_phandle_args structure should be put after usage. Add missing of_node_put() calls in both __set_clk_parents() and __set_clk_rates().
Fixes: 86be408bfbd8 ("clk: Support for clock parents and rates assigned from device tree") Signed-off-by: Clément Léger clement.leger@bootlin.com Link: https://lore.kernel.org/r/20230131083227.10990-1-clement.leger@bootlin.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-conf.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c index 2ef819606c417..1a4e6340f95ce 100644 --- a/drivers/clk/clk-conf.c +++ b/drivers/clk/clk-conf.c @@ -33,9 +33,12 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) else return rc; } - if (clkspec.np == node && !clk_supplier) + if (clkspec.np == node && !clk_supplier) { + of_node_put(clkspec.np); return 0; + } pclk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); if (IS_ERR(pclk)) { if (PTR_ERR(pclk) != -EPROBE_DEFER) pr_warn("clk: couldn't get parent clock %d for %pOF\n", @@ -48,10 +51,12 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) if (rc < 0) goto err; if (clkspec.np == node && !clk_supplier) { + of_node_put(clkspec.np); rc = 0; goto err; } clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); if (IS_ERR(clk)) { if (PTR_ERR(clk) != -EPROBE_DEFER) pr_warn("clk: couldn't get assigned clock %d for %pOF\n", @@ -93,10 +98,13 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier) else return rc; } - if (clkspec.np == node && !clk_supplier) + if (clkspec.np == node && !clk_supplier) { + of_node_put(clkspec.np); return 0; + }
clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); if (IS_ERR(clk)) { if (PTR_ERR(clk) != -EPROBE_DEFER) pr_warn("clk: couldn't get clock %d for %pOF\n",
From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
[ Upstream commit 266e9b3475ba82212062771fdbc40be0e3c06ec8 ]
syzbot is reporting that siw_netdev_event(NETDEV_UNREGISTER) cannot destroy siw_device created after unshare(CLONE_NEWNET) due to net namespace check. It seems that this check was by error there and should be removed.
Reported-by: syzbot syzbot+5e70d01ee8985ae62a3b@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=5e70d01ee8985ae62a3b Suggested-by: Jason Gunthorpe jgg@ziepe.ca Suggested-by: Leon Romanovsky leon@kernel.org Fixes: bdcf26bf9b3a ("rdma/siw: network and RDMA core interface") Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Link: https://lore.kernel.org/r/a44e9ac5-44e2-d575-9e30-02483cc7ffd1@I-love.SAKURA... Reviewed-by: Bernard Metzler bmt@zurich.ibm.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/siw/siw_main.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/infiniband/sw/siw/siw_main.c b/drivers/infiniband/sw/siw/siw_main.c index 32a553a1b905e..5ba0893f1f017 100644 --- a/drivers/infiniband/sw/siw/siw_main.c +++ b/drivers/infiniband/sw/siw/siw_main.c @@ -458,9 +458,6 @@ static int siw_netdev_event(struct notifier_block *nb, unsigned long event,
dev_dbg(&netdev->dev, "siw: event %lu\n", event);
- if (dev_net(netdev) != &init_net) - return NOTIFY_OK; - base_dev = ib_device_get_by_netdev(netdev, RDMA_DRIVER_SIW); if (!base_dev) return NOTIFY_OK;
From: Mark Zhang markzhang@nvidia.com
[ Upstream commit bd9de1badac7e4ff6780365d4aa38983f5e2a436 ]
Trace icm_send_rej event before the cm state is reset to idle, so that correct cm state will be logged. For example when an incoming request is rejected, the old trace log was: icm_send_rej: local_id=961102742 remote_id=3829151631 state=IDLE reason=REJ_CONSUMER_DEFINED With this patch: icm_send_rej: local_id=312971016 remote_id=3778819983 state=MRA_REQ_SENT reason=REJ_CONSUMER_DEFINED
Fixes: 8dc105befe16 ("RDMA/cm: Add tracepoints to track MAD send operations") Signed-off-by: Mark Zhang markzhang@nvidia.com Link: https://lore.kernel.org/r/20230330072351.481200-1-markzhang@nvidia.com Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/core/cm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 3133b6be6cab9..db1a25fbe2fa9 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -2924,6 +2924,8 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, (ari && ari_length > IB_CM_REJ_ARI_LENGTH)) return -EINVAL;
+ trace_icm_send_rej(&cm_id_priv->id, reason); + switch (state) { case IB_CM_REQ_SENT: case IB_CM_MRA_REQ_RCVD: @@ -2954,7 +2956,6 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, return -EINVAL; }
- trace_icm_send_rej(&cm_id_priv->id, reason); ret = ib_post_send_mad(msg, NULL); if (ret) { cm_free_msg(msg);
From: Saravanan Vajravel saravanan.vajravel@broadcom.com
[ Upstream commit eca5cd9474cd26d62f9756f536e2e656d3f62f3a ]
When unregistering MAD agent, srpt module has a non-null check for 'mad_agent' pointer before invoking ib_unregister_mad_agent(). This check can pass if 'mad_agent' variable holds an error value. The 'mad_agent' can have an error value for a short window when srpt_add_one() and srpt_remove_one() is executed simultaneously.
In srpt module, added a valid pointer check for 'sport->mad_agent' before unregistering MAD agent.
This issue can hit when RoCE driver unregisters ib_device
Stack Trace: ------------ BUG: kernel NULL pointer dereference, address: 000000000000004d PGD 145003067 P4D 145003067 PUD 2324fe067 PMD 0 Oops: 0002 [#1] PREEMPT SMP NOPTI CPU: 10 PID: 4459 Comm: kworker/u80:0 Kdump: loaded Tainted: P Hardware name: Dell Inc. PowerEdge R640/06NR82, BIOS 2.5.4 01/13/2020 Workqueue: bnxt_re bnxt_re_task [bnxt_re] RIP: 0010:_raw_spin_lock_irqsave+0x19/0x40 Call Trace: ib_unregister_mad_agent+0x46/0x2f0 [ib_core] IPv6: ADDRCONF(NETDEV_CHANGE): bond0: link becomes ready ? __schedule+0x20b/0x560 srpt_unregister_mad_agent+0x93/0xd0 [ib_srpt] srpt_remove_one+0x20/0x150 [ib_srpt] remove_client_context+0x88/0xd0 [ib_core] bond0: (slave p2p1): link status definitely up, 100000 Mbps full duplex disable_device+0x8a/0x160 [ib_core] bond0: active interface up! ? kernfs_name_hash+0x12/0x80 (NULL device *): Bonding Info Received: rdev: 000000006c0b8247 __ib_unregister_device+0x42/0xb0 [ib_core] (NULL device *): Master: mode: 4 num_slaves:2 ib_unregister_device+0x22/0x30 [ib_core] (NULL device *): Slave: id: 105069936 name:p2p1 link:0 state:0 bnxt_re_stopqps_and_ib_uninit+0x83/0x90 [bnxt_re] bnxt_re_alloc_lag+0x12e/0x4e0 [bnxt_re]
Fixes: a42d985bd5b2 ("ib_srpt: Initial SRP Target merge for v3.3-rc1") Reviewed-by: Selvin Xavier selvin.xavier@broadcom.com Reviewed-by: Kashyap Desai kashyap.desai@broadcom.com Signed-off-by: Saravanan Vajravel saravanan.vajravel@broadcom.com Link: https://lore.kernel.org/r/20230406042549.507328-1-saravanan.vajravel@broadco... Reviewed-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/srpt/ib_srpt.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index c0ed08fcab480..983f59c87b79f 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -549,6 +549,7 @@ static int srpt_format_guid(char *buf, unsigned int size, const __be64 *guid) */ static int srpt_refresh_port(struct srpt_port *sport) { + struct ib_mad_agent *mad_agent; struct ib_mad_reg_req reg_req; struct ib_port_modify port_modify; struct ib_port_attr port_attr; @@ -593,24 +594,26 @@ static int srpt_refresh_port(struct srpt_port *sport) set_bit(IB_MGMT_METHOD_GET, reg_req.method_mask); set_bit(IB_MGMT_METHOD_SET, reg_req.method_mask);
- sport->mad_agent = ib_register_mad_agent(sport->sdev->device, - sport->port, - IB_QPT_GSI, - ®_req, 0, - srpt_mad_send_handler, - srpt_mad_recv_handler, - sport, 0); - if (IS_ERR(sport->mad_agent)) { + mad_agent = ib_register_mad_agent(sport->sdev->device, + sport->port, + IB_QPT_GSI, + ®_req, 0, + srpt_mad_send_handler, + srpt_mad_recv_handler, + sport, 0); + if (IS_ERR(mad_agent)) { pr_err("%s-%d: MAD agent registration failed (%ld). Note: this is expected if SR-IOV is enabled.\n", dev_name(&sport->sdev->device->dev), sport->port, - PTR_ERR(sport->mad_agent)); + PTR_ERR(mad_agent)); sport->mad_agent = NULL; memset(&port_modify, 0, sizeof(port_modify)); port_modify.clr_port_cap_mask = IB_PORT_DEVICE_MGMT_SUP; ib_modify_port(sport->sdev->device, sport->port, 0, &port_modify); - + return 0; } + + sport->mad_agent = mad_agent; }
return 0;
From: Patrick Kelsey pat.kelsey@cornelisnetworks.com
[ Upstream commit 9fe8fec5e43d5a80f43cbf61aaada1b047a1eb61 ]
hfi1_mmu_rb_remove_unless_exact() did not move mmu_rb_node objects in mmu_rb_handler->lru_list after getting a cache hit on an mmu_rb_node.
As a result, hfi1_mmu_rb_evict() was not guaranteed to evict truly least-recently used nodes.
This could be a performance issue for an application when that application: - Uses some long-lived buffers frequently. - Uses a large number of buffers once. - Hits the mmu_rb_handler cache size or pinned-page limits, forcing mmu_rb_handler cache entries to be evicted.
In this case, the one-time use buffers cause the long-lived buffer entries to eventually filter to the end of the LRU list where hfi1_mmu_rb_evict() will consider evicting a frequently-used long-lived entry instead of evicting one of the one-time use entries.
Fix this by inserting new mmu_rb_node at the tail of mmu_rb_handler->lru_list and move mmu_rb_ndoe to the tail of mmu_rb_handler->lru_list when the mmu_rb_node is a hit in hfi1_mmu_rb_remove_unless_exact(). Change hfi1_mmu_rb_evict() to evict from the head of mmu_rb_handler->lru_list instead of the tail.
Fixes: 0636e9ab8355 ("IB/hfi1: Add cache evict LRU list") Signed-off-by: Brendan Cunningham bcunningham@cornelisnetworks.com Signed-off-by: Patrick Kelsey pat.kelsey@cornelisnetworks.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com Link: https://lore.kernel.org/r/168088635931.3027109.10423156330761536044.stgit@25... Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/mmu_rb.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c index ed8a96ae61cef..d8b6bf271db8f 100644 --- a/drivers/infiniband/hw/hfi1/mmu_rb.c +++ b/drivers/infiniband/hw/hfi1/mmu_rb.c @@ -171,7 +171,7 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, goto unlock; } __mmu_int_rb_insert(mnode, &handler->root); - list_add(&mnode->list, &handler->lru_list); + list_add_tail(&mnode->list, &handler->lru_list);
ret = handler->ops->insert(handler->ops_arg, mnode); if (ret) { @@ -222,8 +222,10 @@ bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler, spin_lock_irqsave(&handler->lock, flags); node = __mmu_rb_search(handler, addr, len); if (node) { - if (node->addr == addr && node->len == len) + if (node->addr == addr && node->len == len) { + list_move_tail(&node->list, &handler->lru_list); goto unlock; + } __mmu_int_rb_remove(node, &handler->root); list_del(&node->list); /* remove from LRU list */ ret = true; @@ -247,8 +249,7 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) INIT_LIST_HEAD(&del_list);
spin_lock_irqsave(&handler->lock, flags); - list_for_each_entry_safe_reverse(rbnode, ptr, &handler->lru_list, - list) { + list_for_each_entry_safe(rbnode, ptr, &handler->lru_list, list) { if (handler->ops->evict(handler->ops_arg, rbnode, evict_arg, &stop)) { __mmu_int_rb_remove(rbnode, &handler->root); @@ -260,9 +261,7 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) } spin_unlock_irqrestore(&handler->lock, flags);
- while (!list_empty(&del_list)) { - rbnode = list_first_entry(&del_list, struct mmu_rb_node, list); - list_del(&rbnode->list); + list_for_each_entry_safe(rbnode, ptr, &del_list, list) { handler->ops->remove(handler->ops_arg, rbnode); } }
From: Mike Marciniszyn mike.marciniszyn@cornelisnetworks.com
[ Upstream commit 4bd00b55c978017aad10f0ff3e45525cd62cca07 ]
Add traces to allow for debugging issues with AIP tx.
Link: https://lore.kernel.org/r/1617026056-50483-2-git-send-email-dennis.dalessand... Reviewed-by: Kaike Wan kaike.wan@intel.com Signed-off-by: Mike Marciniszyn mike.marciniszyn@cornelisnetworks.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Stable-dep-of: 00cbce5cbf88 ("IB/hfi1: Fix bugs with non-PAGE_SIZE-end multi-iovec user SDMA requests") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/ipoib_tx.c | 18 ++++- drivers/infiniband/hw/hfi1/trace_tx.h | 104 ++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/hfi1/ipoib_tx.c b/drivers/infiniband/hw/hfi1/ipoib_tx.c index ab1eefffc14b3..ec187ec746749 100644 --- a/drivers/infiniband/hw/hfi1/ipoib_tx.c +++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c @@ -15,6 +15,7 @@ #include "verbs.h" #include "trace_ibhdrs.h" #include "ipoib.h" +#include "trace_tx.h"
/* Add a convenience helper */ #define CIRC_ADD(val, add, size) (((val) + (add)) & ((size) - 1)) @@ -63,12 +64,14 @@ static u64 hfi1_ipoib_used(struct hfi1_ipoib_txq *txq)
static void hfi1_ipoib_stop_txq(struct hfi1_ipoib_txq *txq) { + trace_hfi1_txq_stop(txq); if (atomic_inc_return(&txq->stops) == 1) netif_stop_subqueue(txq->priv->netdev, txq->q_idx); }
static void hfi1_ipoib_wake_txq(struct hfi1_ipoib_txq *txq) { + trace_hfi1_txq_wake(txq); if (atomic_dec_and_test(&txq->stops)) netif_wake_subqueue(txq->priv->netdev, txq->q_idx); } @@ -89,8 +92,10 @@ static void hfi1_ipoib_check_queue_depth(struct hfi1_ipoib_txq *txq) { ++txq->sent_txreqs; if (hfi1_ipoib_used(txq) >= hfi1_ipoib_ring_hwat(txq) && - !atomic_xchg(&txq->ring_full, 1)) + !atomic_xchg(&txq->ring_full, 1)) { + trace_hfi1_txq_full(txq); hfi1_ipoib_stop_txq(txq); + } }
static void hfi1_ipoib_check_queue_stopped(struct hfi1_ipoib_txq *txq) @@ -112,8 +117,10 @@ static void hfi1_ipoib_check_queue_stopped(struct hfi1_ipoib_txq *txq) * to protect against ring overflow. */ if (hfi1_ipoib_used(txq) < hfi1_ipoib_ring_lwat(txq) && - atomic_xchg(&txq->ring_full, 0)) + atomic_xchg(&txq->ring_full, 0)) { + trace_hfi1_txq_xmit_unstopped(txq); hfi1_ipoib_wake_txq(txq); + } }
static void hfi1_ipoib_free_tx(struct ipoib_txreq *tx, int budget) @@ -405,6 +412,7 @@ static struct ipoib_txreq *hfi1_ipoib_send_dma_common(struct net_device *dev, sdma_select_engine_sc(priv->dd, txp->flow.tx_queue, txp->flow.sc5); + trace_hfi1_flow_switch(txp->txq); }
return tx; @@ -525,6 +533,7 @@ static int hfi1_ipoib_send_dma_list(struct net_device *dev, if (txq->flow.as_int != txp->flow.as_int) { int ret;
+ trace_hfi1_flow_flush(txq); ret = hfi1_ipoib_flush_tx_list(dev, txq); if (unlikely(ret)) { if (ret == -EBUSY) @@ -635,8 +644,10 @@ static int hfi1_ipoib_sdma_sleep(struct sdma_engine *sde, /* came from non-list submit */ list_add_tail(&txreq->list, &txq->tx_list); if (list_empty(&txq->wait.list)) { - if (!atomic_xchg(&txq->no_desc, 1)) + if (!atomic_xchg(&txq->no_desc, 1)) { + trace_hfi1_txq_queued(txq); hfi1_ipoib_stop_txq(txq); + } iowait_queue(pkts_sent, wait->iow, &sde->dmawait); }
@@ -659,6 +670,7 @@ static void hfi1_ipoib_sdma_wakeup(struct iowait *wait, int reason) struct hfi1_ipoib_txq *txq = container_of(wait, struct hfi1_ipoib_txq, wait);
+ trace_hfi1_txq_wakeup(txq); if (likely(txq->priv->netdev->reg_state == NETREG_REGISTERED)) iowait_schedule(wait, system_highpri_wq, WORK_CPU_UNBOUND); } diff --git a/drivers/infiniband/hw/hfi1/trace_tx.h b/drivers/infiniband/hw/hfi1/trace_tx.h index 769e5e4710c64..847654196dd34 100644 --- a/drivers/infiniband/hw/hfi1/trace_tx.h +++ b/drivers/infiniband/hw/hfi1/trace_tx.h @@ -53,6 +53,7 @@ #include "hfi.h" #include "mad.h" #include "sdma.h" +#include "ipoib.h"
const char *parse_sdma_flags(struct trace_seq *p, u64 desc0, u64 desc1);
@@ -858,6 +859,109 @@ DEFINE_EVENT( TP_ARGS(qp, flag) );
+DECLARE_EVENT_CLASS(/* AIP */ + hfi1_ipoib_txq_template, + TP_PROTO(struct hfi1_ipoib_txq *txq), + TP_ARGS(txq), + TP_STRUCT__entry(/* entry */ + DD_DEV_ENTRY(txq->priv->dd) + __field(struct hfi1_ipoib_txq *, txq) + __field(struct sdma_engine *, sde) + __field(ulong, head) + __field(ulong, tail) + __field(uint, used) + __field(uint, flow) + __field(int, stops) + __field(int, no_desc) + __field(u8, idx) + __field(u8, stopped) + ), + TP_fast_assign(/* assign */ + DD_DEV_ASSIGN(txq->priv->dd) + __entry->txq = txq; + __entry->sde = txq->sde; + __entry->head = txq->tx_ring.head; + __entry->tail = txq->tx_ring.tail; + __entry->idx = txq->q_idx; + __entry->used = + txq->sent_txreqs - + atomic64_read(&txq->complete_txreqs); + __entry->flow = txq->flow.as_int; + __entry->stops = atomic_read(&txq->stops); + __entry->no_desc = atomic_read(&txq->no_desc); + __entry->stopped = + __netif_subqueue_stopped(txq->priv->netdev, txq->q_idx); + ), + TP_printk(/* print */ + "[%s] txq %llx idx %u sde %llx head %lx tail %lx flow %x used %u stops %d no_desc %d stopped %u", + __get_str(dev), + (unsigned long long)__entry->txq, + __entry->idx, + (unsigned long long)__entry->sde, + __entry->head, + __entry->tail, + __entry->flow, + __entry->used, + __entry->stops, + __entry->no_desc, + __entry->stopped + ) +); + +DEFINE_EVENT(/* queue stop */ + hfi1_ipoib_txq_template, hfi1_txq_stop, + TP_PROTO(struct hfi1_ipoib_txq *txq), + TP_ARGS(txq) +); + +DEFINE_EVENT(/* queue wake */ + hfi1_ipoib_txq_template, hfi1_txq_wake, + TP_PROTO(struct hfi1_ipoib_txq *txq), + TP_ARGS(txq) +); + +DEFINE_EVENT(/* flow flush */ + hfi1_ipoib_txq_template, hfi1_flow_flush, + TP_PROTO(struct hfi1_ipoib_txq *txq), + TP_ARGS(txq) +); + +DEFINE_EVENT(/* flow switch */ + hfi1_ipoib_txq_template, hfi1_flow_switch, + TP_PROTO(struct hfi1_ipoib_txq *txq), + TP_ARGS(txq) +); + +DEFINE_EVENT(/* wakeup */ + hfi1_ipoib_txq_template, hfi1_txq_wakeup, + TP_PROTO(struct hfi1_ipoib_txq *txq), + TP_ARGS(txq) +); + +DEFINE_EVENT(/* full */ + hfi1_ipoib_txq_template, hfi1_txq_full, + TP_PROTO(struct hfi1_ipoib_txq *txq), + TP_ARGS(txq) +); + +DEFINE_EVENT(/* queued */ + hfi1_ipoib_txq_template, hfi1_txq_queued, + TP_PROTO(struct hfi1_ipoib_txq *txq), + TP_ARGS(txq) +); + +DEFINE_EVENT(/* xmit_stopped */ + hfi1_ipoib_txq_template, hfi1_txq_xmit_stopped, + TP_PROTO(struct hfi1_ipoib_txq *txq), + TP_ARGS(txq) +); + +DEFINE_EVENT(/* xmit_unstopped */ + hfi1_ipoib_txq_template, hfi1_txq_xmit_unstopped, + TP_PROTO(struct hfi1_ipoib_txq *txq), + TP_ARGS(txq) +); + #endif /* __HFI1_TRACE_TX_H */
#undef TRACE_INCLUDE_PATH
From: Mike Marciniszyn mike.marciniszyn@cornelisnetworks.com
[ Upstream commit 6b13215df1d37f5be23fc4a01a915a287b25ce15 ]
Add traces that were vital in isolating an issue with pq waitlist in commit fa8dac396863 ("IB/hfi1: Fix another case where pq is left on waitlist")
Link: https://lore.kernel.org/r/1617026056-50483-8-git-send-email-dennis.dalessand... Reviewed-by: Kaike Wan kaike.wan@intel.com Signed-off-by: Mike Marciniszyn mike.marciniszyn@cornelisnetworks.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Stable-dep-of: 00cbce5cbf88 ("IB/hfi1: Fix bugs with non-PAGE_SIZE-end multi-iovec user SDMA requests") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/trace_tx.h | 75 ++++++++++++++++++++++++++ drivers/infiniband/hw/hfi1/user_sdma.c | 12 +++-- drivers/infiniband/hw/hfi1/user_sdma.h | 1 + 3 files changed, 85 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/hfi1/trace_tx.h b/drivers/infiniband/hw/hfi1/trace_tx.h index 847654196dd34..d44fc54858b90 100644 --- a/drivers/infiniband/hw/hfi1/trace_tx.h +++ b/drivers/infiniband/hw/hfi1/trace_tx.h @@ -54,6 +54,7 @@ #include "mad.h" #include "sdma.h" #include "ipoib.h" +#include "user_sdma.h"
const char *parse_sdma_flags(struct trace_seq *p, u64 desc0, u64 desc1);
@@ -654,6 +655,80 @@ TRACE_EVENT(hfi1_sdma_user_completion, __entry->code) );
+TRACE_EVENT(hfi1_usdma_defer, + TP_PROTO(struct hfi1_user_sdma_pkt_q *pq, + struct sdma_engine *sde, + struct iowait *wait), + TP_ARGS(pq, sde, wait), + TP_STRUCT__entry(DD_DEV_ENTRY(pq->dd) + __field(struct hfi1_user_sdma_pkt_q *, pq) + __field(struct sdma_engine *, sde) + __field(struct iowait *, wait) + __field(int, engine) + __field(int, empty) + ), + TP_fast_assign(DD_DEV_ASSIGN(pq->dd); + __entry->pq = pq; + __entry->sde = sde; + __entry->wait = wait; + __entry->engine = sde->this_idx; + __entry->empty = list_empty(&__entry->wait->list); + ), + TP_printk("[%s] pq %llx sde %llx wait %llx engine %d empty %d", + __get_str(dev), + (unsigned long long)__entry->pq, + (unsigned long long)__entry->sde, + (unsigned long long)__entry->wait, + __entry->engine, + __entry->empty + ) +); + +TRACE_EVENT(hfi1_usdma_activate, + TP_PROTO(struct hfi1_user_sdma_pkt_q *pq, + struct iowait *wait, + int reason), + TP_ARGS(pq, wait, reason), + TP_STRUCT__entry(DD_DEV_ENTRY(pq->dd) + __field(struct hfi1_user_sdma_pkt_q *, pq) + __field(struct iowait *, wait) + __field(int, reason) + ), + TP_fast_assign(DD_DEV_ASSIGN(pq->dd); + __entry->pq = pq; + __entry->wait = wait; + __entry->reason = reason; + ), + TP_printk("[%s] pq %llx wait %llx reason %d", + __get_str(dev), + (unsigned long long)__entry->pq, + (unsigned long long)__entry->wait, + __entry->reason + ) +); + +TRACE_EVENT(hfi1_usdma_we, + TP_PROTO(struct hfi1_user_sdma_pkt_q *pq, + int we_ret), + TP_ARGS(pq, we_ret), + TP_STRUCT__entry(DD_DEV_ENTRY(pq->dd) + __field(struct hfi1_user_sdma_pkt_q *, pq) + __field(int, state) + __field(int, we_ret) + ), + TP_fast_assign(DD_DEV_ASSIGN(pq->dd); + __entry->pq = pq; + __entry->state = pq->state; + __entry->we_ret = we_ret; + ), + TP_printk("[%s] pq %llx state %d we_ret %d", + __get_str(dev), + (unsigned long long)__entry->pq, + __entry->state, + __entry->we_ret + ) +); + const char *print_u32_array(struct trace_seq *, u32 *, int); #define __print_u32_hex(arr, len) print_u32_array(p, arr, len)
diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c index 4a4956f96a7eb..da5b2e37355ab 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.c +++ b/drivers/infiniband/hw/hfi1/user_sdma.c @@ -133,6 +133,7 @@ static int defer_packet_queue( container_of(wait->iow, struct hfi1_user_sdma_pkt_q, busy);
write_seqlock(&sde->waitlock); + trace_hfi1_usdma_defer(pq, sde, &pq->busy); if (sdma_progress(sde, seq, txreq)) goto eagain; /* @@ -157,7 +158,8 @@ static void activate_packet_queue(struct iowait *wait, int reason) { struct hfi1_user_sdma_pkt_q *pq = container_of(wait, struct hfi1_user_sdma_pkt_q, busy); - pq->busy.lock = NULL; + + trace_hfi1_usdma_activate(pq, wait, reason); xchg(&pq->state, SDMA_PKT_Q_ACTIVE); wake_up(&wait->wait_dma); }; @@ -599,13 +601,17 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd, while (req->seqsubmitted != req->info.npkts) { ret = user_sdma_send_pkts(req, pcount); if (ret < 0) { + int we_ret; + if (ret != -EBUSY) goto free_req; - if (wait_event_interruptible_timeout( + we_ret = wait_event_interruptible_timeout( pq->busy.wait_dma, pq->state == SDMA_PKT_Q_ACTIVE, msecs_to_jiffies( - SDMA_IOWAIT_TIMEOUT)) <= 0) + SDMA_IOWAIT_TIMEOUT)); + trace_hfi1_usdma_we(pq, we_ret); + if (we_ret <= 0) flush_pq_iowait(pq); } } diff --git a/drivers/infiniband/hw/hfi1/user_sdma.h b/drivers/infiniband/hw/hfi1/user_sdma.h index 1e8c02fe8ad1d..fabe581399068 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.h +++ b/drivers/infiniband/hw/hfi1/user_sdma.h @@ -53,6 +53,7 @@ #include "common.h" #include "iowait.h" #include "user_exp_rcv.h" +#include "mmu_rb.h"
/* The maximum number of Data io vectors per message/request */ #define MAX_VECTORS_PER_REQ 8
From: Patrick Kelsey pat.kelsey@cornelisnetworks.com
[ Upstream commit 00cbce5cbf88459cd1aa1d60d0f1df15477df127 ]
hfi1 user SDMA request processing has two bugs that can cause data corruption for user SDMA requests that have multiple payload iovecs where an iovec other than the tail iovec does not run up to the page boundary for the buffer pointed to by that iovec.a
Here are the specific bugs: 1. user_sdma_txadd() does not use struct user_sdma_iovec->iov.iov_len. Rather, user_sdma_txadd() will add up to PAGE_SIZE bytes from iovec to the packet, even if some of those bytes are past iovec->iov.iov_len and are thus not intended to be in the packet. 2. user_sdma_txadd() and user_sdma_send_pkts() fail to advance to the next iovec in user_sdma_request->iovs when the current iovec is not PAGE_SIZE and does not contain enough data to complete the packet. The transmitted packet will contain the wrong data from the iovec pages.
This has not been an issue with SDMA packets from hfi1 Verbs or PSM2 because they only produce iovecs that end short of PAGE_SIZE as the tail iovec of an SDMA request.
Fixing these bugs exposes other bugs with the SDMA pin cache (struct mmu_rb_handler) that get in way of supporting user SDMA requests with multiple payload iovecs whose buffers do not end at PAGE_SIZE. So this commit fixes those issues as well.
Here are the mmu_rb_handler bugs that non-PAGE_SIZE-end multi-iovec payload user SDMA requests can hit: 1. Overlapping memory ranges in mmu_rb_handler will result in duplicate pinnings. 2. When extending an existing mmu_rb_handler entry (struct mmu_rb_node), the mmu_rb code (1) removes the existing entry under a lock, (2) releases that lock, pins the new pages, (3) then reacquires the lock to insert the extended mmu_rb_node.
If someone else comes in and inserts an overlapping entry between (2) and (3), insert in (3) will fail.
The failure path code in this case unpins _all_ pages in either the original mmu_rb_node or the new mmu_rb_node that was inserted between (2) and (3). 3. In hfi1_mmu_rb_remove_unless_exact(), mmu_rb_node->refcount is incremented outside of mmu_rb_handler->lock. As a result, mmu_rb_node could be evicted by another thread that gets mmu_rb_handler->lock and checks mmu_rb_node->refcount before mmu_rb_node->refcount is incremented. 4. Related to #2 above, SDMA request submission failure path does not check mmu_rb_node->refcount before freeing mmu_rb_node object.
If there are other SDMA requests in progress whose iovecs have pointers to the now-freed mmu_rb_node(s), those pointers to the now-freed mmu_rb nodes will be dereferenced when those SDMA requests complete.
Fixes: 7be85676f1d1 ("IB/hfi1: Don't remove RB entry when not needed.") Fixes: 7724105686e7 ("IB/hfi1: add driver files") Signed-off-by: Brendan Cunningham bcunningham@cornelisnetworks.com Signed-off-by: Patrick Kelsey pat.kelsey@cornelisnetworks.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com Link: https://lore.kernel.org/r/168088636445.3027109.10054635277810177889.stgit@25... Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/ipoib_tx.c | 1 + drivers/infiniband/hw/hfi1/mmu_rb.c | 66 +-- drivers/infiniband/hw/hfi1/mmu_rb.h | 8 +- drivers/infiniband/hw/hfi1/sdma.c | 21 +- drivers/infiniband/hw/hfi1/sdma.h | 16 +- drivers/infiniband/hw/hfi1/sdma_txreq.h | 1 + drivers/infiniband/hw/hfi1/trace_mmu.h | 4 - drivers/infiniband/hw/hfi1/user_sdma.c | 600 +++++++++++++++--------- drivers/infiniband/hw/hfi1/user_sdma.h | 5 - drivers/infiniband/hw/hfi1/verbs.c | 4 +- drivers/infiniband/hw/hfi1/vnic_sdma.c | 1 + 11 files changed, 423 insertions(+), 304 deletions(-)
diff --git a/drivers/infiniband/hw/hfi1/ipoib_tx.c b/drivers/infiniband/hw/hfi1/ipoib_tx.c index ec187ec746749..956fc3fd88b99 100644 --- a/drivers/infiniband/hw/hfi1/ipoib_tx.c +++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c @@ -251,6 +251,7 @@ static int hfi1_ipoib_build_ulp_payload(struct ipoib_txreq *tx, const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
ret = sdma_txadd_page(dd, + NULL, txreq, skb_frag_page(frag), frag->bv_offset, diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.c b/drivers/infiniband/hw/hfi1/mmu_rb.c index d8b6bf271db8f..d331184ded308 100644 --- a/drivers/infiniband/hw/hfi1/mmu_rb.c +++ b/drivers/infiniband/hw/hfi1/mmu_rb.c @@ -167,7 +167,7 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, spin_lock_irqsave(&handler->lock, flags); node = __mmu_rb_search(handler, mnode->addr, mnode->len); if (node) { - ret = -EINVAL; + ret = -EEXIST; goto unlock; } __mmu_int_rb_insert(mnode, &handler->root); @@ -184,6 +184,19 @@ int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, return ret; }
+/* Caller must hold handler lock */ +struct mmu_rb_node *hfi1_mmu_rb_get_first(struct mmu_rb_handler *handler, + unsigned long addr, unsigned long len) +{ + struct mmu_rb_node *node; + + trace_hfi1_mmu_rb_search(addr, len); + node = __mmu_int_rb_iter_first(&handler->root, addr, (addr + len) - 1); + if (node) + list_move_tail(&node->list, &handler->lru_list); + return node; +} + /* Caller must hold handler lock */ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, unsigned long addr, @@ -208,34 +221,6 @@ static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *handler, return node; }
-bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler, - unsigned long addr, unsigned long len, - struct mmu_rb_node **rb_node) -{ - struct mmu_rb_node *node; - unsigned long flags; - bool ret = false; - - if (current->mm != handler->mn.mm) - return ret; - - spin_lock_irqsave(&handler->lock, flags); - node = __mmu_rb_search(handler, addr, len); - if (node) { - if (node->addr == addr && node->len == len) { - list_move_tail(&node->list, &handler->lru_list); - goto unlock; - } - __mmu_int_rb_remove(node, &handler->root); - list_del(&node->list); /* remove from LRU list */ - ret = true; - } -unlock: - spin_unlock_irqrestore(&handler->lock, flags); - *rb_node = node; - return ret; -} - void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) { struct mmu_rb_node *rbnode, *ptr; @@ -266,29 +251,6 @@ void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg) } }
-/* - * It is up to the caller to ensure that this function does not race with the - * mmu invalidate notifier which may be calling the users remove callback on - * 'node'. - */ -void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler, - struct mmu_rb_node *node) -{ - unsigned long flags; - - if (current->mm != handler->mn.mm) - return; - - /* Validity of handler and node pointers has been checked by caller. */ - trace_hfi1_mmu_rb_remove(node->addr, node->len); - spin_lock_irqsave(&handler->lock, flags); - __mmu_int_rb_remove(node, &handler->root); - list_del(&node->list); /* remove from LRU list */ - spin_unlock_irqrestore(&handler->lock, flags); - - handler->ops->remove(handler->ops_arg, node); -} - static int mmu_notifier_range_start(struct mmu_notifier *mn, const struct mmu_notifier_range *range) { diff --git a/drivers/infiniband/hw/hfi1/mmu_rb.h b/drivers/infiniband/hw/hfi1/mmu_rb.h index 423aacc67e948..0265d81c62061 100644 --- a/drivers/infiniband/hw/hfi1/mmu_rb.h +++ b/drivers/infiniband/hw/hfi1/mmu_rb.h @@ -93,10 +93,8 @@ void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler); int hfi1_mmu_rb_insert(struct mmu_rb_handler *handler, struct mmu_rb_node *mnode); void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg); -void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler, - struct mmu_rb_node *mnode); -bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler, - unsigned long addr, unsigned long len, - struct mmu_rb_node **rb_node); +struct mmu_rb_node *hfi1_mmu_rb_get_first(struct mmu_rb_handler *handler, + unsigned long addr, + unsigned long len);
#endif /* _HFI1_MMU_RB_H */ diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index a044bee257f94..061562627dae4 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c @@ -1635,22 +1635,7 @@ static inline void sdma_unmap_desc( struct hfi1_devdata *dd, struct sdma_desc *descp) { - switch (sdma_mapping_type(descp)) { - case SDMA_MAP_SINGLE: - dma_unmap_single( - &dd->pcidev->dev, - sdma_mapping_addr(descp), - sdma_mapping_len(descp), - DMA_TO_DEVICE); - break; - case SDMA_MAP_PAGE: - dma_unmap_page( - &dd->pcidev->dev, - sdma_mapping_addr(descp), - sdma_mapping_len(descp), - DMA_TO_DEVICE); - break; - } + system_descriptor_complete(dd, descp); }
/* @@ -3170,7 +3155,7 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
/* Add descriptor for coalesce buffer */ tx->desc_limit = MAX_DESC; - return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx, + return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, NULL, tx, addr, tx->tlen); }
@@ -3210,10 +3195,12 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) return rval; } } + /* finish the one just added */ make_tx_sdma_desc( tx, SDMA_MAP_NONE, + NULL, dd->sdma_pad_phys, sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1))); _sdma_close_tx(dd, tx); diff --git a/drivers/infiniband/hw/hfi1/sdma.h b/drivers/infiniband/hw/hfi1/sdma.h index 7a851191f9870..7d4f316ac6e43 100644 --- a/drivers/infiniband/hw/hfi1/sdma.h +++ b/drivers/infiniband/hw/hfi1/sdma.h @@ -635,6 +635,7 @@ static inline dma_addr_t sdma_mapping_addr(struct sdma_desc *d) static inline void make_tx_sdma_desc( struct sdma_txreq *tx, int type, + void *pinning_ctx, dma_addr_t addr, size_t len) { @@ -653,6 +654,7 @@ static inline void make_tx_sdma_desc( << SDMA_DESC0_PHY_ADDR_SHIFT) | (((u64)len & SDMA_DESC0_BYTE_COUNT_MASK) << SDMA_DESC0_BYTE_COUNT_SHIFT); + desc->pinning_ctx = pinning_ctx; }
/* helper to extend txreq */ @@ -685,6 +687,7 @@ static inline void _sdma_close_tx(struct hfi1_devdata *dd, static inline int _sdma_txadd_daddr( struct hfi1_devdata *dd, int type, + void *pinning_ctx, struct sdma_txreq *tx, dma_addr_t addr, u16 len) @@ -694,6 +697,7 @@ static inline int _sdma_txadd_daddr( make_tx_sdma_desc( tx, type, + pinning_ctx, addr, len); WARN_ON(len > tx->tlen); tx->tlen -= len; @@ -714,6 +718,7 @@ static inline int _sdma_txadd_daddr( /** * sdma_txadd_page() - add a page to the sdma_txreq * @dd: the device to use for mapping + * @pinning_ctx: context to be released at descriptor retirement * @tx: tx request to which the page is added * @page: page to map * @offset: offset within the page @@ -729,6 +734,7 @@ static inline int _sdma_txadd_daddr( */ static inline int sdma_txadd_page( struct hfi1_devdata *dd, + void *pinning_ctx, struct sdma_txreq *tx, struct page *page, unsigned long offset, @@ -756,8 +762,7 @@ static inline int sdma_txadd_page( return -ENOSPC; }
- return _sdma_txadd_daddr( - dd, SDMA_MAP_PAGE, tx, addr, len); + return _sdma_txadd_daddr(dd, SDMA_MAP_PAGE, pinning_ctx, tx, addr, len); }
/** @@ -791,7 +796,8 @@ static inline int sdma_txadd_daddr( return rval; }
- return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, tx, addr, len); + return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, NULL, tx, + addr, len); }
/** @@ -837,8 +843,7 @@ static inline int sdma_txadd_kvaddr( return -ENOSPC; }
- return _sdma_txadd_daddr( - dd, SDMA_MAP_SINGLE, tx, addr, len); + return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, NULL, tx, addr, len); }
struct iowait_work; @@ -1090,4 +1095,5 @@ extern uint mod_num_sdma;
void sdma_update_lmc(struct hfi1_devdata *dd, u64 mask, u32 lid);
+void system_descriptor_complete(struct hfi1_devdata *dd, struct sdma_desc *descp); #endif diff --git a/drivers/infiniband/hw/hfi1/sdma_txreq.h b/drivers/infiniband/hw/hfi1/sdma_txreq.h index 514a4784566b2..4204650cebc29 100644 --- a/drivers/infiniband/hw/hfi1/sdma_txreq.h +++ b/drivers/infiniband/hw/hfi1/sdma_txreq.h @@ -61,6 +61,7 @@ struct sdma_desc { /* private: don't use directly */ u64 qw[2]; + void *pinning_ctx; };
/** diff --git a/drivers/infiniband/hw/hfi1/trace_mmu.h b/drivers/infiniband/hw/hfi1/trace_mmu.h index 3b7abbc382c20..c3055cff4d6bb 100644 --- a/drivers/infiniband/hw/hfi1/trace_mmu.h +++ b/drivers/infiniband/hw/hfi1/trace_mmu.h @@ -78,10 +78,6 @@ DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_rb_search, TP_PROTO(unsigned long addr, unsigned long len), TP_ARGS(addr, len));
-DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_rb_remove, - TP_PROTO(unsigned long addr, unsigned long len), - TP_ARGS(addr, len)); - DEFINE_EVENT(hfi1_mmu_rb_template, hfi1_mmu_mem_invalidate, TP_PROTO(unsigned long addr, unsigned long len), TP_ARGS(addr, len)); diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c index da5b2e37355ab..1eb5a44a4ae6a 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.c +++ b/drivers/infiniband/hw/hfi1/user_sdma.c @@ -65,7 +65,6 @@
#include "hfi.h" #include "sdma.h" -#include "mmu_rb.h" #include "user_sdma.h" #include "verbs.h" /* for the headers */ #include "common.h" /* for struct hfi1_tid_info */ @@ -80,11 +79,7 @@ static unsigned initial_pkt_count = 8; static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts); static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status); static inline void pq_update(struct hfi1_user_sdma_pkt_q *pq); -static void user_sdma_free_request(struct user_sdma_request *req, bool unpin); -static int pin_vector_pages(struct user_sdma_request *req, - struct user_sdma_iovec *iovec); -static void unpin_vector_pages(struct mm_struct *mm, struct page **pages, - unsigned start, unsigned npages); +static void user_sdma_free_request(struct user_sdma_request *req); static int check_header_template(struct user_sdma_request *req, struct hfi1_pkt_header *hdr, u32 lrhlen, u32 datalen); @@ -122,6 +117,11 @@ static struct mmu_rb_ops sdma_rb_ops = { .invalidate = sdma_rb_invalidate };
+static int add_system_pages_to_sdma_packet(struct user_sdma_request *req, + struct user_sdma_txreq *tx, + struct user_sdma_iovec *iovec, + u32 *pkt_remaining); + static int defer_packet_queue( struct sdma_engine *sde, struct iowait_work *wait, @@ -453,6 +453,7 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd, ret = -EINVAL; goto free_req; } + /* Copy the header from the user buffer */ ret = copy_from_user(&req->hdr, iovec[idx].iov_base + sizeof(info), sizeof(req->hdr)); @@ -527,9 +528,8 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd, memcpy(&req->iovs[i].iov, iovec + idx++, sizeof(req->iovs[i].iov)); - ret = pin_vector_pages(req, &req->iovs[i]); - if (ret) { - req->data_iovs = i; + if (req->iovs[i].iov.iov_len == 0) { + ret = -EINVAL; goto free_req; } req->data_len += req->iovs[i].iov.iov_len; @@ -627,7 +627,7 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd, if (req->seqsubmitted) wait_event(pq->busy.wait_dma, (req->seqcomp == req->seqsubmitted - 1)); - user_sdma_free_request(req, true); + user_sdma_free_request(req); pq_update(pq); set_comp_state(pq, cq, info.comp_idx, ERROR, ret); } @@ -739,48 +739,6 @@ static int user_sdma_txadd_ahg(struct user_sdma_request *req, return ret; }
-static int user_sdma_txadd(struct user_sdma_request *req, - struct user_sdma_txreq *tx, - struct user_sdma_iovec *iovec, u32 datalen, - u32 *queued_ptr, u32 *data_sent_ptr, - u64 *iov_offset_ptr) -{ - int ret; - unsigned int pageidx, len; - unsigned long base, offset; - u64 iov_offset = *iov_offset_ptr; - u32 queued = *queued_ptr, data_sent = *data_sent_ptr; - struct hfi1_user_sdma_pkt_q *pq = req->pq; - - base = (unsigned long)iovec->iov.iov_base; - offset = offset_in_page(base + iovec->offset + iov_offset); - pageidx = (((iovec->offset + iov_offset + base) - (base & PAGE_MASK)) >> - PAGE_SHIFT); - len = offset + req->info.fragsize > PAGE_SIZE ? - PAGE_SIZE - offset : req->info.fragsize; - len = min((datalen - queued), len); - ret = sdma_txadd_page(pq->dd, &tx->txreq, iovec->pages[pageidx], - offset, len); - if (ret) { - SDMA_DBG(req, "SDMA txreq add page failed %d\n", ret); - return ret; - } - iov_offset += len; - queued += len; - data_sent += len; - if (unlikely(queued < datalen && pageidx == iovec->npages && - req->iov_idx < req->data_iovs - 1)) { - iovec->offset += iov_offset; - iovec = &req->iovs[++req->iov_idx]; - iov_offset = 0; - } - - *queued_ptr = queued; - *data_sent_ptr = data_sent; - *iov_offset_ptr = iov_offset; - return ret; -} - static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts) { int ret = 0; @@ -812,8 +770,7 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts) maxpkts = req->info.npkts - req->seqnum;
while (npkts < maxpkts) { - u32 datalen = 0, queued = 0, data_sent = 0; - u64 iov_offset = 0; + u32 datalen = 0;
/* * Check whether any of the completions have come back @@ -906,27 +863,17 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts) goto free_txreq; }
- /* - * If the request contains any data vectors, add up to - * fragsize bytes to the descriptor. - */ - while (queued < datalen && - (req->sent + data_sent) < req->data_len) { - ret = user_sdma_txadd(req, tx, iovec, datalen, - &queued, &data_sent, &iov_offset); - if (ret) - goto free_txreq; - } - /* - * The txreq was submitted successfully so we can update - * the counters. - */ req->koffset += datalen; if (req_opcode(req->info.ctrl) == EXPECTED) req->tidoffset += datalen; - req->sent += data_sent; - if (req->data_len) - iovec->offset += iov_offset; + req->sent += datalen; + while (datalen) { + ret = add_system_pages_to_sdma_packet(req, tx, iovec, + &datalen); + if (ret) + goto free_txreq; + iovec = &req->iovs[req->iov_idx]; + } list_add_tail(&tx->txreq.list, &req->txps); /* * It is important to increment this here as it is used to @@ -963,133 +910,14 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, u16 maxpkts) static u32 sdma_cache_evict(struct hfi1_user_sdma_pkt_q *pq, u32 npages) { struct evict_data evict_data; + struct mmu_rb_handler *handler = pq->handler;
evict_data.cleared = 0; evict_data.target = npages; - hfi1_mmu_rb_evict(pq->handler, &evict_data); + hfi1_mmu_rb_evict(handler, &evict_data); return evict_data.cleared; }
-static int pin_sdma_pages(struct user_sdma_request *req, - struct user_sdma_iovec *iovec, - struct sdma_mmu_node *node, - int npages) -{ - int pinned, cleared; - struct page **pages; - struct hfi1_user_sdma_pkt_q *pq = req->pq; - - pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL); - if (!pages) - return -ENOMEM; - memcpy(pages, node->pages, node->npages * sizeof(*pages)); - - npages -= node->npages; -retry: - if (!hfi1_can_pin_pages(pq->dd, current->mm, - atomic_read(&pq->n_locked), npages)) { - cleared = sdma_cache_evict(pq, npages); - if (cleared >= npages) - goto retry; - } - pinned = hfi1_acquire_user_pages(current->mm, - ((unsigned long)iovec->iov.iov_base + - (node->npages * PAGE_SIZE)), npages, 0, - pages + node->npages); - if (pinned < 0) { - kfree(pages); - return pinned; - } - if (pinned != npages) { - unpin_vector_pages(current->mm, pages, node->npages, pinned); - return -EFAULT; - } - kfree(node->pages); - node->rb.len = iovec->iov.iov_len; - node->pages = pages; - atomic_add(pinned, &pq->n_locked); - return pinned; -} - -static void unpin_sdma_pages(struct sdma_mmu_node *node) -{ - if (node->npages) { - unpin_vector_pages(mm_from_sdma_node(node), node->pages, 0, - node->npages); - atomic_sub(node->npages, &node->pq->n_locked); - } -} - -static int pin_vector_pages(struct user_sdma_request *req, - struct user_sdma_iovec *iovec) -{ - int ret = 0, pinned, npages; - struct hfi1_user_sdma_pkt_q *pq = req->pq; - struct sdma_mmu_node *node = NULL; - struct mmu_rb_node *rb_node; - struct iovec *iov; - bool extracted; - - extracted = - hfi1_mmu_rb_remove_unless_exact(pq->handler, - (unsigned long) - iovec->iov.iov_base, - iovec->iov.iov_len, &rb_node); - if (rb_node) { - node = container_of(rb_node, struct sdma_mmu_node, rb); - if (!extracted) { - atomic_inc(&node->refcount); - iovec->pages = node->pages; - iovec->npages = node->npages; - iovec->node = node; - return 0; - } - } - - if (!node) { - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return -ENOMEM; - - node->rb.addr = (unsigned long)iovec->iov.iov_base; - node->pq = pq; - atomic_set(&node->refcount, 0); - } - - iov = &iovec->iov; - npages = num_user_pages((unsigned long)iov->iov_base, iov->iov_len); - if (node->npages < npages) { - pinned = pin_sdma_pages(req, iovec, node, npages); - if (pinned < 0) { - ret = pinned; - goto bail; - } - node->npages += pinned; - npages = node->npages; - } - iovec->pages = node->pages; - iovec->npages = npages; - iovec->node = node; - - ret = hfi1_mmu_rb_insert(req->pq->handler, &node->rb); - if (ret) { - iovec->node = NULL; - goto bail; - } - return 0; -bail: - unpin_sdma_pages(node); - kfree(node); - return ret; -} - -static void unpin_vector_pages(struct mm_struct *mm, struct page **pages, - unsigned start, unsigned npages) -{ - hfi1_release_user_pages(mm, pages + start, npages, false); - kfree(pages); -} - static int check_header_template(struct user_sdma_request *req, struct hfi1_pkt_header *hdr, u32 lrhlen, u32 datalen) @@ -1431,7 +1259,7 @@ static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status) if (req->seqcomp != req->info.npkts - 1) return;
- user_sdma_free_request(req, false); + user_sdma_free_request(req); set_comp_state(pq, cq, req->info.comp_idx, state, status); pq_update(pq); } @@ -1442,10 +1270,8 @@ static inline void pq_update(struct hfi1_user_sdma_pkt_q *pq) wake_up(&pq->wait); }
-static void user_sdma_free_request(struct user_sdma_request *req, bool unpin) +static void user_sdma_free_request(struct user_sdma_request *req) { - int i; - if (!list_empty(&req->txps)) { struct sdma_txreq *t, *p;
@@ -1458,21 +1284,6 @@ static void user_sdma_free_request(struct user_sdma_request *req, bool unpin) } }
- for (i = 0; i < req->data_iovs; i++) { - struct sdma_mmu_node *node = req->iovs[i].node; - - if (!node) - continue; - - req->iovs[i].node = NULL; - - if (unpin) - hfi1_mmu_rb_remove(req->pq->handler, - &node->rb); - else - atomic_dec(&node->refcount); - } - kfree(req->tids); clear_bit(req->info.comp_idx, req->pq->req_in_use); } @@ -1490,6 +1301,368 @@ static inline void set_comp_state(struct hfi1_user_sdma_pkt_q *pq, idx, state, ret); }
+static void unpin_vector_pages(struct mm_struct *mm, struct page **pages, + unsigned int start, unsigned int npages) +{ + hfi1_release_user_pages(mm, pages + start, npages, false); + kfree(pages); +} + +static void free_system_node(struct sdma_mmu_node *node) +{ + if (node->npages) { + unpin_vector_pages(mm_from_sdma_node(node), node->pages, 0, + node->npages); + atomic_sub(node->npages, &node->pq->n_locked); + } + kfree(node); +} + +static inline void acquire_node(struct sdma_mmu_node *node) +{ + atomic_inc(&node->refcount); + WARN_ON(atomic_read(&node->refcount) < 0); +} + +static inline void release_node(struct mmu_rb_handler *handler, + struct sdma_mmu_node *node) +{ + atomic_dec(&node->refcount); + WARN_ON(atomic_read(&node->refcount) < 0); +} + +static struct sdma_mmu_node *find_system_node(struct mmu_rb_handler *handler, + unsigned long start, + unsigned long end) +{ + struct mmu_rb_node *rb_node; + struct sdma_mmu_node *node; + unsigned long flags; + + spin_lock_irqsave(&handler->lock, flags); + rb_node = hfi1_mmu_rb_get_first(handler, start, (end - start)); + if (!rb_node) { + spin_unlock_irqrestore(&handler->lock, flags); + return NULL; + } + node = container_of(rb_node, struct sdma_mmu_node, rb); + acquire_node(node); + spin_unlock_irqrestore(&handler->lock, flags); + + return node; +} + +static int pin_system_pages(struct user_sdma_request *req, + uintptr_t start_address, size_t length, + struct sdma_mmu_node *node, int npages) +{ + struct hfi1_user_sdma_pkt_q *pq = req->pq; + int pinned, cleared; + struct page **pages; + + pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL); + if (!pages) + return -ENOMEM; + +retry: + if (!hfi1_can_pin_pages(pq->dd, current->mm, atomic_read(&pq->n_locked), + npages)) { + SDMA_DBG(req, "Evicting: nlocked %u npages %u", + atomic_read(&pq->n_locked), npages); + cleared = sdma_cache_evict(pq, npages); + if (cleared >= npages) + goto retry; + } + + SDMA_DBG(req, "Acquire user pages start_address %lx node->npages %u npages %u", + start_address, node->npages, npages); + pinned = hfi1_acquire_user_pages(current->mm, start_address, npages, 0, + pages); + + if (pinned < 0) { + kfree(pages); + SDMA_DBG(req, "pinned %d", pinned); + return pinned; + } + if (pinned != npages) { + unpin_vector_pages(current->mm, pages, node->npages, pinned); + SDMA_DBG(req, "npages %u pinned %d", npages, pinned); + return -EFAULT; + } + node->rb.addr = start_address; + node->rb.len = length; + node->pages = pages; + node->npages = npages; + atomic_add(pinned, &pq->n_locked); + SDMA_DBG(req, "done. pinned %d", pinned); + return 0; +} + +static int add_system_pinning(struct user_sdma_request *req, + struct sdma_mmu_node **node_p, + unsigned long start, unsigned long len) + +{ + struct hfi1_user_sdma_pkt_q *pq = req->pq; + struct sdma_mmu_node *node; + int ret; + + node = kzalloc(sizeof(*node), GFP_KERNEL); + if (!node) + return -ENOMEM; + + node->pq = pq; + ret = pin_system_pages(req, start, len, node, PFN_DOWN(len)); + if (ret == 0) { + ret = hfi1_mmu_rb_insert(pq->handler, &node->rb); + if (ret) + free_system_node(node); + else + *node_p = node; + + return ret; + } + + kfree(node); + return ret; +} + +static int get_system_cache_entry(struct user_sdma_request *req, + struct sdma_mmu_node **node_p, + size_t req_start, size_t req_len) +{ + struct hfi1_user_sdma_pkt_q *pq = req->pq; + u64 start = ALIGN_DOWN(req_start, PAGE_SIZE); + u64 end = PFN_ALIGN(req_start + req_len); + struct mmu_rb_handler *handler = pq->handler; + int ret; + + if ((end - start) == 0) { + SDMA_DBG(req, + "Request for empty cache entry req_start %lx req_len %lx start %llx end %llx", + req_start, req_len, start, end); + return -EINVAL; + } + + SDMA_DBG(req, "req_start %lx req_len %lu", req_start, req_len); + + while (1) { + struct sdma_mmu_node *node = + find_system_node(handler, start, end); + u64 prepend_len = 0; + + SDMA_DBG(req, "node %p start %llx end %llu", node, start, end); + if (!node) { + ret = add_system_pinning(req, node_p, start, + end - start); + if (ret == -EEXIST) { + /* + * Another execution context has inserted a + * conficting entry first. + */ + continue; + } + return ret; + } + + if (node->rb.addr <= start) { + /* + * This entry covers at least part of the region. If it doesn't extend + * to the end, then this will be called again for the next segment. + */ + *node_p = node; + return 0; + } + + SDMA_DBG(req, "prepend: node->rb.addr %lx, node->refcount %d", + node->rb.addr, atomic_read(&node->refcount)); + prepend_len = node->rb.addr - start; + + /* + * This node will not be returned, instead a new node + * will be. So release the reference. + */ + release_node(handler, node); + + /* Prepend a node to cover the beginning of the allocation */ + ret = add_system_pinning(req, node_p, start, prepend_len); + if (ret == -EEXIST) { + /* Another execution context has inserted a conficting entry first. */ + continue; + } + return ret; + } +} + +static int add_mapping_to_sdma_packet(struct user_sdma_request *req, + struct user_sdma_txreq *tx, + struct sdma_mmu_node *cache_entry, + size_t start, + size_t from_this_cache_entry) +{ + struct hfi1_user_sdma_pkt_q *pq = req->pq; + unsigned int page_offset; + unsigned int from_this_page; + size_t page_index; + void *ctx; + int ret; + + /* + * Because the cache may be more fragmented than the memory that is being accessed, + * it's not strictly necessary to have a descriptor per cache entry. + */ + + while (from_this_cache_entry) { + page_index = PFN_DOWN(start - cache_entry->rb.addr); + + if (page_index >= cache_entry->npages) { + SDMA_DBG(req, + "Request for page_index %zu >= cache_entry->npages %u", + page_index, cache_entry->npages); + return -EINVAL; + } + + page_offset = start - ALIGN_DOWN(start, PAGE_SIZE); + from_this_page = PAGE_SIZE - page_offset; + + if (from_this_page < from_this_cache_entry) { + ctx = NULL; + } else { + /* + * In the case they are equal the next line has no practical effect, + * but it's better to do a register to register copy than a conditional + * branch. + */ + from_this_page = from_this_cache_entry; + ctx = cache_entry; + } + + ret = sdma_txadd_page(pq->dd, ctx, &tx->txreq, + cache_entry->pages[page_index], + page_offset, from_this_page); + if (ret) { + /* + * When there's a failure, the entire request is freed by + * user_sdma_send_pkts(). + */ + SDMA_DBG(req, + "sdma_txadd_page failed %d page_index %lu page_offset %u from_this_page %u", + ret, page_index, page_offset, from_this_page); + return ret; + } + start += from_this_page; + from_this_cache_entry -= from_this_page; + } + return 0; +} + +static int add_system_iovec_to_sdma_packet(struct user_sdma_request *req, + struct user_sdma_txreq *tx, + struct user_sdma_iovec *iovec, + size_t from_this_iovec) +{ + struct mmu_rb_handler *handler = req->pq->handler; + + while (from_this_iovec > 0) { + struct sdma_mmu_node *cache_entry; + size_t from_this_cache_entry; + size_t start; + int ret; + + start = (uintptr_t)iovec->iov.iov_base + iovec->offset; + ret = get_system_cache_entry(req, &cache_entry, start, + from_this_iovec); + if (ret) { + SDMA_DBG(req, "pin system segment failed %d", ret); + return ret; + } + + from_this_cache_entry = cache_entry->rb.len - (start - cache_entry->rb.addr); + if (from_this_cache_entry > from_this_iovec) + from_this_cache_entry = from_this_iovec; + + ret = add_mapping_to_sdma_packet(req, tx, cache_entry, start, + from_this_cache_entry); + if (ret) { + /* + * We're guaranteed that there will be no descriptor + * completion callback that releases this node + * because only the last descriptor referencing it + * has a context attached, and a failure means the + * last descriptor was never added. + */ + release_node(handler, cache_entry); + SDMA_DBG(req, "add system segment failed %d", ret); + return ret; + } + + iovec->offset += from_this_cache_entry; + from_this_iovec -= from_this_cache_entry; + } + + return 0; +} + +static int add_system_pages_to_sdma_packet(struct user_sdma_request *req, + struct user_sdma_txreq *tx, + struct user_sdma_iovec *iovec, + u32 *pkt_data_remaining) +{ + size_t remaining_to_add = *pkt_data_remaining; + /* + * Walk through iovec entries, ensure the associated pages + * are pinned and mapped, add data to the packet until no more + * data remains to be added. + */ + while (remaining_to_add > 0) { + struct user_sdma_iovec *cur_iovec; + size_t from_this_iovec; + int ret; + + cur_iovec = iovec; + from_this_iovec = iovec->iov.iov_len - iovec->offset; + + if (from_this_iovec > remaining_to_add) { + from_this_iovec = remaining_to_add; + } else { + /* The current iovec entry will be consumed by this pass. */ + req->iov_idx++; + iovec++; + } + + ret = add_system_iovec_to_sdma_packet(req, tx, cur_iovec, + from_this_iovec); + if (ret) + return ret; + + remaining_to_add -= from_this_iovec; + } + *pkt_data_remaining = remaining_to_add; + + return 0; +} + +void system_descriptor_complete(struct hfi1_devdata *dd, + struct sdma_desc *descp) +{ + switch (sdma_mapping_type(descp)) { + case SDMA_MAP_SINGLE: + dma_unmap_single(&dd->pcidev->dev, sdma_mapping_addr(descp), + sdma_mapping_len(descp), DMA_TO_DEVICE); + break; + case SDMA_MAP_PAGE: + dma_unmap_page(&dd->pcidev->dev, sdma_mapping_addr(descp), + sdma_mapping_len(descp), DMA_TO_DEVICE); + break; + } + + if (descp->pinning_ctx) { + struct sdma_mmu_node *node = descp->pinning_ctx; + + release_node(node->rb.handler, node); + } +} + static bool sdma_rb_filter(struct mmu_rb_node *node, unsigned long addr, unsigned long len) { @@ -1536,8 +1709,7 @@ static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode) struct sdma_mmu_node *node = container_of(mnode, struct sdma_mmu_node, rb);
- unpin_sdma_pages(node); - kfree(node); + free_system_node(node); }
static int sdma_rb_invalidate(void *arg, struct mmu_rb_node *mnode) diff --git a/drivers/infiniband/hw/hfi1/user_sdma.h b/drivers/infiniband/hw/hfi1/user_sdma.h index fabe581399068..9d417aacfa8b7 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.h +++ b/drivers/infiniband/hw/hfi1/user_sdma.h @@ -153,16 +153,11 @@ struct sdma_mmu_node { struct user_sdma_iovec { struct list_head list; struct iovec iov; - /* number of pages in this vector */ - unsigned int npages; - /* array of pinned pages for this vector */ - struct page **pages; /* * offset into the virtual address space of the vector at * which we last left off. */ u64 offset; - struct sdma_mmu_node *node; };
/* evict operation argument */ diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c index 5f3edd255ca3c..693922df3543b 100644 --- a/drivers/infiniband/hw/hfi1/verbs.c +++ b/drivers/infiniband/hw/hfi1/verbs.c @@ -820,8 +820,8 @@ static int build_verbs_tx_desc(
/* add icrc, lt byte, and padding to flit */ if (extra_bytes) - ret = sdma_txadd_daddr(sde->dd, &tx->txreq, - sde->dd->sdma_pad_phys, extra_bytes); + ret = sdma_txadd_daddr(sde->dd, &tx->txreq, sde->dd->sdma_pad_phys, + extra_bytes);
bail_txadd: return ret; diff --git a/drivers/infiniband/hw/hfi1/vnic_sdma.c b/drivers/infiniband/hw/hfi1/vnic_sdma.c index 7d90b900131ba..7658c620a125c 100644 --- a/drivers/infiniband/hw/hfi1/vnic_sdma.c +++ b/drivers/infiniband/hw/hfi1/vnic_sdma.c @@ -106,6 +106,7 @@ static noinline int build_vnic_ulp_payload(struct sdma_engine *sde,
/* combine physically continuous fragments later? */ ret = sdma_txadd_page(sde->dd, + NULL, &tx->txreq, skb_frag_page(frag), skb_frag_off(frag),
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit 40882deb83c29d8df4470d4e5e7f137b6acf7ad1 ]
The spec requires that we always at least send a RECLAIM_COMPLETE when we're done establishing the lease and recovering any state.
Fixes: fce5c838e133 ("nfs41: RECLAIM_COMPLETE functionality") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs4state.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 628e030f8e3ba..ff6ca05a9d441 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -67,6 +67,8 @@
#define OPENOWNER_POOL_SIZE 8
+static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp); + const nfs4_stateid zero_stateid = { { .data = { 0 } }, .type = NFS4_SPECIAL_STATEID_TYPE, @@ -330,6 +332,8 @@ int nfs41_init_clientid(struct nfs_client *clp, const struct cred *cred) status = nfs4_proc_create_session(clp, cred); if (status != 0) goto out; + if (!(clp->cl_exchange_flags & EXCHGID4_FLAG_CONFIRMED_R)) + nfs4_state_start_reclaim_reboot(clp); nfs41_finish_session_reset(clp); nfs_mark_client_ready(clp, NFS_CS_READY); out:
From: Nicolas Saenz Julienne nsaenzjulienne@suse.de
[ Upstream commit f663204c9a1f8d6fcc590667d9d7a9f44e064644 ]
It'll simplify the firmware handling for most consumers.
Suggested-by: Bartosz Golaszewski bgolaszewski@baylibre.com Signed-off-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de Reviewed-by: Florian Fainelli f.fainelli@gmail.com Reviewed-by: Bartosz Golaszewski bgolaszewski@baylibre.com Stable-dep-of: 5bca3688bdbc ("Input: raspberrypi-ts - fix refcount leak in rpi_ts_probe") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/raspberrypi.c | 29 ++++++++++++++++++++++ include/soc/bcm2835/raspberrypi-firmware.h | 8 ++++++ 2 files changed, 37 insertions(+)
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c index 9eef49da47e04..45ff03da234a6 100644 --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c @@ -243,6 +243,13 @@ void rpi_firmware_put(struct rpi_firmware *fw) } EXPORT_SYMBOL_GPL(rpi_firmware_put);
+static void devm_rpi_firmware_put(void *data) +{ + struct rpi_firmware *fw = data; + + rpi_firmware_put(fw); +} + static int rpi_firmware_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -338,6 +345,28 @@ struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node) } EXPORT_SYMBOL_GPL(rpi_firmware_get);
+/** + * devm_rpi_firmware_get - Get pointer to rpi_firmware structure. + * @firmware_node: Pointer to the firmware Device Tree node. + * + * Returns NULL is the firmware device is not ready. + */ +struct rpi_firmware *devm_rpi_firmware_get(struct device *dev, + struct device_node *firmware_node) +{ + struct rpi_firmware *fw; + + fw = rpi_firmware_get(firmware_node); + if (!fw) + return NULL; + + if (devm_add_action_or_reset(dev, devm_rpi_firmware_put, fw)) + return NULL; + + return fw; +} +EXPORT_SYMBOL_GPL(devm_rpi_firmware_get); + static const struct of_device_id rpi_firmware_of_match[] = { { .compatible = "raspberrypi,bcm2835-firmware", }, {}, diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h index fdfef7fe40df9..73ad784fca966 100644 --- a/include/soc/bcm2835/raspberrypi-firmware.h +++ b/include/soc/bcm2835/raspberrypi-firmware.h @@ -142,6 +142,8 @@ int rpi_firmware_property_list(struct rpi_firmware *fw, void *data, size_t tag_size); void rpi_firmware_put(struct rpi_firmware *fw); struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node); +struct rpi_firmware *devm_rpi_firmware_get(struct device *dev, + struct device_node *firmware_node); #else static inline int rpi_firmware_property(struct rpi_firmware *fw, u32 tag, void *data, size_t len) @@ -160,6 +162,12 @@ static inline struct rpi_firmware *rpi_firmware_get(struct device_node *firmware { return NULL; } + +static inline struct rpi_firmware *devm_rpi_firmware_get(struct device *dev, + struct device_node *firmware_node) +{ + return NULL; +} #endif
#endif /* __SOC_RASPBERRY_FIRMWARE_H__ */
From: Nicolas Saenz Julienne nsaenzjulienne@suse.de
[ Upstream commit 3b8ddff780b7d12e99ae39177f84b9003097777a ]
There is no use for the firmware interface after getting the touch buffer address, so release it.
Signed-off-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de Acked-by: Dmitry Torokhov dmitry.torokhov@gmail.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Stable-dep-of: 5bca3688bdbc ("Input: raspberrypi-ts - fix refcount leak in rpi_ts_probe") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/touchscreen/raspberrypi-ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/touchscreen/raspberrypi-ts.c b/drivers/input/touchscreen/raspberrypi-ts.c index ef6aaed217cfb..5000f5fd9ec38 100644 --- a/drivers/input/touchscreen/raspberrypi-ts.c +++ b/drivers/input/touchscreen/raspberrypi-ts.c @@ -160,7 +160,7 @@ static int rpi_ts_probe(struct platform_device *pdev) touchbuf = (u32)ts->fw_regs_phys; error = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF, &touchbuf, sizeof(touchbuf)); - + rpi_firmware_put(fw); if (error || touchbuf != 0) { dev_warn(dev, "Failed to set touchbuf, %d\n", error); return error;
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 5bca3688bdbc3b58a2894b8671a8e2378efe28bd ]
rpi_firmware_get() take reference, we need to release it in error paths as well. Use devm_rpi_firmware_get() helper to handling the resources. Also remove the existing rpi_firmware_put().
Fixes: 0b9f28fed3f7 ("Input: add official Raspberry Pi's touchscreen driver") Fixes: 3b8ddff780b7 ("input: raspberrypi-ts: Release firmware handle when not needed") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Mattijs Korpershoek mkorpershoek@baylibre.com Link: https://lore.kernel.org/r/20221223074657.810346-1-linmq006@gmail.com Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/touchscreen/raspberrypi-ts.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/input/touchscreen/raspberrypi-ts.c b/drivers/input/touchscreen/raspberrypi-ts.c index 5000f5fd9ec38..45c575df994e0 100644 --- a/drivers/input/touchscreen/raspberrypi-ts.c +++ b/drivers/input/touchscreen/raspberrypi-ts.c @@ -134,7 +134,7 @@ static int rpi_ts_probe(struct platform_device *pdev) return -ENOENT; }
- fw = rpi_firmware_get(fw_node); + fw = devm_rpi_firmware_get(&pdev->dev, fw_node); of_node_put(fw_node); if (!fw) return -EPROBE_DEFER; @@ -160,7 +160,6 @@ static int rpi_ts_probe(struct platform_device *pdev) touchbuf = (u32)ts->fw_regs_phys; error = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF, &touchbuf, sizeof(touchbuf)); - rpi_firmware_put(fw); if (error || touchbuf != 0) { dev_warn(dev, "Failed to set touchbuf, %d\n", error); return error;
From: Mark Bloch mbloch@nvidia.com
[ Upstream commit 3e358ea8614ddfbc59ca7a3f5dff5dde2b350b2c ]
Commit cited in "fixes" tag added bulk support for flow counters but it didn't account that's also possible to query a counter using a non-base id if the counter was allocated as bulk.
When a user performs a query, validate the flow counter id given in the mailbox is inside the valid range taking bulk value into account.
Fixes: 208d70f562e5 ("IB/mlx5: Support flow counters offset for bulk counters") Signed-off-by: Mark Bloch mbloch@nvidia.com Reviewed-by: Maor Gottlieb maorg@nvidia.com Link: https://lore.kernel.org/r/79d7fbe291690128e44672418934256254d93115.168137711... Signed-off-by: Leon Romanovsky leon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/mlx5/devx.c | 31 ++++++++++++++++++++++++++----- include/linux/mlx5/mlx5_ifc.h | 3 ++- 2 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c index 2f053f48f1beb..a56ebdc15723c 100644 --- a/drivers/infiniband/hw/mlx5/devx.c +++ b/drivers/infiniband/hw/mlx5/devx.c @@ -595,7 +595,21 @@ static bool devx_is_valid_obj_id(struct uverbs_attr_bundle *attrs, obj_id;
case MLX5_IB_OBJECT_DEVX_OBJ: - return ((struct devx_obj *)uobj->object)->obj_id == obj_id; + { + u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, in, opcode); + struct devx_obj *devx_uobj = uobj->object; + + if (opcode == MLX5_CMD_OP_QUERY_FLOW_COUNTER && + devx_uobj->flow_counter_bulk_size) { + u64 end; + + end = devx_uobj->obj_id + + devx_uobj->flow_counter_bulk_size; + return devx_uobj->obj_id <= obj_id && end > obj_id; + } + + return devx_uobj->obj_id == obj_id; + }
default: return false; @@ -1416,10 +1430,17 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)( goto obj_free;
if (opcode == MLX5_CMD_OP_ALLOC_FLOW_COUNTER) { - u8 bulk = MLX5_GET(alloc_flow_counter_in, - cmd_in, - flow_counter_bulk); - obj->flow_counter_bulk_size = 128UL * bulk; + u32 bulk = MLX5_GET(alloc_flow_counter_in, + cmd_in, + flow_counter_bulk_log_size); + + if (bulk) + bulk = 1 << bulk; + else + bulk = 128UL * MLX5_GET(alloc_flow_counter_in, + cmd_in, + flow_counter_bulk); + obj->flow_counter_bulk_size = bulk; }
uobj->object = obj; diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 6ca97729b54a4..88dbb20090805 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -8331,7 +8331,8 @@ struct mlx5_ifc_alloc_flow_counter_in_bits { u8 reserved_at_20[0x10]; u8 op_mod[0x10];
- u8 reserved_at_40[0x38]; + u8 reserved_at_40[0x33]; + u8 flow_counter_bulk_log_size[0x5]; u8 flow_counter_bulk[0x8]; };
From: Dai Ngo dai.ngo@oracle.com
[ Upstream commit 691d0b782066a6eeeecbfceb7910a8f6184e6105 ]
Currently call_bind_status places a hard limit of 3 to the number of retries on EACCES error. This limit was done to prevent NLM unlock requests from being hang forever when the server keeps returning garbage. However this change causes problem for cases when NLM service takes longer than 9 seconds to register with the port mapper after a restart.
This patch removes this hard coded limit and let the RPC handles the retry based on the standard hard/soft task semantics.
Fixes: 0b760113a3a1 ("NLM: Don't hang forever on NLM unlock requests") Reported-by: Helen Chao helen.chao@oracle.com Tested-by: Helen Chao helen.chao@oracle.com Signed-off-by: Dai Ngo dai.ngo@oracle.com Reviewed-by: Jeff Layton jlayton@kernel.org Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/sunrpc/sched.h | 3 +-- net/sunrpc/clnt.c | 3 --- net/sunrpc/sched.c | 1 - 3 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index df696efdd6753..256dff36cf720 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -90,8 +90,7 @@ struct rpc_task { #endif unsigned char tk_priority : 2,/* Task priority */ tk_garb_retry : 2, - tk_cred_retry : 2, - tk_rebind_retry : 2; + tk_cred_retry : 2; };
typedef void (*rpc_action)(struct rpc_task *); diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index c6e8bd78e35d6..e1ce0f261f0be 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1967,9 +1967,6 @@ call_bind_status(struct rpc_task *task) status = -EOPNOTSUPP; break; } - if (task->tk_rebind_retry == 0) - break; - task->tk_rebind_retry--; rpc_delay(task, 3*HZ); goto retry_timeout; case -ENOBUFS: diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index f0f55fbd13752..a00890962e115 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -796,7 +796,6 @@ rpc_init_task_statistics(struct rpc_task *task) /* Initialize retry counters */ task->tk_garb_retry = 2; task->tk_cred_retry = 2; - task->tk_rebind_retry = 2;
/* starting timestamp */ task->tk_start = ktime_get();
From: Mark Zhang markzhang@nvidia.com
[ Upstream commit 746aa3c8cb1a650ff2583497ac646e505831b9b9 ]
Just like other QP types, when modify DC, the port_num should be compared with dev->num_ports, instead of HCA_CAP.num_ports. Otherwise Multi-port vHCA on DC may not work.
Fixes: 776a3906b692 ("IB/mlx5: Add support for DC target QP") Link: https://lore.kernel.org/r/20230420013906.1244185-1-markzhang@nvidia.com Signed-off-by: Mark Zhang markzhang@nvidia.com Reviewed-by: Maor Gottlieb maorg@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/mlx5/qp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 0caff276f2c18..0c47e3e24b2a4 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -4164,7 +4164,7 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr, return -EINVAL;
if (attr->port_num == 0 || - attr->port_num > MLX5_CAP_GEN(dev->mdev, num_ports)) { + attr->port_num > dev->num_ports) { mlx5_ib_dbg(dev, "invalid port number %d. number of ports is %d\n", attr->port_num, dev->num_ports); return -EINVAL;
From: Qinrun Dai flno@hust.edu.cn
[ Upstream commit fb73556386e074e9bee9fa2d253aeaefe4e063e0 ]
Smatch reports: drivers/clocksource/timer-davinci.c:332 davinci_timer_register() warn: 'base' from ioremap() not released on lines: 274.
Fix this and other potential memory leak problems by adding a set of corresponding exit lables.
Fixes: 721154f972aa ("clocksource/drivers/davinci: Add support for clockevents") Signed-off-by: Qinrun Dai flno@hust.edu.cn Link: https://lore.kernel.org/r/20230413135037.1505799-1-flno@hust.edu.cn Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clocksource/timer-davinci.c | 30 +++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/drivers/clocksource/timer-davinci.c b/drivers/clocksource/timer-davinci.c index bb4eee31ae082..3dc0c6ceed027 100644 --- a/drivers/clocksource/timer-davinci.c +++ b/drivers/clocksource/timer-davinci.c @@ -258,21 +258,25 @@ int __init davinci_timer_register(struct clk *clk, resource_size(&timer_cfg->reg), "davinci-timer")) { pr_err("Unable to request memory region\n"); - return -EBUSY; + rv = -EBUSY; + goto exit_clk_disable; }
base = ioremap(timer_cfg->reg.start, resource_size(&timer_cfg->reg)); if (!base) { pr_err("Unable to map the register range\n"); - return -ENOMEM; + rv = -ENOMEM; + goto exit_mem_region; }
davinci_timer_init(base); tick_rate = clk_get_rate(clk);
clockevent = kzalloc(sizeof(*clockevent), GFP_KERNEL); - if (!clockevent) - return -ENOMEM; + if (!clockevent) { + rv = -ENOMEM; + goto exit_iounmap_base; + }
clockevent->dev.name = "tim12"; clockevent->dev.features = CLOCK_EVT_FEAT_ONESHOT; @@ -297,7 +301,7 @@ int __init davinci_timer_register(struct clk *clk, "clockevent/tim12", clockevent); if (rv) { pr_err("Unable to request the clockevent interrupt\n"); - return rv; + goto exit_free_clockevent; }
davinci_clocksource.dev.rating = 300; @@ -324,13 +328,27 @@ int __init davinci_timer_register(struct clk *clk, rv = clocksource_register_hz(&davinci_clocksource.dev, tick_rate); if (rv) { pr_err("Unable to register clocksource\n"); - return rv; + goto exit_free_irq; }
sched_clock_register(davinci_timer_read_sched_clock, DAVINCI_TIMER_CLKSRC_BITS, tick_rate);
return 0; + +exit_free_irq: + free_irq(timer_cfg->irq[DAVINCI_TIMER_CLOCKEVENT_IRQ].start, + clockevent); +exit_free_clockevent: + kfree(clockevent); +exit_iounmap_base: + iounmap(base); +exit_mem_region: + release_mem_region(timer_cfg->reg.start, + resource_size(&timer_cfg->reg)); +exit_clk_disable: + clk_disable_unprepare(clk); + return rv; }
static int __init of_davinci_timer_register(struct device_node *np)
From: Stafford Horne shorne@gmail.com
[ Upstream commit 812489ac4dd91144a74ce65ecf232252a2e406fb ]
In commit 91993c8c2ed5 ("openrisc: use shadow registers to save regs on exception") the unhandled exception path was changed to do an early store of r30 instead of r31. The entry code was not updated and r31 is not getting stored to pt_regs.
This patch updates the entry handler to store r31 instead of r30. We also remove some misleading commented out store r30 and r31 instructrions.
I noticed this while working on adding floating point exception handling, This issue probably would never impact anything since we kill the process or Oops right away on unhandled exceptions.
Fixes: 91993c8c2ed5 ("openrisc: use shadow registers to save regs on exception") Signed-off-by: Stafford Horne shorne@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/openrisc/kernel/entry.S | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S index b42d32d79b2e6..7257e942731df 100644 --- a/arch/openrisc/kernel/entry.S +++ b/arch/openrisc/kernel/entry.S @@ -173,7 +173,6 @@ handler: ;\ l.sw PT_GPR28(r1),r28 ;\ l.sw PT_GPR29(r1),r29 ;\ /* r30 already save */ ;\ -/* l.sw PT_GPR30(r1),r30*/ ;\ l.sw PT_GPR31(r1),r31 ;\ TRACE_IRQS_OFF_ENTRY ;\ /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ @@ -211,9 +210,8 @@ handler: ;\ l.sw PT_GPR27(r1),r27 ;\ l.sw PT_GPR28(r1),r28 ;\ l.sw PT_GPR29(r1),r29 ;\ - /* r31 already saved */ ;\ - l.sw PT_GPR30(r1),r30 ;\ -/* l.sw PT_GPR31(r1),r31 */ ;\ + /* r30 already saved */ ;\ + l.sw PT_GPR31(r1),r31 ;\ /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ l.addi r30,r0,-1 ;\ l.sw PT_ORIG_GPR11(r1),r30 ;\
From: Ye Bin yebin10@huawei.com
[ Upstream commit 835659598c67907b98cd2aa57bb951dfaf675c69 ]
Syzbot found the following issue: loop0: detected capacity change from 0 to 2048 EXT4-fs (loop0): mounted filesystem 00000000-0000-0000-0000-000000000000 without journal. Quota mode: none. ================================================================== BUG: KASAN: use-after-free in ext4_ext_binsearch_idx fs/ext4/extents.c:768 [inline] BUG: KASAN: use-after-free in ext4_find_extent+0x76e/0xd90 fs/ext4/extents.c:931 Read of size 4 at addr ffff888073644750 by task syz-executor420/5067
CPU: 0 PID: 5067 Comm: syz-executor420 Not tainted 6.2.0-rc1-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1b1/0x290 lib/dump_stack.c:106 print_address_description+0x74/0x340 mm/kasan/report.c:306 print_report+0x107/0x1f0 mm/kasan/report.c:417 kasan_report+0xcd/0x100 mm/kasan/report.c:517 ext4_ext_binsearch_idx fs/ext4/extents.c:768 [inline] ext4_find_extent+0x76e/0xd90 fs/ext4/extents.c:931 ext4_clu_mapped+0x117/0x970 fs/ext4/extents.c:5809 ext4_insert_delayed_block fs/ext4/inode.c:1696 [inline] ext4_da_map_blocks fs/ext4/inode.c:1806 [inline] ext4_da_get_block_prep+0x9e8/0x13c0 fs/ext4/inode.c:1870 ext4_block_write_begin+0x6a8/0x2290 fs/ext4/inode.c:1098 ext4_da_write_begin+0x539/0x760 fs/ext4/inode.c:3082 generic_perform_write+0x2e4/0x5e0 mm/filemap.c:3772 ext4_buffered_write_iter+0x122/0x3a0 fs/ext4/file.c:285 ext4_file_write_iter+0x1d0/0x18f0 call_write_iter include/linux/fs.h:2186 [inline] new_sync_write fs/read_write.c:491 [inline] vfs_write+0x7dc/0xc50 fs/read_write.c:584 ksys_write+0x177/0x2a0 fs/read_write.c:637 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f4b7a9737b9 RSP: 002b:00007ffc5cac3668 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f4b7a9737b9 RDX: 00000000175d9003 RSI: 0000000020000200 RDI: 0000000000000004 RBP: 00007f4b7a933050 R08: 0000000000000000 R09: 0000000000000000 R10: 000000000000079f R11: 0000000000000246 R12: 00007f4b7a9330e0 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 </TASK>
Above issue is happens when enable bigalloc and inline data feature. As commit 131294c35ed6 fixed delayed allocation bug in ext4_clu_mapped for bigalloc + inline. But it only resolved issue when has inline data, if inline data has been converted to extent(ext4_da_convert_inline_data_to_extent) before writepages, there is no EXT4_STATE_MAY_INLINE_DATA flag. However i_data is still store inline data in this scene. Then will trigger UAF when find extent. To resolve above issue, there is need to add judge "ext4_has_inline_data(inode)" in ext4_clu_mapped().
Fixes: 131294c35ed6 ("ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline") Reported-by: syzbot+bf4bb7731ef73b83a3b4@syzkaller.appspotmail.com Reviewed-by: Jan Kara jack@suse.cz Reviewed-by: Ye Bin yebin10@huawei.com Reviewed-by: Tudor Ambarus tudor.ambarus@linaro.org Tested-by: Tudor Ambarus tudor.ambarus@linaro.org Link: https://lore.kernel.org/r/20230406111627.1916759-1-tudor.ambarus@linaro.org Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ext4/extents.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 6c06ce9dd6bd8..2c2e1cc43e0e8 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5805,7 +5805,8 @@ int ext4_clu_mapped(struct inode *inode, ext4_lblk_t lclu) * mapped - no physical clusters have been allocated, and the * file has no extents */ - if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) + if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA) || + ext4_has_inline_data(inode)) return 0;
/* search for the extent closest to the first block in the cluster */
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit a61079efc87888587e463afaed82417b162fbd69 ]
REGMAP is a hidden (not user visible) symbol. Users cannot set it directly thru "make *config", so drivers should select it instead of depending on it if they need it.
Consistently using "select" or "depends on" can also help reduce Kconfig circular dependency issues.
Therefore, change the use of "depends on REGMAP" to "select REGMAP".
Fixes: 3fce8e1eb994 ("leds: TI LMU: Add common code for TI LMU devices") Signed-off-by: Randy Dunlap rdunlap@infradead.org Acked-by: Pavel Machek pavel@ucw.cz Signed-off-by: Lee Jones lee@kernel.org Link: https://lore.kernel.org/r/20230226053953.4681-5-rdunlap@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/leds/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 56e8198e13d10..ad84be4f68171 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -871,7 +871,7 @@ config LEDS_SPI_BYTE config LEDS_TI_LMU_COMMON tristate "LED driver for TI LMU" depends on LEDS_CLASS - depends on REGMAP + select REGMAP help Say Y to enable the LED driver for TI LMU devices. This supports common features between the TI LM3532, LM3631, LM3632,
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 827026ae2e56ec05ef1155661079badbbfc0b038 ]
If the probe is deferred, -EPROBE_DEFER should be returned, not +EPROBE_DEFER.
Fixes: 3cd2c313f1d6 ("dmaengine: mv_xor_v2: Fix clock resource by adding a register clock") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/201170dff832a3c496d125772e10070cd834ebf2.167981435... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/mv_xor_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/mv_xor_v2.c b/drivers/dma/mv_xor_v2.c index 4800c596433ad..9f3e011fbd914 100644 --- a/drivers/dma/mv_xor_v2.c +++ b/drivers/dma/mv_xor_v2.c @@ -756,7 +756,7 @@ static int mv_xor_v2_probe(struct platform_device *pdev)
xor_dev->clk = devm_clk_get(&pdev->dev, NULL); if (PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) { - ret = EPROBE_DEFER; + ret = -EPROBE_DEFER; goto disable_reg_clk; } if (!IS_ERR(xor_dev->clk)) {
From: H. Nikolaus Schaller hns@goldelico.com
[ Upstream commit c1087c29e96a48e9080377e168d35dcb52fb068b ]
Commit 96f524105b9c ("leds: tca6507: use fwnode API instead of OF")
changed to fwnode API but did not take into account that a missing property "linux,default-trigger" now seems to return an error and as a side effect sets value to -1. This seems to be different from of_get_property() which always returned NULL in any case of error.
Neglecting this side-effect leads to
[ 11.201965] Unable to handle kernel paging request at virtual address ffffffff when read
in the strcmp() of led_trigger_set_default() if there is no led-trigger defined in the DTS.
I don't know if this was recently introduced somewhere in the fwnode lib or if the effect was missed in initial testing. Anyways it seems to be a bug to ignore the error return value of an optional value here in the driver.
Fixes: 96f524105b9c ("leds: tca6507: use fwnode API instead of OF") Signed-off-by: H. Nikolaus Schaller hns@goldelico.com Acked-by: Pavel Machek pavel@ucw.cz Reviewed-by: Marek Behún kabel@kernel.org Signed-off-by: Lee Jones lee@kernel.org Link: https://lore.kernel.org/r/cbae7617db83113de726fcc423a805ebaa1bfca6.168043397... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/leds/leds-tca6507.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c index 225b765830bdc..caad9d3e0eac8 100644 --- a/drivers/leds/leds-tca6507.c +++ b/drivers/leds/leds-tca6507.c @@ -696,8 +696,9 @@ tca6507_led_dt_init(struct device *dev) if (fwnode_property_read_string(child, "label", &led.name)) led.name = fwnode_get_name(child);
- fwnode_property_read_string(child, "linux,default-trigger", - &led.default_trigger); + if (fwnode_property_read_string(child, "linux,default-trigger", + &led.default_trigger)) + led.default_trigger = NULL;
led.flags = 0; if (fwnode_property_match_string(child, "compatible",
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 9b7b5736ffd5da6f8f6329ebe5f1829cbcf8afae ]
pwmchip_remove() returns always 0. Don't use the value to make it possible to eventually change the function to return void. Also the driver core ignores the return value of mtk_disp_pwm_remove().
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Thierry Reding thierry.reding@gmail.com Stable-dep-of: 36dd7f530ae7 ("pwm: mtk-disp: Disable shadow registers before setting backlight values") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-mtk-disp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c index 83b8be0209b74..af63aaab8e153 100644 --- a/drivers/pwm/pwm-mtk-disp.c +++ b/drivers/pwm/pwm-mtk-disp.c @@ -240,13 +240,12 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev) static int mtk_disp_pwm_remove(struct platform_device *pdev) { struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev); - int ret;
- ret = pwmchip_remove(&mdp->chip); + pwmchip_remove(&mdp->chip); clk_unprepare(mdp->clk_mm); clk_unprepare(mdp->clk_main);
- return ret; + return 0; }
static const struct mtk_pwm_data mt2701_pwm_data = {
From: Jitao Shi jitao.shi@mediatek.com
[ Upstream commit d7a4e582587d97a586b1f7709e3bddcf35928e96 ]
The clks "main" and "mm" are prepared in .probe() (and unprepared in .remove()). This results in the clocks being on during suspend which results in unnecessarily increased power consumption.
Remove the clock operations from .probe() and .remove(). Add the clk_prepare_enable() in .enable() and the clk_disable_unprepare() in .disable().
Signed-off-by: Jitao Shi jitao.shi@mediatek.com [thierry.reding@gmail.com: squashed in fixup patch] Signed-off-by: Thierry Reding thierry.reding@gmail.com Stable-dep-of: 36dd7f530ae7 ("pwm: mtk-disp: Disable shadow registers before setting backlight values") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-mtk-disp.c | 91 +++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 50 deletions(-)
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c index af63aaab8e153..a594a0fdddd7b 100644 --- a/drivers/pwm/pwm-mtk-disp.c +++ b/drivers/pwm/pwm-mtk-disp.c @@ -74,6 +74,19 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, u64 div, rate; int err;
+ err = clk_prepare_enable(mdp->clk_main); + if (err < 0) { + dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err)); + return err; + } + + err = clk_prepare_enable(mdp->clk_mm); + if (err < 0) { + dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err)); + clk_disable_unprepare(mdp->clk_main); + return err; + } + /* * Find period, high_width and clk_div to suit duty_ns and period_ns. * Calculate proper div value to keep period value in the bound. @@ -87,8 +100,11 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, rate = clk_get_rate(mdp->clk_main); clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >> PWM_PERIOD_BIT_WIDTH; - if (clk_div > PWM_CLKDIV_MAX) + if (clk_div > PWM_CLKDIV_MAX) { + clk_disable_unprepare(mdp->clk_mm); + clk_disable_unprepare(mdp->clk_main); return -EINVAL; + }
div = NSEC_PER_SEC * (clk_div + 1); period = div64_u64(rate * period_ns, div); @@ -98,16 +114,6 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, high_width = div64_u64(rate * duty_ns, div); value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
- err = clk_enable(mdp->clk_main); - if (err < 0) - return err; - - err = clk_enable(mdp->clk_mm); - if (err < 0) { - clk_disable(mdp->clk_main); - return err; - } - mtk_disp_pwm_update_bits(mdp, mdp->data->con0, PWM_CLKDIV_MASK, clk_div << PWM_CLKDIV_SHIFT); @@ -122,10 +128,21 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, mtk_disp_pwm_update_bits(mdp, mdp->data->commit, mdp->data->commit_mask, 0x0); + } else { + /* + * For MT2701, disable double buffer before writing register + * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH. + */ + mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug, + mdp->data->bls_debug_mask, + mdp->data->bls_debug_mask); + mtk_disp_pwm_update_bits(mdp, mdp->data->con0, + mdp->data->con0_sel, + mdp->data->con0_sel); }
- clk_disable(mdp->clk_mm); - clk_disable(mdp->clk_main); + clk_disable_unprepare(mdp->clk_mm); + clk_disable_unprepare(mdp->clk_main);
return 0; } @@ -135,13 +152,16 @@ static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip); int err;
- err = clk_enable(mdp->clk_main); - if (err < 0) + err = clk_prepare_enable(mdp->clk_main); + if (err < 0) { + dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err)); return err; + }
- err = clk_enable(mdp->clk_mm); + err = clk_prepare_enable(mdp->clk_mm); if (err < 0) { - clk_disable(mdp->clk_main); + dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err)); + clk_disable_unprepare(mdp->clk_main); return err; }
@@ -158,8 +178,8 @@ static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask, 0x0);
- clk_disable(mdp->clk_mm); - clk_disable(mdp->clk_main); + clk_disable_unprepare(mdp->clk_mm); + clk_disable_unprepare(mdp->clk_main); }
static const struct pwm_ops mtk_disp_pwm_ops = { @@ -194,14 +214,6 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev) if (IS_ERR(mdp->clk_mm)) return PTR_ERR(mdp->clk_mm);
- ret = clk_prepare(mdp->clk_main); - if (ret < 0) - return ret; - - ret = clk_prepare(mdp->clk_mm); - if (ret < 0) - goto disable_clk_main; - mdp->chip.dev = &pdev->dev; mdp->chip.ops = &mtk_disp_pwm_ops; mdp->chip.base = -1; @@ -209,32 +221,13 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
ret = pwmchip_add(&mdp->chip); if (ret < 0) { - dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); - goto disable_clk_mm; + dev_err(&pdev->dev, "pwmchip_add() failed: %pe\n", ERR_PTR(ret)); + return ret; }
platform_set_drvdata(pdev, mdp);
- /* - * For MT2701, disable double buffer before writing register - * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH. - */ - if (!mdp->data->has_commit) { - mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug, - mdp->data->bls_debug_mask, - mdp->data->bls_debug_mask); - mtk_disp_pwm_update_bits(mdp, mdp->data->con0, - mdp->data->con0_sel, - mdp->data->con0_sel); - } - return 0; - -disable_clk_mm: - clk_unprepare(mdp->clk_mm); -disable_clk_main: - clk_unprepare(mdp->clk_main); - return ret; }
static int mtk_disp_pwm_remove(struct platform_device *pdev) @@ -242,8 +235,6 @@ static int mtk_disp_pwm_remove(struct platform_device *pdev) struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
pwmchip_remove(&mdp->chip); - clk_unprepare(mdp->clk_mm); - clk_unprepare(mdp->clk_main);
return 0; }
From: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com
[ Upstream commit 36dd7f530ae7d9ce9e853ffb8aa337de65c6600b ]
If shadow registers usage is not desired, disable that before performing any write to CON0/1 registers in the .apply() callback, otherwise we may lose clkdiv or period/width updates.
Fixes: cd4b45ac449a ("pwm: Add MediaTek MT2701 display PWM driver support") Signed-off-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Nícolas F. R. A. Prado nfraprado@collabora.com Tested-by: Nícolas F. R. A. Prado nfraprado@collabora.com Reviewed-by: Alexandre Mergnat amergnat@baylibre.com Tested-by: Alexandre Mergnat amergnat@baylibre.com Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-mtk-disp.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c index a594a0fdddd7b..327c780d433da 100644 --- a/drivers/pwm/pwm-mtk-disp.c +++ b/drivers/pwm/pwm-mtk-disp.c @@ -114,6 +114,19 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, high_width = div64_u64(rate * duty_ns, div); value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
+ if (mdp->data->bls_debug && !mdp->data->has_commit) { + /* + * For MT2701, disable double buffer before writing register + * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH. + */ + mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug, + mdp->data->bls_debug_mask, + mdp->data->bls_debug_mask); + mtk_disp_pwm_update_bits(mdp, mdp->data->con0, + mdp->data->con0_sel, + mdp->data->con0_sel); + } + mtk_disp_pwm_update_bits(mdp, mdp->data->con0, PWM_CLKDIV_MASK, clk_div << PWM_CLKDIV_SHIFT); @@ -128,17 +141,6 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, mtk_disp_pwm_update_bits(mdp, mdp->data->commit, mdp->data->commit_mask, 0x0); - } else { - /* - * For MT2701, disable double buffer before writing register - * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH. - */ - mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug, - mdp->data->bls_debug_mask, - mdp->data->bls_debug_mask); - mtk_disp_pwm_update_bits(mdp, mdp->data->con0, - mdp->data->con0_sel, - mdp->data->con0_sel); }
clk_disable_unprepare(mdp->clk_mm);
From: Gaosheng Cui cuigaosheng1@huawei.com
[ Upstream commit e024854048e733391b31fe5a398704b31b9af803 ]
The tegra_xusb_port_unregister should be called when usb2_port and ulpi_port map fails in tegra_xusb_add_usb2_port() or in tegra_xusb_add_ulpi_port(), fix it.
Fixes: 53d2a715c240 ("phy: Add Tegra XUSB pad controller support") Signed-off-by: Gaosheng Cui cuigaosheng1@huawei.com Acked-by: Thierry Reding treding@nvidia.com Link: https://lore.kernel.org/r/20221129111634.1547747-1-cuigaosheng1@huawei.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/tegra/xusb.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index 181a1be5f4917..d07f33ec79397 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -775,6 +775,7 @@ static int tegra_xusb_add_usb2_port(struct tegra_xusb_padctl *padctl, usb2->base.lane = usb2->base.ops->map(&usb2->base); if (IS_ERR(usb2->base.lane)) { err = PTR_ERR(usb2->base.lane); + tegra_xusb_port_unregister(&usb2->base); goto out; }
@@ -841,6 +842,7 @@ static int tegra_xusb_add_ulpi_port(struct tegra_xusb_padctl *padctl, ulpi->base.lane = ulpi->base.ops->map(&ulpi->base); if (IS_ERR(ulpi->base.lane)) { err = PTR_ERR(ulpi->base.lane); + tegra_xusb_port_unregister(&ulpi->base); goto out; }
From: Shunsuke Mie mie@igel.co.jp
[ Upstream commit a251994a441ee0a69ba7062c8cd2d08ead3db379 ]
The dw-edma driver stops after processing a DMA request even if a request remains in the issued queue, which is not the expected behavior. The DMA engine API requires continuous processing.
Add a trigger to start after one processing finished if there are requests remain.
Fixes: e63d79d1ffcd ("dmaengine: Add Synopsys eDMA IP core driver") Signed-off-by: Shunsuke Mie mie@igel.co.jp Link: https://lore.kernel.org/r/20230411101758.438472-1-mie@igel.co.jp Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/dw-edma/dw-edma-core.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index d7ed50f8b9294..a3790f7b1b530 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -166,7 +166,7 @@ static void vchan_free_desc(struct virt_dma_desc *vdesc) dw_edma_free_desc(vd2dw_edma_desc(vdesc)); }
-static void dw_edma_start_transfer(struct dw_edma_chan *chan) +static int dw_edma_start_transfer(struct dw_edma_chan *chan) { struct dw_edma_chunk *child; struct dw_edma_desc *desc; @@ -174,16 +174,16 @@ static void dw_edma_start_transfer(struct dw_edma_chan *chan)
vd = vchan_next_desc(&chan->vc); if (!vd) - return; + return 0;
desc = vd2dw_edma_desc(vd); if (!desc) - return; + return 0;
child = list_first_entry_or_null(&desc->chunk->list, struct dw_edma_chunk, list); if (!child) - return; + return 0;
dw_edma_v0_core_start(child, !desc->xfer_sz); desc->xfer_sz += child->ll_region.sz; @@ -191,6 +191,8 @@ static void dw_edma_start_transfer(struct dw_edma_chan *chan) list_del(&child->list); kfree(child); desc->chunks_alloc--; + + return 1; }
static int dw_edma_device_config(struct dma_chan *dchan, @@ -497,14 +499,14 @@ static void dw_edma_done_interrupt(struct dw_edma_chan *chan) switch (chan->request) { case EDMA_REQ_NONE: desc = vd2dw_edma_desc(vd); - if (desc->chunks_alloc) { - chan->status = EDMA_ST_BUSY; - dw_edma_start_transfer(chan); - } else { + if (!desc->chunks_alloc) { list_del(&vd->node); vchan_cookie_complete(vd); - chan->status = EDMA_ST_IDLE; } + + /* Continue transferring if there are remaining chunks or issued requests. + */ + chan->status = dw_edma_start_transfer(chan) ? EDMA_ST_BUSY : EDMA_ST_IDLE; break;
case EDMA_REQ_STOP:
From: Shunsuke Mie mie@igel.co.jp
[ Upstream commit 970b17dfe264a9085ba4e593730ecfd496b950ab ]
The issue_pending request is ignored while driver is processing a DMA request. Fix to issue the pending requests on any dma channel status.
Fixes: e63d79d1ffcd ("dmaengine: Add Synopsys eDMA IP core driver") Signed-off-by: Shunsuke Mie mie@igel.co.jp Link: https://lore.kernel.org/r/20230411101758.438472-2-mie@igel.co.jp Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/dw-edma/dw-edma-core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index a3790f7b1b530..f91dbf43a5980 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -276,9 +276,12 @@ static void dw_edma_device_issue_pending(struct dma_chan *dchan) struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan); unsigned long flags;
+ if (!chan->configured) + return; + spin_lock_irqsave(&chan->vc.lock, flags); - if (chan->configured && chan->request == EDMA_REQ_NONE && - chan->status == EDMA_ST_IDLE && vchan_issue_pending(&chan->vc)) { + if (vchan_issue_pending(&chan->vc) && chan->request == EDMA_REQ_NONE && + chan->status == EDMA_ST_IDLE) { chan->status = EDMA_ST_BUSY; dw_edma_start_transfer(chan); }
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit f8435befd81dd85b7b610598551fadf675849bc1 ]
Do not global enable all the cyclic channels in at_xdmac_resume(). Instead save the global status in at_xdmac_suspend() and re-enable the cyclic channel only if it was active before suspend.
Fixes: e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel eXtended DMA Controller driver") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20230214151827.1050280-6-claudiu.beznea@microchip.... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/at_xdmac.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index b5d691ae45dcf..1fe006cc643e7 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -212,6 +212,7 @@ struct at_xdmac { int irq; struct clk *clk; u32 save_gim; + u32 save_gs; struct dma_pool *at_xdmac_desc_pool; struct at_xdmac_chan chan[]; }; @@ -1910,6 +1911,7 @@ static int atmel_xdmac_suspend(struct device *dev) } } atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM); + atxdmac->save_gs = at_xdmac_read(atxdmac, AT_XDMAC_GS);
at_xdmac_off(atxdmac); clk_disable_unprepare(atxdmac->clk); @@ -1946,7 +1948,8 @@ static int atmel_xdmac_resume(struct device *dev) at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc); at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim); wmb(); - at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); + if (atxdmac->save_gs & atchan->mask) + at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); } } return 0;
From: Kang Chen void0red@hust.edu.cn
[ Upstream commit f05c7b7d9ea9477fcc388476c6f4ade8c66d2d26 ]
Smatch reports: 1. mtk_thermal_probe() warn: 'apmixed_base' from of_iomap() not released. 2. mtk_thermal_probe() warn: 'auxadc_base' from of_iomap() not released.
The original code forgets to release iomap resource when handling errors, fix it by switch to devm_of_iomap.
Fixes: 89945047b166 ("thermal: mediatek: Add tsensor support for V2 thermal system") Signed-off-by: Kang Chen void0red@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/20230419020749.621257-1-void0red@hust.edu.cn Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/mtk_thermal.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 0bd7aa564bc25..9fe169dbed887 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -1026,7 +1026,12 @@ static int mtk_thermal_probe(struct platform_device *pdev) return -ENODEV; }
- auxadc_base = of_iomap(auxadc, 0); + auxadc_base = devm_of_iomap(&pdev->dev, auxadc, 0, NULL); + if (IS_ERR(auxadc_base)) { + of_node_put(auxadc); + return PTR_ERR(auxadc_base); + } + auxadc_phys_base = of_get_phys_base(auxadc);
of_node_put(auxadc); @@ -1042,7 +1047,12 @@ static int mtk_thermal_probe(struct platform_device *pdev) return -ENODEV; }
- apmixed_base = of_iomap(apmixedsys, 0); + apmixed_base = devm_of_iomap(&pdev->dev, apmixedsys, 0, NULL); + if (IS_ERR(apmixed_base)) { + of_node_put(apmixedsys); + return PTR_ERR(apmixed_base); + } + apmixed_phys_base = of_get_phys_base(apmixedsys);
of_node_put(apmixedsys);
From: Matthias Schiffer matthias.schiffer@ew.tq-group.com
[ Upstream commit 1be1b23696b3d4b0231c694f5e0767b4471d33a9 ]
The I2C_DETECT register is at IO port 0x1a7, which is outside the range passed to devm_ioport_map() for io_base, and was only working because there aren't actually any bounds checks for IO port accesses.
Extending the range does not seem like a good solution here, as it would then conflict with the IO resource assigned to the I2C controller. As this is just a one-off access during probe, use a simple inb() instead.
While we're at it, drop the unused define TQMX86_REG_I2C_INT_EN.
Fixes: 2f17dd34ffed ("mfd: tqmx86: IO controller with I2C, Wachdog and GPIO") Signed-off-by: Matthias Schiffer matthias.schiffer@ew.tq-group.com Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: Lee Jones lee@kernel.org Link: https://lore.kernel.org/r/e8300a30f0791afb67d79db8089fb6004855f378.167689222... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/tqmx86.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/mfd/tqmx86.c b/drivers/mfd/tqmx86.c index 732013f40e4e8..99a59341e4492 100644 --- a/drivers/mfd/tqmx86.c +++ b/drivers/mfd/tqmx86.c @@ -45,9 +45,8 @@ #define TQMX86_REG_IO_EXT_INT_MASK 0x3 #define TQMX86_REG_IO_EXT_INT_GPIO_SHIFT 4
-#define TQMX86_REG_I2C_DETECT 0x47 +#define TQMX86_REG_I2C_DETECT 0x1a7 #define TQMX86_REG_I2C_DETECT_SOFT 0xa5 -#define TQMX86_REG_I2C_INT_EN 0x49
static uint gpio_irq; module_param(gpio_irq, uint, 0); @@ -195,7 +194,12 @@ static int tqmx86_probe(struct platform_device *pdev) "Found %s - Board ID %d, PCB Revision %d, PLD Revision %d\n", board_name, board_id, rev >> 4, rev & 0xf);
- i2c_det = ioread8(io_base + TQMX86_REG_I2C_DETECT); + /* + * The I2C_DETECT register is in the range assigned to the I2C driver + * later, so we don't extend TQMX86_IOSIZE. Use inb() for this one-off + * access instead of ioport_map + unmap. + */ + i2c_det = inb(TQMX86_REG_I2C_DETECT);
if (gpio_irq_cfg) { io_ext_int_val =
From: Matthias Schiffer matthias.schiffer@ew.tq-group.com
[ Upstream commit 16b2ad150f74db0eb91f445061f16140b5aaa650 ]
No TQMx90UC exists at the moment, and it is undecided whether ID 10 will be used eventually (and if it is, how that SoM will be named).
Signed-off-by: Matthias Schiffer matthias.schiffer@ew.tq-group.com Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: Lee Jones lee.jones@linaro.org Stable-dep-of: 051c69ff4f60 ("mfd: tqmx86: Specify IO port register range more precisely") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/tqmx86.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/drivers/mfd/tqmx86.c b/drivers/mfd/tqmx86.c index 99a59341e4492..c5c5846dcf995 100644 --- a/drivers/mfd/tqmx86.c +++ b/drivers/mfd/tqmx86.c @@ -35,7 +35,6 @@ #define TQMX86_REG_BOARD_ID_E39x 7 #define TQMX86_REG_BOARD_ID_70EB 8 #define TQMX86_REG_BOARD_ID_80UC 9 -#define TQMX86_REG_BOARD_ID_90UC 10 #define TQMX86_REG_BOARD_REV 0x21 #define TQMX86_REG_IO_EXT_INT 0x26 #define TQMX86_REG_IO_EXT_INT_NONE 0 @@ -127,8 +126,6 @@ static const char *tqmx86_board_id_to_name(u8 board_id) return "TQMx70EB"; case TQMX86_REG_BOARD_ID_80UC: return "TQMx80UC"; - case TQMX86_REG_BOARD_ID_90UC: - return "TQMx90UC"; default: return "Unknown"; } @@ -141,7 +138,6 @@ static int tqmx86_board_id_to_clk_rate(u8 board_id) case TQMX86_REG_BOARD_ID_60EB: case TQMX86_REG_BOARD_ID_70EB: case TQMX86_REG_BOARD_ID_80UC: - case TQMX86_REG_BOARD_ID_90UC: return 24000; case TQMX86_REG_BOARD_ID_E39M: case TQMX86_REG_BOARD_ID_E39C:
From: Matthias Schiffer matthias.schiffer@ew.tq-group.com
[ Upstream commit 3da48ccb1d0f3b53b1e8c9022edbedc2a6e3f50a ]
Add the board IDs for the TQMx110EB and the TQMxE40x family. All use a 24MHz LPC clock.
Signed-off-by: Matthias Schiffer matthias.schiffer@ew.tq-group.com Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: Lee Jones lee.jones@linaro.org Stable-dep-of: 051c69ff4f60 ("mfd: tqmx86: Specify IO port register range more precisely") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/tqmx86.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/drivers/mfd/tqmx86.c b/drivers/mfd/tqmx86.c index c5c5846dcf995..1db95aed5012e 100644 --- a/drivers/mfd/tqmx86.c +++ b/drivers/mfd/tqmx86.c @@ -35,6 +35,11 @@ #define TQMX86_REG_BOARD_ID_E39x 7 #define TQMX86_REG_BOARD_ID_70EB 8 #define TQMX86_REG_BOARD_ID_80UC 9 +#define TQMX86_REG_BOARD_ID_110EB 11 +#define TQMX86_REG_BOARD_ID_E40M 12 +#define TQMX86_REG_BOARD_ID_E40S 13 +#define TQMX86_REG_BOARD_ID_E40C1 14 +#define TQMX86_REG_BOARD_ID_E40C2 15 #define TQMX86_REG_BOARD_REV 0x21 #define TQMX86_REG_IO_EXT_INT 0x26 #define TQMX86_REG_IO_EXT_INT_NONE 0 @@ -126,6 +131,16 @@ static const char *tqmx86_board_id_to_name(u8 board_id) return "TQMx70EB"; case TQMX86_REG_BOARD_ID_80UC: return "TQMx80UC"; + case TQMX86_REG_BOARD_ID_110EB: + return "TQMx110EB"; + case TQMX86_REG_BOARD_ID_E40M: + return "TQMxE40M"; + case TQMX86_REG_BOARD_ID_E40S: + return "TQMxE40S"; + case TQMX86_REG_BOARD_ID_E40C1: + return "TQMxE40C1"; + case TQMX86_REG_BOARD_ID_E40C2: + return "TQMxE40C2"; default: return "Unknown"; } @@ -138,6 +153,11 @@ static int tqmx86_board_id_to_clk_rate(u8 board_id) case TQMX86_REG_BOARD_ID_60EB: case TQMX86_REG_BOARD_ID_70EB: case TQMX86_REG_BOARD_ID_80UC: + case TQMX86_REG_BOARD_ID_110EB: + case TQMX86_REG_BOARD_ID_E40M: + case TQMX86_REG_BOARD_ID_E40S: + case TQMX86_REG_BOARD_ID_E40C1: + case TQMX86_REG_BOARD_ID_E40C2: return 24000; case TQMX86_REG_BOARD_ID_E39M: case TQMX86_REG_BOARD_ID_E39C:
From: Matthias Schiffer matthias.schiffer@ew.tq-group.com
[ Upstream commit 051c69ff4f607aa114c7bbdd7c41ed881367aeee ]
Registers 0x160..0x17f are unassigned. Use 0x180 as base register and update offets accordingly.
Also change the size of the range to include 0x19f. While 0x19f is currently reserved for future extensions, so are several of the previous registers up to 0x19e, and it is weird to leave out just the last one.
Fixes: 2f17dd34ffed ("mfd: tqmx86: IO controller with I2C, Wachdog and GPIO") Signed-off-by: Matthias Schiffer matthias.schiffer@ew.tq-group.com Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: Lee Jones lee@kernel.org Link: https://lore.kernel.org/r/db4677ac318b1283c8956f637f409995a30a31c3.167689222... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/tqmx86.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/mfd/tqmx86.c b/drivers/mfd/tqmx86.c index 1db95aed5012e..c8ec0f92bc10a 100644 --- a/drivers/mfd/tqmx86.c +++ b/drivers/mfd/tqmx86.c @@ -16,8 +16,8 @@ #include <linux/platform_data/i2c-ocores.h> #include <linux/platform_device.h>
-#define TQMX86_IOBASE 0x160 -#define TQMX86_IOSIZE 0x3f +#define TQMX86_IOBASE 0x180 +#define TQMX86_IOSIZE 0x20 #define TQMX86_IOBASE_I2C 0x1a0 #define TQMX86_IOSIZE_I2C 0xa #define TQMX86_IOBASE_WATCHDOG 0x18b @@ -25,7 +25,7 @@ #define TQMX86_IOBASE_GPIO 0x18d #define TQMX86_IOSIZE_GPIO 0x4
-#define TQMX86_REG_BOARD_ID 0x20 +#define TQMX86_REG_BOARD_ID 0x00 #define TQMX86_REG_BOARD_ID_E38M 1 #define TQMX86_REG_BOARD_ID_50UC 2 #define TQMX86_REG_BOARD_ID_E38C 3 @@ -40,8 +40,8 @@ #define TQMX86_REG_BOARD_ID_E40S 13 #define TQMX86_REG_BOARD_ID_E40C1 14 #define TQMX86_REG_BOARD_ID_E40C2 15 -#define TQMX86_REG_BOARD_REV 0x21 -#define TQMX86_REG_IO_EXT_INT 0x26 +#define TQMX86_REG_BOARD_REV 0x01 +#define TQMX86_REG_IO_EXT_INT 0x06 #define TQMX86_REG_IO_EXT_INT_NONE 0 #define TQMX86_REG_IO_EXT_INT_7 1 #define TQMX86_REG_IO_EXT_INT_9 2
From: Matthias Schiffer matthias.schiffer@ew.tq-group.com
[ Upstream commit f376c479668557bcc2fd9e9fbc0f53e7819a11cd ]
It seems that this driver was developed based on preliminary documentation. Report the correct names for all TQMxE39x variants, as they are used by the released hardware revisions:
- Fix names for TQMxE39C1/C2 board IDs - Distinguish TQMxE39M and TQMxE39S, which use the same board ID
The TQMxE39M/S are distinguished using the SAUC (Sanctioned Alternate Uses Configuration) register of the GPIO controller. This also prepares for the correct handling of the differences between the GPIO controllers of our COMe and SMARC modules.
Fixes: 2f17dd34ffed ("mfd: tqmx86: IO controller with I2C, Wachdog and GPIO") Signed-off-by: Matthias Schiffer matthias.schiffer@ew.tq-group.com Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: Lee Jones lee@kernel.org Link: https://lore.kernel.org/r/aca9a7cb42a85181bcb456c437554d2728e708ec.167689222... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/tqmx86.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/drivers/mfd/tqmx86.c b/drivers/mfd/tqmx86.c index c8ec0f92bc10a..0498f1b7e2e36 100644 --- a/drivers/mfd/tqmx86.c +++ b/drivers/mfd/tqmx86.c @@ -30,9 +30,9 @@ #define TQMX86_REG_BOARD_ID_50UC 2 #define TQMX86_REG_BOARD_ID_E38C 3 #define TQMX86_REG_BOARD_ID_60EB 4 -#define TQMX86_REG_BOARD_ID_E39M 5 -#define TQMX86_REG_BOARD_ID_E39C 6 -#define TQMX86_REG_BOARD_ID_E39x 7 +#define TQMX86_REG_BOARD_ID_E39MS 5 +#define TQMX86_REG_BOARD_ID_E39C1 6 +#define TQMX86_REG_BOARD_ID_E39C2 7 #define TQMX86_REG_BOARD_ID_70EB 8 #define TQMX86_REG_BOARD_ID_80UC 9 #define TQMX86_REG_BOARD_ID_110EB 11 @@ -48,6 +48,7 @@ #define TQMX86_REG_IO_EXT_INT_12 3 #define TQMX86_REG_IO_EXT_INT_MASK 0x3 #define TQMX86_REG_IO_EXT_INT_GPIO_SHIFT 4 +#define TQMX86_REG_SAUC 0x17
#define TQMX86_REG_I2C_DETECT 0x1a7 #define TQMX86_REG_I2C_DETECT_SOFT 0xa5 @@ -110,7 +111,7 @@ static const struct mfd_cell tqmx86_devs[] = { }, };
-static const char *tqmx86_board_id_to_name(u8 board_id) +static const char *tqmx86_board_id_to_name(u8 board_id, u8 sauc) { switch (board_id) { case TQMX86_REG_BOARD_ID_E38M: @@ -121,12 +122,12 @@ static const char *tqmx86_board_id_to_name(u8 board_id) return "TQMxE38C"; case TQMX86_REG_BOARD_ID_60EB: return "TQMx60EB"; - case TQMX86_REG_BOARD_ID_E39M: - return "TQMxE39M"; - case TQMX86_REG_BOARD_ID_E39C: - return "TQMxE39C"; - case TQMX86_REG_BOARD_ID_E39x: - return "TQMxE39x"; + case TQMX86_REG_BOARD_ID_E39MS: + return (sauc == 0xff) ? "TQMxE39M" : "TQMxE39S"; + case TQMX86_REG_BOARD_ID_E39C1: + return "TQMxE39C1"; + case TQMX86_REG_BOARD_ID_E39C2: + return "TQMxE39C2"; case TQMX86_REG_BOARD_ID_70EB: return "TQMx70EB"; case TQMX86_REG_BOARD_ID_80UC: @@ -159,9 +160,9 @@ static int tqmx86_board_id_to_clk_rate(u8 board_id) case TQMX86_REG_BOARD_ID_E40C1: case TQMX86_REG_BOARD_ID_E40C2: return 24000; - case TQMX86_REG_BOARD_ID_E39M: - case TQMX86_REG_BOARD_ID_E39C: - case TQMX86_REG_BOARD_ID_E39x: + case TQMX86_REG_BOARD_ID_E39MS: + case TQMX86_REG_BOARD_ID_E39C1: + case TQMX86_REG_BOARD_ID_E39C2: return 25000; case TQMX86_REG_BOARD_ID_E38M: case TQMX86_REG_BOARD_ID_E38C: @@ -173,7 +174,7 @@ static int tqmx86_board_id_to_clk_rate(u8 board_id)
static int tqmx86_probe(struct platform_device *pdev) { - u8 board_id, rev, i2c_det, io_ext_int_val; + u8 board_id, sauc, rev, i2c_det, io_ext_int_val; struct device *dev = &pdev->dev; u8 gpio_irq_cfg, readback; const char *board_name; @@ -203,7 +204,8 @@ static int tqmx86_probe(struct platform_device *pdev) return -ENOMEM;
board_id = ioread8(io_base + TQMX86_REG_BOARD_ID); - board_name = tqmx86_board_id_to_name(board_id); + sauc = ioread8(io_base + TQMX86_REG_SAUC); + board_name = tqmx86_board_id_to_name(board_id, sauc); rev = ioread8(io_base + TQMX86_REG_BOARD_REV);
dev_info(dev,
From: Marc Dionne marc.dionne@auristor.com
[ Upstream commit d7f74e9a917503ee78f2b603a456d7227cf38919 ]
If the data version returned from the server is larger than expected, the local data is invalidated, but we may still want to note the remote file size.
Since we're setting change_size, we have to also set data_changed for the i_size to get updated.
Fixes: 3f4aa9818163 ("afs: Fix EOF corruption") Signed-off-by: Marc Dionne marc.dionne@auristor.com Signed-off-by: David Howells dhowells@redhat.com cc: linux-afs@lists.infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/afs/inode.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 826fae22a8cc9..fdca4262f806a 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -218,6 +218,7 @@ static void afs_apply_status(struct afs_operation *op, set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags); } change_size = true; + data_changed = true; } else if (vnode->status.type == AFS_FTYPE_DIR) { /* Expected directory change is handled elsewhere so * that we can locally edit the directory and save on a
From: Peng Liu liupeng17@lenovo.com
commit 7362042f3556528e9e9b1eb5ce8d7a3a6331476b upstream.
Below incompatibilities between Python2 and Python3 made lx-timerlist fail to run under Python3.
o xrange() is replaced by range() in Python3 o bytes and str are different types in Python3 o the return value of Inferior.read_memory() is memoryview object in Python3
akpm: cc stable so that older kernels are properly debuggable under newer Python.
Link: https://lkml.kernel.org/r/TYCP286MB2146EE1180A4D5176CBA8AB2C6819@TYCP286MB21... Signed-off-by: Peng Liu liupeng17@lenovo.com Reviewed-by: Jan Kiszka jan.kiszka@siemens.com Cc: Florian Fainelli f.fainelli@gmail.com Cc: Kieran Bingham kbingham@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- scripts/gdb/linux/timerlist.py | 4 +++- scripts/gdb/linux/utils.py | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-)
--- a/scripts/gdb/linux/timerlist.py +++ b/scripts/gdb/linux/timerlist.py @@ -73,7 +73,7 @@ def print_cpu(hrtimer_bases, cpu, max_cl ts = cpus.per_cpu(tick_sched_ptr, cpu)
text = "cpu: {}\n".format(cpu) - for i in xrange(max_clock_bases): + for i in range(max_clock_bases): text += " clock {}:\n".format(i) text += print_base(cpu_base['clock_base'][i])
@@ -158,6 +158,8 @@ def pr_cpumask(mask): num_bytes = (nr_cpu_ids + 7) / 8 buf = utils.read_memoryview(inf, bits, num_bytes).tobytes() buf = binascii.b2a_hex(buf) + if type(buf) is not str: + buf=buf.decode()
chunks = [] i = num_bytes --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py @@ -89,7 +89,10 @@ def get_target_endianness():
def read_memoryview(inf, start, length): - return memoryview(inf.read_memory(start, length)) + m = inf.read_memory(start, length) + if type(m) is memoryview: + return m + return memoryview(m)
def read_u16(buffer, offset):
From: Qu Wenruo wqu@suse.com
commit 604e6681e114d05a2e384c4d1e8ef81918037ef5 upstream.
Since the introduction of scrub interface, the only flag that we support is BTRFS_SCRUB_READONLY. Thus there is no sanity checks, if there are some undefined flags passed in, we just ignore them.
This is problematic if we want to introduce new scrub flags, as we have no way to determine if such flags are supported.
Address the problem by introducing a check for the flags, and if unsupported flags are set, return -EOPNOTSUPP to inform the user space.
This check should be backported for all supported kernels before any new scrub flags are introduced.
CC: stable@vger.kernel.org # 4.14+ Reviewed-by: Anand Jain anand.jain@oracle.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/ioctl.c | 5 +++++ include/uapi/linux/btrfs.h | 1 + 2 files changed, 6 insertions(+)
--- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3702,6 +3702,11 @@ static long btrfs_ioctl_scrub(struct fil if (IS_ERR(sa)) return PTR_ERR(sa);
+ if (sa->flags & ~BTRFS_SCRUB_SUPPORTED_FLAGS) { + ret = -EOPNOTSUPP; + goto out; + } + if (!(sa->flags & BTRFS_SCRUB_READONLY)) { ret = mnt_want_write_file(file); if (ret) --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -181,6 +181,7 @@ struct btrfs_scrub_progress { };
#define BTRFS_SCRUB_READONLY 1 +#define BTRFS_SCRUB_SUPPORTED_FLAGS (BTRFS_SCRUB_READONLY) struct btrfs_ioctl_scrub_args { __u64 devid; /* in */ __u64 start; /* in */
From: Stefan Haberland sth@linux.ibm.com
commit d8898ee50edecacdf0141f26fd90acf43d7e9cd7 upstream.
The DASD driver does not kick the requeue list when requeuing IO requests to the blocklayer. This might lead to hanging blockdevice when there is no other trigger for this.
Fix by automatically kick the requeue list when requeuing DASD requests to the blocklayer.
Fixes: e443343e509a ("s390/dasd: blk-mq conversion") CC: stable@vger.kernel.org # 4.14+ Signed-off-by: Stefan Haberland sth@linux.ibm.com Reviewed-by: Jan Hoeppner hoeppner@linux.ibm.com Reviewed-by: Halil Pasic pasic@linux.ibm.com Link: https://lore.kernel.org/r/20230405142017.2446986-8-sth@linux.ibm.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/block/dasd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -3000,7 +3000,7 @@ static int _dasd_requeue_request(struct return 0; spin_lock_irq(&cqr->dq->lock); req = (struct request *) cqr->callback_data; - blk_mq_requeue_request(req, false); + blk_mq_requeue_request(req, true); spin_unlock_irq(&cqr->dq->lock);
return 0;
From: Hugh Dickins hughd@google.com
commit 3647ebcfbfca384840231fe13fae665453238a61 upstream.
I know nothing of ia64 htlbpage_to_page(), but guess that the p4d line should be using taddr rather than addr, like everywhere else.
Link: https://lkml.kernel.org/r/732eae88-3beb-246-2c72-281de786740@google.com Fixes: c03ab9e32a2c ("ia64: add support for folded p4d page tables") Signed-off-by: Hugh Dickins <hughd@google.com Acked-by: Mike Kravetz mike.kravetz@oracle.com Acked-by: Mike Rapoport (IBM) rppt@kernel.org Cc: Ard Biesheuvel ardb@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/ia64/mm/hugetlbpage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c @@ -57,7 +57,7 @@ huge_pte_offset (struct mm_struct *mm, u
pgd = pgd_offset(mm, taddr); if (pgd_present(*pgd)) { - p4d = p4d_offset(pgd, addr); + p4d = p4d_offset(pgd, taddr); if (p4d_present(*p4d)) { pud = pud_offset(p4d, taddr); if (pud_present(*pud)) {
From: Mike Snitzer snitzer@kernel.org
commit 6827af4a9a9f5bb664c42abf7c11af4978d72201 upstream.
Otherwise the _hydration_cache will leak if dm_register_target() fails.
Cc: stable@vger.kernel.org Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/dm-clone-target.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/md/dm-clone-target.c +++ b/drivers/md/dm-clone-target.c @@ -2221,6 +2221,7 @@ static int __init dm_clone_init(void) r = dm_register_target(&clone_target); if (r < 0) { DMERR("Failed to register clone target"); + kmem_cache_destroy(_hydration_cache); return r; }
From: Mike Snitzer snitzer@kernel.org
commit 6b79a428c02769f2a11f8ae76bf866226d134887 upstream.
Otherwise the journal_io_cache will leak if dm_register_target() fails.
Cc: stable@vger.kernel.org Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/dm-integrity.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -4481,11 +4481,13 @@ static int __init dm_integrity_init(void }
r = dm_register_target(&integrity_target); - - if (r < 0) + if (r < 0) { DMERR("register failed %d", r); + kmem_cache_destroy(journal_io_cache); + return r; + }
- return r; + return 0; }
static void __exit dm_integrity_exit(void)
From: Mikulas Patocka mpatocka@redhat.com
commit 98dba02d9a93eec11bffbb93c7c51624290702d2 upstream.
This command will crash with NULL pointer dereference: dmsetup create flakey --table \ "0 `blockdev --getsize /dev/ram0` flakey /dev/ram0 0 0 1 2 corrupt_bio_byte 512"
Fix the crash by checking if arg_name is non-NULL before comparing it.
Cc: stable@vger.kernel.org Signed-off-by: Mikulas Patocka mpatocka@redhat.com Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/dm-flakey.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -124,9 +124,9 @@ static int parse_features(struct dm_arg_ * Direction r or w? */ arg_name = dm_shift_arg(as); - if (!strcasecmp(arg_name, "w")) + if (arg_name && !strcasecmp(arg_name, "w")) fc->corrupt_bio_rw = WRITE; - else if (!strcasecmp(arg_name, "r")) + else if (arg_name && !strcasecmp(arg_name, "r")) fc->corrupt_bio_rw = READ; else { ti->error = "Invalid corrupt bio direction (r or w)";
From: Mike Snitzer snitzer@kernel.org
commit 3d32aaa7e66d5c1479a3c31d6c2c5d45dd0d3b89 upstream.
syzkaller found the following problematic rwsem locking (with write lock already held):
down_read+0x9d/0x450 kernel/locking/rwsem.c:1509 dm_get_inactive_table+0x2b/0xc0 drivers/md/dm-ioctl.c:773 __dev_status+0x4fd/0x7c0 drivers/md/dm-ioctl.c:844 table_clear+0x197/0x280 drivers/md/dm-ioctl.c:1537
In table_clear, it first acquires a write lock https://elixir.bootlin.com/linux/v6.2/source/drivers/md/dm-ioctl.c#L1520 down_write(&_hash_lock);
Then before the lock is released at L1539, there is a path shown above: table_clear -> __dev_status -> dm_get_inactive_table -> down_read https://elixir.bootlin.com/linux/v6.2/source/drivers/md/dm-ioctl.c#L773 down_read(&_hash_lock);
It tries to acquire the same read lock again, resulting in the deadlock problem.
Fix this by moving table_clear()'s __dev_status() call to after its up_write(&_hash_lock);
Cc: stable@vger.kernel.org Reported-by: Zheng Zhang zheng.zhang@email.ucr.edu Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/dm-ioctl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -1435,11 +1435,12 @@ static int table_clear(struct file *filp hc->new_map = NULL; }
- param->flags &= ~DM_INACTIVE_PRESENT_FLAG; - - __dev_status(hc->md, param); md = hc->md; up_write(&_hash_lock); + + param->flags &= ~DM_INACTIVE_PRESENT_FLAG; + __dev_status(md, param); + if (old_map) { dm_sync_table(md); dm_table_destroy(old_map);
From: Adrian Hunter adrian.hunter@intel.com
commit 1f9f33ccf0320be21703d9195dd2b36a1c9a07cb upstream.
kallsyms is not completely in address order.
In find_entire_kern_cb(), calculate the kernel end from the maximum address not the last symbol.
Example:
Before:
$ sudo cat /proc/kallsyms | grep ' [twTw] ' | tail -1 ffffffffc00b8bd0 t bpf_prog_6deef7357e7b4530 [bpf] $ sudo cat /proc/kallsyms | grep ' [twTw] ' | sort | tail -1 ffffffffc15e0cc0 t iwl_mvm_exit [iwlmvm] $ perf.d093603a05aa record -v --kcore -e intel_pt// --filter 'filter *' -- uname |& grep filter Address filter: filter 0xffffffff93200000/0x2ceba000
After:
$ perf.8fb0f7a01f8e record -v --kcore -e intel_pt// --filter 'filter *' -- uname |& grep filter Address filter: filter 0xffffffff93200000/0x2e3e2000
Fixes: 1b36c03e356936d6 ("perf record: Add support for using symbols in address filters") Signed-off-by: Adrian Hunter adrian.hunter@intel.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Ian Rogers irogers@google.com Cc: Jiri Olsa jolsa@kernel.org Cc: Namhyung Kim namhyung@kernel.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230403154831.8651-2-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/perf/util/auxtrace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -2279,6 +2279,7 @@ static int find_entire_kern_cb(void *arg char type, u64 start) { struct sym_args *args = arg; + u64 size;
if (!kallsyms__is_function(type)) return 0; @@ -2288,7 +2289,9 @@ static int find_entire_kern_cb(void *arg args->start = start; } /* Don't know exactly where the kernel ends, so we add a page */ - args->size = round_up(start, page_size) + page_size - args->start; + size = round_up(start, page_size) + page_size - args->start; + if (size > args->size) + args->size = size;
return 0; }
From: Adrian Hunter adrian.hunter@intel.com
commit 430635a0ef1ce958b7b4311f172694ece2c692b8 upstream.
After a standalone CBR (not associated with TSC), update the cycles reference timestamp and reset the cycle count, so that CYC timestamps are calculated relative to that point with the new frequency.
Fixes: cc33618619cefc6d ("perf tools: Add Intel PT support for decoding CYC packets") Signed-off-by: Adrian Hunter adrian.hunter@intel.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Ian Rogers irogers@google.com Cc: Jiri Olsa jolsa@kernel.org Cc: Namhyung Kim namhyung@kernel.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230403154831.8651-2-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c @@ -1639,6 +1639,8 @@ static void intel_pt_calc_cbr(struct int
decoder->cbr = cbr; decoder->cbr_cyc_to_tsc = decoder->max_non_turbo_ratio_fp / cbr; + decoder->cyc_ref_timestamp = decoder->timestamp; + decoder->cycle_cnt = 0;
intel_pt_mtc_cyc_cnt_cbr(decoder); }
From: Ard Biesheuvel ardb@kernel.org
commit 2198d07c509f1db4a1185d1f65aaada794c6ea59 upstream.
All occurrences of the scs_load macro load the value of the shadow call stack pointer from the task which is current at that point. So instead of taking a task struct register argument in the scs_load macro to specify the task struct to load from, let's always reference the current task directly. This should make it much harder to exploit any instruction sequences reloading the shadow call stack pointer register from memory.
Signed-off-by: Ard Biesheuvel ardb@kernel.org Acked-by: Mark Rutland mark.rutland@arm.com Reviewed-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20230109174800.3286265-2-ardb@kernel.org Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/include/asm/scs.h | 7 ++++--- arch/arm64/kernel/entry.S | 4 ++-- arch/arm64/kernel/head.S | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-)
--- a/arch/arm64/include/asm/scs.h +++ b/arch/arm64/include/asm/scs.h @@ -9,15 +9,16 @@ #ifdef CONFIG_SHADOW_CALL_STACK scs_sp .req x18
- .macro scs_load tsk, tmp - ldr scs_sp, [\tsk, #TSK_TI_SCS_SP] + .macro scs_load_current + get_current_task scs_sp + ldr scs_sp, [scs_sp, #TSK_TI_SCS_SP] .endm
.macro scs_save tsk, tmp str scs_sp, [\tsk, #TSK_TI_SCS_SP] .endm #else - .macro scs_load tsk, tmp + .macro scs_load_current .endm
.macro scs_save tsk, tmp --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -221,7 +221,7 @@ alternative_else_nop_endif
ptrauth_keys_install_kernel tsk, x20, x22, x23
- scs_load tsk, x20 + scs_load_current .else add x21, sp, #S_FRAME_SIZE get_current_task tsk @@ -1025,7 +1025,7 @@ SYM_FUNC_START(cpu_switch_to) msr sp_el0, x1 ptrauth_keys_install_kernel x1, x8, x9, x10 scs_save x0, x8 - scs_load x1, x8 + scs_load_current ret SYM_FUNC_END(cpu_switch_to) NOKPROBE(cpu_switch_to) --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -747,7 +747,7 @@ SYM_FUNC_START_LOCAL(__secondary_switche ldr x2, [x0, #CPU_BOOT_TASK] cbz x2, __secondary_too_slow msr sp_el0, x2 - scs_load x2, x3 + scs_load_current mov x29, #0 mov x30, #0
From: Ard Biesheuvel ardb@kernel.org
commit 59b37fe52f49955791a460752c37145f1afdcad1 upstream.
Instead of reloading the shadow call stack pointer from the ordinary stack, which may be vulnerable to the kind of gadget based attacks shadow call stacks were designed to prevent, let's store a task's shadow call stack pointer in the task struct when switching to the shadow IRQ stack.
Given that currently, the task_struct::scs_sp field is only used to preserve the shadow call stack pointer while a task is scheduled out or running in user space, reusing this field to preserve and restore it while running off the IRQ stack must be safe, as those occurrences are guaranteed to never overlap. (The stack switching logic only switches stacks when running from the task stack, and so the value being saved here always corresponds to the task mode shadow stack)
While at it, fold a mov/add/mov sequence into a single add.
Signed-off-by: Ard Biesheuvel ardb@kernel.org Reviewed-by: Kees Cook keescook@chromium.org Acked-by: Mark Rutland mark.rutland@arm.com Link: https://lore.kernel.org/r/20230109174800.3286265-3-ardb@kernel.org Signed-off-by: Catalin Marinas catalin.marinas@arm.com [ardb: v5.10 backport, which doesn't have call_on_irq_stack() yet *] Signed-off-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/kernel/entry.S | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
--- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -431,9 +431,7 @@ SYM_CODE_END(__swpan_exit_el0)
.macro irq_stack_entry mov x19, sp // preserve the original sp -#ifdef CONFIG_SHADOW_CALL_STACK - mov x24, scs_sp // preserve the original shadow stack -#endif + scs_save tsk // preserve the original shadow stack
/* * Compare sp with the base of the task stack. @@ -467,9 +465,7 @@ SYM_CODE_END(__swpan_exit_el0) */ .macro irq_stack_exit mov sp, x19 -#ifdef CONFIG_SHADOW_CALL_STACK - mov scs_sp, x24 -#endif + scs_load_current .endm
/* GPRs used by entry code */
From: Thomas Gleixner tglx@linutronix.de
commit 0af462f19e635ad522f28981238334620881badc upstream.
The recent fix to ensure atomicity of lookup and allocation inadvertently broke the pool refill mechanism.
Prior to that change debug_objects_activate() and debug_objecs_assert_init() invoked debug_objecs_init() to set up the tracking object for statically initialized objects. That's not longer the case and debug_objecs_init() is now the only place which does pool refills.
Depending on the number of statically initialized objects this can be enough to actually deplete the pool, which was observed by Ido via a debugobjects OOM warning.
Restore the old behaviour by adding explicit refill opportunities to debug_objects_activate() and debug_objecs_assert_init().
Fixes: 63a759694eed ("debugobject: Prevent init race with static objects") Reported-by: Ido Schimmel idosch@nvidia.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Tested-by: Ido Schimmel idosch@nvidia.com Link: https://lore.kernel.org/r/871qk05a9d.ffs@tglx Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- lib/debugobjects.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
--- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -590,6 +590,16 @@ static struct debug_obj *lookup_object_o return NULL; }
+static void debug_objects_fill_pool(void) +{ + /* + * On RT enabled kernels the pool refill must happen in preemptible + * context: + */ + if (!IS_ENABLED(CONFIG_PREEMPT_RT) || preemptible()) + fill_pool(); +} + static void __debug_object_init(void *addr, const struct debug_obj_descr *descr, int onstack) { @@ -598,7 +608,7 @@ __debug_object_init(void *addr, const st struct debug_obj *obj; unsigned long flags;
- fill_pool(); + debug_objects_fill_pool();
db = get_bucket((unsigned long) addr);
@@ -683,6 +693,8 @@ int debug_object_activate(void *addr, co if (!debug_objects_enabled) return 0;
+ debug_objects_fill_pool(); + db = get_bucket((unsigned long) addr);
raw_spin_lock_irqsave(&db->lock, flags); @@ -892,6 +904,8 @@ void debug_object_assert_init(void *addr if (!debug_objects_enabled) return;
+ debug_objects_fill_pool(); + db = get_bucket((unsigned long) addr);
raw_spin_lock_irqsave(&db->lock, flags);
From: Miles Chen miles.chen@mediatek.com
commit 357ad4d898286b94aaae0cb7e3f573459e5b98b9 upstream.
We observed: 'dmasound_setup' defined but not used error with COMPILER=gcc ARCH=m68k DEFCONFIG=allmodconfig build.
Fix it by adding __maybe_unused to dmasound_setup.
Error(s): sound/oss/dmasound/dmasound_core.c:1431:12: error: 'dmasound_setup' defined but not used [-Werror=unused-function]
Fixes: 9dd7c46346ca ("sound/oss/dmasound: fix build when drivers are mixed =y/=m") Signed-off-by: Miles Chen miles.chen@mediatek.com Acked-by: Randy Dunlap rdunlap@infradead.org Link: https://lore.kernel.org/r/20220414091940.2216-1-miles.chen@mediatek.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/oss/dmasound/dmasound_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -1442,7 +1442,7 @@ void dmasound_deinit(void) unregister_sound_dsp(sq_unit); }
-static int dmasound_setup(char *str) +static int __maybe_unused dmasound_setup(char *str) { int ints[6], size;
From: Vincent Guittot vincent.guittot@linaro.org
commit 44750f153699b6e4f851a399287e5c8df208d696 upstream.
While stressing EAS on my dragonboard RB3, I have noticed that LITTLE cores where never selected as the most energy efficient CPU whatever the utilization level of waking task.
energy model framework uses its cost field to estimate the energy with the formula:
nrg = cost of the selected OPP * utilization / CPU's max capacity
which ends up selecting the CPU with lowest cost / max capacity ration as long as the utilization fits in the OPP's capacity.
If we compare the cost of a little OPP with similar capacity of a big OPP like : OPP(kHz) OPP capacity cost max capacity cost/max capacity LITTLE 1766400 407 351114 407 863 big 1056000 408 520267 1024 508
This can be interpreted as the LITTLE core consumes 70% more than big core for the same compute capacity.
According to [1], LITTLE consumes 10% less than big core for Coremark benchmark at those OPPs. If we consider that everything else stays unchanged, the dynamic-power-coefficient of LITTLE core should be only 53% of the current value: 290 * 53% = 154
Set the dynamic-power-coefficient of CPU0-3 to 154 to fix the energy model.
[1] https://github.com/kdrag0n/freqbench/tree/master/results/sdm845/main
Fixes: 0e0a8e35d725 ("arm64: dts: qcom: sdm845: correct dynamic power coefficients") Signed-off-by: Vincent Guittot vincent.guittot@linaro.org Signed-off-by: Bjorn Andersson andersson@kernel.org Link: https://lore.kernel.org/r/20230106164618.1845281-1-vincent.guittot@linaro.or... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -197,7 +197,7 @@ &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; capacity-dmips-mhz = <611>; - dynamic-power-coefficient = <290>; + dynamic-power-coefficient = <154>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, @@ -222,7 +222,7 @@ &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; capacity-dmips-mhz = <611>; - dynamic-power-coefficient = <290>; + dynamic-power-coefficient = <154>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, @@ -244,7 +244,7 @@ &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; capacity-dmips-mhz = <611>; - dynamic-power-coefficient = <290>; + dynamic-power-coefficient = <154>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>, @@ -266,7 +266,7 @@ &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; capacity-dmips-mhz = <611>; - dynamic-power-coefficient = <290>; + dynamic-power-coefficient = <154>; qcom,freq-domain = <&cpufreq_hw 0>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gladiator_noc MASTER_APPSS_PROC 3 &mem_noc SLAVE_EBI1 3>,
From: Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com
commit 70ca3c57ff914113f681e657634f7fbfa68e1ad1 upstream.
The BUG message "BUG: using smp_processor_id() in preemptible [00000000] code" was observed for TCMU devices with kernel config DEBUG_PREEMPT.
The message was observed when blktests block/005 was run on TCMU devices with fileio backend or user:zbc backend [1]. The commit 1130b499b4a7 ("scsi: target: tcm_loop: Use LIO wq cmd submission helper") triggered the symptom. The commit modified work queue to handle commands and changed 'current->nr_cpu_allowed' at smp_processor_id() call.
The message was also observed at system shutdown when TCMU devices were not cleaned up [2]. The function smp_processor_id() was called in SCSI host work queue for abort handling, and triggered the BUG message. This symptom was observed regardless of the commit 1130b499b4a7 ("scsi: target: tcm_loop: Use LIO wq cmd submission helper").
To avoid the preemptible code check at smp_processor_id(), get CPU ID with raw_smp_processor_id() instead. The CPU ID is used for performance improvement then thread move to other CPU will not affect the code.
[1]
[ 56.468103] run blktests block/005 at 2021-05-12 14:16:38 [ 57.369473] check_preemption_disabled: 85 callbacks suppressed [ 57.369480] BUG: using smp_processor_id() in preemptible [00000000] code: fio/1511 [ 57.369506] BUG: using smp_processor_id() in preemptible [00000000] code: fio/1510 [ 57.369512] BUG: using smp_processor_id() in preemptible [00000000] code: fio/1506 [ 57.369552] caller is __target_init_cmd+0x157/0x170 [target_core_mod] [ 57.369606] CPU: 4 PID: 1506 Comm: fio Not tainted 5.13.0-rc1+ #34 [ 57.369613] Hardware name: System manufacturer System Product Name/PRIME Z270-A, BIOS 1302 03/15/2018 [ 57.369617] Call Trace: [ 57.369621] BUG: using smp_processor_id() in preemptible [00000000] code: fio/1507 [ 57.369628] dump_stack+0x6d/0x89 [ 57.369642] check_preemption_disabled+0xc8/0xd0 [ 57.369628] caller is __target_init_cmd+0x157/0x170 [target_core_mod] [ 57.369655] __target_init_cmd+0x157/0x170 [target_core_mod] [ 57.369695] target_init_cmd+0x76/0x90 [target_core_mod] [ 57.369732] tcm_loop_queuecommand+0x109/0x210 [tcm_loop] [ 57.369744] scsi_queue_rq+0x38e/0xc40 [ 57.369761] __blk_mq_try_issue_directly+0x109/0x1c0 [ 57.369779] blk_mq_try_issue_directly+0x43/0x90 [ 57.369790] blk_mq_submit_bio+0x4e5/0x5d0 [ 57.369812] submit_bio_noacct+0x46e/0x4e0 [ 57.369830] __blkdev_direct_IO_simple+0x1a3/0x2d0 [ 57.369859] ? set_init_blocksize.isra.0+0x60/0x60 [ 57.369880] generic_file_read_iter+0x89/0x160 [ 57.369898] blkdev_read_iter+0x44/0x60 [ 57.369906] new_sync_read+0x102/0x170 [ 57.369929] vfs_read+0xd4/0x160 [ 57.369941] __x64_sys_pread64+0x6e/0xa0 [ 57.369946] ? lockdep_hardirqs_on+0x79/0x100 [ 57.369958] do_syscall_64+0x3a/0x70 [ 57.369965] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 57.369973] RIP: 0033:0x7f7ed4c1399f [ 57.369979] Code: 08 89 3c 24 48 89 4c 24 18 e8 7d f3 ff ff 4c 8b 54 24 18 48 8b 54 24 10 41 89 c0 48 8b 74 24 08 8b 3c 24 b8 11 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 31 44 89 c7 48 89 04 24 e8 cd f3 ff ff 48 8b [ 57.369983] RSP: 002b:00007ffd7918c580 EFLAGS: 00000293 ORIG_RAX: 0000000000000011 [ 57.369990] RAX: ffffffffffffffda RBX: 00000000015b4540 RCX: 00007f7ed4c1399f [ 57.369993] RDX: 0000000000001000 RSI: 00000000015de000 RDI: 0000000000000009 [ 57.369996] RBP: 00000000015b4540 R08: 0000000000000000 R09: 0000000000000001 [ 57.369999] R10: 0000000000e5c000 R11: 0000000000000293 R12: 00007f7eb5269a70 [ 57.370002] R13: 0000000000000000 R14: 0000000000001000 R15: 00000000015b4568 [ 57.370031] CPU: 7 PID: 1507 Comm: fio Not tainted 5.13.0-rc1+ #34 [ 57.370036] Hardware name: System manufacturer System Product Name/PRIME Z270-A, BIOS 1302 03/15/2018 [ 57.370039] Call Trace: [ 57.370045] dump_stack+0x6d/0x89 [ 57.370056] check_preemption_disabled+0xc8/0xd0 [ 57.370068] __target_init_cmd+0x157/0x170 [target_core_mod] [ 57.370121] target_init_cmd+0x76/0x90 [target_core_mod] [ 57.370178] tcm_loop_queuecommand+0x109/0x210 [tcm_loop] [ 57.370197] scsi_queue_rq+0x38e/0xc40 [ 57.370224] __blk_mq_try_issue_directly+0x109/0x1c0 ...
[2]
[ 117.458597] BUG: using smp_processor_id() in preemptible [00000000] code: kworker/u16:8 [ 117.467279] caller is __target_init_cmd+0x157/0x170 [target_core_mod] [ 117.473893] CPU: 1 PID: 418 Comm: kworker/u16:6 Not tainted 5.13.0-rc1+ #34 [ 117.481150] Hardware name: System manufacturer System Product Name/PRIME Z270-A, BIOS 8 [ 117.481153] Workqueue: scsi_tmf_7 scmd_eh_abort_handler [ 117.481156] Call Trace: [ 117.481158] dump_stack+0x6d/0x89 [ 117.481162] check_preemption_disabled+0xc8/0xd0 [ 117.512575] target_submit_tmr+0x41/0x150 [target_core_mod] [ 117.519705] tcm_loop_issue_tmr+0xa7/0x100 [tcm_loop] [ 117.524913] tcm_loop_abort_task+0x43/0x60 [tcm_loop] [ 117.530137] scmd_eh_abort_handler+0x7b/0x230 [ 117.534681] process_one_work+0x268/0x580 [ 117.538862] worker_thread+0x55/0x3b0 [ 117.542652] ? process_one_work+0x580/0x580 [ 117.548351] kthread+0x143/0x160 [ 117.551675] ? kthread_create_worker_on_cpu+0x40/0x40 [ 117.556873] ret_from_fork+0x1f/0x30
Link: https://lore.kernel.org/r/20210515070315.215801-1-shinichiro.kawasaki@wdc.co... Fixes: 1526d9f10c61 ("scsi: target: Make state_list per CPU") Cc: stable@vger.kernel.org # v5.11+ Reviewed-by: Mike Christie michael.christie@oracle.com Signed-off-by: Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/target/target_core_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1396,7 +1396,7 @@ void transport_init_se_cmd( cmd->orig_fe_lun = unpacked_lun;
if (!(cmd->se_cmd_flags & SCF_USE_CPUID)) - cmd->cpuid = smp_processor_id(); + cmd->cpuid = raw_smp_processor_id();
cmd->state_active = false; }
From: Pablo Neira Ayuso pablo@netfilter.org
commit c1592a89942e9678f7d9c8030efa777c0d57edab upstream.
Toggle deleted anonymous sets as inactive in the next generation, so users cannot perform any update on it. Clear the generation bitmask in case the transaction is aborted.
The following KASAN splat shows a set element deletion for a bound anonymous set that has been already removed in the same transaction.
[ 64.921510] ================================================================== [ 64.923123] BUG: KASAN: wild-memory-access in nf_tables_commit+0xa24/0x1490 [nf_tables] [ 64.924745] Write of size 8 at addr dead000000000122 by task test/890 [ 64.927903] CPU: 3 PID: 890 Comm: test Not tainted 6.3.0+ #253 [ 64.931120] Call Trace: [ 64.932699] <TASK> [ 64.934292] dump_stack_lvl+0x33/0x50 [ 64.935908] ? nf_tables_commit+0xa24/0x1490 [nf_tables] [ 64.937551] kasan_report+0xda/0x120 [ 64.939186] ? nf_tables_commit+0xa24/0x1490 [nf_tables] [ 64.940814] nf_tables_commit+0xa24/0x1490 [nf_tables] [ 64.942452] ? __kasan_slab_alloc+0x2d/0x60 [ 64.944070] ? nf_tables_setelem_notify+0x190/0x190 [nf_tables] [ 64.945710] ? kasan_set_track+0x21/0x30 [ 64.947323] nfnetlink_rcv_batch+0x709/0xd90 [nfnetlink] [ 64.948898] ? nfnetlink_rcv_msg+0x480/0x480 [nfnetlink]
Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/net/netfilter/nf_tables.h | 1 + net/netfilter/nf_tables_api.c | 12 ++++++++++++ net/netfilter/nft_dynset.c | 2 +- net/netfilter/nft_lookup.c | 2 +- net/netfilter/nft_objref.c | 2 +- 5 files changed, 16 insertions(+), 3 deletions(-)
--- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -507,6 +507,7 @@ struct nft_set_binding { };
enum nft_trans_phase; +void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set); void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, struct nft_set_binding *binding, enum nft_trans_phase phase); --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -4479,12 +4479,24 @@ static void nf_tables_unbind_set(const s } }
+void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set) +{ + if (nft_set_is_anonymous(set)) + nft_clear(ctx->net, set); + + set->use++; +} +EXPORT_SYMBOL_GPL(nf_tables_activate_set); + void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, struct nft_set_binding *binding, enum nft_trans_phase phase) { switch (phase) { case NFT_TRANS_PREPARE: + if (nft_set_is_anonymous(set)) + nft_deactivate_next(ctx->net, set); + set->use--; return; case NFT_TRANS_ABORT: --- a/net/netfilter/nft_dynset.c +++ b/net/netfilter/nft_dynset.c @@ -233,7 +233,7 @@ static void nft_dynset_activate(const st { struct nft_dynset *priv = nft_expr_priv(expr);
- priv->set->use++; + nf_tables_activate_set(ctx, priv->set); }
static void nft_dynset_destroy(const struct nft_ctx *ctx, --- a/net/netfilter/nft_lookup.c +++ b/net/netfilter/nft_lookup.c @@ -132,7 +132,7 @@ static void nft_lookup_activate(const st { struct nft_lookup *priv = nft_expr_priv(expr);
- priv->set->use++; + nf_tables_activate_set(ctx, priv->set); }
static void nft_lookup_destroy(const struct nft_ctx *ctx, --- a/net/netfilter/nft_objref.c +++ b/net/netfilter/nft_objref.c @@ -180,7 +180,7 @@ static void nft_objref_map_activate(cons { struct nft_objref_map *priv = nft_expr_priv(expr);
- priv->set->use++; + nf_tables_activate_set(ctx, priv->set); }
static void nft_objref_map_destroy(const struct nft_ctx *ctx,
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
[ Upstream commit 98602c010ceba82f2c2384122dbd07bc965fd367 ]
There are a number of functions and #defines in include/linux/tty.h that do not belong there as they are private to the tty core code.
Create an initial drivers/tty/tty.h file and copy the odd "tty logging" macros into it to seed the file with some initial things that we know nothing outside of the tty core should be calling.
Cc: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp Cc: Jiri Slaby jirislaby@kernel.org Link: https://lore.kernel.org/r/20210408125134.3016837-2-gregkh@linuxfoundation.or... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Stable-dep-of: 094fb49a2d0d ("tty: Prevent writing chars during tcsetattr TCSADRAIN/FLUSH") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_tty.c | 1 + drivers/tty/pty.c | 1 + drivers/tty/tty.h | 21 +++++++++++++++++++++ drivers/tty/tty_io.c | 1 + drivers/tty/tty_jobctrl.c | 1 + drivers/tty/tty_ldisc.c | 1 + drivers/tty/tty_port.c | 1 + include/linux/tty.h | 12 ------------ 8 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 drivers/tty/tty.h
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 12dde01e576b5..8e7931d935438 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -49,6 +49,7 @@ #include <linux/module.h> #include <linux/ratelimit.h> #include <linux/vmalloc.h> +#include "tty.h"
/* * Until this number of characters is queued in the xmit buffer, select will diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 16498f5fba64d..ca3e5a6c1a497 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -29,6 +29,7 @@ #include <linux/file.h> #include <linux/ioctl.h> #include <linux/compat.h> +#include "tty.h"
#undef TTY_DEBUG_HANGUP #ifdef TTY_DEBUG_HANGUP diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h new file mode 100644 index 0000000000000..f4cd20261e914 --- /dev/null +++ b/drivers/tty/tty.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * TTY core internal functions + */ + +#ifndef _TTY_INTERNAL_H +#define _TTY_INTERNAL_H + +#define tty_msg(fn, tty, f, ...) \ + fn("%s %s: " f, tty_driver_name(tty), tty_name(tty), ##__VA_ARGS__) + +#define tty_debug(tty, f, ...) tty_msg(pr_debug, tty, f, ##__VA_ARGS__) +#define tty_info(tty, f, ...) tty_msg(pr_info, tty, f, ##__VA_ARGS__) +#define tty_notice(tty, f, ...) tty_msg(pr_notice, tty, f, ##__VA_ARGS__) +#define tty_warn(tty, f, ...) tty_msg(pr_warn, tty, f, ##__VA_ARGS__) +#define tty_err(tty, f, ...) tty_msg(pr_err, tty, f, ##__VA_ARGS__) + +#define tty_info_ratelimited(tty, f, ...) \ + tty_msg(pr_info_ratelimited, tty, f, ##__VA_ARGS__) + +#endif diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index c37d2657308cd..86fbfe42ce0ac 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -108,6 +108,7 @@
#include <linux/kmod.h> #include <linux/nsproxy.h> +#include "tty.h"
#undef TTY_DEBUG_HANGUP #ifdef TTY_DEBUG_HANGUP diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c index aa6d0537b379e..95d67613b25b6 100644 --- a/drivers/tty/tty_jobctrl.c +++ b/drivers/tty/tty_jobctrl.c @@ -11,6 +11,7 @@ #include <linux/tty.h> #include <linux/fcntl.h> #include <linux/uaccess.h> +#include "tty.h"
static int is_ignored(int sig) { diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index fe37ec331289b..c23938b8628d1 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -19,6 +19,7 @@ #include <linux/seq_file.h> #include <linux/uaccess.h> #include <linux/ratelimit.h> +#include "tty.h"
#undef LDISC_DEBUG_HANGUP
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index ea80bf872f543..cbb56f725bc4a 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -18,6 +18,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/serdev.h> +#include "tty.h"
static int tty_port_default_receive_buf(struct tty_port *port, const unsigned char *p, diff --git a/include/linux/tty.h b/include/linux/tty.h index 5972f43b9d5ae..9e3725589214e 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -786,16 +786,4 @@ static inline void proc_tty_register_driver(struct tty_driver *d) {} static inline void proc_tty_unregister_driver(struct tty_driver *d) {} #endif
-#define tty_msg(fn, tty, f, ...) \ - fn("%s %s: " f, tty_driver_name(tty), tty_name(tty), ##__VA_ARGS__) - -#define tty_debug(tty, f, ...) tty_msg(pr_debug, tty, f, ##__VA_ARGS__) -#define tty_info(tty, f, ...) tty_msg(pr_info, tty, f, ##__VA_ARGS__) -#define tty_notice(tty, f, ...) tty_msg(pr_notice, tty, f, ##__VA_ARGS__) -#define tty_warn(tty, f, ...) tty_msg(pr_warn, tty, f, ##__VA_ARGS__) -#define tty_err(tty, f, ...) tty_msg(pr_err, tty, f, ##__VA_ARGS__) - -#define tty_info_ratelimited(tty, f, ...) \ - tty_msg(pr_info_ratelimited, tty, f, ##__VA_ARGS__) - #endif
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
[ Upstream commit da5d669e00d2c437b3f508d60add417fc74f4bb6 ]
The functions tty_audit_add_data() and tty_audit_tiocsti() are local to the tty core code, and do not need to be in a "kernel-wide" header file so move them to drivers/tty/tty.h
Cc: Jiri Slaby jirislaby@kernel.org Link: https://lore.kernel.org/r/20210408125134.3016837-9-gregkh@linuxfoundation.or... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Stable-dep-of: 094fb49a2d0d ("tty: Prevent writing chars during tcsetattr TCSADRAIN/FLUSH") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/tty.h | 14 ++++++++++++++ drivers/tty/tty_audit.c | 1 + include/linux/tty.h | 10 ---------- 3 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index f4cd20261e914..f131d538b62b9 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -18,4 +18,18 @@ #define tty_info_ratelimited(tty, f, ...) \ tty_msg(pr_info_ratelimited, tty, f, ##__VA_ARGS__)
+/* tty_audit.c */ +#ifdef CONFIG_AUDIT +void tty_audit_add_data(struct tty_struct *tty, const void *data, size_t size); +void tty_audit_tiocsti(struct tty_struct *tty, char ch); +#else +static inline void tty_audit_add_data(struct tty_struct *tty, const void *data, + size_t size) +{ +} +static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch) +{ +} +#endif + #endif diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c index 9f906a5b8e810..9b30edee71fe9 100644 --- a/drivers/tty/tty_audit.c +++ b/drivers/tty/tty_audit.c @@ -10,6 +10,7 @@ #include <linux/audit.h> #include <linux/slab.h> #include <linux/tty.h> +#include "tty.h"
struct tty_audit_buf { struct mutex mutex; /* Protects all data below */ diff --git a/include/linux/tty.h b/include/linux/tty.h index 9e3725589214e..a1a9c4b8210ea 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -731,20 +731,10 @@ static inline void n_tty_init(void) { }
/* tty_audit.c */ #ifdef CONFIG_AUDIT -extern void tty_audit_add_data(struct tty_struct *tty, const void *data, - size_t size); extern void tty_audit_exit(void); extern void tty_audit_fork(struct signal_struct *sig); -extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); extern int tty_audit_push(void); #else -static inline void tty_audit_add_data(struct tty_struct *tty, const void *data, - size_t size) -{ -} -static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch) -{ -} static inline void tty_audit_exit(void) { }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
[ Upstream commit 6c80c0b94b94192d9a34b400f8237703c6475f4d ]
Move the TTY_LOCK_* enums and tty_ldisc lock functions out of the global tty.h into the local header file to clean things up.
Cc: Jiri Slaby jirislaby@kernel.org Link: https://lore.kernel.org/r/20210408125134.3016837-10-gregkh@linuxfoundation.o... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Stable-dep-of: 094fb49a2d0d ("tty: Prevent writing chars during tcsetattr TCSADRAIN/FLUSH") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/tty.h | 26 ++++++++++++++++++++++++++ drivers/tty/tty_buffer.c | 2 +- drivers/tty/tty_mutex.c | 1 + include/linux/tty.h | 26 -------------------------- 4 files changed, 28 insertions(+), 27 deletions(-)
diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index f131d538b62b9..552e263e02dfb 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -18,6 +18,32 @@ #define tty_info_ratelimited(tty, f, ...) \ tty_msg(pr_info_ratelimited, tty, f, ##__VA_ARGS__)
+/* + * Lock subclasses for tty locks + * + * TTY_LOCK_NORMAL is for normal ttys and master ptys. + * TTY_LOCK_SLAVE is for slave ptys only. + * + * Lock subclasses are necessary for handling nested locking with pty pairs. + * tty locks which use nested locking: + * + * legacy_mutex - Nested tty locks are necessary for releasing pty pairs. + * The stable lock order is master pty first, then slave pty. + * termios_rwsem - The stable lock order is tty_buffer lock->termios_rwsem. + * Subclassing this lock enables the slave pty to hold its + * termios_rwsem when claiming the master tty_buffer lock. + * tty_buffer lock - slave ptys can claim nested buffer lock when handling + * signal chars. The stable lock order is slave pty, then + * master. + */ +enum { + TTY_LOCK_NORMAL = 0, + TTY_LOCK_SLAVE, +}; + +int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout); +void tty_ldisc_unlock(struct tty_struct *tty); + /* tty_audit.c */ #ifdef CONFIG_AUDIT void tty_audit_add_data(struct tty_struct *tty, const void *data, size_t size); diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 5bbc2e010b483..9f23798155573 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -17,7 +17,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/ratelimit.h> - +#include "tty.h"
#define MIN_TTYB_SIZE 256 #define TTYB_ALIGN_MASK 255 diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index 2640635ee177d..393518a24cfe2 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c @@ -4,6 +4,7 @@ #include <linux/kallsyms.h> #include <linux/semaphore.h> #include <linux/sched.h> +#include "tty.h"
/* Legacy tty mutex glue */
diff --git a/include/linux/tty.h b/include/linux/tty.h index a1a9c4b8210ea..af398d0aa9fdc 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -16,30 +16,6 @@ #include <linux/llist.h>
-/* - * Lock subclasses for tty locks - * - * TTY_LOCK_NORMAL is for normal ttys and master ptys. - * TTY_LOCK_SLAVE is for slave ptys only. - * - * Lock subclasses are necessary for handling nested locking with pty pairs. - * tty locks which use nested locking: - * - * legacy_mutex - Nested tty locks are necessary for releasing pty pairs. - * The stable lock order is master pty first, then slave pty. - * termios_rwsem - The stable lock order is tty_buffer lock->termios_rwsem. - * Subclassing this lock enables the slave pty to hold its - * termios_rwsem when claiming the master tty_buffer lock. - * tty_buffer lock - slave ptys can claim nested buffer lock when handling - * signal chars. The stable lock order is slave pty, then - * master. - */ - -enum { - TTY_LOCK_NORMAL = 0, - TTY_LOCK_SLAVE, -}; - /* * (Note: the *_driver.minor_start values 1, 64, 128, 192 are * hardcoded at present.) @@ -419,8 +395,6 @@ extern const char *tty_name(const struct tty_struct *tty); extern struct tty_struct *tty_kopen(dev_t device); extern void tty_kclose(struct tty_struct *tty); extern int tty_dev_name_to_number(const char *name, dev_t *number); -extern int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout); -extern void tty_ldisc_unlock(struct tty_struct *tty); extern ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *); #else static inline void tty_kref_put(struct tty_struct *tty)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
[ Upstream commit 9f72cab1596327e1011ab4599c07b165e0fb45db ]
The flow change and restricted_tty_write() logic is internal to the tty core only, so move it out of the include/linux/tty.h file.
Cc: Jiri Slaby jirislaby@kernel.org Link: https://lore.kernel.org/r/20210408125134.3016837-12-gregkh@linuxfoundation.o... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Stable-dep-of: 094fb49a2d0d ("tty: Prevent writing chars during tcsetattr TCSADRAIN/FLUSH") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/tty.h | 17 +++++++++++++++++ drivers/tty/tty_ioctl.c | 1 + include/linux/tty.h | 16 ---------------- 3 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index 552e263e02dfb..9eda9e5f8ad5e 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -41,6 +41,21 @@ enum { TTY_LOCK_SLAVE, };
+/* Values for tty->flow_change */ +#define TTY_THROTTLE_SAFE 1 +#define TTY_UNTHROTTLE_SAFE 2 + +static inline void __tty_set_flow_change(struct tty_struct *tty, int val) +{ + tty->flow_change = val; +} + +static inline void tty_set_flow_change(struct tty_struct *tty, int val) +{ + tty->flow_change = val; + smp_mb(); +} + int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout); void tty_ldisc_unlock(struct tty_struct *tty);
@@ -58,4 +73,6 @@ static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch) } #endif
+ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *); + #endif diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 803da2d111c8c..50e65784fbf77 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -21,6 +21,7 @@ #include <linux/bitops.h> #include <linux/mutex.h> #include <linux/compat.h> +#include "tty.h"
#include <asm/io.h> #include <linux/uaccess.h> diff --git a/include/linux/tty.h b/include/linux/tty.h index af398d0aa9fdc..a641fc6a7fa8b 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -350,21 +350,6 @@ struct tty_file_private { #define TTY_LDISC_CHANGING 20 /* Change pending - non-block IO */ #define TTY_LDISC_HALTED 22 /* Line discipline is halted */
-/* Values for tty->flow_change */ -#define TTY_THROTTLE_SAFE 1 -#define TTY_UNTHROTTLE_SAFE 2 - -static inline void __tty_set_flow_change(struct tty_struct *tty, int val) -{ - tty->flow_change = val; -} - -static inline void tty_set_flow_change(struct tty_struct *tty, int val) -{ - tty->flow_change = val; - smp_mb(); -} - static inline bool tty_io_nonblock(struct tty_struct *tty, struct file *file) { return file->f_flags & O_NONBLOCK || @@ -395,7 +380,6 @@ extern const char *tty_name(const struct tty_struct *tty); extern struct tty_struct *tty_kopen(dev_t device); extern void tty_kclose(struct tty_struct *tty); extern int tty_dev_name_to_number(const char *name, dev_t *number); -extern ssize_t redirected_tty_write(struct kiocb *, struct iov_iter *); #else static inline void tty_kref_put(struct tty_struct *tty) { }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
[ Upstream commit 5ffa6e344a1c92a27c242f500fc74e6eb361a4bc ]
There are a lot of tty-core-only functions that are listed in include/linux/tty.h. Move them to drivers/tty/tty.h so that no one else can accidentally call them or think that they are public functions.
Cc: Jiri Slaby jirislaby@kernel.org Link: https://lore.kernel.org/r/20210408125134.3016837-14-gregkh@linuxfoundation.o... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Stable-dep-of: 094fb49a2d0d ("tty: Prevent writing chars during tcsetattr TCSADRAIN/FLUSH") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/n_gsm.c | 1 + drivers/tty/n_hdlc.c | 1 + drivers/tty/tty.h | 37 +++++++++++++++++++++++++++++++++++++ drivers/tty/tty_baudrate.c | 1 + include/linux/tty.h | 33 --------------------------------- 5 files changed, 40 insertions(+), 33 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index f5063499f9cf6..23b014b8c9199 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -50,6 +50,7 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/gsmmux.h> +#include "tty.h"
static int debug; module_param(debug, int, 0600); diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index 48c64e68017cd..697199a3ca019 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -100,6 +100,7 @@
#include <asm/termios.h> #include <linux/uaccess.h> +#include "tty.h"
/* * Buffers for individual HDLC frames diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index 9eda9e5f8ad5e..74ed99bc5449a 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -59,6 +59,43 @@ static inline void tty_set_flow_change(struct tty_struct *tty, int val) int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout); void tty_ldisc_unlock(struct tty_struct *tty);
+int __tty_check_change(struct tty_struct *tty, int sig); +int tty_check_change(struct tty_struct *tty); +void __stop_tty(struct tty_struct *tty); +void __start_tty(struct tty_struct *tty); +void tty_vhangup_session(struct tty_struct *tty); +void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty); +int tty_signal_session_leader(struct tty_struct *tty, int exit_session); +void session_clear_tty(struct pid *session); +void tty_buffer_free_all(struct tty_port *port); +void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld); +void tty_buffer_init(struct tty_port *port); +void tty_buffer_set_lock_subclass(struct tty_port *port); +bool tty_buffer_restart_work(struct tty_port *port); +bool tty_buffer_cancel_work(struct tty_port *port); +void tty_buffer_flush_work(struct tty_port *port); +speed_t tty_termios_input_baud_rate(struct ktermios *termios); +void tty_ldisc_hangup(struct tty_struct *tty, bool reset); +int tty_ldisc_reinit(struct tty_struct *tty, int disc); +long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +long tty_jobctrl_ioctl(struct tty_struct *tty, struct tty_struct *real_tty, + struct file *file, unsigned int cmd, unsigned long arg); +void tty_default_fops(struct file_operations *fops); +struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx); +int tty_alloc_file(struct file *file); +void tty_add_file(struct tty_struct *tty, struct file *file); +void tty_free_file(struct file *file); +int tty_release(struct inode *inode, struct file *filp); + +#define tty_is_writelocked(tty) (mutex_is_locked(&tty->atomic_write_lock)) + +int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty); +void tty_ldisc_release(struct tty_struct *tty); +int __must_check tty_ldisc_init(struct tty_struct *tty); +void tty_ldisc_deinit(struct tty_struct *tty); + +void tty_sysctl_init(void); + /* tty_audit.c */ #ifdef CONFIG_AUDIT void tty_audit_add_data(struct tty_struct *tty, const void *data, size_t size); diff --git a/drivers/tty/tty_baudrate.c b/drivers/tty/tty_baudrate.c index 84fec3c62d6a4..9d0093d84e085 100644 --- a/drivers/tty/tty_baudrate.c +++ b/drivers/tty/tty_baudrate.c @@ -8,6 +8,7 @@ #include <linux/termios.h> #include <linux/tty.h> #include <linux/export.h> +#include "tty.h"
/* diff --git a/include/linux/tty.h b/include/linux/tty.h index a641fc6a7fa8b..e51d75f5165b5 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -432,11 +432,7 @@ static inline struct tty_struct *tty_kref_get(struct tty_struct *tty)
extern const char *tty_driver_name(const struct tty_struct *tty); extern void tty_wait_until_sent(struct tty_struct *tty, long timeout); -extern int __tty_check_change(struct tty_struct *tty, int sig); -extern int tty_check_change(struct tty_struct *tty); -extern void __stop_tty(struct tty_struct *tty); extern void stop_tty(struct tty_struct *tty); -extern void __start_tty(struct tty_struct *tty); extern void start_tty(struct tty_struct *tty); extern int tty_register_driver(struct tty_driver *driver); extern int tty_unregister_driver(struct tty_driver *driver); @@ -461,23 +457,11 @@ extern int tty_do_resize(struct tty_struct *tty, struct winsize *ws); extern int is_current_pgrp_orphaned(void); extern void tty_hangup(struct tty_struct *tty); extern void tty_vhangup(struct tty_struct *tty); -extern void tty_vhangup_session(struct tty_struct *tty); extern int tty_hung_up_p(struct file *filp); extern void do_SAK(struct tty_struct *tty); extern void __do_SAK(struct tty_struct *tty); -extern void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty); -extern int tty_signal_session_leader(struct tty_struct *tty, int exit_session); -extern void session_clear_tty(struct pid *session); extern void no_tty(void); -extern void tty_buffer_free_all(struct tty_port *port); -extern void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld); -extern void tty_buffer_init(struct tty_port *port); -extern void tty_buffer_set_lock_subclass(struct tty_port *port); -extern bool tty_buffer_restart_work(struct tty_port *port); -extern bool tty_buffer_cancel_work(struct tty_port *port); -extern void tty_buffer_flush_work(struct tty_port *port); extern speed_t tty_termios_baud_rate(struct ktermios *termios); -extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); extern void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud); extern void tty_encode_baud_rate(struct tty_struct *tty, @@ -505,27 +489,16 @@ extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt); extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); extern void tty_ldisc_deref(struct tty_ldisc *); extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *); -extern void tty_ldisc_hangup(struct tty_struct *tty, bool reset); -extern int tty_ldisc_reinit(struct tty_struct *tty, int disc); extern const struct seq_operations tty_ldiscs_seq_ops;
extern void tty_wakeup(struct tty_struct *tty); extern void tty_ldisc_flush(struct tty_struct *tty);
-extern long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); extern int tty_mode_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); -extern long tty_jobctrl_ioctl(struct tty_struct *tty, struct tty_struct *real_tty, - struct file *file, unsigned int cmd, unsigned long arg); extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg); -extern void tty_default_fops(struct file_operations *fops); -extern struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx); -extern int tty_alloc_file(struct file *file); -extern void tty_add_file(struct tty_struct *tty, struct file *file); -extern void tty_free_file(struct file *file); extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); extern void tty_release_struct(struct tty_struct *tty, int idx); -extern int tty_release(struct inode *inode, struct file *filp); extern void tty_init_termios(struct tty_struct *tty); extern void tty_save_termios(struct tty_struct *tty); extern int tty_standard_install(struct tty_driver *driver, @@ -533,8 +506,6 @@ extern int tty_standard_install(struct tty_driver *driver,
extern struct mutex tty_mutex;
-#define tty_is_writelocked(tty) (mutex_is_locked(&tty->atomic_write_lock)) - extern void tty_port_init(struct tty_port *port); extern void tty_port_link_device(struct tty_port *port, struct tty_driver *driver, unsigned index); @@ -672,10 +643,6 @@ static inline int tty_port_users(struct tty_port *port) extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); extern int tty_unregister_ldisc(int disc); extern int tty_set_ldisc(struct tty_struct *tty, int disc); -extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty); -extern void tty_ldisc_release(struct tty_struct *tty); -extern int __must_check tty_ldisc_init(struct tty_struct *tty); -extern void tty_ldisc_deinit(struct tty_struct *tty); extern int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p, char *f, int count);
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
[ Upstream commit 094fb49a2d0d6827c86d2e0840873e6db0c491d2 ]
If userspace races tcsetattr() with a write, the drained condition might not be guaranteed by the kernel. There is a race window after checking Tx is empty before tty_set_termios() takes termios_rwsem for write. During that race window, more characters can be queued by a racing writer.
Any ongoing transmission might produce garbage during HW's ->set_termios() call. The intent of TCSADRAIN/FLUSH seems to be preventing such a character corruption. If those flags are set, take tty's write lock to stop any writer before performing the lower layer Tx empty check and wait for the pending characters to be sent (if any).
The initial wait for all-writers-done must be placed outside of tty's write lock to avoid deadlock which makes it impossible to use tty_wait_until_sent(). The write lock is retried if a racing write is detected.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Link: https://lore.kernel.org/r/20230317113318.31327-2-ilpo.jarvinen@linux.intel.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/tty.h | 2 ++ drivers/tty/tty_io.c | 4 ++-- drivers/tty/tty_ioctl.c | 45 ++++++++++++++++++++++++++++++----------- 3 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index 74ed99bc5449a..1908f27a795a0 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -63,6 +63,8 @@ int __tty_check_change(struct tty_struct *tty, int sig); int tty_check_change(struct tty_struct *tty); void __stop_tty(struct tty_struct *tty); void __start_tty(struct tty_struct *tty); +void tty_write_unlock(struct tty_struct *tty); +int tty_write_lock(struct tty_struct *tty, int ndelay); void tty_vhangup_session(struct tty_struct *tty); void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty); int tty_signal_session_leader(struct tty_struct *tty, int exit_session); diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 86fbfe42ce0ac..094e82a12d298 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -942,13 +942,13 @@ static ssize_t tty_read(struct kiocb *iocb, struct iov_iter *to) return i; }
-static void tty_write_unlock(struct tty_struct *tty) +void tty_write_unlock(struct tty_struct *tty) { mutex_unlock(&tty->atomic_write_lock); wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT); }
-static int tty_write_lock(struct tty_struct *tty, int ndelay) +int tty_write_lock(struct tty_struct *tty, int ndelay) { if (!mutex_trylock(&tty->atomic_write_lock)) { if (ndelay) diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 50e65784fbf77..68b07250dcb60 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -398,21 +398,42 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
- ld = tty_ldisc_ref(tty); + if (opt & (TERMIOS_FLUSH|TERMIOS_WAIT)) { +retry_write_wait: + retval = wait_event_interruptible(tty->write_wait, !tty_chars_in_buffer(tty)); + if (retval < 0) + return retval;
- if (ld != NULL) { - if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) - ld->ops->flush_buffer(tty); - tty_ldisc_deref(ld); - } + if (tty_write_lock(tty, 0) < 0) + goto retry_write_wait;
- if (opt & TERMIOS_WAIT) { - tty_wait_until_sent(tty, 0); - if (signal_pending(current)) - return -ERESTARTSYS; - } + /* Racing writer? */ + if (tty_chars_in_buffer(tty)) { + tty_write_unlock(tty); + goto retry_write_wait; + }
- tty_set_termios(tty, &tmp_termios); + ld = tty_ldisc_ref(tty); + if (ld != NULL) { + if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) + ld->ops->flush_buffer(tty); + tty_ldisc_deref(ld); + } + + if ((opt & TERMIOS_WAIT) && tty->ops->wait_until_sent) { + tty->ops->wait_until_sent(tty, 0); + if (signal_pending(current)) { + tty_write_unlock(tty); + return -ERESTARTSYS; + } + } + + tty_set_termios(tty, &tmp_termios); + + tty_write_unlock(tty); + } else { + tty_set_termios(tty, &tmp_termios); + }
/* FIXME: Arguably if tmp_termios == tty->termios AND the actual requested termios was not tmp_termios then we may
From: Tze-nan Wu Tze-nan.Wu@mediatek.com
[ Upstream commit 7c339fb4d8577792378136c15fde773cfb863cb8 ]
In ring_buffer_reset_online_cpus, the buffer_size_kb write operation may permanently fail if the cpu_online_mask changes between two for_each_online_buffer_cpu loops. The number of increases and decreases on both cpu_buffer->resize_disabled and cpu_buffer->record_disabled may be inconsistent, causing some CPUs to have non-zero values for these atomic variables after the function returns.
This issue can be reproduced by "echo 0 > trace" while hotplugging cpu. After reproducing success, we can find out buffer_size_kb will not be functional anymore.
To prevent leaving 'resize_disabled' and 'record_disabled' non-zero after ring_buffer_reset_online_cpus returns, we ensure that each atomic variable has been set up before atomic_sub() to it.
Link: https://lore.kernel.org/linux-trace-kernel/20230426062027.17451-1-Tze-nan.Wu...
Cc: stable@vger.kernel.org Cc: mhiramat@kernel.org Cc: npiggin@gmail.com Fixes: b23d7a5f4a07 ("ring-buffer: speed up buffer resets by avoiding synchronize_rcu for each CPU") Reviewed-by: Cheng-Jui Wang cheng-jui.wang@mediatek.com Signed-off-by: Tze-nan Wu Tze-nan.Wu@mediatek.com Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/trace/ring_buffer.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 1fe6b29366f10..f08904914166b 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -5051,6 +5051,9 @@ void ring_buffer_reset_cpu(struct trace_buffer *buffer, int cpu) } EXPORT_SYMBOL_GPL(ring_buffer_reset_cpu);
+/* Flag to ensure proper resetting of atomic variables */ +#define RESET_BIT (1 << 30) + /** * ring_buffer_reset_cpu - reset a ring buffer per CPU buffer * @buffer: The ring buffer to reset a per cpu buffer of @@ -5067,20 +5070,27 @@ void ring_buffer_reset_online_cpus(struct trace_buffer *buffer) for_each_online_buffer_cpu(buffer, cpu) { cpu_buffer = buffer->buffers[cpu];
- atomic_inc(&cpu_buffer->resize_disabled); + atomic_add(RESET_BIT, &cpu_buffer->resize_disabled); atomic_inc(&cpu_buffer->record_disabled); }
/* Make sure all commits have finished */ synchronize_rcu();
- for_each_online_buffer_cpu(buffer, cpu) { + for_each_buffer_cpu(buffer, cpu) { cpu_buffer = buffer->buffers[cpu];
+ /* + * If a CPU came online during the synchronize_rcu(), then + * ignore it. + */ + if (!(atomic_read(&cpu_buffer->resize_disabled) & RESET_BIT)) + continue; + reset_disabled_cpu_buffer(cpu_buffer);
atomic_dec(&cpu_buffer->record_disabled); - atomic_dec(&cpu_buffer->resize_disabled); + atomic_sub(RESET_BIT, &cpu_buffer->resize_disabled); }
mutex_unlock(&buffer->mutex);
From: Jeremi Piotrowski jpiotrowski@linux.microsoft.com
[ Upstream commit 45121ad4a1750ca47ce3f32bd434bdb0cdbf0043 ]
The PSP IRQ is edge-triggered (MSI or MSI-X) in all cases supported by the psp module so clear the interrupt status register early in the handler to prevent missed interrupts. sev_irq_handler() calls wake_up() on a wait queue, which can result in a new command being submitted from a different CPU. This then races with the clearing of isr and can result in missed interrupts. A missed interrupt results in a command waiting until it times out, which results in the psp being declared dead.
This is unlikely on bare metal, but has been observed when running virtualized. In the cases where this is observed, sev->cmdresp_reg has PSP_CMDRESP_RESP set which indicates that the command was processed correctly but no interrupt was asserted.
The full sequence of events looks like this:
CPU 1: submits SEV cmd #1 CPU 1: calls wait_event_timeout() CPU 0: enters psp_irq_handler() CPU 0: calls sev_handler()->wake_up() CPU 1: wakes up; finishes processing cmd #1 CPU 1: submits SEV cmd #2 CPU 1: calls wait_event_timeout() PSP: finishes processing cmd #2; interrupt status is still set; no interrupt CPU 0: clears intsts CPU 0: exits psp_irq_handler() CPU 1: wait_event_timeout() times out; psp_dead=true
Fixes: 200664d5237f ("crypto: ccp: Add Secure Encrypted Virtualization (SEV) command support") Cc: stable@vger.kernel.org Signed-off-by: Jeremi Piotrowski jpiotrowski@linux.microsoft.com Acked-by: Tom Lendacky thomas.lendacky@amd.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/ccp/psp-dev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c index ae7b445999144..4bf9eaab4456f 100644 --- a/drivers/crypto/ccp/psp-dev.c +++ b/drivers/crypto/ccp/psp-dev.c @@ -42,6 +42,9 @@ static irqreturn_t psp_irq_handler(int irq, void *data) /* Read the interrupt status: */ status = ioread32(psp->io_regs + psp->vdata->intsts_reg);
+ /* Clear the interrupt status by writing the same value we read. */ + iowrite32(status, psp->io_regs + psp->vdata->intsts_reg); + /* invoke subdevice interrupt handlers */ if (status) { if (psp->sev_irq_handler) @@ -51,9 +54,6 @@ static irqreturn_t psp_irq_handler(int irq, void *data) psp->tee_irq_handler(irq, psp->tee_irq_data, status); }
- /* Clear the interrupt status by writing the same value we read. */ - iowrite32(status, psp->io_regs + psp->vdata->intsts_reg); - return IRQ_HANDLED; }
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 043f85ce81cb1714e14d31c322c5646513dde3fb ]
Using flexible array is more straight forward. It - saves 1 pointer in the 'zynqmp_ipi_pdata' structure - saves an indirection when using this array - saves some LoC and avoids some always spurious pointer arithmetic
Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Stable-dep-of: f72f805e7288 ("mailbox: zynqmp: Fix counts of child nodes") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/zynqmp-ipi-mailbox.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c index 05e36229622e3..136a84ad871cc 100644 --- a/drivers/mailbox/zynqmp-ipi-mailbox.c +++ b/drivers/mailbox/zynqmp-ipi-mailbox.c @@ -110,7 +110,7 @@ struct zynqmp_ipi_pdata { unsigned int method; u32 local_id; int num_mboxes; - struct zynqmp_ipi_mbox *ipi_mboxes; + struct zynqmp_ipi_mbox ipi_mboxes[]; };
static struct device_driver zynqmp_ipi_mbox_driver = { @@ -635,7 +635,7 @@ static int zynqmp_ipi_probe(struct platform_device *pdev) int num_mboxes, ret = -EINVAL;
num_mboxes = of_get_child_count(np); - pdata = devm_kzalloc(dev, sizeof(*pdata) + (num_mboxes * sizeof(*mbox)), + pdata = devm_kzalloc(dev, struct_size(pdata, ipi_mboxes, num_mboxes), GFP_KERNEL); if (!pdata) return -ENOMEM; @@ -649,8 +649,6 @@ static int zynqmp_ipi_probe(struct platform_device *pdev) }
pdata->num_mboxes = num_mboxes; - pdata->ipi_mboxes = (struct zynqmp_ipi_mbox *) - ((char *)pdata + sizeof(*pdata));
mbox = pdata->ipi_mboxes; for_each_available_child_of_node(np, nc) {
From: Tanmay Shah tanmay.shah@amd.com
[ Upstream commit f72f805e72882c361e2a612c64a6e549f3da7152 ]
If child mailbox node status is disabled it causes crash in interrupt handler. Fix this by assigning only available child node during driver probe.
Fixes: 4981b82ba2ff ("mailbox: ZynqMP IPI mailbox controller") Signed-off-by: Tanmay Shah tanmay.shah@amd.com Acked-by: Michal Simek michal.simek@amd.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230311012407.1292118-2-tanmay.shah@amd.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/zynqmp-ipi-mailbox.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c index 136a84ad871cc..be06de791c544 100644 --- a/drivers/mailbox/zynqmp-ipi-mailbox.c +++ b/drivers/mailbox/zynqmp-ipi-mailbox.c @@ -634,7 +634,12 @@ static int zynqmp_ipi_probe(struct platform_device *pdev) struct zynqmp_ipi_mbox *mbox; int num_mboxes, ret = -EINVAL;
- num_mboxes = of_get_child_count(np); + num_mboxes = of_get_available_child_count(np); + if (num_mboxes == 0) { + dev_err(dev, "mailbox nodes not available\n"); + return -EINVAL; + } + pdata = devm_kzalloc(dev, struct_size(pdata, ipi_mboxes, num_mboxes), GFP_KERNEL); if (!pdata)
From: Akilesh Kailash akailash@google.com
[ Upstream commit 2c0468e054c0adb660ac055fc396622ec7235df9 ]
Without FEC, dm-verity won't call verity_handle_err() when I/O fails, but with FEC enabled, it currently does even if an I/O error has occurred.
If there is an I/O error and FEC correction fails, return the error instead of calling verity_handle_err() again.
Suggested-by: Sami Tolvanen samitolvanen@google.com Signed-off-by: Akilesh Kailash akailash@google.com Reviewed-by: Sami Tolvanen samitolvanen@google.com Signed-off-by: Mike Snitzer snitzer@redhat.com Stable-dep-of: e8c5d45f82ce ("dm verity: fix error handling for check_at_most_once on FEC") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/dm-verity-target.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index c801f6b93b7b4..d9c388e6ce76c 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -475,6 +475,7 @@ static int verity_verify_io(struct dm_verity_io *io) struct bvec_iter start; unsigned b; struct crypto_wait wait; + struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
for (b = 0; b < io->n_blocks; b++) { int r; @@ -529,9 +530,17 @@ static int verity_verify_io(struct dm_verity_io *io) else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_DATA, cur_block, NULL, &start) == 0) continue; - else if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA, - cur_block)) - return -EIO; + else { + if (bio->bi_status) { + /* + * Error correction failed; Just return error + */ + return -EIO; + } + if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA, + cur_block)) + return -EIO; + } }
return 0;
From: Yeongjin Gil youngjin.gil@samsung.com
[ Upstream commit e8c5d45f82ce0c238a4817739892fe8897a3dcc3 ]
In verity_end_io(), if bi_status is not BLK_STS_OK, it can be return directly. But if FEC configured, it is desired to correct the data page through verity_verify_io. And the return value will be converted to blk_status and passed to verity_finish_io().
BTW, when a bit is set in v->validated_blocks, verity_verify_io() skips verification regardless of I/O error for the corresponding bio. In this case, the I/O error could not be returned properly, and as a result, there is a problem that abnormal data could be read for the corresponding block.
To fix this problem, when an I/O error occurs, do not skip verification even if the bit related is set in v->validated_blocks.
Fixes: 843f38d382b1 ("dm verity: add 'check_at_most_once' option to only validate hashes once") Cc: stable@vger.kernel.org Reviewed-by: Sungjong Seo sj1557.seo@samsung.com Signed-off-by: Yeongjin Gil youngjin.gil@samsung.com Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/dm-verity-target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index d9c388e6ce76c..0c2048d2b847e 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -482,7 +482,7 @@ static int verity_verify_io(struct dm_verity_io *io) sector_t cur_block = io->block + b; struct ahash_request *req = verity_io_hash_req(v, io);
- if (v->validated_blocks && + if (v->validated_blocks && bio->bi_status == BLK_STS_OK && likely(test_bit(cur_block, v->validated_blocks))) { verity_bv_skip_block(v, io, &io->iter); continue;
From: Yeongjin Gil youngjin.gil@samsung.com
[ Upstream commit e8c5d45f82ce0c238a4817739892fe8897a3dcc3 ]
In verity_end_io(), if bi_status is not BLK_STS_OK, it can be return directly. But if FEC configured, it is desired to correct the data page through verity_verify_io. And the return value will be converted to blk_status and passed to verity_finish_io().
BTW, when a bit is set in v->validated_blocks, verity_verify_io() skips verification regardless of I/O error for the corresponding bio. In this case, the I/O error could not be returned properly, and as a result, there is a problem that abnormal data could be read for the corresponding block.
To fix this problem, when an I/O error occurs, do not skip verification even if the bit related is set in v->validated_blocks.
Fixes: 843f38d382b1 ("dm verity: add 'check_at_most_once' option to only validate hashes once") Cc: stable@vger.kernel.org Reviewed-by: Sungjong Seo sj1557.seo@samsung.com Signed-off-by: Yeongjin Gil youngjin.gil@samsung.com Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
Hello Greg. This patch is the wrong patch I mentioned :( Please check the v2 patch I sent yesterday. If you are still confused, would it be better to change mail subject and send v3?
drivers/md/dm-verity-target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index d9c388e6ce76c..0c2048d2b847e 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -482,7 +482,7 @@ static int verity_verify_io(struct dm_verity_io *io) sector_t cur_block = io->block + b; struct ahash_request *req = verity_io_hash_req(v, io);
if (v->validated_blocks &&
likely(test_bit(cur_block, v->validated_blocks))) { verity_bv_skip_block(v, io, &io->iter); continue;if (v->validated_blocks && bio->bi_status == BLK_STS_OK &&
-- 2.39.2
From: Yeongjin Gil youngjin.gil@samsung.com
[ Upstream commit e8c5d45f82ce0c238a4817739892fe8897a3dcc3 ]
In verity_end_io(), if bi_status is not BLK_STS_OK, it can be return directly. But if FEC configured, it is desired to correct the data page through verity_verify_io. And the return value will be converted to blk_status and passed to verity_finish_io().
BTW, when a bit is set in v->validated_blocks, verity_verify_io() skips verification regardless of I/O error for the corresponding bio. In this case, the I/O error could not be returned properly, and as a result, there is a problem that abnormal data could be read for the
corresponding block.
To fix this problem, when an I/O error occurs, do not skip verification even if the bit related is set in v->validated_blocks.
Fixes: 843f38d382b1 ("dm verity: add 'check_at_most_once' option to only validate hashes once") Cc: stable@vger.kernel.org Reviewed-by: Sungjong Seo sj1557.seo@samsung.com Signed-off-by: Yeongjin Gil youngjin.gil@samsung.com Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
Hello Greg. This patch is the wrong patch I mentioned :( Please check the v2 patch I sent yesterday. If you are still confused, would it be better to change mail subject and send v3?
I checked that the previous patch was queued in stable kernel. (dm verity: skip redundant verity_handle_err() on I/O errors) I didn't know how to handle dependent commit in stable kernel. There is no problem with the below current patch. Thank you and I'm sorry for confusion.
drivers/md/dm-verity-target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index d9c388e6ce76c..0c2048d2b847e 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -482,7 +482,7 @@ static int verity_verify_io(struct dm_verity_io *io) sector_t cur_block = io->block + b; struct ahash_request *req = verity_io_hash_req(v, io);
if (v->validated_blocks &&
likely(test_bit(cur_block, v->validated_blocks))) { verity_bv_skip_block(v, io, &io->iter); continue;if (v->validated_blocks && bio->bi_status == BLK_STS_OK &&
-- 2.39.2
On Tue, May 16, 2023 at 10:38:30AM +0900, Yeongjin Gil wrote:
From: Yeongjin Gil youngjin.gil@samsung.com
[ Upstream commit e8c5d45f82ce0c238a4817739892fe8897a3dcc3 ]
In verity_end_io(), if bi_status is not BLK_STS_OK, it can be return directly. But if FEC configured, it is desired to correct the data page through verity_verify_io. And the return value will be converted to blk_status and passed to verity_finish_io().
BTW, when a bit is set in v->validated_blocks, verity_verify_io() skips verification regardless of I/O error for the corresponding bio. In this case, the I/O error could not be returned properly, and as a result, there is a problem that abnormal data could be read for the
corresponding block.
To fix this problem, when an I/O error occurs, do not skip verification even if the bit related is set in v->validated_blocks.
Fixes: 843f38d382b1 ("dm verity: add 'check_at_most_once' option to only validate hashes once") Cc: stable@vger.kernel.org Reviewed-by: Sungjong Seo sj1557.seo@samsung.com Signed-off-by: Yeongjin Gil youngjin.gil@samsung.com Signed-off-by: Mike Snitzer snitzer@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
Hello Greg. This patch is the wrong patch I mentioned :( Please check the v2 patch I sent yesterday. If you are still confused, would it be better to change mail subject and send v3?
I checked that the previous patch was queued in stable kernel. (dm verity: skip redundant verity_handle_err() on I/O errors)
It is queued up, see the full series for details.
I didn't know how to handle dependent commit in stable kernel.
The documentation shows how to do this.
There is no problem with the below current patch. Thank you and I'm sorry for confusion.
Thanks for checking!
greg k-h
From: Zheng Wang zyytlz.wz@163.com
[ Upstream commit c5749639f2d0a1f6cbe187d05f70c2e7c544d748 ]
In qedi_probe() we call __qedi_probe() which initializes &qedi->recovery_work with qedi_recovery_handler() and &qedi->board_disable_work with qedi_board_disable_work().
When qedi_schedule_recovery_handler() is called, schedule_delayed_work() will finally start the work.
In qedi_remove(), which is called to remove the driver, the following sequence may be observed:
Fix this by finishing the work before cleanup in qedi_remove().
CPU0 CPU1
|qedi_recovery_handler qedi_remove | __qedi_remove | iscsi_host_free | scsi_host_put | //free shost | |iscsi_host_for_each_session |//use qedi->shost
Cancel recovery_work and board_disable_work in __qedi_remove().
Fixes: 4b1068f5d74b ("scsi: qedi: Add MFW error recovery process") Signed-off-by: Zheng Wang zyytlz.wz@163.com Link: https://lore.kernel.org/r/20230413033422.28003-1-zyytlz.wz@163.com Acked-by: Manish Rangankar mrangankar@marvell.com Reviewed-by: Mike Christie michael.christie@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qedi/qedi_main.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index 299d0369e4f08..7df0106f132ee 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c @@ -2456,6 +2456,9 @@ static void __qedi_remove(struct pci_dev *pdev, int mode) qedi_ops->ll2->stop(qedi->cdev); }
+ cancel_delayed_work_sync(&qedi->recovery_work); + cancel_delayed_work_sync(&qedi->board_disable_work); + qedi_free_iscsi_pf_param(qedi);
rval = qedi_ops->common->update_drv_state(qedi->cdev, false);
From: Cosmo Chou chou.cosmo@gmail.com
[ Upstream commit 6f75cd166a5a3c0bc50441faa8b8304f60522fdd ]
ncsi_channel_is_tx() determines whether a given channel should be used for Tx or not. However, when reconfiguring the channel by handling a Configuration Required AEN, there is a misjudgment that the channel Tx has already been enabled, which results in the Enable Channel Network Tx command not being sent.
Clear the channel Tx enable flag before reconfiguring the channel to avoid the misjudgment.
Fixes: 8d951a75d022 ("net/ncsi: Configure multi-package, multi-channel modes with failover") Signed-off-by: Cosmo Chou chou.cosmo@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ncsi/ncsi-aen.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c index b635c194f0a85..62fb1031763d1 100644 --- a/net/ncsi/ncsi-aen.c +++ b/net/ncsi/ncsi-aen.c @@ -165,6 +165,7 @@ static int ncsi_aen_handler_cr(struct ncsi_dev_priv *ndp, nc->state = NCSI_CHANNEL_INACTIVE; list_add_tail_rcu(&nc->link, &ndp->channel_queue); spin_unlock_irqrestore(&ndp->lock, flags); + nc->modes[NCSI_MODE_TX_ENABLE].enable = 0;
return ncsi_process_next_channel(ndp); }
From: Vlad Buslov vladbu@nvidia.com
[ Upstream commit da94a7781fc3c92e7df7832bc2746f4d39bc624e ]
Error handler of tcf_block_bind() frees the whole bo->cb_list on error. However, by that time the flow_block_cb instances are already in the driver list because driver ndo_setup_tc() callback is called before that up the call chain in tcf_block_offload_cmd(). This leaves dangling pointers to freed objects in the list and causes use-after-free[0]. Fix it by also removing flow_block_cb instances from driver_list before deallocating them.
[0]: [ 279.868433] ================================================================== [ 279.869964] BUG: KASAN: slab-use-after-free in flow_block_cb_setup_simple+0x631/0x7c0 [ 279.871527] Read of size 8 at addr ffff888147e2bf20 by task tc/2963
[ 279.873151] CPU: 6 PID: 2963 Comm: tc Not tainted 6.3.0-rc6+ #4 [ 279.874273] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 [ 279.876295] Call Trace: [ 279.876882] <TASK> [ 279.877413] dump_stack_lvl+0x33/0x50 [ 279.878198] print_report+0xc2/0x610 [ 279.878987] ? flow_block_cb_setup_simple+0x631/0x7c0 [ 279.879994] kasan_report+0xae/0xe0 [ 279.880750] ? flow_block_cb_setup_simple+0x631/0x7c0 [ 279.881744] ? mlx5e_tc_reoffload_flows_work+0x240/0x240 [mlx5_core] [ 279.883047] flow_block_cb_setup_simple+0x631/0x7c0 [ 279.884027] tcf_block_offload_cmd.isra.0+0x189/0x2d0 [ 279.885037] ? tcf_block_setup+0x6b0/0x6b0 [ 279.885901] ? mutex_lock+0x7d/0xd0 [ 279.886669] ? __mutex_unlock_slowpath.constprop.0+0x2d0/0x2d0 [ 279.887844] ? ingress_init+0x1c0/0x1c0 [sch_ingress] [ 279.888846] tcf_block_get_ext+0x61c/0x1200 [ 279.889711] ingress_init+0x112/0x1c0 [sch_ingress] [ 279.890682] ? clsact_init+0x2b0/0x2b0 [sch_ingress] [ 279.891701] qdisc_create+0x401/0xea0 [ 279.892485] ? qdisc_tree_reduce_backlog+0x470/0x470 [ 279.893473] tc_modify_qdisc+0x6f7/0x16d0 [ 279.894344] ? tc_get_qdisc+0xac0/0xac0 [ 279.895213] ? mutex_lock+0x7d/0xd0 [ 279.896005] ? __mutex_lock_slowpath+0x10/0x10 [ 279.896910] rtnetlink_rcv_msg+0x5fe/0x9d0 [ 279.897770] ? rtnl_calcit.isra.0+0x2b0/0x2b0 [ 279.898672] ? __sys_sendmsg+0xb5/0x140 [ 279.899494] ? do_syscall_64+0x3d/0x90 [ 279.900302] ? entry_SYSCALL_64_after_hwframe+0x46/0xb0 [ 279.901337] ? kasan_save_stack+0x2e/0x40 [ 279.902177] ? kasan_save_stack+0x1e/0x40 [ 279.903058] ? kasan_set_track+0x21/0x30 [ 279.903913] ? kasan_save_free_info+0x2a/0x40 [ 279.904836] ? ____kasan_slab_free+0x11a/0x1b0 [ 279.905741] ? kmem_cache_free+0x179/0x400 [ 279.906599] netlink_rcv_skb+0x12c/0x360 [ 279.907450] ? rtnl_calcit.isra.0+0x2b0/0x2b0 [ 279.908360] ? netlink_ack+0x1550/0x1550 [ 279.909192] ? rhashtable_walk_peek+0x170/0x170 [ 279.910135] ? kmem_cache_alloc_node+0x1af/0x390 [ 279.911086] ? _copy_from_iter+0x3d6/0xc70 [ 279.912031] netlink_unicast+0x553/0x790 [ 279.912864] ? netlink_attachskb+0x6a0/0x6a0 [ 279.913763] ? netlink_recvmsg+0x416/0xb50 [ 279.914627] netlink_sendmsg+0x7a1/0xcb0 [ 279.915473] ? netlink_unicast+0x790/0x790 [ 279.916334] ? iovec_from_user.part.0+0x4d/0x220 [ 279.917293] ? netlink_unicast+0x790/0x790 [ 279.918159] sock_sendmsg+0xc5/0x190 [ 279.918938] ____sys_sendmsg+0x535/0x6b0 [ 279.919813] ? import_iovec+0x7/0x10 [ 279.920601] ? kernel_sendmsg+0x30/0x30 [ 279.921423] ? __copy_msghdr+0x3c0/0x3c0 [ 279.922254] ? import_iovec+0x7/0x10 [ 279.923041] ___sys_sendmsg+0xeb/0x170 [ 279.923854] ? copy_msghdr_from_user+0x110/0x110 [ 279.924797] ? ___sys_recvmsg+0xd9/0x130 [ 279.925630] ? __perf_event_task_sched_in+0x183/0x470 [ 279.926656] ? ___sys_sendmsg+0x170/0x170 [ 279.927529] ? ctx_sched_in+0x530/0x530 [ 279.928369] ? update_curr+0x283/0x4f0 [ 279.929185] ? perf_event_update_userpage+0x570/0x570 [ 279.930201] ? __fget_light+0x57/0x520 [ 279.931023] ? __switch_to+0x53d/0xe70 [ 279.931846] ? sockfd_lookup_light+0x1a/0x140 [ 279.932761] __sys_sendmsg+0xb5/0x140 [ 279.933560] ? __sys_sendmsg_sock+0x20/0x20 [ 279.934436] ? fpregs_assert_state_consistent+0x1d/0xa0 [ 279.935490] do_syscall_64+0x3d/0x90 [ 279.936300] entry_SYSCALL_64_after_hwframe+0x46/0xb0 [ 279.937311] RIP: 0033:0x7f21c814f887 [ 279.938085] Code: 0a 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b9 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 89 54 24 1c 48 89 74 24 10 [ 279.941448] RSP: 002b:00007fff11efd478 EFLAGS: 00000246 ORIG_RAX: 000000000000002e [ 279.942964] RAX: ffffffffffffffda RBX: 0000000064401979 RCX: 00007f21c814f887 [ 279.944337] RDX: 0000000000000000 RSI: 00007fff11efd4e0 RDI: 0000000000000003 [ 279.945660] RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000 [ 279.947003] R10: 00007f21c8008708 R11: 0000000000000246 R12: 0000000000000001 [ 279.948345] R13: 0000000000409980 R14: 000000000047e538 R15: 0000000000485400 [ 279.949690] </TASK>
[ 279.950706] Allocated by task 2960: [ 279.951471] kasan_save_stack+0x1e/0x40 [ 279.952338] kasan_set_track+0x21/0x30 [ 279.953165] __kasan_kmalloc+0x77/0x90 [ 279.954006] flow_block_cb_setup_simple+0x3dd/0x7c0 [ 279.955001] tcf_block_offload_cmd.isra.0+0x189/0x2d0 [ 279.956020] tcf_block_get_ext+0x61c/0x1200 [ 279.956881] ingress_init+0x112/0x1c0 [sch_ingress] [ 279.957873] qdisc_create+0x401/0xea0 [ 279.958656] tc_modify_qdisc+0x6f7/0x16d0 [ 279.959506] rtnetlink_rcv_msg+0x5fe/0x9d0 [ 279.960392] netlink_rcv_skb+0x12c/0x360 [ 279.961216] netlink_unicast+0x553/0x790 [ 279.962044] netlink_sendmsg+0x7a1/0xcb0 [ 279.962906] sock_sendmsg+0xc5/0x190 [ 279.963702] ____sys_sendmsg+0x535/0x6b0 [ 279.964534] ___sys_sendmsg+0xeb/0x170 [ 279.965343] __sys_sendmsg+0xb5/0x140 [ 279.966132] do_syscall_64+0x3d/0x90 [ 279.966908] entry_SYSCALL_64_after_hwframe+0x46/0xb0
[ 279.968407] Freed by task 2960: [ 279.969114] kasan_save_stack+0x1e/0x40 [ 279.969929] kasan_set_track+0x21/0x30 [ 279.970729] kasan_save_free_info+0x2a/0x40 [ 279.971603] ____kasan_slab_free+0x11a/0x1b0 [ 279.972483] __kmem_cache_free+0x14d/0x280 [ 279.973337] tcf_block_setup+0x29d/0x6b0 [ 279.974173] tcf_block_offload_cmd.isra.0+0x226/0x2d0 [ 279.975186] tcf_block_get_ext+0x61c/0x1200 [ 279.976080] ingress_init+0x112/0x1c0 [sch_ingress] [ 279.977065] qdisc_create+0x401/0xea0 [ 279.977857] tc_modify_qdisc+0x6f7/0x16d0 [ 279.978695] rtnetlink_rcv_msg+0x5fe/0x9d0 [ 279.979562] netlink_rcv_skb+0x12c/0x360 [ 279.980388] netlink_unicast+0x553/0x790 [ 279.981214] netlink_sendmsg+0x7a1/0xcb0 [ 279.982043] sock_sendmsg+0xc5/0x190 [ 279.982827] ____sys_sendmsg+0x535/0x6b0 [ 279.983703] ___sys_sendmsg+0xeb/0x170 [ 279.984510] __sys_sendmsg+0xb5/0x140 [ 279.985298] do_syscall_64+0x3d/0x90 [ 279.986076] entry_SYSCALL_64_after_hwframe+0x46/0xb0
[ 279.987532] The buggy address belongs to the object at ffff888147e2bf00 which belongs to the cache kmalloc-192 of size 192 [ 279.989747] The buggy address is located 32 bytes inside of freed 192-byte region [ffff888147e2bf00, ffff888147e2bfc0)
[ 279.992367] The buggy address belongs to the physical page: [ 279.993430] page:00000000550f405c refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x147e2a [ 279.995182] head:00000000550f405c order:1 entire_mapcount:0 nr_pages_mapped:0 pincount:0 [ 279.996713] anon flags: 0x200000000010200(slab|head|node=0|zone=2) [ 279.997878] raw: 0200000000010200 ffff888100042a00 0000000000000000 dead000000000001 [ 279.999384] raw: 0000000000000000 0000000000200020 00000001ffffffff 0000000000000000 [ 280.000894] page dumped because: kasan: bad access detected
[ 280.002386] Memory state around the buggy address: [ 280.003338] ffff888147e2be00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 280.004781] ffff888147e2be80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc [ 280.006224] >ffff888147e2bf00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 280.007700] ^ [ 280.008592] ffff888147e2bf80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc [ 280.010035] ffff888147e2c000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 280.011564] ==================================================================
Fixes: 59094b1e5094 ("net: sched: use flow block API") Signed-off-by: Vlad Buslov vladbu@nvidia.com Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/cls_api.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index c410a736301bc..53d315ed94307 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -1466,6 +1466,7 @@ static int tcf_block_bind(struct tcf_block *block,
err_unroll: list_for_each_entry_safe(block_cb, next, &bo->cb_list, list) { + list_del(&block_cb->driver_list); if (i-- > 0) { list_del(&block_cb->list); tcf_block_playback_offloads(block, block_cb->cb,
From: Cong Wang cong.wang@bytedance.com
[ Upstream commit c88f8d5cd95fd039cff95d682b8e71100c001df0 ]
When a tunnel device is bound with the underlying device, its dev->needed_headroom needs to be updated properly. IPv4 tunnels already do the same in ip_tunnel_bind_dev(). Otherwise we may not have enough header room for skb, especially after commit b17f709a2401 ("gue: TX support for using remote checksum offload option").
Fixes: 32b8a8e59c9c ("sit: add IPv4 over IPv4 support") Reported-by: Palash Oswal oswalpalash@gmail.com Link: https://lore.kernel.org/netdev/CAGyP=7fDcSPKu6nttbGwt7RXzE3uyYxLjCSE97J64pRx... Cc: Kuniyuki Iwashima kuniyu@amazon.com Cc: Eric Dumazet edumazet@google.com Signed-off-by: Cong Wang cong.wang@bytedance.com Reviewed-by: Eric Dumazet edumazet@google.com Reviewed-by: Kuniyuki Iwashima kuniyu@amazon.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv6/sit.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 1ce486a9bc076..9806bd56b95f1 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1094,12 +1094,13 @@ static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb,
static void ipip6_tunnel_bind_dev(struct net_device *dev) { + struct ip_tunnel *tunnel = netdev_priv(dev); + int t_hlen = tunnel->hlen + sizeof(struct iphdr); struct net_device *tdev = NULL; - struct ip_tunnel *tunnel; + int hlen = LL_MAX_HEADER; const struct iphdr *iph; struct flowi4 fl4;
- tunnel = netdev_priv(dev); iph = &tunnel->parms.iph;
if (iph->daddr) { @@ -1122,14 +1123,15 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev) tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
if (tdev && !netif_is_l3_master(tdev)) { - int t_hlen = tunnel->hlen + sizeof(struct iphdr); int mtu;
mtu = tdev->mtu - t_hlen; if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU; WRITE_ONCE(dev->mtu, mtu); + hlen = tdev->hard_header_len + tdev->needed_headroom; } + dev->needed_headroom = t_hlen + hlen; }
static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p,
From: Angelo Dureghello angelo.dureghello@timesys.com
[ Upstream commit 6686317855c6997671982d4489ccdd946f644957 ]
Add rsvd2cpu capability for mv88e6321 model, to allow proper bpdu processing.
Signed-off-by: Angelo Dureghello angelo.dureghello@timesys.com Fixes: 51c901a775621 ("net: dsa: mv88e6xxx: distinguish Global 2 Rsvd2CPU") Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/mv88e6xxx/chip.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 0b104a90c0d80..321c821876f65 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -4182,6 +4182,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = { .set_cpu_port = mv88e6095_g1_set_cpu_port, .set_egress_port = mv88e6095_g1_set_egress_port, .watchdog_ops = &mv88e6390_watchdog_ops, + .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, .reset = mv88e6352_g1_reset, .vtu_getnext = mv88e6185_g1_vtu_getnext, .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
From: Maxim Korotkov korotkov.maxim.s@gmail.com
[ Upstream commit 3e46c89c74f2c38e5337d2cf44b0b551adff1cb4 ]
the variable 'history' is of type u16, it may be an error that the hweight32 macro was used for it I guess macro hweight16 should be used
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 2a81490811d0 ("writeback: implement foreign cgroup inode detection") Signed-off-by: Maxim Korotkov korotkov.maxim.s@gmail.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20230119104443.3002-1-korotkov.maxim.s@gmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/fs-writeback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 6f18459f5e381..045a3bd520cae 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -700,7 +700,7 @@ void wbc_detach_inode(struct writeback_control *wbc) * is okay. The main goal is avoiding keeping an inode on * the wrong wb for an extended period of time. */ - if (hweight32(history) > WB_FRN_HIST_THR_SLOTS) + if (hweight16(history) > WB_FRN_HIST_THR_SLOTS) inode_switch_wbs(inode, max_id); }
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 7f5390750645756bd5da2b24fac285f2654dd922 ]
The commit in Fixes has only updated the remove function and missed the error handling path of the probe.
Add the missing reset_control_assert() call.
Fixes: 65a3b6935d92 ("watchdog: dw_wdt: get reset lines from dt") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Philipp Zabel p.zabel@pengutronix.de Reviewed-by: Guenter Roeck linux@roeck-us.net Link: https://lore.kernel.org/r/fbb650650bbb33a8fa2fd028c23157bedeed50e1.168249186... Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Wim Van Sebroeck wim@linux-watchdog.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/watchdog/dw_wdt.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index 32d0e1781e63c..3cd1182819809 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -638,7 +638,7 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
ret = dw_wdt_init_timeouts(dw_wdt, dev); if (ret) - goto out_disable_clk; + goto out_assert_rst;
wdd = &dw_wdt->wdd; wdd->ops = &dw_wdt_ops; @@ -669,12 +669,15 @@ static int dw_wdt_drv_probe(struct platform_device *pdev)
ret = watchdog_register_device(wdd); if (ret) - goto out_disable_pclk; + goto out_assert_rst;
dw_wdt_dbgfs_init(dw_wdt);
return 0;
+out_assert_rst: + reset_control_assert(dw_wdt->rst); + out_disable_pclk: clk_disable_unprepare(dw_wdt->pclk);
From: Victor Nogueira victor@mojatatu.com
[ Upstream commit 526f28bd0fbdc699cda31426928802650c1528e5 ]
There are cases where the device is adminstratively UP, but operationally down. For example, we have a physical device (Nvidia ConnectX-6 Dx, 25Gbps) who's cable was pulled out, here is its ip link output:
5: ens2f1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000 link/ether b8:ce:f6:4b:68:35 brd ff:ff:ff:ff:ff:ff altname enp179s0f1np1
As you can see, it's administratively UP but operationally down. In this case, sending a packet to this port caused a nasty kernel hang (so nasty that we were unable to capture it). Aborting a transmit based on operational status (in addition to administrative status) fixes the issue.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Acked-by: Jamal Hadi Salim jhs@mojatatu.com Signed-off-by: Victor Nogueira victor@mojatatu.com v1->v2: Add fixes tag v2->v3: Remove blank line between tags + add change log, suggested by Leon Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/act_mirred.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 24d561d8d9c97..25dad1921baf2 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -244,7 +244,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, goto out; }
- if (unlikely(!(dev->flags & IFF_UP))) { + if (unlikely(!(dev->flags & IFF_UP)) || !netif_carrier_ok(dev)) { net_notice_ratelimited("tc mirred to Houston: device %s is down\n", dev->name); goto out;
From: Andy Moreton andy.moreton@amd.com
[ Upstream commit 281900a923d4c50df109b52a22ae3cdac150159b ]
The sfc driver does not report QSFP module EEPROM contents correctly as only the first page is fetched from hardware.
Commit 0e1a2a3e6e7d ("ethtool: Add SFF-8436 and SFF-8636 max EEPROM length definitions") added ETH_MODULE_SFF_8436_MAX_LEN for the overall size of the EEPROM info, so use that to report the full EEPROM contents.
Fixes: 9b17010da57a ("sfc: Add ethtool -m support for QSFP modules") Signed-off-by: Andy Moreton andy.moreton@amd.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/sfc/mcdi_port_common.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/sfc/mcdi_port_common.c b/drivers/net/ethernet/sfc/mcdi_port_common.c index c4fe3c48ac46a..eccb97a5d9387 100644 --- a/drivers/net/ethernet/sfc/mcdi_port_common.c +++ b/drivers/net/ethernet/sfc/mcdi_port_common.c @@ -974,12 +974,15 @@ static u32 efx_mcdi_phy_module_type(struct efx_nic *efx)
/* A QSFP+ NIC may actually have an SFP+ module attached. * The ID is page 0, byte 0. + * QSFP28 is of type SFF_8636, however, this is treated + * the same by ethtool, so we can also treat them the same. */ switch (efx_mcdi_phy_get_module_eeprom_byte(efx, 0, 0)) { - case 0x3: + case 0x3: /* SFP */ return MC_CMD_MEDIA_SFP_PLUS; - case 0xc: - case 0xd: + case 0xc: /* QSFP */ + case 0xd: /* QSFP+ */ + case 0x11: /* QSFP28 */ return MC_CMD_MEDIA_QSFP_PLUS; default: return 0; @@ -1077,7 +1080,7 @@ int efx_mcdi_phy_get_module_info(struct efx_nic *efx, struct ethtool_modinfo *mo
case MC_CMD_MEDIA_QSFP_PLUS: modinfo->type = ETH_MODULE_SFF_8436; - modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN; + modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN; break;
default:
From: David Howells dhowells@redhat.com
[ Upstream commit 0d098d83c5d9e107b2df7f5e11f81492f56d2fe7 ]
The hard call timeout is specified in the RXRPC_SET_CALL_TIMEOUT cmsg in seconds, so fix the point at which sendmsg() applies it to the call to convert to jiffies from seconds, not milliseconds.
Fixes: a158bdd3247b ("rxrpc: Fix timeout of a call that hasn't yet been granted a channel") Signed-off-by: David Howells dhowells@redhat.com cc: Marc Dionne marc.dionne@auristor.com cc: "David S. Miller" davem@davemloft.net cc: Eric Dumazet edumazet@google.com cc: Jakub Kicinski kuba@kernel.org cc: Paolo Abeni pabeni@redhat.com cc: linux-afs@lists.infradead.org cc: netdev@vger.kernel.org cc: linux-kernel@vger.kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/rxrpc/sendmsg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index a670553159abe..1882fea719035 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c @@ -753,7 +753,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) fallthrough; case 1: if (p.call.timeouts.hard > 0) { - j = msecs_to_jiffies(p.call.timeouts.hard); + j = p.call.timeouts.hard * HZ; now = jiffies; j += now; WRITE_ONCE(call->expect_term_by, j);
From: Subbaraya Sundeep sbhatta@marvell.com
[ Upstream commit c926252205c424c4842dbdbe02f8e3296f623204 ]
At the stage of enabling packet I/O in otx2_open, If mailbox timeout occurs then interface ends up in down state where as hardware packet I/O is enabled. Hence disable packet I/O also before bailing out.
Fixes: 1ea0166da050 ("octeontx2-pf: Fix the device state on error") Signed-off-by: Subbaraya Sundeep sbhatta@marvell.com Signed-off-by: Sunil Kovvuri Goutham sgoutham@marvell.com Signed-off-by: Sai Krishna saikrishnag@marvell.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c index 161174be51c31..54aeb276b9a0a 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -1589,11 +1589,20 @@ int otx2_open(struct net_device *netdev) otx2_config_pause_frm(pf);
err = otx2_rxtx_enable(pf, true); - if (err) + /* If a mbox communication error happens at this point then interface + * will end up in a state such that it is in down state but hardware + * mcam entries are enabled to receive the packets. Hence disable the + * packet I/O. + */ + if (err == EIO) + goto err_disable_rxtx; + else if (err) goto err_tx_stop_queues;
return 0;
+err_disable_rxtx: + otx2_rxtx_enable(pf, false); err_tx_stop_queues: netif_tx_stop_all_queues(netdev); netif_carrier_off(netdev);
From: Subbaraya Sundeep sbhatta@marvell.com
[ Upstream commit 99ae1260fdb5f15beab8a3adfb93a9041c87a2c1 ]
When a VF device probe fails due to error in MSIX vector allocation then the resources NIX and NPA LFs were not detached. Fix this by detaching the LFs when MSIX vector allocation fails.
Fixes: 3184fb5ba96e ("octeontx2-vf: Virtual function driver support") Signed-off-by: Subbaraya Sundeep sbhatta@marvell.com Signed-off-by: Sunil Kovvuri Goutham sgoutham@marvell.com Signed-off-by: Sai Krishna saikrishnag@marvell.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c index 67fabf265fe6f..5310b71795ecd 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c @@ -542,7 +542,7 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err = otx2vf_realloc_msix_vectors(vf); if (err) - goto err_mbox_destroy; + goto err_detach_rsrc;
err = otx2_set_real_num_queues(netdev, qcount, qcount); if (err)
From: Shannon Nelson shannon.nelson@amd.com
[ Upstream commit 3711d44fac1f80ea69ecb7315fed05b3812a7401 ]
It seems that ethtool is calling into .get_rxnfc more often with ETHTOOL_GRXCLSRLCNT which ionic doesn't know about. We don't need to log a message about it, just return not supported.
Fixes: aa3198819bea6 ("ionic: Add RSS support") Signed-off-by: Shannon Nelson shannon.nelson@amd.com Reviewed-by: Simon Horman simon.horman@corigine.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/pensando/ionic/ionic_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c index 35c72d4a78b3f..8e5b01af85ed2 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c @@ -693,7 +693,7 @@ static int ionic_get_rxnfc(struct net_device *netdev, info->data = lif->nxqs; break; default: - netdev_err(netdev, "Command parameter %d is not supported\n", + netdev_dbg(netdev, "Command parameter %d is not supported\n", info->cmd); err = -EOPNOTSUPP; }
From: Kuniyuki Iwashima kuniyu@amazon.com
[ Upstream commit 6a341729fb31b4c5df9f74f24b4b1c98410c9b87 ]
syzkaller reported a warning below [0].
We can reproduce it by sending 0-byte data from the (AF_PACKET, SOCK_PACKET) socket via some devices whose dev->hard_header_len is 0.
struct sockaddr_pkt addr = { .spkt_family = AF_PACKET, .spkt_device = "tun0", }; int fd;
fd = socket(AF_PACKET, SOCK_PACKET, 0); sendto(fd, NULL, 0, 0, (struct sockaddr *)&addr, sizeof(addr));
We have a similar fix for the (AF_PACKET, SOCK_RAW) socket as commit dc633700f00f ("net/af_packet: check len when min_header_len equals to 0").
Let's add the same test for the SOCK_PACKET socket.
[0]: skb_assert_len WARNING: CPU: 1 PID: 19945 at include/linux/skbuff.h:2552 skb_assert_len include/linux/skbuff.h:2552 [inline] WARNING: CPU: 1 PID: 19945 at include/linux/skbuff.h:2552 __dev_queue_xmit+0x1f26/0x31d0 net/core/dev.c:4159 Modules linked in: CPU: 1 PID: 19945 Comm: syz-executor.0 Not tainted 6.3.0-rc7-02330-gca6270c12e20 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 RIP: 0010:skb_assert_len include/linux/skbuff.h:2552 [inline] RIP: 0010:__dev_queue_xmit+0x1f26/0x31d0 net/core/dev.c:4159 Code: 89 de e8 1d a2 85 fd 84 db 75 21 e8 64 a9 85 fd 48 c7 c6 80 2a 1f 86 48 c7 c7 c0 06 1f 86 c6 05 23 cf 27 04 01 e8 fa ee 56 fd <0f> 0b e8 43 a9 85 fd 0f b6 1d 0f cf 27 04 31 ff 89 de e8 e3 a1 85 RSP: 0018:ffff8880217af6e0 EFLAGS: 00010282 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffc90001133000 RDX: 0000000000040000 RSI: ffffffff81186922 RDI: 0000000000000001 RBP: ffff8880217af8b0 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000001 R12: ffff888030045640 R13: ffff8880300456b0 R14: ffff888030045650 R15: ffff888030045718 FS: 00007fc5864da640(0000) GS:ffff88806cd00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020005740 CR3: 000000003f856003 CR4: 0000000000770ee0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <TASK> dev_queue_xmit include/linux/netdevice.h:3085 [inline] packet_sendmsg_spkt+0xc4b/0x1230 net/packet/af_packet.c:2066 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0x1b4/0x200 net/socket.c:747 ____sys_sendmsg+0x331/0x970 net/socket.c:2503 ___sys_sendmsg+0x11d/0x1c0 net/socket.c:2557 __sys_sendmmsg+0x18c/0x430 net/socket.c:2643 __do_sys_sendmmsg net/socket.c:2672 [inline] __se_sys_sendmmsg net/socket.c:2669 [inline] __x64_sys_sendmmsg+0x9c/0x100 net/socket.c:2669 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3c/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc RIP: 0033:0x7fc58791de5d Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 9f 1b 00 f7 d8 64 89 01 48 RSP: 002b:00007fc5864d9cc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: ffffffffffffffda RBX: 00000000004bbf80 RCX: 00007fc58791de5d RDX: 0000000000000001 RSI: 0000000020005740 RDI: 0000000000000004 RBP: 00000000004bbf80 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 000000000000000b R14: 00007fc58797e530 R15: 0000000000000000 </TASK> ---[ end trace 0000000000000000 ]--- skb len=0 headroom=16 headlen=0 tailroom=304 mac=(16,0) net=(16,-1) trans=-1 shinfo(txflags=0 nr_frags=0 gso(size=0 type=0 segs=0)) csum(0x0 ip_summed=0 complete_sw=0 valid=0 level=0) hash(0x0 sw=0 l4=0) proto=0x0000 pkttype=0 iif=0 dev name=sit0 feat=0x00000006401d7869 sk family=17 type=10 proto=0
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.com Reviewed-by: Willem de Bruijn willemb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/packet/af_packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 9b6f6a5e0b147..2e766490a739b 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1996,7 +1996,7 @@ static int packet_sendmsg_spkt(struct socket *sock, struct msghdr *msg, goto retry; }
- if (!dev_validate_header(dev, skb->data, len)) { + if (!dev_validate_header(dev, skb->data, len) || !skb->len) { err = -EINVAL; goto out_unlock; }
From: Chia-I Wu olvaffe@gmail.com
[ Upstream commit 2397e3d8d2e120355201a8310b61929f5a8bd2c0 ]
mgr->ctx_handles should be protected by mgr->lock.
v2: improve commit message v3: add a Fixes tag
Signed-off-by: Chia-I Wu olvaffe@gmail.com Reviewed-by: Christian König christian.koenig@amd.com Fixes: 52c6a62c64fa ("drm/amdgpu: add interface for editing a foreign process's priority v3") Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index 0da0a0d986720..15c0a3068eab8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -66,6 +66,7 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev, { struct fd f = fdget(fd); struct amdgpu_fpriv *fpriv; + struct amdgpu_ctx_mgr *mgr; struct amdgpu_ctx *ctx; uint32_t id; int r; @@ -79,8 +80,11 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev, return r; }
- idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id) + mgr = &fpriv->ctx_mgr; + mutex_lock(&mgr->lock); + idr_for_each_entry(&mgr->ctx_handles, ctx, id) amdgpu_ctx_priority_override(ctx, priority); + mutex_unlock(&mgr->lock);
fdput(f); return 0;
From: Ruliang Lin u202112092@hust.edu.cn
[ Upstream commit 0d727e1856ef22dd9337199430258cb64cbbc658 ]
Smatch complains that: snd_usb_caiaq_input_init() warn: missing error code 'ret'
This patch adds a new case to handle the situation where the device does not support any input methods in the `snd_usb_caiaq_input_init` function. It returns an `-EINVAL` error code to indicate that no input methods are supported on the device.
Fixes: 523f1dce3743 ("[ALSA] Add Native Instrument usb audio device support") Signed-off-by: Ruliang Lin u202112092@hust.edu.cn Reviewed-by: Dongliang Mu dzm91@hust.edu.cn Acked-by: Daniel Mack daniel@zonque.org Link: https://lore.kernel.org/r/20230504065054.3309-1-u202112092@hust.edu.cn Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/caiaq/input.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c index 1e2cf2f08eecd..84f26dce7f5d0 100644 --- a/sound/usb/caiaq/input.c +++ b/sound/usb/caiaq/input.c @@ -804,6 +804,7 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
default: /* no input methods supported on this device */ + ret = -EINVAL; goto exit_free_idev; }
From: Arınç ÜNAL arinc.unal@arinc9.com
[ Upstream commit 37c218d8021e36e226add4bab93d071d30fe0704 ]
The multi-chip module MT7530 switch with a 40 MHz oscillator on the MT7621AT, MT7621DAT, and MT7621ST SoCs forwards corrupt frames using trgmii.
This is caused by the assumption that MT7621 SoCs have got 150 MHz PLL, hence using the ncpo1 value, 0x0780.
My testing shows this value works on Unielec U7621-06, Bartel's testing shows it won't work on Hi-Link HLK-MT7621A and Netgear WAC104. All devices tested have got 40 MHz oscillators.
Using the value for 125 MHz PLL, 0x0640, works on all boards at hand. The definitions for 125 MHz PLL exist on the Banana Pi BPI-R2 BSP source code whilst 150 MHz PLL don't.
Forwarding frames using trgmii on the MCM MT7530 switch with a 25 MHz oscillator on the said MT7621 SoCs works fine because the ncpo1 value defined for it is for 125 MHz PLL.
Change the 150 MHz PLL comment to 125 MHz PLL, and use the 125 MHz PLL ncpo1 values for both oscillator frequencies.
Link: https://github.com/BPI-SINOVOIP/BPI-R2-bsp/blob/81d24bbce7d99524d0771a8bdb2d... Fixes: 7ef6f6f8d237 ("net: dsa: mt7530: Add MT7621 TRGMII mode support") Tested-by: Bartel Eerdekens bartel.eerdekens@constell8.be Signed-off-by: Arınç ÜNAL arinc.unal@arinc9.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/mt7530.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index 70155e996f7d7..d3b42adef057b 100644 --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c @@ -404,9 +404,9 @@ mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface) case PHY_INTERFACE_MODE_TRGMII: trgint = 1; if (priv->id == ID_MT7621) { - /* PLL frequency: 150MHz: 1.2GBit */ + /* PLL frequency: 125MHz: 1.0GBit */ if (xtal == HWTRAP_XTAL_40MHZ) - ncpo1 = 0x0780; + ncpo1 = 0x0640; if (xtal == HWTRAP_XTAL_25MHZ) ncpo1 = 0x0a00; } else { /* PLL frequency: 250MHz: 2.0Gbit */
From: Xuan Zhuo xuanzhuo@linux.alibaba.com
[ Upstream commit 6e345f8c7cd029ad3aaece15ad4425ac26e4eb63 ]
This patch separates two functions for freeing sq buf and rq buf from free_unused_bufs().
When supporting the enable/disable tx/rq queue in the future, it is necessary to support separate recovery of a sq buf or a rq buf.
Signed-off-by: Xuan Zhuo xuanzhuo@linux.alibaba.com Acked-by: Jason Wang jasowang@redhat.com Message-Id: 20220801063902.129329-40-xuanzhuo@linux.alibaba.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Stable-dep-of: f8bb51043945 ("virtio_net: suppress cpu stall when free_unused_bufs") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/virtio_net.c | 41 ++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 47c9118cc92a3..75219c8f4a63e 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -2747,6 +2747,27 @@ static void free_receive_page_frags(struct virtnet_info *vi) put_page(vi->rq[i].alloc_frag.page); }
+static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf) +{ + if (!is_xdp_frame(buf)) + dev_kfree_skb(buf); + else + xdp_return_frame(ptr_to_xdp(buf)); +} + +static void virtnet_rq_free_unused_buf(struct virtqueue *vq, void *buf) +{ + struct virtnet_info *vi = vq->vdev->priv; + int i = vq2rxq(vq); + + if (vi->mergeable_rx_bufs) + put_page(virt_to_head_page(buf)); + else if (vi->big_packets) + give_pages(&vi->rq[i], buf); + else + put_page(virt_to_head_page(buf)); +} + static void free_unused_bufs(struct virtnet_info *vi) { void *buf; @@ -2754,26 +2775,14 @@ static void free_unused_bufs(struct virtnet_info *vi)
for (i = 0; i < vi->max_queue_pairs; i++) { struct virtqueue *vq = vi->sq[i].vq; - while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) { - if (!is_xdp_frame(buf)) - dev_kfree_skb(buf); - else - xdp_return_frame(ptr_to_xdp(buf)); - } + while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) + virtnet_sq_free_unused_buf(vq, buf); }
for (i = 0; i < vi->max_queue_pairs; i++) { struct virtqueue *vq = vi->rq[i].vq; - - while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) { - if (vi->mergeable_rx_bufs) { - put_page(virt_to_head_page(buf)); - } else if (vi->big_packets) { - give_pages(&vi->rq[i], buf); - } else { - put_page(virt_to_head_page(buf)); - } - } + while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) + virtnet_rq_free_unused_buf(vq, buf); } }
From: Wenliang Wang wangwenliang.1995@bytedance.com
[ Upstream commit f8bb5104394560e29017c25bcade4c6b7aabd108 ]
For multi-queue and large ring-size use case, the following error occurred when free_unused_bufs: rcu: INFO: rcu_sched self-detected stall on CPU.
Fixes: 986a4f4d452d ("virtio_net: multiqueue support") Signed-off-by: Wenliang Wang wangwenliang.1995@bytedance.com Acked-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/virtio_net.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 75219c8f4a63e..119a32f34b539 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -2777,12 +2777,14 @@ static void free_unused_bufs(struct virtnet_info *vi) struct virtqueue *vq = vi->sq[i].vq; while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) virtnet_sq_free_unused_buf(vq, buf); + cond_resched(); }
for (i = 0; i < vi->max_queue_pairs; i++) { struct virtqueue *vq = vi->rq[i].vq; while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) virtnet_rq_free_unused_buf(vq, buf); + cond_resched(); } }
From: Wei Fang wei.fang@nxp.com
[ Upstream commit 299efdc2380aac588557f4d0b2ce7bee05bd0cf2 ]
We should check whether the current SFI (Stream Filter Instance) table is full before creating a new SFI entry. However, the previous logic checks the handle by mistake and might lead to unpredictable behavior.
Fixes: 888ae5a3952b ("net: enetc: add tc flower psfp offload driver") Signed-off-by: Wei Fang wei.fang@nxp.com Reviewed-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/enetc/enetc_qos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c index 5841721c81190..8d92dc6bc9945 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c @@ -1266,7 +1266,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv, int index;
index = enetc_get_free_index(priv); - if (sfi->handle < 0) { + if (index < 0) { NL_SET_ERR_MSG_MOD(extack, "No Stream Filter resource!"); err = -ENOSPC; goto free_fmi;
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit 93e0401e0fc0c54b0ac05b687cd135c2ac38187c ]
The call to phy_stop() races with the later call to phy_disconnect(), resulting in concurrent phy_suspend() calls being run from different CPUs. The final call to phy_disconnect() ensures that the PHY is stopped and suspended, too.
Fixes: c96e731c93ff ("net: bcmgenet: connect and disconnect from the PHY state machine") Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 7667cbb5adfd6..20b161620fee9 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -3412,7 +3412,6 @@ static void bcmgenet_netif_stop(struct net_device *dev) /* Disable MAC transmit. TX DMA disabled must be done before this */ umac_enable_set(priv, CMD_TX_EN, false);
- phy_stop(dev->phydev); bcmgenet_disable_rx_napi(priv); bcmgenet_intr_disable(priv);
On 5/15/2023 9:29 AM, Greg Kroah-Hartman wrote:
From: Florian Fainelli f.fainelli@gmail.com
[ Upstream commit 93e0401e0fc0c54b0ac05b687cd135c2ac38187c ]
The call to phy_stop() races with the later call to phy_disconnect(), resulting in concurrent phy_suspend() calls being run from different CPUs. The final call to phy_disconnect() ensures that the PHY is stopped and suspended, too.
Fixes: c96e731c93ff ("net: bcmgenet: connect and disconnect from the PHY state machine") Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org
Please drop this patch until https://lore.kernel.org/lkml/20230515025608.2587012-1-f.fainelli@gmail.com/ is merged, thanks!
From: Kajol Jain kjain@linux.ibm.com
[ Upstream commit 5d9df8731c0941f3add30f96745a62586a0c9d52 ]
Commit 3c22ba5243040c13 ("perf vendor events powerpc: Update POWER9 events") added and updated power9 PMU JSON events. However some of the JSON events which are part of other.json and pipeline.json files, contains UTF-8 characters in their brief description. Having UTF-8 character could breaks the perf build on some distros.
Fix this issue by removing the UTF-8 characters from other.json and pipeline.json files.
Result without the fix:
[command]# file -i pmu-events/arch/powerpc/power9/* pmu-events/arch/powerpc/power9/cache.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/floating-point.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/frontend.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/marked.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/memory.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/metrics.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/nest_metrics.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/other.json: application/json; charset=utf-8 pmu-events/arch/powerpc/power9/pipeline.json: application/json; charset=utf-8 pmu-events/arch/powerpc/power9/pmc.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/translation.json: application/json; charset=us-ascii [command]#
Result with the fix:
[command]# file -i pmu-events/arch/powerpc/power9/* pmu-events/arch/powerpc/power9/cache.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/floating-point.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/frontend.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/marked.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/memory.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/metrics.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/nest_metrics.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/other.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/pipeline.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/pmc.json: application/json; charset=us-ascii pmu-events/arch/powerpc/power9/translation.json: application/json; charset=us-ascii [command]#
Fixes: 3c22ba5243040c13 ("perf vendor events powerpc: Update POWER9 events") Reported-by: Arnaldo Carvalho de Melo acme@kernel.com Signed-off-by: Kajol Jain kjain@linux.ibm.com Acked-by: Ian Rogers irogers@google.com Tested-by: Arnaldo Carvalho de Melo acme@redhat.com Cc: Athira Rajeev atrajeev@linux.vnet.ibm.com Cc: Disha Goel disgoel@linux.ibm.com Cc: Jiri Olsa jolsa@kernel.org Cc: Madhavan Srinivasan maddy@linux.ibm.com Cc: Sukadev Bhattiprolu sukadev@linux.vnet.ibm.com Cc: linuxppc-dev@lists.ozlabs.org Link: https://lore.kernel.org/lkml/ZBxP77deq7ikTxwG@kernel.org/ Link: https://lore.kernel.org/r/20230328112908.113158-1-kjain@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/pmu-events/arch/powerpc/power9/other.json | 4 ++-- tools/perf/pmu-events/arch/powerpc/power9/pipeline.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/perf/pmu-events/arch/powerpc/power9/other.json b/tools/perf/pmu-events/arch/powerpc/power9/other.json index 3f69422c21f99..f10bd554521a0 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/other.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/other.json @@ -1417,7 +1417,7 @@ { "EventCode": "0x45054", "EventName": "PM_FMA_CMPL", - "BriefDescription": "two flops operation completed (fmadd, fnmadd, fmsub, fnmsub) Scalar instructions only. " + "BriefDescription": "two flops operation completed (fmadd, fnmadd, fmsub, fnmsub) Scalar instructions only." }, { "EventCode": "0x201E8", @@ -2017,7 +2017,7 @@ { "EventCode": "0xC0BC", "EventName": "PM_LSU_FLUSH_OTHER", - "BriefDescription": "Other LSU flushes including: Sync (sync ack from L2 caused search of LRQ for oldest snooped load, This will either signal a Precise Flush of the oldest snooped loa or a Flush Next PPC); Data Valid Flush Next (several cases of this, one example is store and reload are lined up such that a store-hit-reload scenario exists and the CDF has already launched and has gotten bad/stale data); Bad Data Valid Flush Next (might be a few cases of this, one example is a larxa (D$ hit) return data and dval but can't allocate to LMQ (LMQ full or other reason). Already gave dval but can't watch it for snoop_hit_larx. Need to take the “bad dval” back and flush all younger ops)" + "BriefDescription": "Other LSU flushes including: Sync (sync ack from L2 caused search of LRQ for oldest snooped load, This will either signal a Precise Flush of the oldest snooped loa or a Flush Next PPC); Data Valid Flush Next (several cases of this, one example is store and reload are lined up such that a store-hit-reload scenario exists and the CDF has already launched and has gotten bad/stale data); Bad Data Valid Flush Next (might be a few cases of this, one example is a larxa (D$ hit) return data and dval but can't allocate to LMQ (LMQ full or other reason). Already gave dval but can't watch it for snoop_hit_larx. Need to take the 'bad dval' back and flush all younger ops)" }, { "EventCode": "0x5094", diff --git a/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json b/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json index d0265f255de2b..723bffa41c448 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json @@ -442,7 +442,7 @@ { "EventCode": "0x4D052", "EventName": "PM_2FLOP_CMPL", - "BriefDescription": "DP vector version of fmul, fsub, fcmp, fsel, fabs, fnabs, fres ,fsqrte, fneg " + "BriefDescription": "DP vector version of fmul, fsub, fcmp, fsel, fabs, fnabs, fres ,fsqrte, fneg" }, { "EventCode": "0x1F142",
From: Arnaldo Carvalho de Melo acme@redhat.com
[ Upstream commit 57f14b5ae1a97537f2abd2828ee7212cada7036e ]
An audit showed just this one problem with zfree(), fix it.
Fixes: 9fbc61f832ebf432 ("perf pmu: Add support for PMU capabilities") Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/pmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index ac45da0302a73..d322305bc1828 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1670,7 +1670,7 @@ static int perf_pmu__new_caps(struct list_head *list, char *name, char *value) return 0;
free_name: - zfree(caps->name); + zfree(&caps->name); free_caps: free(caps);
From: Markus Elfring Markus.Elfring@web.de
[ Upstream commit c160118a90d4acf335993d8d59b02ae2147a524e ]
Addresses of two data structure members were determined before corresponding null pointer checks in the implementation of the function “sort__sym_from_cmp”.
Thus avoid the risk for undefined behaviour by removing extra initialisations for the local variables “from_l” and “from_r” (also because they were already reassigned with the same value behind this pointer check).
This issue was detected by using the Coccinelle software.
Fixes: 1b9e97a2a95e4941 ("perf tools: Fix report -F symbol_from for data without branch info") Signed-off-by: elfring@users.sourceforge.net Acked-by: Ian Rogers irogers@google.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Andi Kleen ak@linux.intel.com Cc: German Gomez german.gomez@arm.com Cc: Ingo Molnar mingo@redhat.com Cc: Jiri Olsa jolsa@kernel.org Cc: Kan Liang kan.liang@linux.intel.com Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Link: https://lore.kernel.org/cocci/54a21fea-64e3-de67-82ef-d61b90ffad05@web.de/ Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/sort.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 5e9e96452b9e6..42806102010bb 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -873,8 +873,7 @@ static int hist_entry__dso_to_filter(struct hist_entry *he, int type, static int64_t sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right) { - struct addr_map_symbol *from_l = &left->branch_info->from; - struct addr_map_symbol *from_r = &right->branch_info->from; + struct addr_map_symbol *from_l, *from_r;
if (!left->branch_info || !right->branch_info) return cmp_null(left->branch_info, right->branch_info);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 8fd91151ebcb21b3f2f2bf158ac6092192550b2b ]
SS_ENCRYPTION is (0 << 7 = 0), so the test can never be true. Use a direct comparison to SS_ENCRYPTION instead.
The same king of test is already done the same way in sun8i_ss_run_task().
Fixes: 359e893e8af4 ("crypto: sun8i-ss - rework handling of IV") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr 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 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c index 49c7a8b464ddf..8a94f812e6d29 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c @@ -132,7 +132,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq) } rctx->p_iv[i] = a; /* we need to setup all others IVs only in the decrypt way */ - if (rctx->op_dir & SS_ENCRYPTION) + if (rctx->op_dir == SS_ENCRYPTION) return 0; todo = min(len, sg_dma_len(sg)); len -= todo;
From: Yang Jihong yangjihong1@huawei.com
[ Upstream commit 1511e4696acb715a4fe48be89e1e691daec91c0e ]
In elf_read_build_id(), if gnu build_id is found, should return the size of the actually copied data. If descsz is greater thanBuild_ID_SIZE, write_buildid data access may occur.
Fixes: be96ea8ffa788dcc ("perf symbols: Fix issue with binaries using 16-bytes buildids (v2)") Reported-by: Will Ochowicz Will.Ochowicz@genusplc.com Signed-off-by: Yang Jihong yangjihong1@huawei.com Tested-by: Will Ochowicz Will.Ochowicz@genusplc.com Acked-by: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Ian Rogers irogers@google.com Cc: Ingo Molnar mingo@redhat.com Cc: Jiri Olsa jolsa@kernel.org Cc: Leo Yan leo.yan@linaro.org Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Stephane Eranian eranian@google.com Link: https://lore.kernel.org/lkml/CWLP265MB49702F7BA3D6D8F13E4B1A719C649@CWLP265M... Link: https://lore.kernel.org/r/20230427012841.231729-1-yangjihong1@huawei.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/symbol-elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 5221f272f85c6..b171d134ce87a 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -548,7 +548,7 @@ static int elf_read_build_id(Elf *elf, void *bf, size_t size) size_t sz = min(size, descsz); memcpy(bf, ptr, sz); memset(bf + sz, 0, size - sz); - err = descsz; + err = sz; break; } }
From: Filipe Manana fdmanana@suse.com
commit 6f932d4ef007d6a4ae03badcb749fbb8f49196f6 upstream.
A call to btrfs_prev_leaf() may end up returning a path that points to the same item (key) again. This happens if while btrfs_prev_leaf(), after we release the path, a concurrent insertion happens, which moves items off from a sibling into the front of the previous leaf, and an item with the computed previous key does not exists.
For example, suppose we have the two following leaves:
Leaf A
------------------------------------------------------------- | ... key (300 96 10) key (300 96 15) key (300 96 16) | ------------------------------------------------------------- slot 20 slot 21 slot 22
Leaf B
------------------------------------------------------------- | key (300 96 20) key (300 96 21) key (300 96 22) ... | ------------------------------------------------------------- slot 0 slot 1 slot 2
If we call btrfs_prev_leaf(), from btrfs_previous_item() for example, with a path pointing to leaf B and slot 0 and the following happens:
1) At btrfs_prev_leaf() we compute the previous key to search as: (300 96 19), which is a key that does not exists in the tree;
2) Then we call btrfs_release_path() at btrfs_prev_leaf();
3) Some other task inserts a key at leaf A, that sorts before the key at slot 20, for example it has an objectid of 299. In order to make room for the new key, the key at slot 22 is moved to the front of leaf B. This happens at push_leaf_right(), called from split_leaf().
After this leaf B now looks like:
-------------------------------------------------------------------------------- | key (300 96 16) key (300 96 20) key (300 96 21) key (300 96 22) ... | -------------------------------------------------------------------------------- slot 0 slot 1 slot 2 slot 3
4) At btrfs_prev_leaf() we call btrfs_search_slot() for the computed previous key: (300 96 19). Since the key does not exists, btrfs_search_slot() returns 1 and with a path pointing to leaf B and slot 1, the item with key (300 96 20);
5) This makes btrfs_prev_leaf() return a path that points to slot 1 of leaf B, the same key as before it was called, since the key at slot 0 of leaf B (300 96 16) is less than the computed previous key, which is (300 96 19);
6) As a consequence btrfs_previous_item() returns a path that points again to the item with key (300 96 20).
For some users of btrfs_prev_leaf() or btrfs_previous_item() this may not be functional a problem, despite not making sense to return a new path pointing again to the same item/key. However for a caller such as tree-log.c:log_dir_items(), this has a bad consequence, as it can result in not logging some dir index deletions in case the directory is being logged without holding the inode's VFS lock (logging triggered while logging a child inode for example) - for the example scenario above, in case the dir index keys 17, 18 and 19 were deleted in the current transaction.
CC: stable@vger.kernel.org # 4.14+ 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/ctree.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
--- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -5160,10 +5160,12 @@ int btrfs_del_items(struct btrfs_trans_h int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) { struct btrfs_key key; + struct btrfs_key orig_key; struct btrfs_disk_key found_key; int ret;
btrfs_item_key_to_cpu(path->nodes[0], &key, 0); + orig_key = key;
if (key.offset > 0) { key.offset--; @@ -5180,8 +5182,36 @@ int btrfs_prev_leaf(struct btrfs_root *r
btrfs_release_path(path); ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); - if (ret < 0) + if (ret <= 0) return ret; + + /* + * Previous key not found. Even if we were at slot 0 of the leaf we had + * before releasing the path and calling btrfs_search_slot(), we now may + * be in a slot pointing to the same original key - this can happen if + * after we released the path, one of more items were moved from a + * sibling leaf into the front of the leaf we had due to an insertion + * (see push_leaf_right()). + * If we hit this case and our slot is > 0 and just decrement the slot + * so that the caller does not process the same key again, which may or + * may not break the caller, depending on its logic. + */ + if (path->slots[0] < btrfs_header_nritems(path->nodes[0])) { + btrfs_item_key(path->nodes[0], &found_key, path->slots[0]); + ret = comp_keys(&found_key, &orig_key); + if (ret == 0) { + if (path->slots[0] > 0) { + path->slots[0]--; + return 0; + } + /* + * At slot 0, same key as before, it means orig_key is + * the lowest, leftmost, key in the tree. We're done. + */ + return 1; + } + } + btrfs_item_key(path->nodes[0], &found_key, 0); ret = comp_keys(&found_key, &key); /*
From: Josef Bacik josef@toxicpanda.com
commit d246331b78cbef86237f9c22389205bc9b4e1cc1 upstream.
Boris noticed in his simple quotas testing that he was getting a leak with Sweet Tea's change to subvol create that stopped doing a transaction commit. This was just a side effect of that change.
In the delayed inode code we have an optimization that will free extra reservations if we think we can pack a dir item into an already modified leaf. Previously this wouldn't be triggered in the subvolume create case because we'd commit the transaction, it was still possible but much harder to trigger. It could actually be triggered if we did a mkdir && subvol create with qgroups enabled.
This occurs because in btrfs_insert_delayed_dir_index(), which gets called when we're adding the dir item, we do the following:
btrfs_block_rsv_release(fs_info, trans->block_rsv, bytes, NULL);
if we're able to skip reserving space.
The problem here is that trans->block_rsv points at the temporary block rsv for the subvolume create, which has qgroup reservations in the block rsv.
This is a problem because btrfs_block_rsv_release() will do the following:
if (block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) { qgroup_to_release = block_rsv->qgroup_rsv_reserved - block_rsv->qgroup_rsv_size; block_rsv->qgroup_rsv_reserved = block_rsv->qgroup_rsv_size; }
The temporary block rsv just has ->qgroup_rsv_reserved set, ->qgroup_rsv_size == 0. The optimization in btrfs_insert_delayed_dir_index() sets ->qgroup_rsv_reserved = 0. Then later on when we call btrfs_subvolume_release_metadata() which has
btrfs_block_rsv_release(fs_info, rsv, (u64)-1, &qgroup_to_release); btrfs_qgroup_convert_reserved_meta(root, qgroup_to_release);
qgroup_to_release is set to 0, and we do not convert the reserved metadata space.
The problem here is that the block rsv code has been unconditionally messing with ->qgroup_rsv_reserved, because the main place this is used is delalloc, and any time we call btrfs_block_rsv_release() we do it with qgroup_to_release set, and thus do the proper accounting.
The subvolume code is the only other code that uses the qgroup reservation stuff, but it's intermingled with the above optimization, and thus was getting its reservation freed out from underneath it and thus leaking the reserved space.
The solution is to simply not mess with the qgroup reservations if we don't have qgroup_to_release set. This works with the existing code as anything that messes with the delalloc reservations always have qgroup_to_release set. This fixes the leak that Boris was observing.
Reviewed-by: Qu Wenruo wqu@suse.com CC: stable@vger.kernel.org # 5.4+ Signed-off-by: Josef Bacik josef@toxicpanda.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/block-rsv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/btrfs/block-rsv.c +++ b/fs/btrfs/block-rsv.c @@ -121,7 +121,8 @@ static u64 block_rsv_release_bytes(struc } else { num_bytes = 0; } - if (block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) { + if (qgroup_to_release_ret && + block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) { qgroup_to_release = block_rsv->qgroup_rsv_reserved - block_rsv->qgroup_rsv_size; block_rsv->qgroup_rsv_reserved = block_rsv->qgroup_rsv_size;
From: Anastasia Belova abelova@astralinux.ru
commit c87f318e6f47696b4040b58f460d5c17ea0280e6 upstream.
Check nodesize to sectorsize in alignment check in print_extent_item. The comment states that and this is correct, similar check is done elsewhere in the functions.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: ea57788eb76d ("btrfs: require only sector size alignment for parent eb bytenr") CC: stable@vger.kernel.org # 4.14+ Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Anastasia Belova abelova@astralinux.ru 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/print-tree.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c @@ -147,10 +147,10 @@ static void print_extent_item(struct ext pr_cont("shared data backref parent %llu count %u\n", offset, btrfs_shared_data_ref_count(eb, sref)); /* - * offset is supposed to be a tree block which - * must be aligned to nodesize. + * Offset is supposed to be a tree block which must be + * aligned to sectorsize. */ - if (!IS_ALIGNED(offset, eb->fs_info->nodesize)) + if (!IS_ALIGNED(offset, eb->fs_info->sectorsize)) pr_info( "\t\t\t(parent %llu not aligned to sectorsize %u)\n", offset, eb->fs_info->sectorsize);
From: Pawel Witek pawel.ireneusz.witek@gmail.com
commit d66cde50c3c868af7abddafce701bb86e4a93039 upstream.
Change type of pcchunk->Length from u32 to u64 to match smb2_copychunk_range arguments type. Fixes the problem where performing server-side copy with CIFS_IOC_COPYCHUNK_FILE ioctl resulted in incomplete copy of large files while returning -EINVAL.
Fixes: 9bf0c9cd4314 ("CIFS: Fix SMB2/SMB3 Copy offload support (refcopy) for large files") Cc: stable@vger.kernel.org Signed-off-by: Pawel Witek pawel.ireneusz.witek@gmail.com 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 @@ -1784,7 +1784,7 @@ smb2_copychunk_range(const unsigned int pcchunk->SourceOffset = cpu_to_le64(src_off); pcchunk->TargetOffset = cpu_to_le64(dest_off); pcchunk->Length = - cpu_to_le32(min_t(u32, len, tcon->max_bytes_chunk)); + cpu_to_le32(min_t(u64, len, tcon->max_bytes_chunk));
/* Request server copy to target from src identified by key */ kfree(retbuf);
From: Hans de Goede hdegoede@redhat.com
commit 6abfa99ce52f61a31bcfc2aaaae09006f5665495 upstream.
The Juno Computers Juno Tablet has an upside-down mounted Goodix touchscreen. Add a quirk to invert both axis to correct for this.
Link: https://junocomputers.com/us/product/juno-tablet/ Cc: stable@vger.kernel.org Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230505210323.43177-1-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/platform/x86/touchscreen_dmi.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
--- a/drivers/platform/x86/touchscreen_dmi.c +++ b/drivers/platform/x86/touchscreen_dmi.c @@ -381,6 +381,11 @@ static const struct ts_dmi_data glavey_t .properties = glavey_tm800a550l_props, };
+static const struct ts_dmi_data gdix1002_00_upside_down_data = { + .acpi_name = "GDIX1002:00", + .properties = gdix1001_upside_down_props, +}; + static const struct property_entry gp_electronic_t701_props[] = { PROPERTY_ENTRY_U32("touchscreen-size-x", 960), PROPERTY_ENTRY_U32("touchscreen-size-y", 640), @@ -1228,6 +1233,18 @@ const struct dmi_system_id touchscreen_d }, }, { + /* Juno Tablet */ + .driver_data = (void *)&gdix1002_00_upside_down_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Default string"), + /* Both product- and board-name being "Default string" is somewhat rare */ + DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), + DMI_MATCH(DMI_BOARD_NAME, "Default string"), + /* Above matches are too generic, add partial bios-version match */ + DMI_MATCH(DMI_BIOS_VERSION, "JP2V1."), + }, + }, + { /* Mediacom WinPad 7.0 W700 (same hw as Wintron surftab 7") */ .driver_data = (void *)&trekstor_surftab_wintron70_data, .matches = {
From: Andrey Avdeev jamesstoun@gmail.com
commit 4b65f95c87c35699bc6ad540d6b9dd7f950d0924 upstream.
Add touchscreen info for the Dexp Ursus KX210i
Signed-off-by: Andrey Avdeev jamesstoun@gmail.com Link: https://lore.kernel.org/r/ZE4gRgzRQCjXFYD0@avdeevavpc Cc: stable@vger.kernel.org Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/platform/x86/touchscreen_dmi.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
--- a/drivers/platform/x86/touchscreen_dmi.c +++ b/drivers/platform/x86/touchscreen_dmi.c @@ -327,6 +327,22 @@ static const struct ts_dmi_data dexp_urs .properties = dexp_ursus_7w_props, };
+static const struct property_entry dexp_ursus_kx210i_props[] = { + PROPERTY_ENTRY_U32("touchscreen-min-x", 5), + PROPERTY_ENTRY_U32("touchscreen-min-y", 2), + PROPERTY_ENTRY_U32("touchscreen-size-x", 1720), + PROPERTY_ENTRY_U32("touchscreen-size-y", 1137), + PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-dexp-ursus-kx210i.fw"), + PROPERTY_ENTRY_U32("silead,max-fingers", 10), + PROPERTY_ENTRY_BOOL("silead,home-button"), + { } +}; + +static const struct ts_dmi_data dexp_ursus_kx210i_data = { + .acpi_name = "MSSL1680:00", + .properties = dexp_ursus_kx210i_props, +}; + static const struct property_entry digma_citi_e200_props[] = { PROPERTY_ENTRY_U32("touchscreen-size-x", 1980), PROPERTY_ENTRY_U32("touchscreen-size-y", 1500), @@ -1124,6 +1140,14 @@ const struct dmi_system_id touchscreen_d }, }, { + /* DEXP Ursus KX210i */ + .driver_data = (void *)&dexp_ursus_kx210i_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "INSYDE Corp."), + DMI_MATCH(DMI_PRODUCT_NAME, "S107I"), + }, + }, + { /* Digma Citi E200 */ .driver_data = (void *)&digma_citi_e200_data, .matches = {
From: Jan Kara jack@suse.cz
commit c915d8f5918bea7c3962b09b8884ca128bfd9b0c upstream.
When inotify_freeing_mark() races with inotify_handle_inode_event() it can happen that inotify_handle_inode_event() sees that i_mark->wd got already reset to -1 and reports this value to userspace which can confuse the inotify listener. Avoid the problem by validating that wd is sensible (and pretend the mark got removed before the event got generated otherwise).
CC: stable@vger.kernel.org Fixes: 7e790dd5fc93 ("inotify: fix error paths in inotify_update_watch") Message-Id: 20230424163219.9250-1-jack@suse.cz Reported-by: syzbot+4a06d4373fd52f0b2f9c@syzkaller.appspotmail.com Reviewed-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/notify/inotify/inotify_fsnotify.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
--- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -64,7 +64,7 @@ int inotify_handle_inode_event(struct fs struct fsnotify_event *fsn_event; struct fsnotify_group *group = inode_mark->group; int ret; - int len = 0; + int len = 0, wd; int alloc_len = sizeof(struct inotify_event_info); struct mem_cgroup *old_memcg;
@@ -80,6 +80,13 @@ int inotify_handle_inode_event(struct fs fsn_mark);
/* + * We can be racing with mark being detached. Don't report event with + * invalid wd. + */ + wd = READ_ONCE(i_mark->wd); + if (wd == -1) + return 0; + /* * Whoever is interested in the event, pays for the allocation. Do not * trigger OOM killer in the target monitoring memcg as it may have * security repercussion. @@ -109,7 +116,7 @@ int inotify_handle_inode_event(struct fs fsn_event = &event->fse; fsnotify_init_event(fsn_event, 0); event->mask = mask; - event->wd = i_mark->wd; + event->wd = wd; event->sync_cookie = cookie; event->name_len = len; if (len)
From: Randy Dunlap rdunlap@infradead.org
commit 58a49ad90939386a8682e842c474a0d2c00ec39c upstream.
Fix a warning that was reported by the kernel test robot:
In file included from ../include/math-emu/soft-fp.h:27, from ../arch/sh/math-emu/math.c:22: ../arch/sh/include/asm/sfp-machine.h:17: warning: "__BYTE_ORDER" redefined 17 | #define __BYTE_ORDER __BIG_ENDIAN In file included from ../arch/sh/math-emu/math.c:21: ../arch/sh/math-emu/sfp-util.h:71: note: this is the location of the previous definition 71 | #define __BYTE_ORDER __LITTLE_ENDIAN
Fixes: b929926f01f2 ("sh: define __BIG_ENDIAN for math-emu") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com Link: lore.kernel.org/r/202111121827.6v6SXtVv-lkp@intel.com Cc: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Cc: Yoshinori Sato ysato@users.sourceforge.jp Cc: Rich Felker dalias@libc.org Cc: linux-sh@vger.kernel.org Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Cc: stable@vger.kernel.org Reviewed-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Link: https://lore.kernel.org/r/20230306040037.20350-5-rdunlap@infradead.org Signed-off-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/sh/math-emu/sfp-util.h | 4 ---- 1 file changed, 4 deletions(-)
--- a/arch/sh/math-emu/sfp-util.h +++ b/arch/sh/math-emu/sfp-util.h @@ -67,7 +67,3 @@ } while (0)
#define abort() return 0 - -#define __BYTE_ORDER __LITTLE_ENDIAN - -
From: Randy Dunlap rdunlap@infradead.org
commit c2bd1e18c6f85c0027da2e5e7753b9bfd9f8e6dc upstream.
Fix a build error in mcount.S when CONFIG_PRINTK is not enabled. Fixes this build error:
sh2-linux-ld: arch/sh/lib/mcount.o: in function `stack_panic': (.text+0xec): undefined reference to `dump_stack'
Fixes: e460ab27b6c3 ("sh: Fix up stack overflow check with ftrace disabled.") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Cc: Yoshinori Sato ysato@users.sourceforge.jp Cc: Rich Felker dalias@libc.org Suggested-by: Geert Uytterhoeven geert@linux-m68k.org Cc: stable@vger.kernel.org Reviewed-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Link: https://lore.kernel.org/r/20230306040037.20350-8-rdunlap@infradead.org Signed-off-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/sh/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -18,7 +18,7 @@ config SH_STANDARD_BIOS
config STACK_DEBUG bool "Check for stack overflows" - depends on DEBUG_KERNEL + depends on DEBUG_KERNEL && PRINTK help This option will cause messages to be printed if free stack space drops below a certain limit. Saying Y here will add overhead to
From: Randy Dunlap rdunlap@infradead.org
commit 6cba655543c7959f8a6d2979b9d40a6a66b7ed4f upstream.
When CONFIG_OF_EARLY_FLATTREE and CONFIG_SH_DEVICE_TREE are not set, SH3 build fails with a call to early_init_dt_scan(), so in arch/sh/kernel/setup.c and arch/sh/kernel/head_32.S, use CONFIG_OF_EARLY_FLATTREE instead of CONFIG_OF_FLATTREE.
Fixes this build error: ../arch/sh/kernel/setup.c: In function 'sh_fdt_init': ../arch/sh/kernel/setup.c:262:26: error: implicit declaration of function 'early_init_dt_scan' [-Werror=implicit-function-declaration] 262 | if (!dt_virt || !early_init_dt_scan(dt_virt)) {
Fixes: 03767daa1387 ("sh: fix build regression with CONFIG_OF && !CONFIG_OF_FLATTREE") Fixes: eb6b6930a70f ("sh: fix memory corruption of unflattened device tree") Signed-off-by: Randy Dunlap rdunlap@infradead.org Suggested-by: Rob Herring robh+dt@kernel.org Cc: Frank Rowand frowand.list@gmail.com Cc: devicetree@vger.kernel.org Cc: Rich Felker dalias@libc.org Cc: Yoshinori Sato ysato@users.sourceforge.jp Cc: Geert Uytterhoeven geert+renesas@glider.be Cc: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Cc: linux-sh@vger.kernel.org Cc: stable@vger.kernel.org Reviewed-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Link: https://lore.kernel.org/r/20230306040037.20350-4-rdunlap@infradead.org Signed-off-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/sh/kernel/head_32.S | 6 +++--- arch/sh/kernel/setup.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-)
--- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -64,7 +64,7 @@ ENTRY(_stext) ldc r0, r6_bank #endif
-#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_OF_EARLY_FLATTREE mov r4, r12 ! Store device tree blob pointer in r12 #endif @@ -315,7 +315,7 @@ ENTRY(_stext) 10: #endif
-#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_OF_EARLY_FLATTREE mov.l 8f, r0 ! Make flat device tree available early. jsr @r0 mov r12, r4 @@ -346,7 +346,7 @@ ENTRY(stack_start) 5: .long start_kernel 6: .long cpu_init 7: .long init_thread_union -#if defined(CONFIG_OF_FLATTREE) +#if defined(CONFIG_OF_EARLY_FLATTREE) 8: .long sh_fdt_init #endif
--- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -244,7 +244,7 @@ void __init __weak plat_early_device_set { }
-#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_OF_EARLY_FLATTREE void __ref sh_fdt_init(phys_addr_t dt_phys) { static int done = 0; @@ -329,7 +329,7 @@ void __init setup_arch(char **cmdline_p) /* Let earlyprintk output early console messages */ sh_early_platform_driver_probe("earlyprintk", 1, 1);
-#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_OF_EARLY_FLATTREE #ifdef CONFIG_USE_BUILTIN_DTB unflatten_and_copy_device_tree(); #else
From: Randy Dunlap rdunlap@infradead.org
commit d1155e4132de712a9d3066e2667ceaad39a539c5 upstream.
__setup() handlers should return 1 to obsolete_checksetup() in init/main.c to indicate that the boot option has been handled. A return of 0 causes the boot option/value to be listed as an Unknown kernel parameter and added to init's (limited) argument or environment strings. Also, error return codes don't mean anything to obsolete_checksetup() -- only non-zero (usually 1) or zero. So return 1 from nmi_debug_setup().
Fixes: 1e1030dccb10 ("sh: nmi_debug support.") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: Igor Zhbanov izh1979@gmail.com Link: lore.kernel.org/r/64644a2f-4a20-bab3-1e15-3b2cdd0defe3@omprussia.ru Cc: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Cc: Yoshinori Sato ysato@users.sourceforge.jp Cc: Rich Felker dalias@libc.org Cc: linux-sh@vger.kernel.org Cc: stable@vger.kernel.org Reviewed-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Link: https://lore.kernel.org/r/20230306040037.20350-3-rdunlap@infradead.org Signed-off-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/sh/kernel/nmi_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/sh/kernel/nmi_debug.c +++ b/arch/sh/kernel/nmi_debug.c @@ -49,7 +49,7 @@ static int __init nmi_debug_setup(char * register_die_notifier(&nmi_debug_nb);
if (*str != '=') - return 0; + return 1;
for (p = str + 1; *p; p = sep + 1) { sep = strchr(p, ','); @@ -70,6 +70,6 @@ static int __init nmi_debug_setup(char * break; }
- return 0; + return 1; } __setup("nmi_debug", nmi_debug_setup);
From: Mathieu Poirier mathieu.poirier@linaro.org
commit ccadca5baf5124a880f2bb50ed1ec265415f025b upstream.
Function of_phandle_iterator_next() calls of_node_put() on the last device_node it iterated over, but when the loop exits prematurely it has to be called explicitly.
Fixes: 13140de09cc2 ("remoteproc: stm32: add an ST stm32_rproc driver") Cc: stable@vger.kernel.org Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Reviewed-by: Arnaud Pouliquen arnaud.pouliquen@foss.st.com Link: https://lore.kernel.org/r/20230320221826.2728078-2-mathieu.poirier@linaro.or... Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/remoteproc/stm32_rproc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -231,11 +231,13 @@ static int stm32_rproc_parse_memory_regi while (of_phandle_iterator_next(&it) == 0) { rmem = of_reserved_mem_lookup(it.node); if (!rmem) { + of_node_put(it.node); dev_err(dev, "unable to acquire memory-region\n"); return -EINVAL; }
if (stm32_rproc_pa_to_da(rproc, rmem->base, &da) < 0) { + of_node_put(it.node); dev_err(dev, "memory region not valid %pa\n", &rmem->base); return -EINVAL; @@ -262,8 +264,10 @@ static int stm32_rproc_parse_memory_regi it.node->name); }
- if (!mem) + if (!mem) { + of_node_put(it.node); return -ENOMEM; + }
rproc_add_carveout(rproc, mem); index++;
From: Mathieu Poirier mathieu.poirier@linaro.org
commit 8a74918948b40317a5b5bab9739d13dcb5de2784 upstream.
Function of_phandle_iterator_next() calls of_node_put() on the last device_node it iterated over, but when the loop exits prematurely it has to be called explicitly.
Fixes: 3df52ed7f269 ("remoteproc: st: add reserved memory support") Cc: stable@vger.kernel.org Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Reviewed-by: Arnaud Pouliquen arnaud.pouliquen@foss.st.com Link: https://lore.kernel.org/r/20230320221826.2728078-3-mathieu.poirier@linaro.or... Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/remoteproc/st_remoteproc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/remoteproc/st_remoteproc.c +++ b/drivers/remoteproc/st_remoteproc.c @@ -129,6 +129,7 @@ static int st_rproc_parse_fw(struct rpro while (of_phandle_iterator_next(&it) == 0) { rmem = of_reserved_mem_lookup(it.node); if (!rmem) { + of_node_put(it.node); dev_err(dev, "unable to acquire memory-region\n"); return -EINVAL; } @@ -150,8 +151,10 @@ static int st_rproc_parse_fw(struct rpro it.node->name); }
- if (!mem) + if (!mem) { + of_node_put(it.node); return -ENOMEM; + }
rproc_add_carveout(rproc, mem); index++;
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
commit 6c950c20da38debf1ed531e0b972bd8b53d1c11f upstream.
The WM8960 Linux driver expects the clock to be named "mclk". Otherwise the clock will be ignored and not prepared/enabled by the driver.
Cc: stable@vger.kernel.org Fixes: 339b2fb36a67 ("ARM: dts: exynos: Add TOPEET itop elite based board") Link: https://lore.kernel.org/r/20230217150627.779764-3-krzysztof.kozlowski@linaro... Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/boot/dts/exynos4412-itop-elite.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm/boot/dts/exynos4412-itop-elite.dts +++ b/arch/arm/boot/dts/exynos4412-itop-elite.dts @@ -179,7 +179,7 @@ compatible = "wlf,wm8960"; reg = <0x1a>; clocks = <&pmu_system_controller 0>; - clock-names = "MCLK1"; + clock-names = "mclk"; wlf,shared-lrclk; #sound-dai-cells = <0>; };
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
commit 665b9459bb53b8f19bd1541567e1fe9782c83c4b upstream.
The Samsung S5P/Exynos MIPI CSIS bindings and Linux driver expect first clock name to be "csis". Otherwise the driver fails to probe.
Fixes: 94ad0f6d9278 ("ARM: dts: Add Device tree for s5pv210 SoC") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230212185818.43503-2-krzysztof.kozlowski@linaro.... Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/boot/dts/s5pv210.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm/boot/dts/s5pv210.dtsi +++ b/arch/arm/boot/dts/s5pv210.dtsi @@ -583,7 +583,7 @@ interrupts = <29>; clocks = <&clocks CLK_CSIS>, <&clocks SCLK_CSIS>; - clock-names = "clk_csis", + clock-names = "csis", "sclk_csis"; bus-width = <4>; status = "disabled";
From: Jaegeuk Kim jaegeuk@kernel.org
commit d94772154e524b329a168678836745d2773a6e02 upstream.
F2FS has the same issue in ext4_rename causing crash revealed by xfstests/generic/707.
See also commit 0813299c586b ("ext4: Fix possible corruption when moving a directory")
CC: stable@vger.kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/namei.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
--- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -969,12 +969,20 @@ static int f2fs_rename(struct inode *old goto out; }
+ /* + * Copied from ext4_rename: we need to protect against old.inode + * directory getting converted from inline directory format into + * a normal one. + */ + if (S_ISDIR(old_inode->i_mode)) + inode_lock_nested(old_inode, I_MUTEX_NONDIR2); + err = -ENOENT; old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); if (!old_entry) { if (IS_ERR(old_page)) err = PTR_ERR(old_page); - goto out; + goto out_unlock_old; }
if (S_ISDIR(old_inode->i_mode)) { @@ -1082,6 +1090,9 @@ static int f2fs_rename(struct inode *old
f2fs_unlock_op(sbi);
+ if (S_ISDIR(old_inode->i_mode)) + inode_unlock(old_inode); + if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) f2fs_sync_fs(sbi->sb, 1);
@@ -1096,6 +1107,9 @@ out_dir: f2fs_put_page(old_dir_page, 0); out_old: f2fs_put_page(old_page, 0); +out_unlock_old: + if (S_ISDIR(old_inode->i_mode)) + inode_unlock(old_inode); out: if (whiteout) iput(whiteout);
From: James Cowgill james.cowgill@blaize.com
commit ab4f869fba6119997f7630d600049762a2b014fa upstream.
This is the logical place to put the backlight device, and it also fixes a kernel crash if the MIPI host is removed. Previously the backlight device would be unregistered twice when this happened - once as a child of the MIPI host through `mipi_dsi_host_unregister`, and once when the panel device is destroyed.
Fixes: 12a6cbd4f3f1 ("drm/panel: otm8009a: Use new backlight API") Signed-off-by: James Cowgill james.cowgill@blaize.com Cc: stable@vger.kernel.org Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20230412173450.199592-1-james.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/panel/panel-orisetech-otm8009a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c +++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c @@ -458,7 +458,7 @@ static int otm8009a_probe(struct mipi_ds DRM_MODE_CONNECTOR_DSI);
ctx->bl_dev = devm_backlight_device_register(dev, dev_name(dev), - dsi->host->dev, ctx, + dev, ctx, &otm8009a_backlight_ops, NULL); if (IS_ERR(ctx->bl_dev)) {
From: Hamza Mahfooz hamza.mahfooz@amd.com
commit 922a76ba31adf84e72bc947267385be420c689ee upstream.
As made mention of in commit 08c677cb0b43 ("drm/amdgpu: fix amdgpu_irq_put call trace in gmc_v10_0_hw_fini") and commit 13af556104fa ("drm/amdgpu: fix amdgpu_irq_put call trace in gmc_v11_0_hw_fini"). It is meaningless to call amdgpu_irq_put() for gmc.ecc_irq. So, remove it from gmc_v9_0_hw_fini().
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2522 Fixes: 3029c855d79f ("drm/amdgpu: Fix desktop freezed after gpu-reset") Reviewed-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Hamza Mahfooz hamza.mahfooz@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1686,7 +1686,6 @@ static int gmc_v9_0_hw_fini(void *handle return 0; }
- amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0);
return 0;
From: Guchun Chen guchun.chen@amd.com
commit 4a76680311330aefe5074bed8f06afa354b85c48 upstream.
gfx9 cp_ecc_error_irq is only enabled when legacy gfx ras is assert. So in gfx_v9_0_hw_fini, interrupt disablement for cp_ecc_error_irq should be executed under such condition, otherwise, an amdgpu_irq_put calltrace will occur.
[ 7283.170322] RIP: 0010:amdgpu_irq_put+0x45/0x70 [amdgpu] [ 7283.170964] RSP: 0018:ffff9a5fc3967d00 EFLAGS: 00010246 [ 7283.170967] RAX: ffff98d88afd3040 RBX: ffff98d89da20000 RCX: 0000000000000000 [ 7283.170969] RDX: 0000000000000000 RSI: ffff98d89da2bef8 RDI: ffff98d89da20000 [ 7283.170971] RBP: ffff98d89da20000 R08: ffff98d89da2ca18 R09: 0000000000000006 [ 7283.170973] R10: ffffd5764243c008 R11: 0000000000000000 R12: 0000000000001050 [ 7283.170975] R13: ffff98d89da38978 R14: ffffffff999ae15a R15: ffff98d880130105 [ 7283.170978] FS: 0000000000000000(0000) GS:ffff98d996f00000(0000) knlGS:0000000000000000 [ 7283.170981] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 7283.170983] CR2: 00000000f7a9d178 CR3: 00000001c42ea000 CR4: 00000000003506e0 [ 7283.170986] Call Trace: [ 7283.170988] <TASK> [ 7283.170989] gfx_v9_0_hw_fini+0x1c/0x6d0 [amdgpu] [ 7283.171655] amdgpu_device_ip_suspend_phase2+0x101/0x1a0 [amdgpu] [ 7283.172245] amdgpu_device_suspend+0x103/0x180 [amdgpu] [ 7283.172823] amdgpu_pmops_freeze+0x21/0x60 [amdgpu] [ 7283.173412] pci_pm_freeze+0x54/0xc0 [ 7283.173419] ? __pfx_pci_pm_freeze+0x10/0x10 [ 7283.173425] dpm_run_callback+0x98/0x200 [ 7283.173430] __device_suspend+0x164/0x5f0
v2: drop gfx11 as it's fixed in a different solution by retiring cp_ecc_irq funcs(Hawking)
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2522 Signed-off-by: Guchun Chen guchun.chen@amd.com Reviewed-by: Tao Zhou tao.zhou1@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -3943,7 +3943,8 @@ static int gfx_v9_0_hw_fini(void *handle { struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0); + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX)) + amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0); amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
From: Guchun Chen guchun.chen@amd.com
commit 8b229ada2669b74fdae06c83fbfda5a5a99fc253 upstream.
sdma_v4_0_ip is shared on a few asics, but in sdma_v4_0_hw_fini, driver unconditionally disables ecc_irq which is only enabled on those asics enabling sdma ecc. This will introduce a warning in suspend cycle on those chips with sdma ip v4.0, while without sdma ecc. So this patch correct this.
[ 7283.166354] RIP: 0010:amdgpu_irq_put+0x45/0x70 [amdgpu] [ 7283.167001] RSP: 0018:ffff9a5fc3967d08 EFLAGS: 00010246 [ 7283.167019] RAX: ffff98d88afd3770 RBX: 0000000000000001 RCX: 0000000000000000 [ 7283.167023] RDX: 0000000000000000 RSI: ffff98d89da30390 RDI: ffff98d89da20000 [ 7283.167025] RBP: ffff98d89da20000 R08: 0000000000036838 R09: 0000000000000006 [ 7283.167028] R10: ffffd5764243c008 R11: 0000000000000000 R12: ffff98d89da30390 [ 7283.167030] R13: ffff98d89da38978 R14: ffffffff999ae15a R15: ffff98d880130105 [ 7283.167032] FS: 0000000000000000(0000) GS:ffff98d996f00000(0000) knlGS:0000000000000000 [ 7283.167036] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 7283.167039] CR2: 00000000f7a9d178 CR3: 00000001c42ea000 CR4: 00000000003506e0 [ 7283.167041] Call Trace: [ 7283.167046] <TASK> [ 7283.167048] sdma_v4_0_hw_fini+0x38/0xa0 [amdgpu] [ 7283.167704] amdgpu_device_ip_suspend_phase2+0x101/0x1a0 [amdgpu] [ 7283.168296] amdgpu_device_suspend+0x103/0x180 [amdgpu] [ 7283.168875] amdgpu_pmops_freeze+0x21/0x60 [amdgpu] [ 7283.169464] pci_pm_freeze+0x54/0xc0
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2522 Signed-off-by: Guchun Chen guchun.chen@amd.com Reviewed-by: Tao Zhou tao.zhou1@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -1979,9 +1979,11 @@ static int sdma_v4_0_hw_fini(void *handl if (amdgpu_sriov_vf(adev)) return 0;
- for (i = 0; i < adev->sdma.num_instances; i++) { - amdgpu_irq_put(adev, &adev->sdma.ecc_irq, - AMDGPU_SDMA_IRQ_INSTANCE0 + i); + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA)) { + for (i = 0; i < adev->sdma.num_instances; i++) { + amdgpu_irq_put(adev, &adev->sdma.ecc_irq, + AMDGPU_SDMA_IRQ_INSTANCE0 + i); + } }
sdma_v4_0_ctx_switch_enable(adev, false);
From: Ping Cheng pinglinux@gmail.com
commit 08a46b4190d345544d04ce4fe2e1844b772b8535 upstream.
Some older tablets may not report physical maximum for X/Y coordinates. Set a default to prevent undefined resolution.
Signed-off-by: Ping Cheng ping.cheng@wacom.com Link: https://lore.kernel.org/r/20230409164229.29777-1-ping.cheng@wacom.com Signed-off-by: Benjamin Tissoires benjamin.tissoires@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hid/wacom_wac.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
--- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1853,6 +1853,7 @@ static void wacom_map_usage(struct input int fmax = field->logical_maximum; unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid); int resolution_code = code; + int resolution = hidinput_calc_abs_res(field, resolution_code);
if (equivalent_usage == HID_DG_TWIST) { resolution_code = ABS_RZ; @@ -1875,8 +1876,15 @@ static void wacom_map_usage(struct input switch (type) { case EV_ABS: input_set_abs_params(input, code, fmin, fmax, fuzz, 0); - input_abs_set_res(input, code, - hidinput_calc_abs_res(field, resolution_code)); + + /* older tablet may miss physical usage */ + if ((code == ABS_X || code == ABS_Y) && !resolution) { + resolution = WACOM_INTUOS_RES; + hid_warn(input, + "Wacom usage (%d) missing resolution \n", + code); + } + input_abs_set_res(input, code, resolution); break; case EV_KEY: input_set_capability(input, EV_KEY, code);
From: Ping Cheng pinglinux@gmail.com
commit 17d793f3ed53080dab6bbeabfc82de890c901001 upstream.
To fully utilize the BT polling/refresh rate, a few input events are sent together to reduce event delay. This causes issue to the timestamp generated by input_sync since all the events in the same packet would pretty much have the same timestamp. This patch inserts time interval to the events by averaging the total time used for sending the packet.
This decision was mainly based on observing the actual time interval between each BT polling. The interval doesn't seem to be constant, due to the network and system environment. So, using solutions other than averaging doesn't end up with valid timestamps.
Signed-off-by: Ping Cheng ping.cheng@wacom.com Reviewed-by: Jason Gerecke jason.gerecke@wacom.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hid/wacom_wac.c | 26 ++++++++++++++++++++++++++ drivers/hid/wacom_wac.h | 1 + 2 files changed, 27 insertions(+)
--- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1265,6 +1265,9 @@ static void wacom_intuos_pro2_bt_pen(str
struct input_dev *pen_input = wacom->pen_input; unsigned char *data = wacom->data; + int number_of_valid_frames = 0; + int time_interval = 15000000; + ktime_t time_packet_received = ktime_get(); int i;
if (wacom->features.type == INTUOSP2_BT || @@ -1285,12 +1288,30 @@ static void wacom_intuos_pro2_bt_pen(str wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF; }
+ /* number of valid frames */ for (i = 0; i < pen_frames; i++) { unsigned char *frame = &data[i*pen_frame_len + 1]; bool valid = frame[0] & 0x80; + + if (valid) + number_of_valid_frames++; + } + + if (number_of_valid_frames) { + if (wacom->hid_data.time_delayed) + time_interval = ktime_get() - wacom->hid_data.time_delayed; + time_interval /= number_of_valid_frames; + wacom->hid_data.time_delayed = time_packet_received; + } + + for (i = 0; i < number_of_valid_frames; i++) { + unsigned char *frame = &data[i*pen_frame_len + 1]; + bool valid = frame[0] & 0x80; bool prox = frame[0] & 0x40; bool range = frame[0] & 0x20; bool invert = frame[0] & 0x10; + int frames_number_reversed = number_of_valid_frames - i - 1; + int event_timestamp = time_packet_received - frames_number_reversed * time_interval;
if (!valid) continue; @@ -1303,6 +1324,7 @@ static void wacom_intuos_pro2_bt_pen(str wacom->tool[0] = 0; wacom->id[0] = 0; wacom->serial[0] = 0; + wacom->hid_data.time_delayed = 0; return; }
@@ -1339,6 +1361,7 @@ static void wacom_intuos_pro2_bt_pen(str get_unaligned_le16(&frame[11])); } } + if (wacom->tool[0]) { input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); if (wacom->features.type == INTUOSP2_BT || @@ -1362,6 +1385,9 @@ static void wacom_intuos_pro2_bt_pen(str
wacom->shared->stylus_in_proximity = prox;
+ /* add timestamp to unpack the frames */ + input_set_timestamp(pen_input, event_timestamp); + input_sync(pen_input); } } --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -320,6 +320,7 @@ struct hid_data { int bat_connected; int ps_connected; bool pad_input_event_flag; + int time_delayed; };
struct wacom_remote_data {
From: Vitaly Kuznetsov vkuznets@redhat.com
commit 6470accc7ba948b0b3aca22b273fe84ec638a116 upstream.
In preparation to making kvm_make_vcpus_request_mask() use for_each_set_bit() switch kvm_hv_flush_tlb() to calling kvm_make_all_cpus_request() for 'all cpus' case.
Note: kvm_make_all_cpus_request() (unlike kvm_make_vcpus_request_mask()) currently dynamically allocates cpumask on each call and this is suboptimal. Both kvm_make_all_cpus_request() and kvm_make_vcpus_request_mask() are going to be switched to using pre-allocated per-cpu masks.
Reviewed-by: Sean Christopherson seanjc@google.com Signed-off-by: Vitaly Kuznetsov vkuznets@redhat.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Message-Id: 20210903075141.403071-4-vkuznets@redhat.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Acked-by: Sean Christopherson seanjc@google.com Fixes: 6100066358ee ("KVM: Optimize kvm_make_vcpus_request_mask() a bit") Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/hyperv.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
--- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -1562,16 +1562,19 @@ static u64 kvm_hv_flush_tlb(struct kvm_v
cpumask_clear(&hv_vcpu->tlb_flush);
- vcpu_mask = all_cpus ? NULL : - sparse_set_to_vcpu_mask(kvm, sparse_banks, valid_bank_mask, - vp_bitmap, vcpu_bitmap); - /* * vcpu->arch.cr3 may not be up-to-date for running vCPUs so we can't * analyze it here, flush TLB regardless of the specified address space. */ - kvm_make_vcpus_request_mask(kvm, KVM_REQ_TLB_FLUSH_GUEST, - NULL, vcpu_mask, &hv_vcpu->tlb_flush); + if (all_cpus) { + kvm_make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH_GUEST); + } else { + vcpu_mask = sparse_set_to_vcpu_mask(kvm, sparse_banks, valid_bank_mask, + vp_bitmap, vcpu_bitmap); + + kvm_make_vcpus_request_mask(kvm, KVM_REQ_TLB_FLUSH_GUEST, + NULL, vcpu_mask, &hv_vcpu->tlb_flush); + }
ret_success: /* We always do full TLB flush, set rep_done = rep_cnt. */
From: Paolo Bonzini pbonzini@redhat.com
commit 6cd88243c7e03845a450795e134b488fc2afb736 upstream.
If a vCPU is outside guest mode and is scheduled out, it might be in the process of making a memory access. A problem occurs if another vCPU uses the PV TLB flush feature during the period when the vCPU is scheduled out, and a virtual address has already been translated but has not yet been accessed, because this is equivalent to using a stale TLB entry.
To avoid this, only report a vCPU as preempted if sure that the guest is at an instruction boundary. A rescheduling request will be delivered to the host physical CPU as an external interrupt, so for simplicity consider any vmexit *not* instruction boundary except for external interrupts.
It would in principle be okay to report the vCPU as preempted also if it is sleeping in kvm_vcpu_block(): a TLB flush IPI will incur the vmentry/vmexit overhead unnecessarily, and optimistic spinning is also unlikely to succeed. However, leave it for later because right now kvm_vcpu_check_block() is doing memory accesses. Even though the TLB flush issue only applies to virtual memory address, it's very much preferrable to be conservative.
Reported-by: Jann Horn jannh@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com [OP: use VCPU_STAT() for debugfs entries] Signed-off-by: Ovidiu Panait ovidiu.panait@windriver.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/include/asm/kvm_host.h | 3 +++ arch/x86/kvm/svm/svm.c | 2 ++ arch/x86/kvm/vmx/vmx.c | 1 + arch/x86/kvm/x86.c | 22 ++++++++++++++++++++++ 4 files changed, 28 insertions(+)
--- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -553,6 +553,7 @@ struct kvm_vcpu_arch { u64 ia32_misc_enable_msr; u64 smbase; u64 smi_count; + bool at_instruction_boundary; bool tpr_access_reporting; bool xsaves_enabled; u64 ia32_xss; @@ -1061,6 +1062,8 @@ struct kvm_vcpu_stat { u64 req_event; u64 halt_poll_success_ns; u64 halt_poll_fail_ns; + u64 preemption_reported; + u64 preemption_other; };
struct x86_instruction_info; --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3983,6 +3983,8 @@ out:
static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu) { + if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_INTR) + vcpu->arch.at_instruction_boundary = true; }
static void svm_sched_in(struct kvm_vcpu *vcpu, int cpu) --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6510,6 +6510,7 @@ static void handle_external_interrupt_ir return;
handle_interrupt_nmi_irqoff(vcpu, gate_offset(desc)); + vcpu->arch.at_instruction_boundary = true; }
static void vmx_handle_exit_irqoff(struct kvm_vcpu *vcpu) --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -231,6 +231,8 @@ struct kvm_stats_debugfs_item debugfs_en VCPU_STAT("l1d_flush", l1d_flush), VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns), VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns), + VCPU_STAT("preemption_reported", preemption_reported), + VCPU_STAT("preemption_other", preemption_other), VM_STAT("mmu_shadow_zapped", mmu_shadow_zapped), VM_STAT("mmu_pte_write", mmu_pte_write), VM_STAT("mmu_pde_zapped", mmu_pde_zapped), @@ -4052,6 +4054,19 @@ static void kvm_steal_time_set_preempted struct kvm_host_map map; struct kvm_steal_time *st;
+ /* + * The vCPU can be marked preempted if and only if the VM-Exit was on + * an instruction boundary and will not trigger guest emulation of any + * kind (see vcpu_run). Vendor specific code controls (conservatively) + * when this is true, for example allowing the vCPU to be marked + * preempted if and only if the VM-Exit was due to a host interrupt. + */ + if (!vcpu->arch.at_instruction_boundary) { + vcpu->stat.preemption_other++; + return; + } + + vcpu->stat.preemption_reported++; if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) return;
@@ -9357,6 +9372,13 @@ static int vcpu_run(struct kvm_vcpu *vcp vcpu->arch.l1tf_flush_l1d = true;
for (;;) { + /* + * If another guest vCPU requests a PV TLB flush in the middle + * of instruction emulation, the rest of the emulation could + * use a stale page translation. Assume that any code after + * this point can start executing an instruction. + */ + vcpu->arch.at_instruction_boundary = false; if (kvm_vcpu_running(vcpu)) { r = vcpu_enter_guest(vcpu); } else {
From: Ye Bin yebin10@huawei.com
commit fa08a7b61dff8a4df11ff1e84abfc214b487caf7 upstream.
Syzbot found the following issue:
EXT4-fs: Warning: mounting with data=journal disables delayed allocation, dioread_nolock, O_DIRECT and fast_commit support! EXT4-fs (loop0): orphan cleanup on readonly fs ------------[ cut here ]------------ WARNING: CPU: 1 PID: 5067 at fs/ext4/mballoc.c:1869 mb_find_extent+0x8a1/0xe30 Modules linked in: CPU: 1 PID: 5067 Comm: syz-executor307 Not tainted 6.2.0-rc1-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 RIP: 0010:mb_find_extent+0x8a1/0xe30 fs/ext4/mballoc.c:1869 RSP: 0018:ffffc90003c9e098 EFLAGS: 00010293 RAX: ffffffff82405731 RBX: 0000000000000041 RCX: ffff8880783457c0 RDX: 0000000000000000 RSI: 0000000000000041 RDI: 0000000000000040 RBP: 0000000000000040 R08: ffffffff82405723 R09: ffffed10053c9402 R10: ffffed10053c9402 R11: 1ffff110053c9401 R12: 0000000000000000 R13: ffffc90003c9e538 R14: dffffc0000000000 R15: ffffc90003c9e2cc FS: 0000555556665300(0000) GS:ffff8880b9900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000056312f6796f8 CR3: 0000000022437000 CR4: 00000000003506e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ext4_mb_complex_scan_group+0x353/0x1100 fs/ext4/mballoc.c:2307 ext4_mb_regular_allocator+0x1533/0x3860 fs/ext4/mballoc.c:2735 ext4_mb_new_blocks+0xddf/0x3db0 fs/ext4/mballoc.c:5605 ext4_ext_map_blocks+0x1868/0x6880 fs/ext4/extents.c:4286 ext4_map_blocks+0xa49/0x1cc0 fs/ext4/inode.c:651 ext4_getblk+0x1b9/0x770 fs/ext4/inode.c:864 ext4_bread+0x2a/0x170 fs/ext4/inode.c:920 ext4_quota_write+0x225/0x570 fs/ext4/super.c:7105 write_blk fs/quota/quota_tree.c:64 [inline] get_free_dqblk+0x34a/0x6d0 fs/quota/quota_tree.c:130 do_insert_tree+0x26b/0x1aa0 fs/quota/quota_tree.c:340 do_insert_tree+0x722/0x1aa0 fs/quota/quota_tree.c:375 do_insert_tree+0x722/0x1aa0 fs/quota/quota_tree.c:375 do_insert_tree+0x722/0x1aa0 fs/quota/quota_tree.c:375 dq_insert_tree fs/quota/quota_tree.c:401 [inline] qtree_write_dquot+0x3b6/0x530 fs/quota/quota_tree.c:420 v2_write_dquot+0x11b/0x190 fs/quota/quota_v2.c:358 dquot_acquire+0x348/0x670 fs/quota/dquot.c:444 ext4_acquire_dquot+0x2dc/0x400 fs/ext4/super.c:6740 dqget+0x999/0xdc0 fs/quota/dquot.c:914 __dquot_initialize+0x3d0/0xcf0 fs/quota/dquot.c:1492 ext4_process_orphan+0x57/0x2d0 fs/ext4/orphan.c:329 ext4_orphan_cleanup+0xb60/0x1340 fs/ext4/orphan.c:474 __ext4_fill_super fs/ext4/super.c:5516 [inline] ext4_fill_super+0x81cd/0x8700 fs/ext4/super.c:5644 get_tree_bdev+0x400/0x620 fs/super.c:1282 vfs_get_tree+0x88/0x270 fs/super.c:1489 do_new_mount+0x289/0xad0 fs/namespace.c:3145 do_mount fs/namespace.c:3488 [inline] __do_sys_mount fs/namespace.c:3697 [inline] __se_sys_mount+0x2d3/0x3c0 fs/namespace.c:3674 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Add some debug information: mb_find_extent: mb_find_extent block=41, order=0 needed=64 next=0 ex=0/41/1@3735929054 64 64 7 block_bitmap: ff 3f 0c 00 fc 01 00 00 d2 3d 00 00 00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Acctually, blocks per group is 64, but block bitmap indicate at least has 128 blocks. Now, ext4_validate_block_bitmap() didn't check invalid block's bitmap if set. To resolve above issue, add check like fsck "Padding at end of block bitmap is not set".
Cc: stable@kernel.org Reported-by: syzbot+68223fe9f6c95ad43bed@syzkaller.appspotmail.com Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20230116020015.1506120-1-yebin@huaweicloud.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/balloc.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
--- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -303,6 +303,22 @@ struct ext4_group_desc * ext4_get_group_ return desc; }
+static ext4_fsblk_t ext4_valid_block_bitmap_padding(struct super_block *sb, + ext4_group_t block_group, + struct buffer_head *bh) +{ + ext4_grpblk_t next_zero_bit; + unsigned long bitmap_size = sb->s_blocksize * 8; + unsigned int offset = num_clusters_in_group(sb, block_group); + + if (bitmap_size <= offset) + return 0; + + next_zero_bit = ext4_find_next_zero_bit(bh->b_data, bitmap_size, offset); + + return (next_zero_bit < bitmap_size ? next_zero_bit : 0); +} + /* * Return the block number which was discovered to be invalid, or 0 if * the block bitmap is valid. @@ -401,6 +417,15 @@ static int ext4_validate_block_bitmap(st EXT4_GROUP_INFO_BBITMAP_CORRUPT); return -EFSCORRUPTED; } + blk = ext4_valid_block_bitmap_padding(sb, block_group, bh); + if (unlikely(blk != 0)) { + ext4_unlock_group(sb, block_group); + ext4_error(sb, "bg %u: block %llu: padding at end of block bitmap is not set", + block_group, blk); + ext4_mark_group_bitmap_corrupted(sb, block_group, + EXT4_GROUP_INFO_BBITMAP_CORRUPT); + return -EFSCORRUPTED; + } set_buffer_verified(bh); verified: ext4_unlock_group(sb, block_group);
From: Tudor Ambarus tudor.ambarus@linaro.org
commit 4f04351888a83e595571de672e0a4a8b74f4fb31 upstream.
When modifying the block device while it is mounted by the filesystem, syzbot reported the following:
BUG: KASAN: slab-out-of-bounds in crc16+0x206/0x280 lib/crc16.c:58 Read of size 1 at addr ffff888075f5c0a8 by task syz-executor.2/15586
CPU: 1 PID: 15586 Comm: syz-executor.2 Not tainted 6.2.0-rc5-syzkaller-00205-gc96618275234 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/12/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1b1/0x290 lib/dump_stack.c:106 print_address_description+0x74/0x340 mm/kasan/report.c:306 print_report+0x107/0x1f0 mm/kasan/report.c:417 kasan_report+0xcd/0x100 mm/kasan/report.c:517 crc16+0x206/0x280 lib/crc16.c:58 ext4_group_desc_csum+0x81b/0xb20 fs/ext4/super.c:3187 ext4_group_desc_csum_set+0x195/0x230 fs/ext4/super.c:3210 ext4_mb_clear_bb fs/ext4/mballoc.c:6027 [inline] ext4_free_blocks+0x191a/0x2810 fs/ext4/mballoc.c:6173 ext4_remove_blocks fs/ext4/extents.c:2527 [inline] ext4_ext_rm_leaf fs/ext4/extents.c:2710 [inline] ext4_ext_remove_space+0x24ef/0x46a0 fs/ext4/extents.c:2958 ext4_ext_truncate+0x177/0x220 fs/ext4/extents.c:4416 ext4_truncate+0xa6a/0xea0 fs/ext4/inode.c:4342 ext4_setattr+0x10c8/0x1930 fs/ext4/inode.c:5622 notify_change+0xe50/0x1100 fs/attr.c:482 do_truncate+0x200/0x2f0 fs/open.c:65 handle_truncate fs/namei.c:3216 [inline] do_open fs/namei.c:3561 [inline] path_openat+0x272b/0x2dd0 fs/namei.c:3714 do_filp_open+0x264/0x4f0 fs/namei.c:3741 do_sys_openat2+0x124/0x4e0 fs/open.c:1310 do_sys_open fs/open.c:1326 [inline] __do_sys_creat fs/open.c:1402 [inline] __se_sys_creat fs/open.c:1396 [inline] __x64_sys_creat+0x11f/0x160 fs/open.c:1396 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f72f8a8c0c9 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 19 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f72f97e3168 EFLAGS: 00000246 ORIG_RAX: 0000000000000055 RAX: ffffffffffffffda RBX: 00007f72f8bac050 RCX: 00007f72f8a8c0c9 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000020000280 RBP: 00007f72f8ae7ae9 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007ffd165348bf R14: 00007f72f97e3300 R15: 0000000000022000
Replace le16_to_cpu(sbi->s_es->s_desc_size) with sbi->s_desc_size
It reduces ext4's compiled text size, and makes the code more efficient (we remove an extra indirect reference and a potential byte swap on big endian systems), and there is no downside. It also avoids the potential KASAN / syzkaller failure, as a bonus.
Reported-by: syzbot+fc51227e7100c9294894@syzkaller.appspotmail.com Reported-by: syzbot+8785e41224a3afd04321@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=70d28d11ab14bd7938f3e088365252aa923cff4... Link: https://syzkaller.appspot.com/bug?id=b85721b38583ecc6b5e72ff524c67302abbc30f... Link: https://lore.kernel.org/all/000000000000ece18705f3b20934@google.com/ Fixes: 717d50e4971b ("Ext4: Uninitialized Block Groups") Cc: stable@vger.kernel.org Signed-off-by: Tudor Ambarus tudor.ambarus@linaro.org Link: https://lore.kernel.org/r/20230504121525.3275886-1-tudor.ambarus@linaro.org 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, 2 insertions(+), 4 deletions(-)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2831,11 +2831,9 @@ static __le16 ext4_group_desc_csum(struc crc = crc16(crc, (__u8 *)gdp, offset); offset += sizeof(gdp->bg_checksum); /* skip checksum */ /* for checksum of struct ext4_group_desc do the rest...*/ - if (ext4_has_feature_64bit(sb) && - offset < le16_to_cpu(sbi->s_es->s_desc_size)) + if (ext4_has_feature_64bit(sb) && offset < sbi->s_desc_size) crc = crc16(crc, (__u8 *)gdp + offset, - le16_to_cpu(sbi->s_es->s_desc_size) - - offset); + sbi->s_desc_size - offset);
out: return cpu_to_le16(crc);
From: Jan Kara jack@suse.cz
commit 492888df0c7b42fc0843631168b0021bc4caee84 upstream.
When using cached extent stored in extent status tree in tree->cache_es another process holding ei->i_es_lock for reading can be racing with us setting new value of tree->cache_es. If the compiler would decide to refetch tree->cache_es at an unfortunate moment, it could result in a bogus in_range() check. Fix the possible race by using READ_ONCE() when using tree->cache_es only under ei->i_es_lock for reading.
Cc: stable@kernel.org Reported-by: syzbot+4a03518df1e31b537066@syzkaller.appspotmail.com Link: https://lore.kernel.org/all/000000000000d3b33905fa0fd4a6@google.com Suggested-by: Dmitry Vyukov dvyukov@google.com Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20230504125524.10802-1-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/extents_status.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-)
--- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -269,14 +269,12 @@ static void __es_find_extent_range(struc
/* see if the extent has been cached */ es->es_lblk = es->es_len = es->es_pblk = 0; - if (tree->cache_es) { - es1 = tree->cache_es; - if (in_range(lblk, es1->es_lblk, es1->es_len)) { - es_debug("%u cached by [%u/%u) %llu %x\n", - lblk, es1->es_lblk, es1->es_len, - ext4_es_pblock(es1), ext4_es_status(es1)); - goto out; - } + es1 = READ_ONCE(tree->cache_es); + if (es1 && in_range(lblk, es1->es_lblk, es1->es_len)) { + es_debug("%u cached by [%u/%u) %llu %x\n", + lblk, es1->es_lblk, es1->es_len, + ext4_es_pblock(es1), ext4_es_status(es1)); + goto out; }
es1 = __es_tree_search(&tree->root, lblk); @@ -295,7 +293,7 @@ out: }
if (es1 && matching_fn(es1)) { - tree->cache_es = es1; + WRITE_ONCE(tree->cache_es, es1); es->es_lblk = es1->es_lblk; es->es_len = es1->es_len; es->es_pblk = es1->es_pblk; @@ -934,14 +932,12 @@ int ext4_es_lookup_extent(struct inode *
/* find extent in cache firstly */ es->es_lblk = es->es_len = es->es_pblk = 0; - if (tree->cache_es) { - es1 = tree->cache_es; - if (in_range(lblk, es1->es_lblk, es1->es_len)) { - es_debug("%u cached by [%u/%u)\n", - lblk, es1->es_lblk, es1->es_len); - found = 1; - goto out; - } + es1 = READ_ONCE(tree->cache_es); + if (es1 && in_range(lblk, es1->es_lblk, es1->es_len)) { + es_debug("%u cached by [%u/%u)\n", + lblk, es1->es_lblk, es1->es_len); + found = 1; + goto out; }
node = tree->root.rb_node;
From: Baokun Li libaokun1@huawei.com
commit fa83c34e3e56b3c672af38059e066242655271b1 upstream.
When ext4_iomap_overwrite_begin() calls ext4_iomap_begin() map blocks may fail for some reason (e.g. memory allocation failure, bare disk write), and later because "iomap->type ! = IOMAP_MAPPED" triggers WARN_ON(). When ext4 iomap_begin() returns an error, it is normal that the type of iomap->type may not match the expectation. Therefore, we only determine if iomap->type is as expected when ext4_iomap_begin() is executed successfully.
Cc: stable@kernel.org Reported-by: syzbot+08106c4b7d60702dbc14@syzkaller.appspotmail.com Link: https://lore.kernel.org/all/00000000000015760b05f9b4eee9@google.com Signed-off-by: Baokun Li libaokun1@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20230505132429.714648-1-libaokun1@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3564,7 +3564,7 @@ static int ext4_iomap_overwrite_begin(st */ flags &= ~IOMAP_WRITE; ret = ext4_iomap_begin(inode, offset, length, flags, iomap, srcmap); - WARN_ON_ONCE(iomap->type != IOMAP_MAPPED); + WARN_ON_ONCE(!ret && iomap->type != IOMAP_MAPPED); return ret; }
From: Theodore Ts'o tytso@mit.edu
commit 4c0b4818b1f636bc96359f7817a2d8bab6370162 upstream.
If there are failures while changing the mount options in __ext4_remount(), we need to restore the old mount options.
This commit fixes two problem. The first is there is a chance that we will free the old quota file names before a potential failure leading to a use-after-free. The second problem addressed in this commit is if there is a failed read/write to read-only transition, if the quota has already been suspended, we need to renable quota handling.
Cc: stable@kernel.org Link: https://lore.kernel.org/r/20230506142419.984260-2-tytso@mit.edu Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/super.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -6028,9 +6028,6 @@ static int ext4_remount(struct super_blo }
#ifdef CONFIG_QUOTA - /* Release old quota file names */ - for (i = 0; i < EXT4_MAXQUOTAS; i++) - kfree(old_opts.s_qf_names[i]); if (enable_quota) { if (sb_any_quota_suspended(sb)) dquot_resume(sb, -1); @@ -6040,6 +6037,9 @@ static int ext4_remount(struct super_blo goto restore_opts; } } + /* Release old quota file names */ + for (i = 0; i < EXT4_MAXQUOTAS; i++) + kfree(old_opts.s_qf_names[i]); #endif if (!test_opt(sb, BLOCK_VALIDITY) && sbi->s_system_blks) ext4_release_system_zone(sb); @@ -6059,6 +6059,13 @@ static int ext4_remount(struct super_blo return 0;
restore_opts: + /* + * If there was a failing r/w to ro transition, we may need to + * re-enable quota + */ + if ((sb->s_flags & SB_RDONLY) && !(old_sb_flags & SB_RDONLY) && + sb_any_quota_suspended(sb)) + dquot_resume(sb, -1); sb->s_flags = old_sb_flags; sbi->s_mount_opt = old_opts.s_mount_opt; sbi->s_mount_opt2 = old_opts.s_mount_opt2;
From: Theodore Ts'o tytso@mit.edu
commit f4ce24f54d9cca4f09a395f3eecce20d6bec4663 upstream.
In no journal mode, ext4_finish_convert_inline_dir() can self-deadlock by calling ext4_handle_dirty_dirblock() when it already has taken the directory lock. There is a similar self-deadlock in ext4_incvert_inline_data_nolock() for data files which we'll fix at the same time.
A simple reproducer demonstrating the problem:
mke2fs -Fq -t ext2 -O inline_data -b 4k /dev/vdc 64 mount -t ext4 -o dirsync /dev/vdc /vdc cd /vdc mkdir file0 cd file0 touch file0 touch file1 attr -s BurnSpaceInEA -V abcde . touch supercalifragilisticexpialidocious
Cc: stable@kernel.org Link: https://lore.kernel.org/r/20230507021608.1290720-1-tytso@mit.edu Reported-by: syzbot+91dccab7c64e2850a4e5@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=ba84cc80a9491d65416bc7877e1650c87530fe8... Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/inline.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -1172,6 +1172,7 @@ static int ext4_finish_convert_inline_di ext4_initialize_dirent_tail(dir_block, inode->i_sb->s_blocksize); set_buffer_uptodate(dir_block); + unlock_buffer(dir_block); err = ext4_handle_dirty_dirblock(handle, inode, dir_block); if (err) return err; @@ -1245,6 +1246,7 @@ static int ext4_convert_inline_data_nolo if (!S_ISDIR(inode->i_mode)) { memcpy(data_bh->b_data, buf, inline_size); set_buffer_uptodate(data_bh); + unlock_buffer(data_bh); error = ext4_handle_dirty_metadata(handle, inode, data_bh); } else { @@ -1252,7 +1254,6 @@ static int ext4_convert_inline_data_nolo buf, inline_size); }
- unlock_buffer(data_bh); out_restore: if (error) ext4_restore_inline_data(handle, inode, iloc, buf, inline_size);
From: Theodore Ts'o tytso@mit.edu
commit 2220eaf90992c11d888fe771055d4de330385f01 upstream.
Normally the extended attributes in the inode body would have been checked when the inode is first opened, but if someone is writing to the block device while the file system is mounted, it's possible for the inode table to get corrupted. Add bounds checking to avoid reading beyond the end of allocated memory if this happens.
Reported-by: syzbot+1966db24521e5f6e23f7@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=1966db24521e5f6e23f7 Cc: stable@kernel.org Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/inline.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
--- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -32,6 +32,7 @@ static int get_max_inline_xattr_value_si struct ext4_xattr_ibody_header *header; struct ext4_xattr_entry *entry; struct ext4_inode *raw_inode; + void *end; int free, min_offs;
if (!EXT4_INODE_HAS_XATTR_SPACE(inode)) @@ -55,14 +56,23 @@ static int get_max_inline_xattr_value_si raw_inode = ext4_raw_inode(iloc); header = IHDR(inode, raw_inode); entry = IFIRST(header); + end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
/* Compute min_offs. */ - for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { + while (!IS_LAST_ENTRY(entry)) { + void *next = EXT4_XATTR_NEXT(entry); + + if (next >= end) { + EXT4_ERROR_INODE(inode, + "corrupt xattr in inline inode"); + return 0; + } if (!entry->e_value_inum && entry->e_value_size) { size_t offs = le16_to_cpu(entry->e_value_offs); if (offs < min_offs) min_offs = offs; } + entry = next; } free = min_offs - ((void *)entry - (void *)IFIRST(header)) - sizeof(__u32);
From: Theodore Ts'o tytso@mit.edu
commit 2a534e1d0d1591e951f9ece2fb460b2ff92edabd upstream.
In ext4_update_inline_data(), if ext4_xattr_ibody_get() fails for any reason, it's best if we just fail as opposed to stumbling on, especially if the failure is EFSCORRUPTED.
Cc: stable@kernel.org Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/inline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -358,7 +358,7 @@ static int ext4_update_inline_data(handl
error = ext4_xattr_ibody_get(inode, i.name_index, i.name, value, len); - if (error == -ENODATA) + if (error < 0) goto out;
BUFFER_TRACE(is.iloc.bh, "get_write_access");
From: Theodore Ts'o tytso@mit.edu
commit 463808f237cf73e98a1a45ff7460c2406a150a0b upstream.
If a malicious fuzzer overwrites the ext4 superblock while it is mounted such that the s_first_data_block is set to a very large number, the calculation of the block group can underflow, and trigger a BUG_ON check. Change this to be an ext4_warning so that we don't crash the kernel.
Cc: stable@kernel.org Link: https://lore.kernel.org/r/20230430154311.579720-3-tytso@mit.edu Reported-by: syzbot+e2efa3efc15a1c9e95c3@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=69b28112e098b070f639efb356393af3ffec422... Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/mballoc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -4250,7 +4250,11 @@ ext4_mb_release_group_pa(struct ext4_bud trace_ext4_mb_release_group_pa(sb, pa); BUG_ON(pa->pa_deleted == 0); ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); - BUG_ON(group != e4b->bd_group && pa->pa_len != 0); + if (unlikely(group != e4b->bd_group && pa->pa_len != 0)) { + ext4_warning(sb, "bad group: expected %u, group %u, pa_start %llu", + e4b->bd_group, group, pa->pa_pstart); + return 0; + } mb_free_blocks(pa->pa_inode, e4b, bit, pa->pa_len); atomic_add(pa->pa_len, &EXT4_SB(sb)->s_mb_discarded); trace_ext4_mballoc_discard(sb, NULL, group, bit, pa->pa_len);
From: Theodore Ts'o tytso@mit.edu
commit b87c7cdf2bed4928b899e1ce91ef0d147017ba45 upstream.
In ext4_xattr_move_to_block(), the value of the extended attribute which we need to move to an external block may be allocated by kvmalloc() if the value is stored in an external inode. So at the end of the function the code tried to check if this was the case by testing entry->e_value_inum.
However, at this point, the pointer to the xattr entry is no longer valid, because it was removed from the original location where it had been stored. So we could end up calling kvfree() on a pointer which was not allocated by kvmalloc(); or we could also potentially leak memory by not freeing the buffer when it should be freed. Fix this by storing whether it should be freed in a separate variable.
Cc: stable@kernel.org Link: https://lore.kernel.org/r/20230430160426.581366-1-tytso@mit.edu Link: https://syzkaller.appspot.com/bug?id=5c2aee8256e30b55ccf57312c16d88417adbd5e... Link: https://syzkaller.appspot.com/bug?id=41a6b5d4917c0412eb3b3c3c604965bed7d7420... Reported-by: syzbot+64b645917ce07d89bde5@syzkaller.appspotmail.com Reported-by: syzbot+0d042627c4f2ad332195@syzkaller.appspotmail.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/xattr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -2554,6 +2554,7 @@ static int ext4_xattr_move_to_block(hand .in_inode = !!entry->e_value_inum, }; struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode); + int needs_kvfree = 0; int error;
is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS); @@ -2576,7 +2577,7 @@ static int ext4_xattr_move_to_block(hand error = -ENOMEM; goto out; } - + needs_kvfree = 1; error = ext4_xattr_inode_get(inode, entry, buffer, value_size); if (error) goto out; @@ -2615,7 +2616,7 @@ static int ext4_xattr_move_to_block(hand
out: kfree(b_entry_name); - if (entry->e_value_inum && buffer) + if (needs_kvfree && buffer) kvfree(buffer); if (is) brelse(is->iloc.bh);
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
commit 146a37e05d620cef4ad430e5d1c9c077fe6fa76f upstream.
There's a potential race before THRE/TEMT deasserts when DMA Tx is starting up (or the next batch of continuous Tx is being submitted). This can lead to misdetecting Tx empty condition.
It is entirely normal for THRE/TEMT to be set for some time after the DMA Tx had been setup in serial8250_tx_dma(). As Tx side is definitely not empty at that point, it seems incorrect for serial8250_tx_empty() claim Tx is empty.
Fix the race by also checking in serial8250_tx_empty() whether there's DMA Tx active.
Note: This fix only addresses in-kernel race mainly to make using TCSADRAIN/FLUSH robust. Userspace can still cause other races but they seem userspace concurrency control problems.
Fixes: 9ee4b83e51f74 ("serial: 8250: Add support for dmaengine") Cc: stable@vger.kernel.org Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Link: https://lore.kernel.org/r/20230317113318.31327-3-ilpo.jarvinen@linux.intel.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/8250/8250.h | 12 ++++++++++++ drivers/tty/serial/8250/8250_port.c | 12 +++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-)
--- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -330,6 +330,13 @@ extern int serial8250_rx_dma(struct uart extern void serial8250_rx_dma_flush(struct uart_8250_port *); extern int serial8250_request_dma(struct uart_8250_port *); extern void serial8250_release_dma(struct uart_8250_port *); + +static inline bool serial8250_tx_dma_running(struct uart_8250_port *p) +{ + struct uart_8250_dma *dma = p->dma; + + return dma && dma->tx_running; +} #else static inline int serial8250_tx_dma(struct uart_8250_port *p) { @@ -345,6 +352,11 @@ static inline int serial8250_request_dma return -1; } static inline void serial8250_release_dma(struct uart_8250_port *p) { } + +static inline bool serial8250_tx_dma_running(struct uart_8250_port *p) +{ + return false; +} #endif
static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1971,19 +1971,25 @@ static int serial8250_tx_threshold_handl static unsigned int serial8250_tx_empty(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); + unsigned int result = 0; unsigned long flags; unsigned int lsr;
serial8250_rpm_get(up);
spin_lock_irqsave(&port->lock, flags); - lsr = serial_port_in(port, UART_LSR); - up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + if (!serial8250_tx_dma_running(up)) { + lsr = serial_port_in(port, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + + if ((lsr & BOTH_EMPTY) == BOTH_EMPTY) + result = TIOCSER_TEMT; + } spin_unlock_irqrestore(&port->lock, flags);
serial8250_rpm_put(up);
- return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; + return result; }
unsigned int serial8250_do_get_mctrl(struct uart_port *port)
From: Christoph Böhmwalder christoph.boehmwalder@linbit.com
commit 3899d94e3831ee07ea6821c032dc297aec80586a upstream.
When we receive a flush command (or "barrier" in DRBD), we currently use a REQ_OP_FLUSH with the REQ_PREFLUSH flag set.
The correct way to submit a flush bio is by using a REQ_OP_WRITE without any data, and set the REQ_PREFLUSH flag.
Since commit b4a6bb3a67aa ("block: add a sanity check for non-write flush/fua bios"), this triggers a warning in the block layer, but this has been broken for quite some time before that.
So use the correct set of flags to actually make the flush happen.
Cc: Christoph Hellwig hch@infradead.org Cc: stable@vger.kernel.org Fixes: f9ff0da56437 ("drbd: allow parallel flushes for multi-volume resources") Reported-by: Thomas Voegtle tv@lio96.de Signed-off-by: Christoph Böhmwalder christoph.boehmwalder@linbit.com Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20230503121937.17232-1-christoph.boehmwalder@linbi... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/block/drbd/drbd_receiver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1299,7 +1299,7 @@ static void submit_one_flush(struct drbd bio_set_dev(bio, device->ldev->backing_bdev); bio->bi_private = octx; bio->bi_end_io = one_flush_endio; - bio->bi_opf = REQ_OP_FLUSH | REQ_PREFLUSH; + bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
device->flush_jif = jiffies; set_bit(FLUSH_PENDING, &device->flags);
From: Rishabh Bhatnagar risbhat@amazon.com
From: Lai Jiangshan laijs@linux.alibaba.com
commit af3511ff7fa2107d6410831f3d71030f5e8d2b25 upstream.
In record_steal_time(), st->preempted is read twice, and trace_kvm_pv_tlb_flush() might output result inconsistent if kvm_vcpu_flush_tlb_guest() see a different st->preempted later.
It is a very trivial problem and hardly has actual harm and can be avoided by reseting and reading st->preempted in atomic way via xchg().
Signed-off-by: Lai Jiangshan laijs@linux.alibaba.com
Message-Id: 20210531174628.10265-1-jiangshanlai@gmail.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Rishabh Bhatnagar risbhat@amazon.com Tested-by: Allen Pais apais@linux.microsoft.com Acked-by: Sean Christopherson seanjc@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3041,9 +3041,11 @@ static void record_steal_time(struct kvm * expensive IPIs. */ if (guest_pv_has(vcpu, KVM_FEATURE_PV_TLB_FLUSH)) { + u8 st_preempted = xchg(&st->preempted, 0); + trace_kvm_pv_tlb_flush(vcpu->vcpu_id, - st->preempted & KVM_VCPU_FLUSH_TLB); - if (xchg(&st->preempted, 0) & KVM_VCPU_FLUSH_TLB) + st_preempted & KVM_VCPU_FLUSH_TLB); + if (st_preempted & KVM_VCPU_FLUSH_TLB) kvm_vcpu_flush_tlb_guest(vcpu); } else { st->preempted = 0;
From: Rishabh Bhatnagar risbhat@amazon.com
From: David Woodhouse dwmw2@infradead.org
commit 7e2175ebd695f17860c5bd4ad7616cce12ed4591 upstream.
In commit b043138246a4 ("x86/KVM: Make sure KVM_VCPU_FLUSH_TLB flag is not missed") we switched to using a gfn_to_pfn_cache for accessing the guest steal time structure in order to allow for an atomic xchg of the preempted field. This has a couple of problems.
Firstly, kvm_map_gfn() doesn't work at all for IOMEM pages when the atomic flag is set, which it is in kvm_steal_time_set_preempted(). So a guest vCPU using an IOMEM page for its steal time would never have its preempted field set.
Secondly, the gfn_to_pfn_cache is not invalidated in all cases where it should have been. There are two stages to the GFN->PFN conversion; first the GFN is converted to a userspace HVA, and then that HVA is looked up in the process page tables to find the underlying host PFN. Correct invalidation of the latter would require being hooked up to the MMU notifiers, but that doesn't happen---so it just keeps mapping and unmapping the *wrong* PFN after the userspace page tables change.
In the !IOMEM case at least the stale page *is* pinned all the time it's cached, so it won't be freed and reused by anyone else while still receiving the steal time updates. The map/unmap dance only takes care of the KVM administrivia such as marking the page dirty.
Until the gfn_to_pfn cache handles the remapping automatically by integrating with the MMU notifiers, we might as well not get a kernel mapping of it, and use the perfectly serviceable userspace HVA that we already have. We just need to implement the atomic xchg on the userspace address with appropriate exception handling, which is fairly trivial.
Cc: stable@vger.kernel.org Fixes: b043138246a4 ("x86/KVM: Make sure KVM_VCPU_FLUSH_TLB flag is not missed") Signed-off-by: David Woodhouse dwmw@amazon.co.uk Message-Id: 3645b9b889dac6438394194bb5586a46b68d581f.camel@infradead.org [I didn't entirely agree with David's assessment of the usefulness of the gfn_to_pfn cache, and integrated the outcome of the discussion in the above commit message. - Paolo] Signed-off-by: Paolo Bonzini pbonzini@redhat.com [risbhat@amazon.com: Use the older mark_page_dirty_in_slot api without kvm argument] Signed-off-by: Rishabh Bhatnagar risbhat@amazon.com Tested-by: Allen Pais apais@linux.microsoft.com Acked-by: Sean Christopherson seanjc@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/include/asm/kvm_host.h | 2 arch/x86/kvm/x86.c | 105 ++++++++++++++++++++++++++++------------ 2 files changed, 76 insertions(+), 31 deletions(-)
--- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -664,7 +664,7 @@ struct kvm_vcpu_arch { u8 preempted; u64 msr_val; u64 last_steal; - struct gfn_to_pfn_cache cache; + struct gfn_to_hva_cache cache; } st;
u64 l1_tsc_offset; --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3022,53 +3022,92 @@ static void kvm_vcpu_flush_tlb_guest(str
static void record_steal_time(struct kvm_vcpu *vcpu) { - struct kvm_host_map map; - struct kvm_steal_time *st; + struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache; + struct kvm_steal_time __user *st; + struct kvm_memslots *slots; + u64 steal; + u32 version;
if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) return;
- /* -EAGAIN is returned in atomic context so we can just return. */ - if (kvm_map_gfn(vcpu, vcpu->arch.st.msr_val >> PAGE_SHIFT, - &map, &vcpu->arch.st.cache, false)) + if (WARN_ON_ONCE(current->mm != vcpu->kvm->mm)) return;
- st = map.hva + - offset_in_page(vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS); + slots = kvm_memslots(vcpu->kvm); + + if (unlikely(slots->generation != ghc->generation || + kvm_is_error_hva(ghc->hva) || !ghc->memslot)) { + gfn_t gfn = vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS; + + /* We rely on the fact that it fits in a single page. */ + BUILD_BUG_ON((sizeof(*st) - 1) & KVM_STEAL_VALID_BITS); + + if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gfn, sizeof(*st)) || + kvm_is_error_hva(ghc->hva) || !ghc->memslot) + return; + } + + st = (struct kvm_steal_time __user *)ghc->hva; + if (!user_access_begin(st, sizeof(*st))) + return;
/* * Doing a TLB flush here, on the guest's behalf, can avoid * expensive IPIs. */ if (guest_pv_has(vcpu, KVM_FEATURE_PV_TLB_FLUSH)) { - u8 st_preempted = xchg(&st->preempted, 0); + u8 st_preempted = 0; + int err = -EFAULT; + + asm volatile("1: xchgb %0, %2\n" + "xor %1, %1\n" + "2:\n" + _ASM_EXTABLE_UA(1b, 2b) + : "+r" (st_preempted), + "+&r" (err) + : "m" (st->preempted)); + if (err) + goto out; + + user_access_end(); + + vcpu->arch.st.preempted = 0;
trace_kvm_pv_tlb_flush(vcpu->vcpu_id, st_preempted & KVM_VCPU_FLUSH_TLB); if (st_preempted & KVM_VCPU_FLUSH_TLB) kvm_vcpu_flush_tlb_guest(vcpu); + + if (!user_access_begin(st, sizeof(*st))) + goto dirty; } else { - st->preempted = 0; + unsafe_put_user(0, &st->preempted, out); + vcpu->arch.st.preempted = 0; }
- vcpu->arch.st.preempted = 0; - - if (st->version & 1) - st->version += 1; /* first time write, random junk */ + unsafe_get_user(version, &st->version, out); + if (version & 1) + version += 1; /* first time write, random junk */
- st->version += 1; + version += 1; + unsafe_put_user(version, &st->version, out);
smp_wmb();
- st->steal += current->sched_info.run_delay - + unsafe_get_user(steal, &st->steal, out); + steal += current->sched_info.run_delay - vcpu->arch.st.last_steal; vcpu->arch.st.last_steal = current->sched_info.run_delay; + unsafe_put_user(steal, &st->steal, out);
- smp_wmb(); - - st->version += 1; + version += 1; + unsafe_put_user(version, &st->version, out);
- kvm_unmap_gfn(vcpu, &map, &vcpu->arch.st.cache, true, false); + out: + user_access_end(); + dirty: + mark_page_dirty_in_slot(ghc->memslot, gpa_to_gfn(ghc->gpa)); }
int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) @@ -4053,8 +4092,10 @@ void kvm_arch_vcpu_load(struct kvm_vcpu
static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu) { - struct kvm_host_map map; - struct kvm_steal_time *st; + struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache; + struct kvm_steal_time __user *st; + struct kvm_memslots *slots; + static const u8 preempted = KVM_VCPU_PREEMPTED;
/* * The vCPU can be marked preempted if and only if the VM-Exit was on @@ -4075,16 +4116,23 @@ static void kvm_steal_time_set_preempted if (vcpu->arch.st.preempted) return;
- if (kvm_map_gfn(vcpu, vcpu->arch.st.msr_val >> PAGE_SHIFT, &map, - &vcpu->arch.st.cache, true)) + /* This happens on process exit */ + if (unlikely(current->mm != vcpu->kvm->mm)) return;
- st = map.hva + - offset_in_page(vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS); + slots = kvm_memslots(vcpu->kvm); + + if (unlikely(slots->generation != ghc->generation || + kvm_is_error_hva(ghc->hva) || !ghc->memslot)) + return;
- st->preempted = vcpu->arch.st.preempted = KVM_VCPU_PREEMPTED; + st = (struct kvm_steal_time __user *)ghc->hva; + BUILD_BUG_ON(sizeof(st->preempted) != sizeof(preempted));
- kvm_unmap_gfn(vcpu, &map, &vcpu->arch.st.cache, true, true); + if (!copy_to_user_nofault(&st->preempted, &preempted, sizeof(preempted))) + vcpu->arch.st.preempted = KVM_VCPU_PREEMPTED; + + mark_page_dirty_in_slot(ghc->memslot, gpa_to_gfn(ghc->gpa)); }
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) @@ -10266,11 +10314,8 @@ void kvm_arch_vcpu_postcreate(struct kvm
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) { - struct gfn_to_pfn_cache *cache = &vcpu->arch.st.cache; int idx;
- kvm_release_pfn(cache->pfn, cache->dirty, cache); - kvmclock_reset(vcpu);
kvm_x86_ops.vcpu_free(vcpu);
From: Rishabh Bhatnagar risbhat@amazon.com
From: David Woodhouse dwmw@amazon.co.uk
commit 964b7aa0b040bdc6ec1c543ee620cda3f8b4c68a upstream.
In 64-bit mode, x86 instruction encoding allows us to use the low 8 bits of any GPR as an 8-bit operand. In 32-bit mode, however, we can only use the [abcd] registers. For which, GCC has the "q" constraint instead of the less restrictive "r".
Also fix st->preempted, which is an input/output operand rather than an input.
Fixes: 7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status") Reported-by: kernel test robot lkp@intel.com Signed-off-by: David Woodhouse dwmw@amazon.co.uk Message-Id: 89bf72db1b859990355f9c40713a34e0d2d86c98.camel@infradead.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Rishabh Bhatnagar risbhat@amazon.com Tested-by: Allen Pais apais@linux.microsoft.com Acked-by: Sean Christopherson seanjc@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3064,9 +3064,9 @@ static void record_steal_time(struct kvm "xor %1, %1\n" "2:\n" _ASM_EXTABLE_UA(1b, 2b) - : "+r" (st_preempted), - "+&r" (err) - : "m" (st->preempted)); + : "+q" (st_preempted), + "+&r" (err), + "+m" (st->preempted)); if (err) goto out;
From: Rishabh Bhatnagar risbhat@amazon.com
From: Sean Christopherson seanjc@google.com
commit 19979fba9bfaeab427a8e106d915f0627c952828 upstream.
Remove the disabling of page faults across kvm_steal_time_set_preempted() as KVM now accesses the steal time struct (shared with the guest) via a cached mapping (see commit b043138246a4, "x86/KVM: Make sure KVM_VCPU_FLUSH_TLB flag is not missed".) The cache lookup is flagged as atomic, thus it would be a bug if KVM tried to resolve a new pfn, i.e. we want the splat that would be reached via might_fault().
Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20210123000334.3123628-2-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Rishabh Bhatnagar risbhat@amazon.com Tested-by: Allen Pais apais@linux.microsoft.com Acked-by: Sean Christopherson seanjc@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 10 ---------- 1 file changed, 10 deletions(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4143,22 +4143,12 @@ void kvm_arch_vcpu_put(struct kvm_vcpu * vcpu->arch.preempted_in_kernel = !kvm_x86_ops.get_cpl(vcpu);
/* - * Disable page faults because we're in atomic context here. - * kvm_write_guest_offset_cached() would call might_fault() - * that relies on pagefault_disable() to tell if there's a - * bug. NOTE: the write to guest memory may not go through if - * during postcopy live migration or if there's heavy guest - * paging. - */ - pagefault_disable(); - /* * kvm_memslots() will be called by * kvm_write_guest_offset_cached() so take the srcu lock. */ idx = srcu_read_lock(&vcpu->kvm->srcu); kvm_steal_time_set_preempted(vcpu); srcu_read_unlock(&vcpu->kvm->srcu, idx); - pagefault_enable(); kvm_x86_ops.vcpu_put(vcpu); vcpu->arch.last_host_tsc = rdtsc(); /*
From: Rishabh Bhatnagar risbhat@amazon.com
From: Paolo Bonzini pbonzini@redhat.com
commit 54aa83c90198e68eee8b0850c749bc70efb548da upstream.
Similar to the Xen path, only change the vCPU's reported state if the vCPU was actually preempted. The reason for KVM's behavior is that for example optimistic spinning might not be a good idea if the guest is doing repeated exits to userspace; however, it is confusing and unlikely to make a difference, because well-tuned guests will hardly ever exit KVM_RUN in the first place.
Suggested-by: Sean Christopherson seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com [risbhat@amazon.com: Don't check for xen msr as support is not available and skip the SEV-ES condition] Signed-off-by: Rishabh Bhatnagar risbhat@amazon.com Tested-by: Allen Pais apais@linux.microsoft.com Acked-by: Sean Christopherson seanjc@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4139,16 +4139,18 @@ void kvm_arch_vcpu_put(struct kvm_vcpu * { int idx;
- if (vcpu->preempted) + if (vcpu->preempted) { vcpu->arch.preempted_in_kernel = !kvm_x86_ops.get_cpl(vcpu);
- /* - * kvm_memslots() will be called by - * kvm_write_guest_offset_cached() so take the srcu lock. - */ - idx = srcu_read_lock(&vcpu->kvm->srcu); - kvm_steal_time_set_preempted(vcpu); - srcu_read_unlock(&vcpu->kvm->srcu, idx); + /* + * Take the srcu lock as memslots will be accessed to check the gfn + * cache generation against the memslots generation. + */ + idx = srcu_read_lock(&vcpu->kvm->srcu); + kvm_steal_time_set_preempted(vcpu); + srcu_read_unlock(&vcpu->kvm->srcu, idx); + } + kvm_x86_ops.vcpu_put(vcpu); vcpu->arch.last_host_tsc = rdtsc(); /*
From: Rishabh Bhatnagar risbhat@amazon.com
From: Paolo Bonzini pbonzini@redhat.com
commit 901d3765fa804ce42812f1d5b1f3de2dfbb26723 upstream.
Commit 7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status", 2021-11-11) open coded the previous call to kvm_map_gfn, but in doing so it dropped the comparison between the cached guest physical address and the one in the MSR. This cause an incorrect cache hit if the guest modifies the steal time address while the memslots remain the same. This can happen with kexec, in which case the steal time data is written at the address used by the old kernel instead of the old one.
While at it, rename the variable from gfn to gpa since it is a plain physical address and not a right-shifted one.
Reported-by: Dave Young ruyang@redhat.com Reported-by: Xiaoying Yan yiyan@redhat.com Analyzed-by: Dr. David Alan Gilbert dgilbert@redhat.com Cc: David Woodhouse dwmw@amazon.co.uk Cc: stable@vger.kernel.org Fixes: 7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status") Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Rishabh Bhatnagar risbhat@amazon.com Tested-by: Allen Pais apais@linux.microsoft.com Acked-by: Sean Christopherson seanjc@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3025,6 +3025,7 @@ static void record_steal_time(struct kvm struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache; struct kvm_steal_time __user *st; struct kvm_memslots *slots; + gpa_t gpa = vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS; u64 steal; u32 version;
@@ -3037,13 +3038,12 @@ static void record_steal_time(struct kvm slots = kvm_memslots(vcpu->kvm);
if (unlikely(slots->generation != ghc->generation || + gpa != ghc->gpa || kvm_is_error_hva(ghc->hva) || !ghc->memslot)) { - gfn_t gfn = vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS; - /* We rely on the fact that it fits in a single page. */ BUILD_BUG_ON((sizeof(*st) - 1) & KVM_STEAL_VALID_BITS);
- if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gfn, sizeof(*st)) || + if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gpa, sizeof(*st)) || kvm_is_error_hva(ghc->hva) || !ghc->memslot) return; }
From: Rishabh Bhatnagar risbhat@amazon.com
From: Paolo Bonzini pbonzini@redhat.com
commit c3c28d24d910a746b02f496d190e0e8c6560224b upstream.
Commit 7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status", 2021-11-11) open coded the previous call to kvm_map_gfn, but in doing so it dropped the comparison between the cached guest physical address and the one in the MSR. This cause an incorrect cache hit if the guest modifies the steal time address while the memslots remain the same. This can happen with kexec, in which case the preempted bit is written at the address used by the old kernel instead of the old one.
Cc: David Woodhouse dwmw@amazon.co.uk Cc: stable@vger.kernel.org Fixes: 7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status") Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Rishabh Bhatnagar risbhat@amazon.com Tested-by: Allen Pais apais@linux.microsoft.com Acked-by: Sean Christopherson seanjc@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4096,6 +4096,7 @@ static void kvm_steal_time_set_preempted struct kvm_steal_time __user *st; struct kvm_memslots *slots; static const u8 preempted = KVM_VCPU_PREEMPTED; + gpa_t gpa = vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS;
/* * The vCPU can be marked preempted if and only if the VM-Exit was on @@ -4123,6 +4124,7 @@ static void kvm_steal_time_set_preempted slots = kvm_memslots(vcpu->kvm);
if (unlikely(slots->generation != ghc->generation || + gpa != ghc->gpa || kvm_is_error_hva(ghc->hva) || !ghc->memslot)) return;
From: Rishabh Bhatnagar risbhat@amazon.com
From: Paolo Bonzini pbonzini@redhat.com
commit 3e067fd8503d6205aa0c1c8f48f6b209c592d19c upstream.
When UBSAN is enabled, the code emitted for the call to guest_pv_has includes a call to __ubsan_handle_load_invalid_value. objtool complains that this call happens with UACCESS enabled; to avoid the warning, pull the calls to user_access_begin into both arms of the "if" statement, after the check for guest_pv_has.
Reported-by: Stephen Rothwell sfr@canb.auug.org.au Cc: David Woodhouse dwmw2@infradead.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Rishabh Bhatnagar risbhat@amazon.com Tested-by: Allen Pais apais@linux.microsoft.com Acked-by: Sean Christopherson seanjc@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3049,9 +3049,6 @@ static void record_steal_time(struct kvm }
st = (struct kvm_steal_time __user *)ghc->hva; - if (!user_access_begin(st, sizeof(*st))) - return; - /* * Doing a TLB flush here, on the guest's behalf, can avoid * expensive IPIs. @@ -3060,6 +3057,9 @@ static void record_steal_time(struct kvm u8 st_preempted = 0; int err = -EFAULT;
+ if (!user_access_begin(st, sizeof(*st))) + return; + asm volatile("1: xchgb %0, %2\n" "xor %1, %1\n" "2:\n" @@ -3082,6 +3082,9 @@ static void record_steal_time(struct kvm if (!user_access_begin(st, sizeof(*st))) goto dirty; } else { + if (!user_access_begin(st, sizeof(*st))) + return; + unsafe_put_user(0, &st->preempted, out); vcpu->arch.st.preempted = 0; }
From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
commit 85e3e7fbbb720b9897fba9a99659e31cbd1c082e upstream.
[This patch implements subset of original commit 85e3e7fbbb72 ("printk: remove NMI tracking") where commit 1007843a9190 ("mm/page_alloc: fix potential deadlock on zonelist_update_seq seqlock") depends on, for commit 3d36424b3b58 ("mm/page_alloc: fix race condition between build_all_zonelists and page allocation") was backported to stable.]
All NMI contexts are handled the same as the safe context: store the message and defer printing. There is no need to have special NMI context tracking for this. Using in_nmi() is enough.
There are several parts of the kernel that are manually calling into the printk NMI context tracking in order to cause general printk deferred printing:
arch/arm/kernel/smp.c arch/powerpc/kexec/crash.c kernel/trace/trace.c
For arm/kernel/smp.c and powerpc/kexec/crash.c, provide a new function pair printk_deferred_enter/exit that explicitly achieves the same objective.
For ftrace, remove the printk context manipulation completely. It was added in commit 03fc7f9c99c1 ("printk/nmi: Prevent deadlock when accessing the main log buffer in NMI"). The purpose was to enforce storing messages directly into the ring buffer even in NMI context. It really should have only modified the behavior in NMI context. There is no need for a special behavior any longer. All messages are always stored directly now. The console deferring is handled transparently in vprintk().
Signed-off-by: John Ogness john.ogness@linutronix.de [pmladek@suse.com: Remove special handling in ftrace.c completely. Signed-off-by: Petr Mladek pmladek@suse.com Link: https://lore.kernel.org/r/20210715193359.25946-5-john.ogness@linutronix.de [penguin-kernel: Copy only printk_deferred_{enter,safe}() definition ] Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/printk.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
--- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -623,4 +623,23 @@ static inline void print_hex_dump_debug( #define print_hex_dump_bytes(prefix_str, prefix_type, buf, len) \ print_hex_dump_debug(prefix_str, prefix_type, 16, 1, buf, len, true)
+#ifdef CONFIG_PRINTK +extern void __printk_safe_enter(void); +extern void __printk_safe_exit(void); +/* + * The printk_deferred_enter/exit macros are available only as a hack for + * some code paths that need to defer all printk console printing. Interrupts + * must be disabled for the deferred duration. + */ +#define printk_deferred_enter __printk_safe_enter +#define printk_deferred_exit __printk_safe_exit +#else +static inline void printk_deferred_enter(void) +{ +} +static inline void printk_deferred_exit(void) +{ +} +#endif + #endif
From: Tian Tao tiantao6@hisilicon.com
commit a4e5eed2c6a689ef2b6ad8d7ae86665c69039379 upstream.
After this patch cbe16f35bee68 genirq: Add IRQF_NO_AUTOEN for request_irq/nmi() is merged. request_irq() after setting IRQ_NOAUTOEN as below
irq_set_status_flags(irq, IRQ_NOAUTOEN); request_irq(dev, irq...); can be replaced by request_irq() with IRQF_NO_AUTOEN flag.
v2: Fix the problem of using wrong flags
Signed-off-by: Tian Tao tiantao6@hisilicon.com Signed-off-by: Inki Dae inki.dae@samsung.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 4 ++-- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-)
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -775,8 +775,8 @@ static int decon_conf_irq(struct decon_c return irq; } } - irq_set_status_flags(irq, IRQ_NOAUTOEN); - ret = devm_request_irq(ctx->dev, irq, handler, flags, "drm_decon", ctx); + ret = devm_request_irq(ctx->dev, irq, handler, + flags | IRQF_NO_AUTOEN, "drm_decon", ctx); if (ret < 0) { dev_err(ctx->dev, "IRQ %s request failed\n", name); return ret; --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1353,10 +1353,9 @@ static int exynos_dsi_register_te_irq(st }
te_gpio_irq = gpio_to_irq(dsi->te_gpio); - irq_set_status_flags(te_gpio_irq, IRQ_NOAUTOEN);
ret = request_threaded_irq(te_gpio_irq, exynos_dsi_te_irq_handler, NULL, - IRQF_TRIGGER_RISING, "TE", dsi); + IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN, "TE", dsi); if (ret) { dev_err(dsi->dev, "request interrupt failed with %d\n", ret); gpio_free(dsi->te_gpio); @@ -1802,9 +1801,9 @@ static int exynos_dsi_probe(struct platf if (dsi->irq < 0) return dsi->irq;
- irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN); ret = devm_request_threaded_irq(dev, dsi->irq, NULL, - exynos_dsi_irq, IRQF_ONESHOT, + exynos_dsi_irq, + IRQF_ONESHOT | IRQF_NO_AUTOEN, dev_name(dev), dsi); if (ret) { dev_err(dev, "failed to request dsi irq\n");
From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
commit 1007843a91909a4995ee78a538f62d8665705b66 upstream.
syzbot is reporting circular locking dependency which involves zonelist_update_seq seqlock [1], for this lock is checked by memory allocation requests which do not need to be retried.
One deadlock scenario is kmalloc(GFP_ATOMIC) from an interrupt handler.
CPU0 ---- __build_all_zonelists() { write_seqlock(&zonelist_update_seq); // makes zonelist_update_seq.seqcount odd // e.g. timer interrupt handler runs at this moment some_timer_func() { kmalloc(GFP_ATOMIC) { __alloc_pages_slowpath() { read_seqbegin(&zonelist_update_seq) { // spins forever because zonelist_update_seq.seqcount is odd } } } } // e.g. timer interrupt handler finishes write_sequnlock(&zonelist_update_seq); // makes zonelist_update_seq.seqcount even }
This deadlock scenario can be easily eliminated by not calling read_seqbegin(&zonelist_update_seq) from !__GFP_DIRECT_RECLAIM allocation requests, for retry is applicable to only __GFP_DIRECT_RECLAIM allocation requests. But Michal Hocko does not know whether we should go with this approach.
Another deadlock scenario which syzbot is reporting is a race between kmalloc(GFP_ATOMIC) from tty_insert_flip_string_and_push_buffer() with port->lock held and printk() from __build_all_zonelists() with zonelist_update_seq held.
CPU0 CPU1 ---- ---- pty_write() { tty_insert_flip_string_and_push_buffer() { __build_all_zonelists() { write_seqlock(&zonelist_update_seq); build_zonelists() { printk() { vprintk() { vprintk_default() { vprintk_emit() { console_unlock() { console_flush_all() { console_emit_next_record() { con->write() = serial8250_console_write() { spin_lock_irqsave(&port->lock, flags); tty_insert_flip_string() { tty_insert_flip_string_fixed_flag() { __tty_buffer_request_room() { tty_buffer_alloc() { kmalloc(GFP_ATOMIC | __GFP_NOWARN) { __alloc_pages_slowpath() { zonelist_iter_begin() { read_seqbegin(&zonelist_update_seq); // spins forever because zonelist_update_seq.seqcount is odd spin_lock_irqsave(&port->lock, flags); // spins forever because port->lock is held } } } } } } } } spin_unlock_irqrestore(&port->lock, flags); // message is printed to console spin_unlock_irqrestore(&port->lock, flags); } } } } } } } } } write_sequnlock(&zonelist_update_seq); } } }
This deadlock scenario can be eliminated by
preventing interrupt context from calling kmalloc(GFP_ATOMIC)
and
preventing printk() from calling console_flush_all()
while zonelist_update_seq.seqcount is odd.
Since Petr Mladek thinks that __build_all_zonelists() can become a candidate for deferring printk() [2], let's address this problem by
disabling local interrupts in order to avoid kmalloc(GFP_ATOMIC)
and
disabling synchronous printk() in order to avoid console_flush_all()
.
As a side effect of minimizing duration of zonelist_update_seq.seqcount being odd by disabling synchronous printk(), latency at read_seqbegin(&zonelist_update_seq) for both !__GFP_DIRECT_RECLAIM and __GFP_DIRECT_RECLAIM allocation requests will be reduced. Although, from lockdep perspective, not calling read_seqbegin(&zonelist_update_seq) (i.e. do not record unnecessary locking dependency) from interrupt context is still preferable, even if we don't allow calling kmalloc(GFP_ATOMIC) inside write_seqlock(&zonelist_update_seq)/write_sequnlock(&zonelist_update_seq) section...
Link: https://lkml.kernel.org/r/8796b95c-3da3-5885-fddd-6ef55f30e4d3@I-love.SAKURA... Fixes: 3d36424b3b58 ("mm/page_alloc: fix race condition between build_all_zonelists and page allocation") Link: https://lkml.kernel.org/r/ZCrs+1cDqPWTDFNM@alley [2] Reported-by: syzbot syzbot+223c7461c58c58a4cb10@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=223c7461c58c58a4cb10 [1] Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Acked-by: Michal Hocko mhocko@suse.com Acked-by: Mel Gorman mgorman@techsingularity.net Cc: Petr Mladek pmladek@suse.com Cc: David Hildenbrand david@redhat.com Cc: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Cc: John Ogness john.ogness@linutronix.de Cc: Patrick Daly quic_pdaly@quicinc.com Cc: Sergey Senozhatsky senozhatsky@chromium.org Cc: Steven Rostedt rostedt@goodmis.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/page_alloc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
--- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5973,7 +5973,21 @@ static void __build_all_zonelists(void * int nid; int __maybe_unused cpu; pg_data_t *self = data; + unsigned long flags;
+ /* + * Explicitly disable this CPU's interrupts before taking seqlock + * to prevent any IRQ handler from calling into the page allocator + * (e.g. GFP_ATOMIC) that could hit zonelist_iter_begin and livelock. + */ + local_irq_save(flags); + /* + * Explicitly disable this CPU's synchronous printk() before taking + * seqlock to prevent any printk() from trying to hold port->lock, for + * tty_insert_flip_string_and_push_buffer() on other CPU might be + * calling kmalloc(GFP_ATOMIC | __GFP_NOWARN) with port->lock held. + */ + printk_deferred_enter(); write_seqlock(&zonelist_update_seq);
#ifdef CONFIG_NUMA @@ -6008,6 +6022,8 @@ static void __build_all_zonelists(void * }
write_sequnlock(&zonelist_update_seq); + printk_deferred_exit(); + local_irq_restore(flags); }
static noinline void __init
From: Aurabindo Pillai aurabindo.pillai@amd.com
commit da5e14909776edea4462672fb4a3007802d262e7 upstream.
[Why&How]
When skipping full modeset since the only state change was a front porch change, the DC commit sequence requires extra checks to handle non existant plane states being asked to be removed from context.
Reviewed-by: Alvin Lee Alvin.Lee2@amd.com Acked-by: Qingqing Zhuo qingqing.zhuo@amd.com Signed-off-by: Aurabindo Pillai aurabindo.pillai@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++++- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7248,6 +7248,8 @@ static void amdgpu_dm_commit_planes(stru continue;
dc_plane = dm_new_plane_state->dc_state; + if (!dc_plane) + continue;
bundle->surface_updates[planes_count].surface = dc_plane; if (new_pcrtc_state->color_mgmt_changed) { @@ -8562,8 +8564,9 @@ static int dm_update_plane_state(struct return -EINVAL; }
+ if (dm_old_plane_state->dc_state) + dc_plane_state_release(dm_old_plane_state->dc_state);
- dc_plane_state_release(dm_old_plane_state->dc_state); dm_new_plane_state->dc_state = NULL;
*lock_and_validation_needed = true; --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1502,6 +1502,9 @@ bool dc_remove_plane_from_context( struct dc_stream_status *stream_status = NULL; struct resource_pool *pool = dc->res_pool;
+ if (!plane_state) + return true; + for (i = 0; i < context->stream_count; i++) if (context->streams[i] == stream) { stream_status = &context->stream_status[i];
Hello Greg,
From: Greg Kroah-Hartman gregkh@linuxfoundation.org Sent: Monday, May 15, 2023 5:24 PM
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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, 17 May 2023 16:16:37 +0000. Anything received after that time might be too late.
CIP configurations built and booted with Linux 5.10.180-rc1 (065b6901e6da): https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/pipelines/86... https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/commits/linu...
Tested-by: Chris Paterson (CIP) chris.paterson2@renesas.com
Kind regards, Chris
On 5/15/23 10:24, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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, 17 May 2023 16:16:37 +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.180-rc... 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
Hi Greg,
On Mon, May 15, 2023 at 06:24:11PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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, 17 May 2023 16:16:37 +0000. Anything received after that time might be too late.
The build fails here with:
sound/soc/intel/boards/sof_sdw.c:187:6: error: ‘RT711_JD2_100K’ undeclared here (not in a function) 187 | RT711_JD2_100K), | ^~~~~~~~~~~~~~ make[7]: *** [scripts/Makefile.build:286: sound/soc/intel/boards/sof_sdw.o] Error 1 make[6]: *** [scripts/Makefile.build:503: sound/soc/intel/boards] Error 2 make[5]: *** [scripts/Makefile.build:503: sound/soc/intel] Error 2 make[4]: *** [scripts/Makefile.build:503: sound/soc] Error 2 make[3]: *** [Makefile:1828: sound] Error 2
I did mention it in https://lore.kernel.org/stable/ZFuHEML1r5Xd6S7g@eldamar.lan/ as well but I guess it felt trough the cracks back then.
Regards, Salvatore
On Tue, May 16, 2023 at 10:35:24AM +0200, Salvatore Bonaccorso wrote:
Hi Greg,
On Mon, May 15, 2023 at 06:24:11PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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, 17 May 2023 16:16:37 +0000. Anything received after that time might be too late.
The build fails here with:
sound/soc/intel/boards/sof_sdw.c:187:6: error: ‘RT711_JD2_100K’ undeclared here (not in a function) 187 | RT711_JD2_100K), | ^~~~~~~~~~~~~~ make[7]: *** [scripts/Makefile.build:286: sound/soc/intel/boards/sof_sdw.o] Error 1 make[6]: *** [scripts/Makefile.build:503: sound/soc/intel/boards] Error 2 make[5]: *** [scripts/Makefile.build:503: sound/soc/intel] Error 2 make[4]: *** [scripts/Makefile.build:503: sound/soc] Error 2 make[3]: *** [Makefile:1828: sound] Error 2
I did mention it in https://lore.kernel.org/stable/ZFuHEML1r5Xd6S7g@eldamar.lan/ as well but I guess it felt trough the cracks back then.
Sorry I missed this back then, now dropped. Interesting that almost no other build testing caught this, it's a hard driver to enable...
thanks,
greg k-h
Hi Greg,
On Mon, May 15, 2023 at 06:24:11PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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.
Build test (gcc version 11.3.1 20230511): mips: 63 configs -> no failure arm: 104 configs -> no failure arm64: 3 configs -> 1 failure x86_64: 4 configs -> no failure alpha allmodconfig -> no failure powerpc allmodconfig -> no failure riscv allmodconfig -> no failure s390 allmodconfig -> no failure xtensa allmodconfig -> no failure
arm64 allmodconfig build fails with the error:
/gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_tlb_flush_vmid_ipa': (.hyp.text+0x1a4c): undefined reference to `__kvm_nvhe_memset' /gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_tlb_flush_vmid': (.hyp.text+0x1b20): undefined reference to `__kvm_nvhe_memset' /gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_flush_cpu_context': (.hyp.text+0x1b80): undefined reference to `__kvm_nvhe_memset'
Boot test: x86_64: Booted on my test laptop. No regression. x86_64: Booted on qemu. No regression. [1] arm64: Booted on rpi4b (4GB model). No regression. [2]
[1]. https://openqa.qa.codethink.co.uk/tests/3530 [2]. https://openqa.qa.codethink.co.uk/tests/3531
Tested-by: Sudip Mukherjee sudip.mukherjee@codethink.co.uk
On Tue, May 16, 2023 at 10:14:36AM +0100, Sudip Mukherjee (Codethink) wrote:
Hi Greg,
On Mon, May 15, 2023 at 06:24:11PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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.
Build test (gcc version 11.3.1 20230511): mips: 63 configs -> no failure arm: 104 configs -> no failure arm64: 3 configs -> 1 failure x86_64: 4 configs -> no failure alpha allmodconfig -> no failure powerpc allmodconfig -> no failure riscv allmodconfig -> no failure s390 allmodconfig -> no failure xtensa allmodconfig -> no failure
arm64 allmodconfig build fails with the error:
/gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_tlb_flush_vmid_ipa': (.hyp.text+0x1a4c): undefined reference to `__kvm_nvhe_memset' /gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_tlb_flush_vmid': (.hyp.text+0x1b20): undefined reference to `__kvm_nvhe_memset' /gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_flush_cpu_context': (.hyp.text+0x1b80): undefined reference to `__kvm_nvhe_memset'
That's odd, I don't see that symbol anywhere in the tree at all.
And the only arm-related kvm changes don't have those symbols either (the other kvm changes are x86-only)
Also, no one else has seen this issue. Can you bisect?
thanks,
greg k-h
On Wed, 17 May 2023 at 14:21, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Tue, May 16, 2023 at 10:14:36AM +0100, Sudip Mukherjee (Codethink) wrote:
Hi Greg,
On Mon, May 15, 2023 at 06:24:11PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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.
Build test (gcc version 11.3.1 20230511): mips: 63 configs -> no failure arm: 104 configs -> no failure arm64: 3 configs -> 1 failure x86_64: 4 configs -> no failure alpha allmodconfig -> no failure powerpc allmodconfig -> no failure riscv allmodconfig -> no failure s390 allmodconfig -> no failure xtensa allmodconfig -> no failure
arm64 allmodconfig build fails with the error:
/gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_tlb_flush_vmid_ipa': (.hyp.text+0x1a4c): undefined reference to `__kvm_nvhe_memset' /gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_tlb_flush_vmid': (.hyp.text+0x1b20): undefined reference to `__kvm_nvhe_memset' /gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_flush_cpu_context': (.hyp.text+0x1b80): undefined reference to `__kvm_nvhe_memset'
That's odd, I don't see that symbol anywhere in the tree at all.
And the only arm-related kvm changes don't have those symbols either (the other kvm changes are x86-only)
Also, no one else has seen this issue. Can you bisect?
This is an old issue, Many other reported long back [1]
[1] https://lore.kernel.org/stable/CADYN=9KSKQx816id-zWepV-E3ozph3k2_i9Rhs6QseFv...
- Naresh
On Wed, May 17, 2023 at 03:11:48PM +0530, Naresh Kamboju wrote:
On Wed, 17 May 2023 at 14:21, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Tue, May 16, 2023 at 10:14:36AM +0100, Sudip Mukherjee (Codethink) wrote:
Hi Greg,
On Mon, May 15, 2023 at 06:24:11PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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.
Build test (gcc version 11.3.1 20230511): mips: 63 configs -> no failure arm: 104 configs -> no failure arm64: 3 configs -> 1 failure x86_64: 4 configs -> no failure alpha allmodconfig -> no failure powerpc allmodconfig -> no failure riscv allmodconfig -> no failure s390 allmodconfig -> no failure xtensa allmodconfig -> no failure
arm64 allmodconfig build fails with the error:
/gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_tlb_flush_vmid_ipa': (.hyp.text+0x1a4c): undefined reference to `__kvm_nvhe_memset' /gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_tlb_flush_vmid': (.hyp.text+0x1b20): undefined reference to `__kvm_nvhe_memset' /gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_flush_cpu_context': (.hyp.text+0x1b80): undefined reference to `__kvm_nvhe_memset'
That's odd, I don't see that symbol anywhere in the tree at all.
And the only arm-related kvm changes don't have those symbols either (the other kvm changes are x86-only)
Also, no one else has seen this issue. Can you bisect?
This is an old issue, Many other reported long back [1]
[1] https://lore.kernel.org/stable/CADYN=9KSKQx816id-zWepV-E3ozph3k2_i9Rhs6QseFv...
Then maybe someone should submit it properly for inclusion?
thanks,
greg k-h
On Wed, May 17, 2023 at 11:51:21AM +0200, Greg Kroah-Hartman wrote:
On Wed, May 17, 2023 at 03:11:48PM +0530, Naresh Kamboju wrote:
On Wed, 17 May 2023 at 14:21, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Tue, May 16, 2023 at 10:14:36AM +0100, Sudip Mukherjee (Codethink) wrote:
Hi Greg,
On Mon, May 15, 2023 at 06:24:11PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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.
Build test (gcc version 11.3.1 20230511): mips: 63 configs -> no failure arm: 104 configs -> no failure arm64: 3 configs -> 1 failure x86_64: 4 configs -> no failure alpha allmodconfig -> no failure powerpc allmodconfig -> no failure riscv allmodconfig -> no failure s390 allmodconfig -> no failure xtensa allmodconfig -> no failure
arm64 allmodconfig build fails with the error:
/gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_tlb_flush_vmid_ipa': (.hyp.text+0x1a4c): undefined reference to `__kvm_nvhe_memset' /gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_tlb_flush_vmid': (.hyp.text+0x1b20): undefined reference to `__kvm_nvhe_memset' /gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_flush_cpu_context': (.hyp.text+0x1b80): undefined reference to `__kvm_nvhe_memset'
That's odd, I don't see that symbol anywhere in the tree at all.
And the only arm-related kvm changes don't have those symbols either (the other kvm changes are x86-only)
Also, no one else has seen this issue. Can you bisect?
This is an old issue, Many other reported long back [1]
[1] https://lore.kernel.org/stable/CADYN=9KSKQx816id-zWepV-E3ozph3k2_i9Rhs6QseFv...
Then maybe someone should submit it properly for inclusion?
Attached the backported patch. Also verified that my build failure is fixed with it.
On Wed, May 17, 2023 at 08:52:40PM +0100, Sudip Mukherjee (Codethink) wrote:
On Wed, May 17, 2023 at 11:51:21AM +0200, Greg Kroah-Hartman wrote:
On Wed, May 17, 2023 at 03:11:48PM +0530, Naresh Kamboju wrote:
On Wed, 17 May 2023 at 14:21, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Tue, May 16, 2023 at 10:14:36AM +0100, Sudip Mukherjee (Codethink) wrote:
Hi Greg,
On Mon, May 15, 2023 at 06:24:11PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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.
Build test (gcc version 11.3.1 20230511): mips: 63 configs -> no failure arm: 104 configs -> no failure arm64: 3 configs -> 1 failure x86_64: 4 configs -> no failure alpha allmodconfig -> no failure powerpc allmodconfig -> no failure riscv allmodconfig -> no failure s390 allmodconfig -> no failure xtensa allmodconfig -> no failure
arm64 allmodconfig build fails with the error:
/gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_tlb_flush_vmid_ipa': (.hyp.text+0x1a4c): undefined reference to `__kvm_nvhe_memset' /gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_tlb_flush_vmid': (.hyp.text+0x1b20): undefined reference to `__kvm_nvhe_memset' /gcc/bin/aarch64-linux-ld: arch/arm64/kvm/hyp/nvhe/kvm_nvhe.o: in function `__kvm_nvhe___kvm_flush_cpu_context': (.hyp.text+0x1b80): undefined reference to `__kvm_nvhe_memset'
That's odd, I don't see that symbol anywhere in the tree at all.
And the only arm-related kvm changes don't have those symbols either (the other kvm changes are x86-only)
Also, no one else has seen this issue. Can you bisect?
This is an old issue, Many other reported long back [1]
[1] https://lore.kernel.org/stable/CADYN=9KSKQx816id-zWepV-E3ozph3k2_i9Rhs6QseFv...
Then maybe someone should submit it properly for inclusion?
Attached the backported patch. Also verified that my build failure is fixed with it.
Thanks, now queued up.
greg k-h
On Mon, 15 May 2023 at 23:03, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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, 17 May 2023 16:16:37 +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.180-rc... 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. Regressions on arm64, arm, x86_64 and i386.
Reported-by: Linux Kernel Functional Testing lkft@linaro.org
We have recently upgraded our selftest sources to stable-rc 6.3 and running on stable rc 6.1, 5.15, 5.10, 5.4, 4.19 and 4.14 kernels.
List of test regressions: ======== kselftest-membarrier - membarrier_membarrier_test_multi_thread - membarrier_membarrier_test_single_thread
kselftest-memfd - memfd_memfd_test
kselftest-rseq - rseq_basic_test
kselftest-kvm - kvm_xapic_state_test
NOTE: The logs are the same as reported on other email reports. link, - https://lore.kernel.org/stable/CA+G9fYu6ZOu_We2GMP0sFnSovOsqd6waW7oKS-Y1VPrj...
## Build * kernel: 5.10.180-rc1 * git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc * git branch: linux-5.10.y * git commit: 065b6901e6dab7dcc7c8884779b96269724c7201 * git describe: v5.10.179-382-g065b6901e6da * test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.10.y/build/v5.10....
## Test Regressions (compared to v5.10.176-363-g1ef2000b94cb) * bcm2711-rpi-4-b, kselftest-membarrier - membarrier_membarrier_test_multi_thread - membarrier_membarrier_test_single_thread
* bcm2711-rpi-4-b, kselftest-memfd - memfd_memfd_test
* bcm2711-rpi-4-b, kselftest-rseq - rseq_basic_test
* dragonboard-410c, kselftest-membarrier - membarrier_membarrier_test_multi_thread - membarrier_membarrier_test_single_thread
* dragonboard-410c, kselftest-memfd - memfd_memfd_test
* i386, kselftest-membarrier - membarrier_membarrier_test_multi_thread - membarrier_membarrier_test_single_thread
* i386, kselftest-memfd - memfd_memfd_test
* i386, kselftest-rseq - rseq_basic_test - rseq_run_param_test_sh
* juno-r2, kselftest-membarrier - membarrier_membarrier_test_multi_thread - membarrier_membarrier_test_single_thread
* juno-r2, kselftest-memfd - memfd_memfd_test
* juno-r2, kselftest-rseq - rseq_basic_test
* qemu_i386, kselftest-membarrier - membarrier_membarrier_test_multi_thread - membarrier_membarrier_test_single_thread
* qemu_i386, kselftest-memfd - memfd_memfd_test
* qemu_i386, kselftest-rseq - rseq_basic_test - rseq_run_param_test_sh
* qemu_x86_64, kselftest-membarrier - membarrier_membarrier_test_multi_thread - membarrier_membarrier_test_single_thread
* qemu_x86_64, kselftest-memfd - memfd_memfd_test
* qemu_x86_64, kselftest-rseq - rseq_basic_test - rseq_run_param_test_sh
* x15, kselftest-membarrier - membarrier_membarrier_test_multi_thread - membarrier_membarrier_test_single_thread
* x15, kselftest-rseq - rseq_basic_test
* x86, kselftest-kvm - kvm_xapic_state_test
* x86, kselftest-membarrier - membarrier_membarrier_test_multi_thread - membarrier_membarrier_test_single_thread
* x86, kselftest-memfd - memfd_memfd_test
* x86, kselftest-rseq - rseq_basic_test - rseq_run_param_test_sh
## Metric Regressions (compared to v5.10.176-363-g1ef2000b94cb)
## Test Fixes (compared to v5.10.176-363-g1ef2000b94cb)
## Metric Fixes (compared to v5.10.176-363-g1ef2000b94cb)
## Test result summary total: 126856, pass: 105919, fail: 3576, skip: 17174, xfail: 187
## Build Summary * arc: 5 total, 5 passed, 0 failed * arm: 117 total, 116 passed, 1 failed * arm64: 45 total, 42 passed, 3 failed * i386: 35 total, 33 passed, 2 failed * mips: 27 total, 26 passed, 1 failed * parisc: 8 total, 8 passed, 0 failed * powerpc: 26 total, 20 passed, 6 failed * riscv: 12 total, 11 passed, 1 failed * s390: 12 total, 12 passed, 0 failed * sh: 14 total, 12 passed, 2 failed * sparc: 8 total, 8 passed, 0 failed * x86_64: 38 total, 36 passed, 2 failed
## Test suites summary * boot * fwts * igt-gpu-tools * kselftest-android * kselftest-arm64 * kselftest-breakpoints * kselftest-capabilities * kselftest-cgroup * kselftest-clone3 * kselftest-core * kselftest-cpu-hotplug * kselftest-cpufreq * kselftest-drivers-dma-buf * kselftest-efivarfs * kselftest-exec * kselftest-filesystems * kselftest-filesystems-binderfs * kselftest-firmware * kselftest-fpu * kselftest-ftrace * kselftest-futex * kselftest-gpio * kselftest-intel_pstate * kselftest-ipc * kselftest-ir * kselftest-kcmp * kselftest-kexec * kselftest-kvm * kselftest-lib * kselftest-livepatch * kselftest-membarrier * kselftest-memfd * kselftest-memory-hotplug * kselftest-mincore * kselftest-mount * kselftest-mqueue * kselftest-net * kselftest-net-forwarding * kselftest-net-mptcp * kselftest-netfilter * kselftest-nsfs * kselftest-openat2 * kselftest-pid_namespace * kselftest-pidfd * kselftest-proc * kselftest-pstore * kselftest-ptrace * kselftest-rseq * kselftest-rtc * kselftest-sigaltstack * kselftest-size * kselftest-tc-testing * kselftest-timens * kselftest-timers * kselftest-tmpfs * kselftest-tpm2 * kselftest-user * kselftest-user_events * kselftest-vDSO * kselftest-watchdog * kselftest-x86 * kselftest-zram * kunit * kvm-unit-tests * libhugetlbfs * log-parser-boot * log-parser-test * ltp-cap_bounds * ltp-commands * ltp-containers * ltp-controllers * ltp-cpuhotplug * ltp-crypto * ltp-cve * ltp-dio * ltp-fcntl-locktests * ltp-filecaps * ltp-fs * ltp-fs_bind * ltp-fs_perms_simple * ltp-fsx * ltp-hugetlb * ltp-io * ltp-ipc * ltp-math * ltp-mm * ltp-nptl * ltp-pty * ltp-sched * ltp-securebits * ltp-smoke * ltp-syscalls * ltp-tracing * network-basic-tests * perf * rcutorture * v4l2-compliance * vdso
-- Linaro LKFT https://lkft.linaro.org
On Mon, May 15, 2023 at 06:24:11PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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, 17 May 2023 16:16:37 +0000. Anything received after that time might be too late.
Build results: total: 162 pass: 162 fail: 0 Qemu test results: total: 485 pass: 485 fail: 0
Tested-by: Guenter Roeck linux@roeck-us.net
Guenter
Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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, 17 May 2023 16:16:37 +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.180-rc... 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:
[...]
Baokun Li libaokun1@huawei.com writeback, cgroup: fix null-ptr-deref write in bdi_split_work_to_wbs
Sorry for not noticing this sooner, but I think there's a benign issue in this backport.
v5.10.180 commit 2b00b2a0e642 ("writeback, cgroup: fix null-ptr-deref write in bdi_split_work_to_wbs") contains:
+static void cgwb_free_rcu(struct rcu_head *rcu_head) +{ + struct bdi_writeback *wb = container_of(rcu_head, + struct bdi_writeback, rcu); + + percpu_ref_exit(&wb->refcnt); + kfree(wb); +}
[...]
@@ -397,7 +406,7 @@ static void cgwb_release_workfn(struct work_struct *work) fprop_local_destroy_percpu(&wb->memcg_completions); percpu_ref_exit(&wb->refcnt); wb_exit(wb); - kfree_rcu(wb, rcu); + call_rcu(&wb->rcu, cgwb_free_rcu); }
Notice there are now 2 percpu_ref_exit() calls. The upstream, and 5.15.y patches remove the cgwb_release_workfn() calls to percpu_ref_exit(). The 5.10.y fixup is below. It's not essential but might be worth applying to track upstream.
From 416e0e8ab5ff41676d04dc819bd667c6ad3f7555 Mon Sep 17 00:00:00 2001 From: Greg Thelen gthelen@google.com Date: Sat, 20 May 2023 12:46:24 -0700 Subject: [PATCH] writeback, cgroup: remove extra percpu_ref_exit()
5.10 stable commit 2b00b2a0e642 ("writeback, cgroup: fix null-ptr-deref write in bdi_split_work_to_wbs") is a backport of upstream 6.3 commit 1ba1199ec574.
In the 5.10 stable commit backport percpu_ref_exit() is called twice: first in cgwb_release_workfn() and then in cgwb_free_rcu(). The 2nd call is benign as percpu_ref_exit() internally detects there's nothing to do.
This fixes an non-upstream issue that only applies to 5.10.y.
Fixes: 2b00b2a0e642 ("writeback, cgroup: fix null-ptr-deref write in bdi_split_work_to_wbs") Signed-off-by: Greg Thelen gthelen@google.com --- mm/backing-dev.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index b28f629c3527..dd08ab928e07 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -404,7 +404,6 @@ static void cgwb_release_workfn(struct work_struct *work) blkcg_unpin_online(blkcg);
fprop_local_destroy_percpu(&wb->memcg_completions); - percpu_ref_exit(&wb->refcnt); wb_exit(wb); call_rcu(&wb->rcu, cgwb_free_rcu); }
On Sat, May 20, 2023 at 02:39:10PM -0700, Greg Thelen wrote:
Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.10.180 release. There are 381 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, 17 May 2023 16:16:37 +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.180-rc... 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:
[...]
Baokun Li libaokun1@huawei.com writeback, cgroup: fix null-ptr-deref write in bdi_split_work_to_wbs
Sorry for not noticing this sooner, but I think there's a benign issue in this backport.
v5.10.180 commit 2b00b2a0e642 ("writeback, cgroup: fix null-ptr-deref write in bdi_split_work_to_wbs") contains:
+static void cgwb_free_rcu(struct rcu_head *rcu_head) +{
struct bdi_writeback *wb = container_of(rcu_head,
struct bdi_writeback, rcu);
percpu_ref_exit(&wb->refcnt);
kfree(wb);
+}
[...]
@@ -397,7 +406,7 @@ static void cgwb_release_workfn(struct work_struct *work) fprop_local_destroy_percpu(&wb->memcg_completions); percpu_ref_exit(&wb->refcnt); wb_exit(wb);
kfree_rcu(wb, rcu);
call_rcu(&wb->rcu, cgwb_free_rcu);
}
Notice there are now 2 percpu_ref_exit() calls. The upstream, and 5.15.y patches remove the cgwb_release_workfn() calls to percpu_ref_exit(). The 5.10.y fixup is below. It's not essential but might be worth applying to track upstream.
Thanks, I've queued this up now.
greg k-h
linux-stable-mirror@lists.linaro.org