This is the start of the stable review cycle for the 6.1.11 release. There are 208 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Feb 2023 12:55:54 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.11-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 6.1.11-rc1
Hao Sun sunhao.th@gmail.com bpf: Skip invalid kfunc call in backtrack_insn
Andreas Gruenbacher agruenba@redhat.com gfs2: Always check inode size of inline inodes
Andreas Gruenbacher agruenba@redhat.com gfs2: Cosmetic gfs2_dinode_{in,out} cleanup
Minsuk Kang linuxlovemin@yonsei.ac.kr wifi: brcmfmac: Check the count value of channel spec to prevent out-of-bounds reads
Chao Yu chao@kernel.org f2fs: fix to do sanity check on i_extra_isize in is_alive()
Dongliang Mu dzm91@hust.edu.cn fbdev: smscufx: fix error handling code in ufx_usb_probe
Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp f2fs: initialize locks earlier in f2fs_fill_super()
Kees Cook keescook@chromium.org ovl: Use "buf" flexible array for memcpy() destination
Abdun Nihaal abdun.nihaal@gmail.com fs/ntfs3: Validate attribute data and valid sizes
Michael Ellerman mpe@ellerman.id.au powerpc/imc-pmu: Revert nest_init_lock to being a mutex
Nicholas Piggin npiggin@gmail.com powerpc/64s: Fix local irq disable when PMIs are disabled
Michael Ellerman mpe@ellerman.id.au powerpc/64s/radix: Fix crash with unaligned relocated kernel
Andreas Kemnade andreas@kemnade.info iio:adc:twl6030: Enable measurement of VAC
Peter Ujfalusi peter.ujfalusi@linux.intel.com ASoC: SOF: sof-audio: prepare_widgets: Check swidget for NULL on sink failure
Arnd Bergmann arnd@arndb.de platform/x86/amd: pmc: add CONFIG_SERIO dependency
Ilpo Järvinen ilpo.jarvinen@linux.intel.com serial: 8250_dma: Fix DMA Rx rearm race
Ilpo Järvinen ilpo.jarvinen@linux.intel.com serial: 8250_dma: Fix DMA Rx completion race
Johan Hovold johan+linaro@kernel.org phy: qcom-qmp-combo: fix runtime suspend
Russell King (Oracle) rmk+kernel@armlinux.org.uk nvmem: core: fix return value
Michael Walle michael@walle.cc nvmem: core: fix cell removal on error
Michael Walle michael@walle.cc nvmem: core: fix device node refcounting
Russell King (Oracle) rmk+kernel@armlinux.org.uk nvmem: core: fix registration vs use race
Russell King (Oracle) rmk+kernel@armlinux.org.uk nvmem: core: fix cleanup after dev_set_name()
Russell King (Oracle) rmk+kernel@armlinux.org.uk nvmem: core: remove nvmem_config wp_gpio
Russell King (Oracle) rmk+kernel@armlinux.org.uk nvmem: core: initialise nvmem->id early
Graham Sider Graham.Sider@amd.com drm/amdgpu: update wave data type to 3 for gfx11
Tim Huang tim.huang@amd.com drm/amd/pm: drop unneeded dpm features disablement for SMU 13.0.4/11
Mario Limonciello mario.limonciello@amd.com drm/amd: Fix initialization for nbio 4.3.0
Rob Clark robdclark@chromium.org drm/i915: Fix potential bit_17 double-free
Rob Clark robdclark@chromium.org drm/i915: Avoid potential vm use-after-free
Marek Vasut marex@denx.de serial: stm32: Merge hard IRQ and threaded IRQ handling into single IRQ handler
Danilo Krummrich dakr@redhat.com dma-buf: actually set signaling bit for private stub fences
Mike Kravetz mike.kravetz@oracle.com migrate: hugetlb: check for hugetlb shared PMD in node migration
Liam Howlett liam.howlett@oracle.com maple_tree: fix mas_empty_area_rev() lower bound validation
Phillip Lougher phillip@squashfs.org.uk Squashfs: fix handling and sanity checking of xattr_ids count
James Morse james.morse@arm.com ia64: fix build error due to switch case label appearing next to declaration
Matthew Wilcox (Oracle) willy@infradead.org highmem: round down the address passed to kunmap_flush_on_unmap()
Zach O'Keefe zokeefe@google.com mm/MADV_COLLAPSE: catch !none !huge !bad pmd lookups
Vlastimil Babka vbabka@suse.cz mm, mremap: fix mremap() expanding for vma's with vm_ops->close()
Jann Horn jannh@google.com mm/khugepaged: fix ->anon_vma race
Longlong Xia xialonglong1@huawei.com mm/swapfile: add cond_resched() in get_swap_pages()
Peter Xu peterx@redhat.com mm/uffd: fix pte marker when fork() without fork event
Zheng Yongjun zhengyongjun3@huawei.com fpga: stratix10-soc: Fix return value check in s10_ops_write_init()
Ilpo Järvinen ilpo.jarvinen@linux.intel.com fpga: m10bmc-sec: Fix probe rollback
Joerg Roedel jroedel@suse.de x86/debug: Fix stack recursion caused by wrongly ordered DR7 accesses
Greg Kroah-Hartman gregkh@linuxfoundation.org HV: hv_balloon: fix memory leak with using debugfs_lookup()
Greg Kroah-Hartman gregkh@linuxfoundation.org kernel/irq/irqdomain.c: fix memory leak with using debugfs_lookup()
Aaro Koskinen aaro.koskinen@iki.fi usb: gadget: udc: do not clear gadget driver.bus
Heikki Krogerus heikki.krogerus@linux.intel.com usb: typec: ucsi: Don't attempt to resume the ports before they exist
Pratham Pratap quic_ppratap@quicinc.com usb: gadget: f_uac2: Fix incorrect increment of bNumEndpoints
Kefeng Wang wangkefeng.wang@huawei.com mm: memcg: fix NULL pointer in mem_cgroup_track_foreign_dirty_slowpath()
Mike Kravetz mike.kravetz@oracle.com mm: hugetlb: proc: check for hugetlb shared PMD in /proc/PID/smaps
Yu Zhao yuzhao@google.com mm: multi-gen LRU: fix crash during cgroup migration
Isaac J. Manjarres isaacmanjarres@google.com Revert "mm: kmemleak: alloc gray object for reserved region with direct map"
Andreas Schwab schwab@suse.de riscv: disable generation of unwind tables
Helge Deller deller@gmx.de parisc: Wire up PTRACE_GETREGS/PTRACE_SETREGS for compat case
Helge Deller deller@gmx.de parisc: Replace hardcoded value with PRIV_USER constant in ptrace.c
Helge Deller deller@gmx.de parisc: Fix return code of pdc_iodc_print()
Johan Hovold johan+linaro@kernel.org nvmem: qcom-spmi-sdam: fix module autoloading
Samuel Holland samuel@sholland.org nvmem: sunxi_sid: Always use 32-bit MMIO reads
Jiasheng Jiang jiasheng@iscas.ac.cn nvmem: brcm_nvram: Add check for kzalloc
Carlos Song carlos.song@nxp.com iio: imu: fxos8700: fix MAGN sensor scale and unit
Carlos Song carlos.song@nxp.com iio: imu: fxos8700: remove definition FXOS8700_CTRL_ODR_MIN
Carlos Song carlos.song@nxp.com iio: imu: fxos8700: fix failed initialization ODR mode assignment
Carlos Song carlos.song@nxp.com iio: imu: fxos8700: fix incorrect ODR mode readback
Carlos Song carlos.song@nxp.com iio: imu: fxos8700: fix swapped ACCEL and MAGN channels readback
Carlos Song carlos.song@nxp.com iio: imu: fxos8700: fix map label of channel type to MAGN sensor
Carlos Song carlos.song@nxp.com iio: imu: fxos8700: fix IMU data bits returned to user space
Carlos Song carlos.song@nxp.com iio: imu: fxos8700: fix incomplete ACCEL and MAGN channels readback
Carlos Song carlos.song@nxp.com iio: imu: fxos8700: fix ACCEL measurement range selection
Kai-Heng Feng kai.heng.feng@canonical.com iio: light: cm32181: Fix PM support on system with 2 I2C resources
Andreas Kemnade andreas@kemnade.info iio:adc:twl6030: Enable measurements of VUSB, VBAT and others
Frank Li Frank.Li@nxp.com iio: imx8qxp-adc: fix irq flood when call imx8qxp_adc_read_raw()
Xiongfeng Wang wangxiongfeng2@huawei.com iio: adc: berlin2-adc: Add missing of_node_put() in error path
Marco Pagani marpagan@redhat.com iio: adc: xilinx-ams: fix devm_krealloc() return value check
Dmitry Perchanov dmitry.perchanov@intel.com iio: hid: fix the retval in gyro_3d_capture_sample
Dmitry Perchanov dmitry.perchanov@intel.com iio: hid: fix the retval in accel_3d_capture_sample
Shanker Donthineni sdonthineni@nvidia.com rtc: efi: Enable SET/GET WAKEUP services as optional
Ard Biesheuvel ardb@kernel.org efi: Accept version 2 of memory attributes table
Bard Liao yung-chuan.liao@linux.intel.com ASoC: SOF: keep prepare/unprepare widgets in sink path
Ranjani Sridharan ranjani.sridharan@linux.intel.com ASoC: SOF: sof-audio: skip prepare/unprepare if swidget is NULL
Bard Liao yung-chuan.liao@linux.intel.com ASoC: SOF: sof-audio: unprepare when swidget->use_count > 0
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ASoC: codecs: wsa883x: correct playback min/max rates
Jeremy Szu jeremy.szu@canonical.com ALSA: hda/realtek: fix mute/micmute LEDs, speaker don't work for a HP platform
Victor Shyba victor1984@riseup.net ALSA: hda/realtek: Add Acer Predator PH315-54
Alexander Egorenkov egorenar@linux.ibm.com watchdog: diag288_wdt: fix __diag288() inline assembly
Alexander Egorenkov egorenar@linux.ibm.com watchdog: diag288_wdt: do not use stack buffers for hardware data
Oliver Hartkopp socketcan@hartkopp.net can: isotp: handle wait_event_interruptible() return values
Oliver Hartkopp socketcan@hartkopp.net can: isotp: split tx timer into transmission and timeout
Natalia Petrova n.petrova@fintech.ru net: qrtr: free memory on error path in radix_tree_insert()
Fabio Estevam festevam@denx.de ARM: dts: imx7d-smegw01: Fix USB host over-current polarity
Michael Kelley mikelley@microsoft.com hv_netvsc: Fix missed pagebuf entries in netvsc_dma_map/unmap()
Waiman Long longman@redhat.com cgroup/cpuset: Fix wrong check in update_parent_subparts_cpumask()
Samuel Thibault samuel.thibault@ens-lyon.org fbcon: Check font dimension limits
George Kennedy george.kennedy@oracle.com vc_screen: move load of struct vc_data pointer in vcs_read() to avoid UAF
Udipto Goswami quic_ugoswami@quicinc.com usb: gadget: f_fs: Fix unbalanced spinlock in __ffs_ep0_queue_wait
Neil Armstrong neil.armstrong@linaro.org usb: dwc3: qcom: enable vbus override when in OTG dr-mode
Olivier Moysan olivier.moysan@foss.st.com iio: adc: stm32-dfsdm: fill module aliases
Kees Cook keescook@chromium.org bcache: Silence memcpy() run-time false positive warnings
Aurabindo Pillai aurabindo.pillai@amd.com drm/amd/display: Fix timing not changning when freesync video is enabled
Hyunwoo Kim v4bel@theori.io net/x25: Fix to not accept on connected socket
Mario Limonciello mario.limonciello@amd.com platform/x86/amd: pmc: Disable IRQ1 wakeup for RN/CZN
Kevin Kuriakose kevinmkuriakose@gmail.com platform/x86: gigabyte-wmi: add support for B450M DS3H WIFI-CF
Rishit Bansal rishitbansal0@gmail.com platform/x86: hp-wmi: Handle Omen Key event
Koba Ko koba.ko@canonical.com platform/x86: dell-wmi: Add a keymap for KEY_MUTE in type 0x0010 table
Nathan Chancellor nathan@kernel.org x86/build: Move '-mindirect-branch-cs-prefix' out of GCC-only block
Andreas Gruenbacher agruenba@redhat.com Revert "gfs2: stop using generic_writepages in gfs2_ail1_start_one"
Randy Dunlap rdunlap@infradead.org i2c: rk3x: fix a bunch of kernel-doc warnings
Mike Christie michael.christie@oracle.com scsi: iscsi_tcp: Fix UAF during login when accessing the shost ipaddress
Mike Christie michael.christie@oracle.com scsi: iscsi_tcp: Fix UAF during logout when accessing the shost ipaddress
Kan Liang kan.liang@linux.intel.com perf/x86/intel/cstate: Add Emerald Rapids
Kan Liang kan.liang@linux.intel.com perf/x86/intel: Add Emerald Rapids
Yair Podemsky ypodemsk@redhat.com x86/aperfmperf: Erase stale arch_freq_scale values when disabling frequency invariance readings
Maurizio Lombardi mlombard@redhat.com scsi: target: core: Fix warning on RT kernels
Stefan Wahren stefan.wahren@i2se.com i2c: mxs: suppress probe-deferral error message
Basavaraj Natikar Basavaraj.Natikar@amd.com i2c: designware-pci: Add new PCI IDs for AMD NAVI GPU
Jan Luebbe jlu@pengutronix.de kbuild: modinst: Fix build error when CONFIG_MODULE_SIG_KEY is a PKCS#11 URI
Jan Luebbe jlu@pengutronix.de certs: Fix build error when PKCS#11 URI contains semicolon
Arnd Bergmann arnd@arndb.de rtc: sunplus: fix format string for printing resource
Anton Gusev aagusev@ispras.ru efi: fix potential NULL deref in efi_mem_reserve_persistent
Fedor Pchelkin pchelkin@ispras.ru net: openvswitch: fix flow memory leak in ovs_flow_cmd_new
Parav Pandit parav@nvidia.com virtio-net: Keep stop() to follow mirror sequence of open()
Andrei Gherzan andrei.gherzan@canonical.com selftests: net: udpgso_bench_tx: Cater for pending datagrams zerocopy benchmarking
Andrei Gherzan andrei.gherzan@canonical.com selftests: net: udpgso_bench: Fix racing bug between the rx/tx programs
Andrei Gherzan andrei.gherzan@canonical.com selftests: net: udpgso_bench_rx/tx: Stop when wrong CLI args are provided
Andrei Gherzan andrei.gherzan@canonical.com selftests: net: udpgso_bench_rx: Fix 'used uninitialized' compiler warning
Damien Le Moal damien.lemoal@opensource.wdc.com ata: libata: Fix sata_down_spd_limit() when no link speed is reported
Marc Kleine-Budde mkl@pengutronix.de can: mcp251xfd: mcp251xfd_ring_set_ringparam(): assign missing tx_obj_num_coalesce_irq
Oliver Hartkopp socketcan@hartkopp.net can: raw: fix CAN FD frame transmissions over CAN XL devices
Ziyang Xuan william.xuanziyang@huawei.com can: j1939: fix errant WARN_ON_ONCE in j1939_session_deactivate
Ratheesh Kannoth rkannoth@marvell.com octeontx2-af: Fix devlink unregister
Tom Rix trix@redhat.com igc: return an error if the mac type is unknown in igc_ptp_systim_to_hwtstamp()
Guo Ren guoren@kernel.org riscv: kprobe: Fixup kernel panic when probing an illegal position
Thomas Winter Thomas.Winter@alliedtelesis.co.nz ip/ip6_gre: Fix non-point-to-point tunnel not generating IPv6 link local address
Thomas Winter Thomas.Winter@alliedtelesis.co.nz ip/ip6_gre: Fix changing addr gen mode not generating IPv6 link local address
Stephen Boyd swboyd@chromium.org drm/panel: boe-tv101wum-nl6: Ensure DSI writes succeed during disable
Chris Healy healych@amazon.com net: phy: meson-gxl: Add generic dummy stubs for MMD register access
Xin Long lucien.xin@gmail.com sctp: do not check hb_timer.expires when resetting hb_timer
Wei Yang richard.weiyang@gmail.com maple_tree: should get pivots boundary by type
Fedor Pchelkin pchelkin@ispras.ru squashfs: harden sanity check in squashfs_read_xattr_id_table
Brendan Higgins brendan.higgins@linux.dev kunit: fix kunit_test_init_section_suites(...)
Liu Xiaodong xiaodong.liu@intel.com block: ublk: extending queue_size to fix overflow
Florian Westphal fw@strlen.de netfilter: br_netfilter: disable sabotage_in hook after first suppression
Takashi Sakamoto o-takashi@sakamocchi.jp ALSA: firewire-motu: fix unreleased lock warning in hwdep device
Pietro Borrello borrello@diag.uniroma1.it net/tls: tls_is_tx_ready() checked list_entry
Chaitanya Kumar Borah chaitanya.kumar.borah@intel.com drm/i915/adlp: Fix typo for reference clock
John Harrison John.C.Harrison@Intel.com drm/i915: Fix up locking around dumping requests lists
John Harrison John.C.Harrison@Intel.com drm/i915: Fix request ref counting during error capture & debugfs dump
John Harrison John.C.Harrison@Intel.com drm/i915/guc: Fix locking when searching for a hung request
Hans de Goede hdegoede@redhat.com platform/x86: thinkpad_acpi: Fix thinklight LED brightness returning 255
Hans de Goede hdegoede@redhat.com platform/x86/amd/pmf: Ensure mutexes are initialized before use
Shyam Sundar S K Shyam-sundar.S-k@amd.com platform/x86/amd/pmf: Fix to update SPS thermals when power supply change
Shyam Sundar S K Shyam-sundar.S-k@amd.com platform/x86/amd/pmf: Add helper routine to check pprof is balanced
Shyam Sundar S K Shyam-sundar.S-k@amd.com platform/x86/amd/pmf: Fix to update SPS default pprof thermals
Shyam Sundar S K Shyam-sundar.S-k@amd.com platform/x86/amd/pmf: Add helper routine to update SPS thermals
Shyam Sundar S K Shyam-sundar.S-k@amd.com platform/x86/amd/pmf: update to auto-mode limits only after AMT event
Hou Tao houtao1@huawei.com fscache: Use wait_on_bit() to wait for the freeing of relinquished volume
Hyunwoo Kim v4bel@theori.io netrom: Fix use-after-free caused by accept on already connected socket
Yu Kuai yukuai3@huawei.com block, bfq: fix uaf for bfqq in bic_set_bfqq()
Yu Kuai yukuai3@huawei.com block, bfq: replace 0/1 with false/true in bic apis
Kornel Dulęba mindal@semihalf.com net: wwan: t7xx: Fix Runtime PM initialization
Andre Kalb andre.kalb@sma.de net: phy: dp83822: Fix null pointer access on DP83825/DP83826 devices
Íñigo Huguet ihuguet@redhat.com sfc: correctly advertise tunneled IPv6 segmentation
Alexander Duyck alexanderduyck@fb.com skb: Do mix page pool and page referenced frags in GRO
Magnus Karlsson magnus.karlsson@intel.com dpaa2-eth: execute xdp_do_flush() before napi_complete_done()
Magnus Karlsson magnus.karlsson@intel.com dpaa_eth: execute xdp_do_flush() before napi_complete_done()
Magnus Karlsson magnus.karlsson@intel.com virtio-net: execute xdp_do_flush() before napi_complete_done()
Magnus Karlsson magnus.karlsson@intel.com qede: execute xdp_do_flush() before napi_complete_done()
Dave Ertman david.m.ertman@intel.com ice: Prevent set_channel from changing queues while RDMA active
Jason Wang jasowang@redhat.com vhost-scsi: unbreak any layout for response
Al Viro viro@zeniv.linux.org.uk use less confusing names for iov_iter direction initializers
Al Viro viro@zeniv.linux.org.uk fix "direction" argument of iov_iter_kvec()
Al Viro viro@zeniv.linux.org.uk fix 'direction' argument of iov_iter_{init,bvec}()
Al Viro viro@zeniv.linux.org.uk fix iov_iter_bvec() "direction" argument
Al Viro viro@zeniv.linux.org.uk memcpy_real(): WRITE is "data source", not destination...
Al Viro viro@zeniv.linux.org.uk zcore: WRITE is "data source", not destination...
Al Viro viro@zeniv.linux.org.uk READ is "data destination", not source...
Al Viro viro@zeniv.linux.org.uk WRITE is "data source", not destination...
Al Viro viro@zeniv.linux.org.uk copy_oldmem_kernel() - WRITE is "data source", not destination
Eric Auger eric.auger@redhat.com vhost/net: Clear the pending messages when the backend is removed
Takashi Iwai tiwai@suse.de ALSA: memalloc: Workaround for Xen PV
Kui-Feng Lee kuifeng@meta.com bpf: Fix the kernel crash caused by bpf_setsockopt().
Martin K. Petersen martin.petersen@oracle.com scsi: Revert "scsi: core: map PQ=1, PDT=other values to SCSI_SCAN_TARGET_PRESENT"
Javier Martinez Canillas javierm@redhat.com drm/ssd130x: Init display before the SSD130X_DISPLAY_ON command
Hans Verkuil hverkuil-cisco@xs4all.nl drm/vc4: hdmi: make CEC adapter name unique
Philippe Schenker philippe.schenker@toradex.com arm64: dts: imx8mm-verdin: Do not power down eth-phy
Pierluigi Passaro pierluigi.p@variscite.com arm64: dts: imx8mm: Fix pad control for UART1_DTE_RX
Jakub Sitnicki jakub@cloudflare.com bpf, sockmap: Check for any of tcp_bpf_prots when cloning a listener
Hans Verkuil hverkuil-cisco@xs4all.nl media: v4l2-ctrls-api.c: move ctrl->is_new = 1 to the correct line
Jiri Olsa jolsa@kernel.org bpf: Add missing btf_put to register_btf_id_dtor_kfuncs
Dan Carpenter error27@gmail.com ASoC: SOF: ipc4-mtrace: prevent underflow in sof_ipc4_priority_mask_dfs_write()
Pengfei Xu pengfei.xu@intel.com selftests/filesystems: grant executable permission to run_fat_tests.sh
Eduard Zingerman eddyz87@gmail.com bpf: Fix to preserve reg parent/live fields when copying range info
Artemii Karasev karasev@ispras.ru ALSA: hda/via: Avoid potential array out-of-bound in add_secret_dac_path()
Yonghong Song yhs@fb.com bpf: Fix a possible task gone issue with bpf_send_signal[_thread]() helpers
Hou Tao houtao1@huawei.com bpf: Fix off-by-one error in bpf_mem_cache_idx()
Peter Xu peterx@redhat.com selftests/vm: remove __USE_GNU in hugetlb-madvise.c
Amadeusz Sławiński amadeuszx.slawinski@linux.intel.com ASoC: Intel: avs: Implement PCI shutdown
Andy Shevchenko andriy.shevchenko@linux.intel.com ASoC: Intel: sof_es8336: Drop reference count of ACPI device after use
Andy Shevchenko andriy.shevchenko@linux.intel.com ASoC: Intel: bytcr_wm5102: Drop reference count of ACPI device after use
Andy Shevchenko andriy.shevchenko@linux.intel.com ASoC: Intel: bytcr_rt5640: Drop reference count of ACPI device after use
Andy Shevchenko andriy.shevchenko@linux.intel.com ASoC: Intel: bytcr_rt5651: Drop reference count of ACPI device after use
Andy Shevchenko andriy.shevchenko@linux.intel.com ASoC: Intel: bytcht_es8316: Drop reference count of ACPI device after use
Andy Shevchenko andriy.shevchenko@linux.intel.com ASoC: amd: acp-es8336: Drop reference count of ACPI device after use
Frank Li Frank.Li@nxp.com arm64: dts: freescale: imx8dxl: fix sc_pwrkey's property name linux,keycode
Fabio Estevam festevam@denx.de arm64: dts: imx8m-venice: Remove incorrect 'uart-has-rtscts'
Yuan Can yuancan@huawei.com bus: sunxi-rsb: Fix error handling in sunxi_rsb_init()
Takashi Sakamoto o-takashi@sakamocchi.jp firewire: fix memory leak for payload of request subaction to IEC 61883-1 FCP region
-------------
Diffstat:
Makefile | 4 +- arch/arm/boot/dts/imx7d-smegw01.dts | 3 +- arch/arm64/boot/dts/freescale/imx8dxl.dtsi | 2 +- arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h | 2 +- .../imx8mm-venice-gw72xx-0x-rs232-rts.dts | 1 - .../imx8mm-venice-gw73xx-0x-rs232-rts.dts | 1 - .../boot/dts/freescale/imx8mm-venice-gw73xx.dtsi | 1 - .../boot/dts/freescale/imx8mm-venice-gw7901.dts | 3 - .../boot/dts/freescale/imx8mm-venice-gw7902.dts | 3 - .../boot/dts/freescale/imx8mm-venice-gw7903.dts | 1 - arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi | 1 + .../boot/dts/freescale/imx8mn-venice-gw7902.dts | 1 - .../boot/dts/freescale/imx8mp-venice-gw74xx.dts | 1 - arch/ia64/kernel/sys_ia64.c | 7 +- arch/parisc/kernel/firmware.c | 5 +- arch/parisc/kernel/ptrace.c | 21 +++- arch/powerpc/include/asm/hw_irq.h | 2 +- arch/powerpc/mm/book3s64/radix_pgtable.c | 11 ++ arch/powerpc/perf/imc-pmu.c | 14 +-- arch/riscv/Makefile | 3 + arch/riscv/kernel/probes/kprobes.c | 18 ++++ arch/s390/kernel/crash_dump.c | 2 +- arch/s390/mm/maccess.c | 2 +- arch/x86/Makefile | 2 +- arch/x86/events/intel/core.c | 1 + arch/x86/events/intel/cstate.c | 1 + arch/x86/include/asm/debugreg.h | 26 ++++- arch/x86/kernel/cpu/aperfmperf.c | 9 ++ arch/x86/kernel/cpu/microcode/intel.c | 2 +- arch/x86/kernel/crash_dump_64.c | 2 +- block/bfq-cgroup.c | 8 +- block/bfq-iosched.c | 8 +- certs/Makefile | 4 +- crypto/testmgr.c | 4 +- drivers/acpi/pfr_update.c | 2 +- drivers/ata/libata-core.c | 2 +- drivers/block/drbd/drbd_main.c | 2 +- drivers/block/drbd/drbd_receiver.c | 2 +- drivers/block/loop.c | 12 +-- drivers/block/nbd.c | 10 +- drivers/block/ublk_drv.c | 2 +- drivers/bus/sunxi-rsb.c | 8 +- drivers/char/random.c | 4 +- drivers/dma-buf/dma-fence.c | 2 +- drivers/firewire/core-cdev.c | 4 +- drivers/firmware/efi/efi.c | 2 + drivers/firmware/efi/memattr.c | 2 +- drivers/fpga/intel-m10-bmc-sec-update.c | 17 +++- drivers/fpga/stratix10-soc.c | 4 +- drivers/fsi/fsi-sbefifo.c | 6 +- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c | 8 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++ drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 14 +++ drivers/gpu/drm/i915/display/intel_cdclk.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_context.c | 14 ++- drivers/gpu/drm/i915/gem/i915_gem_tiling.c | 9 +- drivers/gpu/drm/i915/gt/intel_context.c | 4 +- drivers/gpu/drm/i915/gt/intel_context.h | 3 +- drivers/gpu/drm/i915/gt/intel_engine.h | 4 +- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 74 +++++++------- .../gpu/drm/i915/gt/intel_execlists_submission.c | 27 +++++ .../gpu/drm/i915/gt/intel_execlists_submission.h | 4 + drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 14 ++- drivers/gpu/drm/i915/i915_gpu_error.c | 33 ++---- drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 16 ++- drivers/gpu/drm/solomon/ssd130x.c | 18 ++-- drivers/gpu/drm/vc4/vc4_hdmi.c | 3 +- drivers/hv/hv_balloon.c | 2 +- drivers/i2c/busses/i2c-designware-pcidrv.c | 2 + drivers/i2c/busses/i2c-mxs.c | 4 +- drivers/i2c/busses/i2c-rk3x.c | 44 ++++---- drivers/iio/accel/hid-sensor-accel-3d.c | 1 + drivers/iio/adc/berlin2-adc.c | 4 +- drivers/iio/adc/imx8qxp-adc.c | 11 +- drivers/iio/adc/stm32-dfsdm-adc.c | 1 + drivers/iio/adc/twl6030-gpadc.c | 32 ++++++ drivers/iio/adc/xilinx-ams.c | 2 +- drivers/iio/gyro/hid-sensor-gyro-3d.c | 1 + drivers/iio/imu/fxos8700_core.c | 111 +++++++++++++++++---- drivers/iio/light/cm32181.c | 9 +- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 2 +- drivers/isdn/mISDN/l1oip_core.c | 2 +- drivers/md/bcache/bcache_ondisk.h | 3 +- drivers/md/bcache/journal.c | 3 +- drivers/media/v4l2-core/v4l2-ctrls-api.c | 2 +- drivers/misc/vmw_vmci/vmci_queue_pair.c | 6 +- drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c | 1 + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 6 +- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 9 +- drivers/net/ethernet/intel/ice/ice.h | 2 +- drivers/net/ethernet/intel/ice/ice_dcb_lib.c | 23 +++-- drivers/net/ethernet/intel/ice/ice_dcb_lib.h | 4 +- drivers/net/ethernet/intel/ice/ice_ethtool.c | 28 +++++- drivers/net/ethernet/intel/ice/ice_main.c | 5 +- drivers/net/ethernet/intel/igc/igc_ptp.c | 14 ++- .../ethernet/marvell/octeontx2/af/rvu_devlink.c | 35 +++++-- drivers/net/ethernet/qlogic/qede/qede_fp.c | 7 +- drivers/net/ethernet/sfc/efx.c | 5 +- drivers/net/hyperv/netvsc.c | 9 +- drivers/net/phy/dp83822.c | 6 +- drivers/net/phy/meson-gxl.c | 2 + drivers/net/ppp/ppp_generic.c | 2 +- drivers/net/virtio_net.c | 8 +- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 17 ++++ drivers/net/wwan/t7xx/t7xx_pci.c | 2 + drivers/nvme/host/tcp.c | 4 +- drivers/nvme/target/io-cmd-file.c | 4 +- drivers/nvme/target/tcp.c | 2 +- drivers/nvmem/brcm_nvram.c | 3 + drivers/nvmem/core.c | 60 +++++------ drivers/nvmem/qcom-spmi-sdam.c | 1 + drivers/nvmem/sunxi_sid.c | 15 ++- drivers/of/fdt.c | 6 +- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 12 +-- drivers/platform/x86/amd/Kconfig | 1 + drivers/platform/x86/amd/pmc.c | 50 ++++++++++ drivers/platform/x86/amd/pmf/auto-mode.c | 9 +- drivers/platform/x86/amd/pmf/cnqf.c | 14 +-- drivers/platform/x86/amd/pmf/core.c | 32 +++++- drivers/platform/x86/amd/pmf/pmf.h | 3 + drivers/platform/x86/amd/pmf/sps.c | 28 ++++-- drivers/platform/x86/dell/dell-wmi-base.c | 3 + drivers/platform/x86/gigabyte-wmi.c | 1 + drivers/platform/x86/hp-wmi.c | 4 + drivers/platform/x86/thinkpad_acpi.c | 2 +- drivers/rtc/rtc-efi.c | 48 +++++---- drivers/rtc/rtc-sunplus.c | 4 +- drivers/s390/char/zcore.c | 2 +- drivers/scsi/iscsi_tcp.c | 20 +++- drivers/scsi/libiscsi.c | 38 +++++-- drivers/scsi/scsi_scan.c | 7 +- drivers/scsi/sg.c | 2 +- drivers/target/iscsi/iscsi_target_util.c | 4 +- drivers/target/target_core_file.c | 4 +- drivers/target/target_core_tmr.c | 4 +- drivers/tty/serial/8250/8250_dma.c | 26 ++++- drivers/tty/serial/stm32-usart.c | 33 +----- drivers/tty/vt/vc_screen.c | 9 +- drivers/usb/dwc3/dwc3-qcom.c | 2 +- drivers/usb/gadget/function/f_fs.c | 4 +- drivers/usb/gadget/function/f_uac2.c | 1 + drivers/usb/gadget/udc/bcm63xx_udc.c | 1 - drivers/usb/gadget/udc/fotg210-udc.c | 1 - drivers/usb/gadget/udc/fsl_qe_udc.c | 1 - drivers/usb/gadget/udc/fsl_udc_core.c | 1 - drivers/usb/gadget/udc/fusb300_udc.c | 1 - drivers/usb/gadget/udc/goku_udc.c | 1 - drivers/usb/gadget/udc/gr_udc.c | 1 - drivers/usb/gadget/udc/m66592-udc.c | 1 - drivers/usb/gadget/udc/max3420_udc.c | 1 - drivers/usb/gadget/udc/mv_u3d_core.c | 1 - drivers/usb/gadget/udc/mv_udc_core.c | 1 - drivers/usb/gadget/udc/net2272.c | 1 - drivers/usb/gadget/udc/net2280.c | 1 - drivers/usb/gadget/udc/omap_udc.c | 1 - drivers/usb/gadget/udc/pch_udc.c | 1 - drivers/usb/gadget/udc/snps_udc_core.c | 1 - drivers/usb/typec/ucsi/ucsi.c | 9 +- drivers/usb/usbip/usbip_common.c | 2 +- drivers/vhost/net.c | 9 +- drivers/vhost/scsi.c | 29 ++++-- drivers/vhost/vhost.c | 9 +- drivers/vhost/vhost.h | 1 + drivers/vhost/vringh.c | 4 +- drivers/vhost/vsock.c | 4 +- drivers/video/fbdev/core/fbcon.c | 7 +- drivers/video/fbdev/smscufx.c | 46 ++++++--- drivers/watchdog/diag288_wdt.c | 15 ++- drivers/xen/pvcalls-back.c | 8 +- fs/9p/vfs_addr.c | 4 +- fs/9p/vfs_dir.c | 2 +- fs/9p/xattr.c | 4 +- fs/afs/cmservice.c | 2 +- fs/afs/dir.c | 2 +- fs/afs/file.c | 4 +- fs/afs/internal.h | 4 +- fs/afs/rxrpc.c | 10 +- fs/afs/write.c | 4 +- fs/aio.c | 4 +- fs/btrfs/ioctl.c | 4 +- fs/ceph/addr.c | 4 +- fs/ceph/file.c | 4 +- fs/cifs/connect.c | 6 +- fs/cifs/file.c | 4 +- fs/cifs/fscache.c | 4 +- fs/cifs/smb2ops.c | 4 +- fs/cifs/transport.c | 6 +- fs/coredump.c | 2 +- fs/erofs/fscache.c | 6 +- fs/f2fs/gc.c | 18 ++-- fs/f2fs/super.c | 38 +++---- fs/fscache/io.c | 2 +- fs/fscache/volume.c | 11 +- fs/fuse/ioctl.c | 4 +- fs/gfs2/aops.c | 2 - fs/gfs2/bmap.c | 3 - fs/gfs2/glops.c | 44 ++++---- fs/gfs2/log.c | 11 +- fs/gfs2/super.c | 27 ++--- fs/netfs/io.c | 6 +- fs/nfs/fscache.c | 4 +- fs/nfsd/vfs.c | 4 +- fs/ntfs3/inode.c | 7 ++ fs/ocfs2/cluster/tcp.c | 2 +- fs/orangefs/inode.c | 8 +- fs/overlayfs/export.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- fs/proc/task_mmu.c | 4 +- fs/proc/vmcore.c | 6 +- fs/read_write.c | 12 +-- fs/seq_file.c | 2 +- fs/splice.c | 10 +- fs/squashfs/squashfs_fs.h | 2 +- fs/squashfs/squashfs_fs_sb.h | 2 +- fs/squashfs/xattr.h | 4 +- fs/squashfs/xattr_id.c | 4 +- include/kunit/test.h | 1 - include/linux/efi.h | 3 +- include/linux/highmem-internal.h | 4 +- include/linux/hugetlb.h | 13 +++ include/linux/memcontrol.h | 5 +- include/linux/nvmem-provider.h | 2 - include/linux/uio.h | 3 + include/linux/util_macros.h | 12 +++ include/scsi/libiscsi.h | 2 + io_uring/net.c | 14 +-- io_uring/rw.c | 10 +- kernel/bpf/bpf_lsm.c | 1 - kernel/bpf/btf.c | 4 +- kernel/bpf/memalloc.c | 2 +- kernel/bpf/verifier.c | 31 ++++-- kernel/cgroup/cpuset.c | 3 +- kernel/irq/irqdomain.c | 2 +- kernel/trace/bpf_trace.c | 3 +- kernel/trace/trace_events_user.c | 2 +- lib/maple_tree.c | 22 ++-- lib/test_maple_tree.c | 89 +++++++++++++++++ mm/khugepaged.c | 22 +++- mm/madvise.c | 2 +- mm/memory.c | 8 +- mm/mempolicy.c | 3 +- mm/mremap.c | 25 +++-- mm/page_io.c | 4 +- mm/process_vm_access.c | 2 +- mm/swapfile.c | 1 + mm/vmscan.c | 5 +- net/9p/client.c | 2 +- net/bluetooth/6lowpan.c | 2 +- net/bluetooth/a2mp.c | 2 +- net/bluetooth/smp.c | 2 +- net/bridge/br_netfilter_hooks.c | 1 + net/can/isotp.c | 69 ++++++------- net/can/j1939/transport.c | 4 - net/can/raw.c | 47 ++++++--- net/ceph/messenger_v1.c | 4 +- net/ceph/messenger_v2.c | 14 +-- net/compat.c | 3 +- net/core/gro.c | 9 ++ net/ipv4/tcp.c | 4 +- net/ipv4/tcp_bpf.c | 4 +- net/ipv6/addrconf.c | 59 ++++++----- net/netfilter/ipvs/ip_vs_sync.c | 2 +- net/netrom/af_netrom.c | 5 + net/openvswitch/datapath.c | 12 +-- net/qrtr/ns.c | 5 +- net/sctp/transport.c | 4 +- net/smc/smc_clc.c | 6 +- net/smc/smc_tx.c | 2 +- net/socket.c | 12 +-- net/sunrpc/socklib.c | 6 +- net/sunrpc/svcsock.c | 4 +- net/sunrpc/xprtsock.c | 6 +- net/tipc/topsrv.c | 2 +- net/tls/tls_device.c | 4 +- net/tls/tls_sw.c | 2 +- net/x25/af_x25.c | 6 ++ net/xfrm/espintcp.c | 2 +- scripts/Makefile.modinst | 6 +- security/keys/keyctl.c | 4 +- sound/core/memalloc.c | 87 ++++++++++++---- sound/firewire/motu/motu-hwdep.c | 4 + sound/pci/hda/patch_realtek.c | 2 + sound/pci/hda/patch_via.c | 3 + sound/soc/amd/acp-es8336.c | 6 +- sound/soc/codecs/wsa883x.c | 4 +- sound/soc/intel/avs/core.c | 24 +++++ sound/soc/intel/boards/bytcht_es8316.c | 20 ++-- sound/soc/intel/boards/bytcr_rt5640.c | 12 +-- sound/soc/intel/boards/bytcr_rt5651.c | 2 +- sound/soc/intel/boards/bytcr_wm5102.c | 2 +- sound/soc/intel/boards/sof_es8336.c | 14 +-- sound/soc/sof/ipc4-mtrace.c | 7 +- sound/soc/sof/sof-audio.c | 12 ++- tools/testing/selftests/cgroup/test_cpuset_prs.sh | 1 + .../selftests/filesystems/fat/run_fat_tests.sh | 0 tools/testing/selftests/net/udpgso_bench.sh | 24 ++++- tools/testing/selftests/net/udpgso_bench_rx.c | 4 +- tools/testing/selftests/net/udpgso_bench_tx.c | 36 +++++-- tools/testing/selftests/vm/hugetlb-madvise.c | 1 - 300 files changed, 1829 insertions(+), 940 deletions(-)
From: Takashi Sakamoto o-takashi@sakamocchi.jp
commit 531390a243ef47448f8bad01c186c2787666bf4d upstream.
This patch is fix for Linux kernel v2.6.33 or later.
For request subaction to IEC 61883-1 FCP region, Linux FireWire subsystem have had an issue of use-after-free. The subsystem allows multiple user space listeners to the region, while data of the payload was likely released before the listeners execute read(2) to access to it for copying to user space.
The issue was fixed by a commit 281e20323ab7 ("firewire: core: fix use-after-free regression in FCP handler"). The object of payload is duplicated in kernel space for each listener. When the listener executes ioctl(2) with FW_CDEV_IOC_SEND_RESPONSE request, the object is going to be released.
However, it causes memory leak since the commit relies on call of release_request() in drivers/firewire/core-cdev.c. Against the expectation, the function is never called due to the design of release_client_resource(). The function delegates release task to caller when called with non-NULL fourth argument. The implementation of ioctl_send_response() is the case. It should release the object explicitly.
This commit fixes the bug.
Cc: stable@vger.kernel.org Fixes: 281e20323ab7 ("firewire: core: fix use-after-free regression in FCP handler") Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp Link: https://lore.kernel.org/r/20230117090610.93792-2-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/firewire/core-cdev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -819,8 +819,10 @@ static int ioctl_send_response(struct cl
r = container_of(resource, struct inbound_transaction_resource, resource); - if (is_fcp_request(r->request)) + if (is_fcp_request(r->request)) { + kfree(r->data); goto out; + }
if (a->length != fw_get_response_length(r->request)) { ret = -EINVAL;
From: Yuan Can yuancan@huawei.com
[ Upstream commit f71eaf2708be7831428eacae7db25d8ec6b8b4c5 ]
The sunxi_rsb_init() returns the platform_driver_register() directly without checking its return value, if platform_driver_register() failed, the sunxi_rsb_bus is not unregistered. Fix by unregister sunxi_rsb_bus when platform_driver_register() failed.
Fixes: d787dcdb9c8f ("bus: sunxi-rsb: Add driver for Allwinner Reduced Serial Bus") Signed-off-by: Yuan Can yuancan@huawei.com Reviewed-by: Jernej Skrabec jernej.skrabec@gmail.com Link: https://lore.kernel.org/r/20221123094200.12036-1-yuancan@huawei.com Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/sunxi-rsb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 3aa91aed3bf7..226e87b85116 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -857,7 +857,13 @@ static int __init sunxi_rsb_init(void) return ret; }
- return platform_driver_register(&sunxi_rsb_driver); + ret = platform_driver_register(&sunxi_rsb_driver); + if (ret) { + bus_unregister(&sunxi_rsb_bus); + return ret; + } + + return 0; } module_init(sunxi_rsb_init);
From: Fabio Estevam festevam@denx.de
[ Upstream commit fca053893e8d5be8173c92876c6329cbee78b880 ]
The following build warnings are seen when running:
make dtbs_check DT_SCHEMA_FILES=fsl-imx-uart.yaml
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb: serial@30860000: cts-gpios: False schema does not allow [[33, 3, 1]] From schema: Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dtb: serial@30860000: rts-gpios: False schema does not allow [[33, 5, 1]] From schema: Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml ...
The imx8m Venice Gateworks boards do not expose the UART RTS and CTS as native UART pins, so 'uart-has-rtscts' should not be used.
Using 'uart-has-rtscts' with 'rts-gpios' is an invalid combination detected by serial.yaml.
Fix the problem by removing the incorrect 'uart-has-rtscts' property.
Fixes: 27c8f4ccc1b9 ("arm64: dts: imx8mm-venice-gw72xx-0x: add dt overlays for serial modes") Fixes: d9a9a7cf32c9 ("arm64: dts: imx8m{m,n}-venice-*: add missing uart-has-rtscts property to UARTs") Fixes: 870f645b396b ("arm64: dts: imx8mp-venice-gw74xx: add WiFi/BT module support") Signed-off-by: Fabio Estevam festevam@denx.de Acked-by: Tim Harvey tharvey@gateworks.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts | 1 - .../boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts | 1 - arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi | 1 - arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts | 3 --- arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts | 3 --- arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts | 1 - arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts | 1 - arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts | 1 - 8 files changed, 12 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts index 3ea73a6886ff..f6ad1a4b8b66 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts @@ -33,7 +33,6 @@ pinctrl-0 = <&pinctrl_uart2>; rts-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>; cts-gpios = <&gpio5 28 GPIO_ACTIVE_LOW>; - uart-has-rtscts; status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts index 2fa635e1c1a8..1f8ea20dfafc 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts @@ -33,7 +33,6 @@ pinctrl-0 = <&pinctrl_uart2>; rts-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>; cts-gpios = <&gpio5 28 GPIO_ACTIVE_LOW>; - uart-has-rtscts; status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi index 244ef8d6cc68..7761d5671cb1 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi @@ -222,7 +222,6 @@ pinctrl-0 = <&pinctrl_uart3>, <&pinctrl_bten>; cts-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>; rts-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; - uart-has-rtscts; status = "okay";
bluetooth { diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts index 72311b55f06d..5a770c8b777e 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts @@ -721,7 +721,6 @@ dtr-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; dsr-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; dcd-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; - uart-has-rtscts; status = "okay"; };
@@ -737,7 +736,6 @@ pinctrl-0 = <&pinctrl_uart3>, <&pinctrl_uart3_gpio>; cts-gpios = <&gpio4 10 GPIO_ACTIVE_LOW>; rts-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; - uart-has-rtscts; status = "okay"; };
@@ -746,7 +744,6 @@ pinctrl-0 = <&pinctrl_uart4>, <&pinctrl_uart4_gpio>; cts-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>; rts-gpios = <&gpio5 12 GPIO_ACTIVE_LOW>; - uart-has-rtscts; status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts index 31f4c735fe4f..ba0b3f507855 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts @@ -651,7 +651,6 @@ pinctrl-0 = <&pinctrl_uart1>, <&pinctrl_uart1_gpio>; rts-gpios = <&gpio4 10 GPIO_ACTIVE_LOW>; cts-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>; - uart-has-rtscts; status = "okay"; };
@@ -668,7 +667,6 @@ pinctrl-0 = <&pinctrl_uart3>, <&pinctrl_uart3_gpio>; rts-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>; cts-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; - uart-has-rtscts; status = "okay";
bluetooth { @@ -686,7 +684,6 @@ dtr-gpios = <&gpio4 3 GPIO_ACTIVE_LOW>; dsr-gpios = <&gpio4 4 GPIO_ACTIVE_LOW>; dcd-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>; - uart-has-rtscts; status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts index 19f6d2943d26..8e861b920d09 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts @@ -572,7 +572,6 @@ dtr-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>; dsr-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; dcd-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>; - uart-has-rtscts; status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts index dd4302ac1de4..e7362d7615bd 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts +++ b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts @@ -631,7 +631,6 @@ pinctrl-0 = <&pinctrl_uart3>, <&pinctrl_uart3_gpio>; rts-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>; cts-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; - uart-has-rtscts; status = "okay";
bluetooth { diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts index 06b4c93c5876..d68ef4f0726f 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts @@ -611,7 +611,6 @@ pinctrl-0 = <&pinctrl_uart3>, <&pinctrl_uart3_gpio>; cts-gpios = <&gpio3 21 GPIO_ACTIVE_LOW>; rts-gpios = <&gpio3 22 GPIO_ACTIVE_LOW>; - uart-has-rtscts; status = "okay";
bluetooth {
From: Frank Li Frank.Li@nxp.com
[ Upstream commit cfb47bf5a470bdd80e8ac2f7b2f3a34563ecd4ea ]
linux,keycode should be "linux,keycodes" according binding-doc Documentation/devicetree/bindings/input/fsl,scu-key.yaml
Fixes: f537ee7f1e76 ("arm64: dts: freescale: add i.MX8DXL SoC support") Signed-off-by: Frank Li Frank.Li@nxp.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/freescale/imx8dxl.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi index 5ddbda0b4def..f2c4d13b2f3c 100644 --- a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi @@ -157,7 +157,7 @@
sc_pwrkey: keys { compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key"; - linux,keycode = <KEY_POWER>; + linux,keycodes = <KEY_POWER>; wakeup-source; };
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit d784fc8be6814b31854f7b529919ca4506ff8066 ]
Theoretically the device might gone if its reference count drops to 0. This might be the case when we try to find the first physical node of the ACPI device. We need to keep reference to it until we get a result of the above mentioned call. Refactor the code to drop the reference count at the correct place.
While at it, move to acpi_dev_put() as symmetrical call to the acpi_dev_get_first_match_dev().
Fixes: 02527c3f2300 ("ASoC: amd: add Machine driver for Jadeite platform") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Link: https://lore.kernel.org/r/20230112112356.67643-1-andriy.shevchenko@linux.int... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/amd/acp-es8336.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sound/soc/amd/acp-es8336.c b/sound/soc/amd/acp-es8336.c index 2fe8df86053a..89499542c803 100644 --- a/sound/soc/amd/acp-es8336.c +++ b/sound/soc/amd/acp-es8336.c @@ -198,9 +198,11 @@ static int st_es8336_late_probe(struct snd_soc_card *card) int ret;
adev = acpi_dev_get_first_match_dev("ESSX8336", NULL, -1); - if (adev) - put_device(&adev->dev); + if (!adev) + return -ENODEV; + codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); if (!codec_dev) dev_err(card->dev, "can not find codec dev\n");
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 6b1c0bd6fdefbf3c3d75680c2708f5423ef72e46 ]
Theoretically the device might gone if its reference count drops to 0. This might be the case when we try to find the first physical node of the ACPI device. We need to keep reference to it until we get a result of the above mentioned call. Refactor the code to drop the reference count at the correct place.
While at it, move to acpi_dev_put() as symmetrical call to the acpi_dev_get_first_match_dev().
Fixes: 3c22a73fb873 ("ASoC: Intel: bytcht_es8316: fix HID handling") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20230112112852.67714-2-andriy.shevchenko@linux.int... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/boards/bytcht_es8316.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index a935c5fd9edb..4dd37848b30e 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -497,21 +497,28 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) if (adev) { snprintf(codec_name, sizeof(codec_name), "i2c-%s", acpi_dev_name(adev)); - put_device(&adev->dev); byt_cht_es8316_dais[dai_index].codecs->name = codec_name; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); return -ENXIO; }
+ codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); + if (!codec_dev) + return -EPROBE_DEFER; + priv->codec_dev = get_device(codec_dev); + /* override platform name, if required */ byt_cht_es8316_card.dev = dev; platform_name = mach->mach_params.platform;
ret = snd_soc_fixup_dai_links_platform_name(&byt_cht_es8316_card, platform_name); - if (ret) + if (ret) { + put_device(codec_dev); return ret; + }
/* Check for BYTCR or other platform and setup quirks */ dmi_id = dmi_first_match(byt_cht_es8316_quirk_table); @@ -539,13 +546,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
/* get the clock */ priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3"); - if (IS_ERR(priv->mclk)) + if (IS_ERR(priv->mclk)) { + put_device(codec_dev); return dev_err_probe(dev, PTR_ERR(priv->mclk), "clk_get pmc_plt_clk_3 failed\n"); - - codec_dev = acpi_get_first_physical_node(adev); - if (!codec_dev) - return -EPROBE_DEFER; - priv->codec_dev = get_device(codec_dev); + }
if (quirk & BYT_CHT_ES8316_JD_INVERTED) props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted");
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 721858823d7cdc8f2a897579b040e935989f6f02 ]
Theoretically the device might gone if its reference count drops to 0. This might be the case when we try to find the first physical node of the ACPI device. We need to keep reference to it until we get a result of the above mentioned call. Refactor the code to drop the reference count at the correct place.
While at it, move to acpi_dev_put() as symmetrical call to the acpi_dev_get_first_match_dev().
Fixes: 02c0a3b3047f ("ASoC: Intel: bytcr_rt5651: add MCLK, quirks and cleanups") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20230112112852.67714-3-andriy.shevchenko@linux.int... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/boards/bytcr_rt5651.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 2beb686768f2..d74d184e1c7f 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -922,7 +922,6 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) if (adev) { snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name), "i2c-%s", acpi_dev_name(adev)); - put_device(&adev->dev); byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); @@ -930,6 +929,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) }
codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); if (!codec_dev) return -EPROBE_DEFER; priv->codec_dev = get_device(codec_dev);
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit cbf87bcf46e399e9a5288430d940efbad3551c68 ]
Theoretically the device might gone if its reference count drops to 0. This might be the case when we try to find the first physical node of the ACPI device. We need to keep reference to it until we get a result of the above mentioned call. Refactor the code to drop the reference count at the correct place.
While at it, move to acpi_dev_put() as symmetrical call to the acpi_dev_get_first_match_dev().
Fixes: a232b96dcece ("ASoC: Intel: bytcr_rt5640: use HID translation util") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20230112112852.67714-4-andriy.shevchenko@linux.int... 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, 6 insertions(+), 6 deletions(-)
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index ddd2625bed90..4f46f52c38e4 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -1626,13 +1626,18 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) if (adev) { snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name), "i2c-%s", acpi_dev_name(adev)); - put_device(&adev->dev); byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); return -ENXIO; }
+ codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); + if (!codec_dev) + return -EPROBE_DEFER; + priv->codec_dev = get_device(codec_dev); + /* * swap SSP0 if bytcr is detected * (will be overridden if DMI quirk is detected) @@ -1707,11 +1712,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) byt_rt5640_quirk = quirk_override; }
- codec_dev = acpi_get_first_physical_node(adev); - if (!codec_dev) - return -EPROBE_DEFER; - priv->codec_dev = get_device(codec_dev); - if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) { acpi_dev_add_driver_gpios(ACPI_COMPANION(priv->codec_dev), byt_rt5640_hp_elitepad_1000g2_gpios);
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit c8aa49abdeda2ab587aadb083e670f6aa0236f93 ]
Theoretically the device might gone if its reference count drops to 0. This might be the case when we try to find the first physical node of the ACPI device. We need to keep reference to it until we get a result of the above mentioned call. Refactor the code to drop the reference count at the correct place.
While at it, move to acpi_dev_put() as symmetrical call to the acpi_dev_get_first_match_dev().
Fixes: 9a87fc1e0619 ("ASoC: Intel: bytcr_wm5102: Add machine driver for BYT/WM5102") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20230112112852.67714-5-andriy.shevchenko@linux.int... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/boards/bytcr_wm5102.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 45a6805787f5..f8da1bcd010e 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -411,9 +411,9 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) return -ENOENT; } snprintf(codec_name, sizeof(codec_name), "spi-%s", acpi_dev_name(adev)); - put_device(&adev->dev);
codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, codec_name); + acpi_dev_put(adev); if (!codec_dev) return -EPROBE_DEFER;
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 64e57b2195725c1ae2246a8a2ce224abb60620ac ]
Theoretically the device might gone if its reference count drops to 0. This might be the case when we try to find the first physical node of the ACPI device. We need to keep reference to it until we get a result of the above mentioned call. Refactor the code to drop the reference count at the correct place.
While at it, move to acpi_dev_put() as symmetrical call to the acpi_dev_get_first_match_dev().
Fixes: a164137ce91a ("ASoC: Intel: add machine driver for SOF+ES8336") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20230112112852.67714-6-andriy.shevchenko@linux.int... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/boards/sof_es8336.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c index 773e5d1d87d4..894b6610b9e2 100644 --- a/sound/soc/intel/boards/sof_es8336.c +++ b/sound/soc/intel/boards/sof_es8336.c @@ -681,7 +681,6 @@ static int sof_es8336_probe(struct platform_device *pdev) if (adev) { snprintf(codec_name, sizeof(codec_name), "i2c-%s", acpi_dev_name(adev)); - put_device(&adev->dev); dai_links[0].codecs->name = codec_name;
/* also fixup codec dai name if relevant */ @@ -692,16 +691,19 @@ static int sof_es8336_probe(struct platform_device *pdev) return -ENXIO; }
- ret = snd_soc_fixup_dai_links_platform_name(&sof_es8336_card, - mach->mach_params.platform); - if (ret) - return ret; - codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); if (!codec_dev) return -EPROBE_DEFER; priv->codec_dev = get_device(codec_dev);
+ ret = snd_soc_fixup_dai_links_platform_name(&sof_es8336_card, + mach->mach_params.platform); + if (ret) { + put_device(codec_dev); + return ret; + } + if (quirk & SOF_ES8336_JD_INVERTED) props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted");
From: Amadeusz Sławiński amadeuszx.slawinski@linux.intel.com
[ Upstream commit f89d783d68dcc6b2ce4fe3bda972ae0f84df0dca ]
On shutdown reference to i915 driver needs to be released to not spam logs with unnecessary warnings. While at it do some additional cleanup to make sure DSP is powered down and interrupts from device are disabled.
Fixes: 1affc44ea5dd ("ASoC: Intel: avs: PCI driver implementation") Reported-by: Kornel Dulęba korneld@google.com Signed-off-by: Amadeusz Sławiński amadeuszx.slawinski@linux.intel.com Reviewed-by: Cezary Rojewski cezary.rojewski@intel.com Link: https://lore.kernel.org/r/20230113190310.1451693-2-amadeuszx.slawinski@linux... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/avs/core.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 4f93639ce488..5bb3eee2f783 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -476,6 +476,29 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) return ret; }
+static void avs_pci_shutdown(struct pci_dev *pci) +{ + struct hdac_bus *bus = pci_get_drvdata(pci); + struct avs_dev *adev = hdac_to_avs(bus); + + cancel_work_sync(&adev->probe_work); + avs_ipc_block(adev->ipc); + + snd_hdac_stop_streams(bus); + avs_dsp_op(adev, int_control, false); + snd_hdac_ext_bus_ppcap_int_enable(bus, false); + snd_hdac_ext_bus_link_power_down_all(bus); + + snd_hdac_bus_stop_chip(bus); + snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false); + + if (avs_platattr_test(adev, CLDMA)) + pci_free_irq(pci, 0, &code_loader); + pci_free_irq(pci, 0, adev); + pci_free_irq(pci, 0, bus); + pci_free_irq_vectors(pci); +} + static void avs_pci_remove(struct pci_dev *pci) { struct hdac_device *hdev, *save; @@ -679,6 +702,7 @@ static struct pci_driver avs_pci_driver = { .id_table = avs_ids, .probe = avs_pci_probe, .remove = avs_pci_remove, + .shutdown = avs_pci_shutdown, .driver = { .pm = &avs_dev_pm, },
From: Peter Xu peterx@redhat.com
[ Upstream commit 0ca2c535f5a07f01118a6a70bfab78576e02fcae ]
__USE_GNU should be an internal macro only used inside glibc. Either memfd_create() or fallocate() requires _GNU_SOURCE per man page, where __USE_GNU will further be defined by glibc headers include/features.h:
#ifdef _GNU_SOURCE # define __USE_GNU 1 #endif
This fixes:
hugetlb-madvise.c:20: warning: "__USE_GNU" redefined
20 | #define __USE_GNU | In file included from /usr/include/x86_64-linux-gnu/bits/libc-header-start.h:33, from /usr/include/stdlib.h:26, from hugetlb-madvise.c:16: /usr/include/features.h:407: note: this is the location of the previous definition 407 | # define __USE_GNU 1 |
Link: https://lkml.kernel.org/r/Y8V9z+z6Tk7NetI3@x1n Signed-off-by: Peter Xu peterx@redhat.com Reported-by: kernel test robot lkp@intel.com Cc: Mike Kravetz mike.kravetz@oracle.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/vm/hugetlb-madvise.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/tools/testing/selftests/vm/hugetlb-madvise.c b/tools/testing/selftests/vm/hugetlb-madvise.c index 3c9943131881..b3f01f1f7a60 100644 --- a/tools/testing/selftests/vm/hugetlb-madvise.c +++ b/tools/testing/selftests/vm/hugetlb-madvise.c @@ -16,7 +16,6 @@ #include <stdio.h> #include <unistd.h> #include <sys/mman.h> -#define __USE_GNU #include <fcntl.h>
#define USAGE "USAGE: %s <hugepagefile_name>\n"
From: Hou Tao houtao1@huawei.com
[ Upstream commit 36024d023d139a0c8b552dc3b7f4dc7b4c139e8f ]
According to the definition of sizes[NUM_CACHES], when the size passed to bpf_mem_cache_size() is 256, it should return 6 instead 7.
Fixes: 7c8199e24fa0 ("bpf: Introduce any context BPF specific memory allocator.") Signed-off-by: Hou Tao houtao1@huawei.com Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/r/20230118084630.3750680-1-houtao@huaweicloud.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/memalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/bpf/memalloc.c b/kernel/bpf/memalloc.c index 4901fa1048cd..6187c28d266f 100644 --- a/kernel/bpf/memalloc.c +++ b/kernel/bpf/memalloc.c @@ -71,7 +71,7 @@ static int bpf_mem_cache_idx(size_t size) if (size <= 192) return size_index[(size - 1) / 8] - 1;
- return fls(size - 1) - 1; + return fls(size - 1) - 2; }
#define NUM_CACHES 11
From: Yonghong Song yhs@fb.com
[ Upstream commit bdb7fdb0aca8b96cef9995d3a57e251c2289322f ]
In current bpf_send_signal() and bpf_send_signal_thread() helper implementation, irq_work is used to handle nmi context. Hao Sun reported in [1] that the current task at the entry of the helper might be gone during irq_work callback processing. To fix the issue, a reference is acquired for the current task before enqueuing into the irq_work so that the queued task is still available during irq_work callback processing.
[1] https://lore.kernel.org/bpf/20230109074425.12556-1-sunhao.th@gmail.com/
Fixes: 8b401f9ed244 ("bpf: implement bpf_send_signal() helper") Tested-by: Hao Sun sunhao.th@gmail.com Reported-by: Hao Sun sunhao.th@gmail.com Signed-off-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/r/20230118204815.3331855-1-yhs@fb.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/trace/bpf_trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index eb8c117cc8b6..9d4163abadf4 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -832,6 +832,7 @@ static void do_bpf_send_signal(struct irq_work *entry)
work = container_of(entry, struct send_signal_irq_work, irq_work); group_send_sig_info(work->sig, SEND_SIG_PRIV, work->task, work->type); + put_task_struct(work->task); }
static int bpf_send_signal_common(u32 sig, enum pid_type type) @@ -866,7 +867,7 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type) * to the irq_work. The current task may change when queued * irq works get executed. */ - work->task = current; + work->task = get_task_struct(current); work->sig = sig; work->type = type; irq_work_queue(&work->irq_work);
From: Artemii Karasev karasev@ispras.ru
[ Upstream commit b9cee506da2b7920b5ea02ccd8e78a907d0ee7aa ]
snd_hda_get_connections() can return a negative error code. It may lead to accessing 'conn' array at a negative index.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Artemii Karasev karasev@ispras.ru Fixes: 30b4503378c9 ("ALSA: hda - Expose secret DAC-AA connection of some VIA codecs") Link: https://lore.kernel.org/r/20230119082259.3634-1-karasev@ispras.ru Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/pci/hda/patch_via.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index aea7fae2ca4b..2994f85bc1b9 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -819,6 +819,9 @@ static int add_secret_dac_path(struct hda_codec *codec) return 0; nums = snd_hda_get_connections(codec, spec->gen.mixer_nid, conn, ARRAY_SIZE(conn) - 1); + if (nums < 0) + return nums; + for (i = 0; i < nums; i++) { if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT) return 0;
From: Eduard Zingerman eddyz87@gmail.com
[ Upstream commit 71f656a50176915d6813751188b5758daa8d012b ]
Register range information is copied in several places. The intent is to transfer range/id information from one register/stack spill to another. Currently this is done using direct register assignment, e.g.:
static void find_equal_scalars(..., struct bpf_reg_state *known_reg) { ... struct bpf_reg_state *reg; ... *reg = *known_reg; ... }
However, such assignments also copy the following bpf_reg_state fields:
struct bpf_reg_state { ... struct bpf_reg_state *parent; ... enum bpf_reg_liveness live; ... };
Copying of these fields is accidental and incorrect, as could be demonstrated by the following example:
0: call ktime_get_ns() 1: r6 = r0 2: call ktime_get_ns() 3: r7 = r0 4: if r0 > r6 goto +1 ; r0 & r6 are unbound thus generated ; branch states are identical 5: *(u64 *)(r10 - 8) = 0xdeadbeef ; 64-bit write to fp[-8] --- checkpoint --- 6: r1 = 42 ; r1 marked as written 7: *(u8 *)(r10 - 8) = r1 ; 8-bit write, fp[-8] parent & live ; overwritten 8: r2 = *(u64 *)(r10 - 8) 9: r0 = 0 10: exit
This example is unsafe because 64-bit write to fp[-8] at (5) is conditional, thus not all bytes of fp[-8] are guaranteed to be set when it is read at (8). However, currently the example passes verification.
First, the execution path 1-10 is examined by verifier. Suppose that a new checkpoint is created by is_state_visited() at (6). After checkpoint creation: - r1.parent points to checkpoint.r1, - fp[-8].parent points to checkpoint.fp[-8]. At (6) the r1.live is set to REG_LIVE_WRITTEN. At (7) the fp[-8].parent is set to r1.parent and fp[-8].live is set to REG_LIVE_WRITTEN, because of the following code called in check_stack_write_fixed_off():
static void save_register_state(struct bpf_func_state *state, int spi, struct bpf_reg_state *reg, int size) { ... state->stack[spi].spilled_ptr = *reg; // <--- parent & live copied if (size == BPF_REG_SIZE) state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN; ... }
Note the intent to mark stack spill as written only if 8 bytes are spilled to a slot, however this intent is spoiled by a 'live' field copy. At (8) the checkpoint.fp[-8] should be marked as REG_LIVE_READ but this does not happen: - fp[-8] in a current state is already marked as REG_LIVE_WRITTEN; - fp[-8].parent points to checkpoint.r1, parentage chain is used by mark_reg_read() to mark checkpoint states. At (10) the verification is finished for path 1-10 and jump 4-6 is examined. The checkpoint.fp[-8] never gets REG_LIVE_READ mark and this spill is pruned from the cached states by clean_live_states(). Hence verifier state obtained via path 1-4,6 is deemed identical to one obtained via path 1-6 and program marked as safe.
Note: the example should be executed with BPF_F_TEST_STATE_FREQ flag set to force creation of intermediate verifier states.
This commit revisits the locations where bpf_reg_state instances are copied and replaces the direct copies with a call to a function copy_register_state(dst, src) that preserves 'parent' and 'live' fields of the 'dst'.
Fixes: 679c782de14b ("bpf/verifier: per-register parent pointers") Signed-off-by: Eduard Zingerman eddyz87@gmail.com Link: https://lore.kernel.org/r/20230106142214.1040390-2-eddyz87@gmail.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/verifier.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 398a0008aff7..82f2da71eb35 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -3011,13 +3011,24 @@ static bool __is_pointer_value(bool allow_ptr_leaks, return reg->type != SCALAR_VALUE; }
+/* Copy src state preserving dst->parent and dst->live fields */ +static void copy_register_state(struct bpf_reg_state *dst, const struct bpf_reg_state *src) +{ + struct bpf_reg_state *parent = dst->parent; + enum bpf_reg_liveness live = dst->live; + + *dst = *src; + dst->parent = parent; + dst->live = live; +} + static void save_register_state(struct bpf_func_state *state, int spi, struct bpf_reg_state *reg, int size) { int i;
- state->stack[spi].spilled_ptr = *reg; + copy_register_state(&state->stack[spi].spilled_ptr, reg); if (size == BPF_REG_SIZE) state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN;
@@ -3345,7 +3356,7 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env, */ s32 subreg_def = state->regs[dst_regno].subreg_def;
- state->regs[dst_regno] = *reg; + copy_register_state(&state->regs[dst_regno], reg); state->regs[dst_regno].subreg_def = subreg_def; } else { for (i = 0; i < size; i++) { @@ -3366,7 +3377,7 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
if (dst_regno >= 0) { /* restore register state from stack */ - state->regs[dst_regno] = *reg; + copy_register_state(&state->regs[dst_regno], reg); /* mark reg as written since spilled pointer state likely * has its liveness marks cleared by is_state_visited() * which resets stack/reg liveness for state transitions @@ -8085,7 +8096,7 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, */ if (!ptr_is_dst_reg) { tmp = *dst_reg; - *dst_reg = *ptr_reg; + copy_register_state(dst_reg, ptr_reg); } ret = sanitize_speculative_path(env, NULL, env->insn_idx + 1, env->insn_idx); @@ -9338,7 +9349,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) * to propagate min/max range. */ src_reg->id = ++env->id_gen; - *dst_reg = *src_reg; + copy_register_state(dst_reg, src_reg); dst_reg->live |= REG_LIVE_WRITTEN; dst_reg->subreg_def = DEF_NOT_SUBREG; } else { @@ -9349,7 +9360,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) insn->src_reg); return -EACCES; } else if (src_reg->type == SCALAR_VALUE) { - *dst_reg = *src_reg; + copy_register_state(dst_reg, src_reg); /* Make sure ID is cleared otherwise * dst_reg min/max could be incorrectly * propagated into src_reg by find_equal_scalars() @@ -10145,7 +10156,7 @@ static void find_equal_scalars(struct bpf_verifier_state *vstate,
bpf_for_each_reg_in_vstate(vstate, state, reg, ({ if (reg->type == SCALAR_VALUE && reg->id == known_reg->id) - *reg = *known_reg; + copy_register_state(reg, known_reg); })); }
From: Pengfei Xu pengfei.xu@intel.com
[ Upstream commit 24b5308cf5ee9f52dd22f3af78a5b0cdc9d35e72 ]
When use tools/testing/selftests/kselftest_install.sh to make the kselftest-list.txt under tools/testing/selftests/kselftest_install.
Then use tools/testing/selftests/kselftest_install/run_kselftest.sh to run all the kselftests in kselftest-list.txt, it will be blocked by case "filesystems/fat: run_fat_tests.sh" with "Warning: file run_fat_tests.sh is not executable", so grant executable permission to run_fat_tests.sh to fix this issue.
Link: https://lkml.kernel.org/r/dfdbba6df8a1ab34bb1e81cd8bd7ca3f9ed5c369.167342474... Fixes: dd7c9be330d8 ("selftests/filesystems: add a vfat RENAME_EXCHANGE test") Signed-off-by: Pengfei Xu pengfei.xu@intel.com Reviewed-by: Javier Martinez Canillas javierm@redhat.com Cc: Shuah Khan shuah@kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/filesystems/fat/run_fat_tests.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/testing/selftests/filesystems/fat/run_fat_tests.sh
diff --git a/tools/testing/selftests/filesystems/fat/run_fat_tests.sh b/tools/testing/selftests/filesystems/fat/run_fat_tests.sh old mode 100644 new mode 100755
From: Dan Carpenter error27@gmail.com
[ Upstream commit ea57680af47587397f5005d7758022441ed66d54 ]
The "id" comes from the user. Change the type to unsigned to prevent an array underflow.
Fixes: f4ea22f7aa75 ("ASoC: SOF: ipc4: Add support for mtrace log extraction") Signed-off-by: Dan Carpenter error27@gmail.com Acked-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Link: https://lore.kernel.org/r/Y8laruWOEwOC/dx9@kili Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sof/ipc4-mtrace.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/sound/soc/sof/ipc4-mtrace.c b/sound/soc/sof/ipc4-mtrace.c index 70dea8ae706e..0ec6ef681012 100644 --- a/sound/soc/sof/ipc4-mtrace.c +++ b/sound/soc/sof/ipc4-mtrace.c @@ -344,9 +344,10 @@ static ssize_t sof_ipc4_priority_mask_dfs_write(struct file *file, size_t count, loff_t *ppos) { struct sof_mtrace_priv *priv = file->private_data; - int id, ret; + unsigned int id; char *buf; u32 mask; + int ret;
/* * To update Nth mask entry, write: @@ -357,9 +358,9 @@ static ssize_t sof_ipc4_priority_mask_dfs_write(struct file *file, if (IS_ERR(buf)) return PTR_ERR(buf);
- ret = sscanf(buf, "%d,0x%x", &id, &mask); + ret = sscanf(buf, "%u,0x%x", &id, &mask); if (ret != 2) { - ret = sscanf(buf, "%d,%x", &id, &mask); + ret = sscanf(buf, "%u,%x", &id, &mask); if (ret != 2) { ret = -EINVAL; goto out;
From: Jiri Olsa jolsa@kernel.org
[ Upstream commit 74bc3a5acc82f020d2e126f56c535d02d1e74e37 ]
We take the BTF reference before we register dtors and we need to put it back when it's done.
We probably won't se a problem with kernel BTF, but module BTF would stay loaded (because of the extra ref) even when its module is removed.
Cc: Kumar Kartikeya Dwivedi memxor@gmail.com Fixes: 5ce937d613a4 ("bpf: Populate pairs of btf_id and destructor kfunc in btf") Acked-by: Kumar Kartikeya Dwivedi memxor@gmail.com Signed-off-by: Jiri Olsa jolsa@kernel.org Link: https://lore.kernel.org/r/20230120122148.1522359-1-jolsa@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/btf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index efdbba2a0230..a7c2f0c3fc19 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -7607,9 +7607,9 @@ int register_btf_id_dtor_kfuncs(const struct btf_id_dtor_kfunc *dtors, u32 add_c
sort(tab->dtors, tab->cnt, sizeof(tab->dtors[0]), btf_id_cmp_func, NULL);
- return 0; end: - btf_free_dtor_kfunc_tab(btf); + if (ret) + btf_free_dtor_kfunc_tab(btf); btf_put(btf); return ret; }
From: Hans Verkuil hverkuil-cisco@xs4all.nl
[ Upstream commit a1550700629f30c5bd554161524f14f14600d554 ]
The patch that fixed string control support somehow got mangled when it was merged in mainline: the added line ended up in the wrong place.
Fix this.
Fixes: 73278d483378 ("media: v4l2-ctrls-api.c: add back dropped ctrl->is_new = 1") 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/v4l2-core/v4l2-ctrls-api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c index 3d3b6dc24ca6..002ea6588edf 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-api.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c @@ -150,8 +150,8 @@ static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) * then return an error. */ if (strlen(ctrl->p_new.p_char) == ctrl->maximum && last) - ctrl->is_new = 1; return -ERANGE; + ctrl->is_new = 1; } return ret; default:
From: Jakub Sitnicki jakub@cloudflare.com
[ Upstream commit ddce1e091757d0259107c6c0c7262df201de2b66 ]
A listening socket linked to a sockmap has its sk_prot overridden. It points to one of the struct proto variants in tcp_bpf_prots. The variant depends on the socket's family and which sockmap programs are attached.
A child socket cloned from a TCP listener initially inherits their sk_prot. But before cloning is finished, we restore the child's proto to the listener's original non-tcp_bpf_prots one. This happens in tcp_create_openreq_child -> tcp_bpf_clone.
Today, in tcp_bpf_clone we detect if the child's proto should be restored by checking only for the TCP_BPF_BASE proto variant. This is not correct. The sk_prot of listening socket linked to a sockmap can point to to any variant in tcp_bpf_prots.
If the listeners sk_prot happens to be not the TCP_BPF_BASE variant, then the child socket unintentionally is left if the inherited sk_prot by tcp_bpf_clone.
This leads to issues like infinite recursion on close [1], because the child state is otherwise not set up for use with tcp_bpf_prot operations.
Adjust the check in tcp_bpf_clone to detect all of tcp_bpf_prots variants.
Note that it wouldn't be sufficient to check the socket state when overriding the sk_prot in tcp_bpf_update_proto in order to always use the TCP_BPF_BASE variant for listening sockets. Since commit b8b8315e39ff ("bpf, sockmap: Remove unhash handler for BPF sockmap usage") it is possible for a socket to transition to TCP_LISTEN state while already linked to a sockmap, e.g. connect() -> insert into map -> connect(AF_UNSPEC) -> listen().
[1]: https://lore.kernel.org/all/00000000000073b14905ef2e7401@google.com/
Fixes: e80251555f0b ("tcp_bpf: Don't let child socket inherit parent protocol ops on copy") Reported-by: syzbot+04c21ed96d861dccc5cd@syzkaller.appspotmail.com Signed-off-by: Jakub Sitnicki jakub@cloudflare.com Acked-by: John Fastabend john.fastabend@gmail.com Link: https://lore.kernel.org/r/20230113-sockmap-fix-v2-2-1e0ee7ac2f90@cloudflare.... Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/util_macros.h | 12 ++++++++++++ net/ipv4/tcp_bpf.c | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/include/linux/util_macros.h b/include/linux/util_macros.h index 72299f261b25..43db6e47503c 100644 --- a/include/linux/util_macros.h +++ b/include/linux/util_macros.h @@ -38,4 +38,16 @@ */ #define find_closest_descending(x, a, as) __find_closest(x, a, as, >=)
+/** + * is_insidevar - check if the @ptr points inside the @var memory range. + * @ptr: the pointer to a memory address. + * @var: the variable which address and size identify the memory range. + * + * Evaluates to true if the address in @ptr lies within the memory + * range allocated to @var. + */ +#define is_insidevar(ptr, var) \ + ((uintptr_t)(ptr) >= (uintptr_t)(var) && \ + (uintptr_t)(ptr) < (uintptr_t)(var) + sizeof(var)) + #endif diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c index 94aad3870c5f..cf26d65ca389 100644 --- a/net/ipv4/tcp_bpf.c +++ b/net/ipv4/tcp_bpf.c @@ -6,6 +6,7 @@ #include <linux/bpf.h> #include <linux/init.h> #include <linux/wait.h> +#include <linux/util_macros.h>
#include <net/inet_common.h> #include <net/tls.h> @@ -639,10 +640,9 @@ EXPORT_SYMBOL_GPL(tcp_bpf_update_proto); */ void tcp_bpf_clone(const struct sock *sk, struct sock *newsk) { - int family = sk->sk_family == AF_INET6 ? TCP_BPF_IPV6 : TCP_BPF_IPV4; struct proto *prot = newsk->sk_prot;
- if (prot == &tcp_bpf_prots[family][TCP_BPF_BASE]) + if (is_insidevar(prot, tcp_bpf_prots)) newsk->sk_prot = sk->sk_prot_creator; } #endif /* CONFIG_BPF_SYSCALL */
From: Pierluigi Passaro pierluigi.p@variscite.com
[ Upstream commit 47123900f3e4a7f769631d6ec15abf44086276f6 ]
According section 8.2.5.313 Select Input Register (IOMUXC_UART1_RXD_SELECT_INPUT) of i.MX 8M Mini Applications Processor Reference Manual, Rev. 3, 11/2020 the required setting for this specific pin configuration is "1"
Signed-off-by: Pierluigi Passaro pierluigi.p@variscite.com Reviewed-by: Fabio Estevam festevam@gmail.com Fixes: c1c9d41319c3 ("dt-bindings: imx: Add pinctrl binding doc for imx8mm") Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h index 83c8f715cd90..b1f11098d248 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h +++ b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h @@ -602,7 +602,7 @@ #define MX8MM_IOMUXC_UART1_RXD_GPIO5_IO22 0x234 0x49C 0x000 0x5 0x0 #define MX8MM_IOMUXC_UART1_RXD_TPSMP_HDATA24 0x234 0x49C 0x000 0x7 0x0 #define MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x238 0x4A0 0x000 0x0 0x0 -#define MX8MM_IOMUXC_UART1_TXD_UART1_DTE_RX 0x238 0x4A0 0x4F4 0x0 0x0 +#define MX8MM_IOMUXC_UART1_TXD_UART1_DTE_RX 0x238 0x4A0 0x4F4 0x0 0x1 #define MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI 0x238 0x4A0 0x000 0x1 0x0 #define MX8MM_IOMUXC_UART1_TXD_GPIO5_IO23 0x238 0x4A0 0x000 0x5 0x0 #define MX8MM_IOMUXC_UART1_TXD_TPSMP_HDATA25 0x238 0x4A0 0x000 0x7 0x0
From: Philippe Schenker philippe.schenker@toradex.com
[ Upstream commit 39c95d0c357d7ef76aea958c1bece6b24f9b2e7e ]
Currently if suspending using either freeze or memory state, the fec driver tries to power down the phy which leads to crash of the kernel and non-responsible kernel with the following call trace:
[ 24.839889 ] Call trace: [ 24.839892 ] phy_error+0x18/0x60 [ 24.839898 ] kszphy_handle_interrupt+0x6c/0x80 [ 24.839903 ] phy_interrupt+0x20/0x2c [ 24.839909 ] irq_thread_fn+0x30/0xa0 [ 24.839919 ] irq_thread+0x178/0x2c0 [ 24.839925 ] kthread+0x154/0x160 [ 24.839932 ] ret_from_fork+0x10/0x20
Since there is currently no functionality in the phy subsystem to power down phys let's just disable the feature of powering-down the ethernet phy.
Fixes: 6a57f224f734 ("arm64: dts: freescale: add initial support for verdin imx8m mini") Signed-off-by: Philippe Schenker philippe.schenker@toradex.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi index bcab830c6e95..59445f916d7f 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi @@ -98,6 +98,7 @@ off-on-delay = <500000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_reg_eth>; + regulator-always-on; regulator-boot-on; regulator-max-microvolt = <3300000>; regulator-min-microvolt = <3300000>;
From: Hans Verkuil hverkuil-cisco@xs4all.nl
[ Upstream commit 51128c3f2a7c98055ea1d27e34910dc10977f618 ]
The bcm2711 has two HDMI outputs, each with their own CEC adapter. The CEC adapter name has to be unique, but it is currently hardcoded to "vc4" for both outputs. Change this to use the card_name from the variant information in order to make the adapter name unique.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Fixes: 15b4511a4af6 ("drm/vc4: add HDMI CEC support") Signed-off-by: Maxime Ripard maxime@cerno.tech Link: https://patchwork.freedesktop.org/patch/msgid/dcf1db75-d9cc-62cc-fa12-baf1b2... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hdmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 470432c8fd70..c4b73d9dd040 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -3009,7 +3009,8 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) }
vc4_hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops, - vc4_hdmi, "vc4", + vc4_hdmi, + vc4_hdmi->variant->card_name, CEC_CAP_DEFAULTS | CEC_CAP_CONNECTOR_INFO, 1); ret = PTR_ERR_OR_ZERO(vc4_hdmi->cec_adap);
From: Javier Martinez Canillas javierm@redhat.com
[ Upstream commit 343c700480982214dc4f834f536a49a4098e556a ]
Commit 622113b9f11f ("drm/ssd130x: Replace simple display helpers with the atomic helpers") changed the driver to just use the atomic helpers instead of the simple KMS abstraction layer.
But the commit also made a subtle change on the display power sequence and initialization order, by moving the ssd130x_power_on() call to the encoder .atomic_enable handler and the ssd130x_init() call to CRTC .reset handler.
Before this change, both ssd130x_power_on() and ssd130x_init() were called in the simple display pipeline .enable handler, so the display was already initialized by the time the SSD130X_DISPLAY_ON command was sent.
For some reasons, it only made the ssd130x SPI driver to fail but the I2C was still working. That is the reason why the bug was not noticed before.
To revert to the old driver behavior, move the ssd130x_init() call to the encoder .atomic_enable as well. Besides fixing the panel not being turned on when using SPI, it also gets rid of the custom CRTC .reset callback.
Fixes: 622113b9f11f ("drm/ssd130x: Replace simple display helpers with the atomic helpers") Signed-off-by: Javier Martinez Canillas javierm@redhat.com Reviewed-by: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/20230125184230.3343206-1-javie... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/solomon/ssd130x.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index bc41a5ae810a..4bb3a247732d 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -665,18 +665,8 @@ static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs = { .atomic_check = ssd130x_crtc_helper_atomic_check, };
-static void ssd130x_crtc_reset(struct drm_crtc *crtc) -{ - struct drm_device *drm = crtc->dev; - struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); - - ssd130x_init(ssd130x); - - drm_atomic_helper_crtc_reset(crtc); -} - static const struct drm_crtc_funcs ssd130x_crtc_funcs = { - .reset = ssd130x_crtc_reset, + .reset = drm_atomic_helper_crtc_reset, .destroy = drm_crtc_cleanup, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, @@ -695,6 +685,12 @@ static void ssd130x_encoder_helper_atomic_enable(struct drm_encoder *encoder, if (ret) return;
+ ret = ssd130x_init(ssd130x); + if (ret) { + ssd130x_power_off(ssd130x); + return; + } + ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_ON);
backlight_enable(ssd130x->bl_dev);
From: Martin K. Petersen martin.petersen@oracle.com
[ Upstream commit 15600159bcc6abbeae6b33a849bef90dca28b78f ]
This reverts commit 948e922fc44611ee2de0c89583ca958cb5307d36.
Not all targets that return PQ=1 and PDT=0 should be ignored. While the SCSI spec is vague in this department, there appears to be a critical mass of devices which rely on devices being accessible with this combination of reported values.
Fixes: 948e922fc446 ("scsi: core: map PQ=1, PDT=other values to SCSI_SCAN_TARGET_PRESENT") Link: https://lore.kernel.org/r/yq1lelrleqr.fsf@ca-mkp.ca.oracle.com Acked-by: Bart Van Assche bvanassche@acm.org Acked-by: Martin Wilck mwilck@suse.com Acked-by: Hannes Reinecke hare@suse.de Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/scsi_scan.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 5d27f5196de6..d149b218715e 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1233,8 +1233,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, * that no LUN is present, so don't add sdev in these cases. * Two specific examples are: * 1) NetApp targets: return PQ=1, PDT=0x1f - * 2) IBM/2145 targets: return PQ=1, PDT=0 - * 3) USB UFI: returns PDT=0x1f, with the PQ bits being "reserved" + * 2) USB UFI: returns PDT=0x1f, with the PQ bits being "reserved" * in the UFI 1.0 spec (we cannot rely on reserved bits). * * References: @@ -1248,8 +1247,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, * PDT=00h Direct-access device (floppy) * PDT=1Fh none (no FDD connected to the requested logical unit) */ - if (((result[0] >> 5) == 1 || - (starget->pdt_1f_for_no_lun && (result[0] & 0x1f) == 0x1f)) && + if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) && + (result[0] & 0x1f) == 0x1f && !scsi_is_wlun(lun)) { SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev, "scsi scan: peripheral device type"
From: Kui-Feng Lee kuifeng@meta.com
[ Upstream commit 5416c9aea8323583e8696f0500b6142dfae80821 ]
The kernel crash was caused by a BPF program attached to the "lsm_cgroup/socket_sock_rcv_skb" hook, which performed a call to `bpf_setsockopt()` in order to set the TCP_NODELAY flag as an example. Flags like TCP_NODELAY can prompt the kernel to flush a socket's outgoing queue, and this hook "lsm_cgroup/socket_sock_rcv_skb" is frequently triggered by softirqs. The issue was that in certain circumstances, when `tcp_write_xmit()` was called to flush the queue, it would also allow BH (bottom-half) to run. This could lead to our program attempting to flush the same socket recursively, which caused a `skbuff` to be unlinked twice.
`security_sock_rcv_skb()` is triggered by `tcp_filter()`. This occurs before the sock ownership is checked in `tcp_v4_rcv()`. Consequently, if a bpf program runs on `security_sock_rcv_skb()` while under softirq conditions, it may not possess the lock needed for `bpf_setsockopt()`, thus presenting an issue.
The patch fixes this issue by ensuring that a BPF program attached to the "lsm_cgroup/socket_sock_rcv_skb" hook is not allowed to call `bpf_setsockopt()`.
The differences from v1 are - changing commit log to explain holding the lock of the sock, - emphasizing that TCP_NODELAY is not the only flag, and - adding the fixes tag.
v1: https://lore.kernel.org/bpf/20230125000244.1109228-1-kuifeng@meta.com/
Signed-off-by: Kui-Feng Lee kuifeng@meta.com Fixes: 9113d7e48e91 ("bpf: expose bpf_{g,s}etsockopt to lsm cgroup") Link: https://lore.kernel.org/r/20230127001732.4162630-1-kuifeng@meta.com Signed-off-by: Martin KaFai Lau martin.lau@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/bpf_lsm.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c index d6c9b3705f24..e6a76da4bca7 100644 --- a/kernel/bpf/bpf_lsm.c +++ b/kernel/bpf/bpf_lsm.c @@ -51,7 +51,6 @@ BTF_SET_END(bpf_lsm_current_hooks) */ BTF_SET_START(bpf_lsm_locked_sockopt_hooks) #ifdef CONFIG_SECURITY_NETWORK -BTF_ID(func, bpf_lsm_socket_sock_rcv_skb) BTF_ID(func, bpf_lsm_sock_graft) BTF_ID(func, bpf_lsm_inet_csk_clone) BTF_ID(func, bpf_lsm_inet_conn_established)
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 53466ebdec614f915c691809b0861acecb941e30 ]
We change recently the memalloc helper to use dma_alloc_noncontiguous() and the fallback to get_pages(). Although lots of issues with IOMMU (or non-IOMMU) have been addressed, but there seems still a regression on Xen PV. Interestingly, the only proper way to work is use dma_alloc_coherent(). The use of dma_alloc_coherent() for SG buffer was dropped as it's problematic on IOMMU systems. OTOH, Xen PV has a different way, and it's fine to use the dma_alloc_coherent().
This patch is a workaround for Xen PV. It consists of the following changes: - For Xen PV, use only the fallback allocation without dma_alloc_noncontiguous() - In the fallback allocation, use dma_alloc_coherent(); the DMA address from dma_alloc_coherent() is returned in get_addr ops - The DMA addresses are stored in an array; the first entry stores the number of allocated pages in lower bits, which are referred at releasing pages again
Reported-by: Marek Marczykowski-Górecki marmarek@invisiblethingslab.com Tested-by: Marek Marczykowski-Górecki marmarek@invisiblethingslab.com Fixes: a8d302a0b770 ("ALSA: memalloc: Revive x86-specific WC page allocations again") Fixes: 9736a325137b ("ALSA: memalloc: Don't fall back for SG-buffer with IOMMU") Link: https://lore.kernel.org/r/87tu256lqs.wl-tiwai@suse.de Link: https://lore.kernel.org/r/20230125153104.5527-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/core/memalloc.c | 87 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 18 deletions(-)
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 7268304009ad..11ff1ee51345 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -542,16 +542,15 @@ static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size) struct sg_table *sgt; void *p;
+#ifdef CONFIG_SND_DMA_SGBUF + if (cpu_feature_enabled(X86_FEATURE_XENPV)) + return snd_dma_sg_fallback_alloc(dmab, size); +#endif sgt = dma_alloc_noncontiguous(dmab->dev.dev, size, dmab->dev.dir, DEFAULT_GFP, 0); #ifdef CONFIG_SND_DMA_SGBUF - if (!sgt && !get_dma_ops(dmab->dev.dev)) { - if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG) - dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK; - else - dmab->dev.type = SNDRV_DMA_TYPE_DEV_SG_FALLBACK; + if (!sgt && !get_dma_ops(dmab->dev.dev)) return snd_dma_sg_fallback_alloc(dmab, size); - } #endif if (!sgt) return NULL; @@ -718,19 +717,38 @@ static const struct snd_malloc_ops snd_dma_sg_wc_ops = {
/* Fallback SG-buffer allocations for x86 */ struct snd_dma_sg_fallback { + bool use_dma_alloc_coherent; size_t count; struct page **pages; + /* DMA address array; the first page contains #pages in ~PAGE_MASK */ + dma_addr_t *addrs; };
static void __snd_dma_sg_fallback_free(struct snd_dma_buffer *dmab, struct snd_dma_sg_fallback *sgbuf) { - bool wc = dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK; - size_t i; - - for (i = 0; i < sgbuf->count && sgbuf->pages[i]; i++) - do_free_pages(page_address(sgbuf->pages[i]), PAGE_SIZE, wc); + size_t i, size; + + if (sgbuf->pages && sgbuf->addrs) { + i = 0; + while (i < sgbuf->count) { + if (!sgbuf->pages[i] || !sgbuf->addrs[i]) + break; + size = sgbuf->addrs[i] & ~PAGE_MASK; + if (WARN_ON(!size)) + break; + if (sgbuf->use_dma_alloc_coherent) + dma_free_coherent(dmab->dev.dev, size << PAGE_SHIFT, + page_address(sgbuf->pages[i]), + sgbuf->addrs[i] & PAGE_MASK); + else + do_free_pages(page_address(sgbuf->pages[i]), + size << PAGE_SHIFT, false); + i += size; + } + } kvfree(sgbuf->pages); + kvfree(sgbuf->addrs); kfree(sgbuf); }
@@ -739,24 +757,36 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size) struct snd_dma_sg_fallback *sgbuf; struct page **pagep, *curp; size_t chunk, npages; + dma_addr_t *addrp; dma_addr_t addr; void *p; - bool wc = dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK; + + /* correct the type */ + if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) + dmab->dev.type = SNDRV_DMA_TYPE_DEV_SG_FALLBACK; + else if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG) + dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK;
sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL); if (!sgbuf) return NULL; + sgbuf->use_dma_alloc_coherent = cpu_feature_enabled(X86_FEATURE_XENPV); size = PAGE_ALIGN(size); sgbuf->count = size >> PAGE_SHIFT; sgbuf->pages = kvcalloc(sgbuf->count, sizeof(*sgbuf->pages), GFP_KERNEL); - if (!sgbuf->pages) + sgbuf->addrs = kvcalloc(sgbuf->count, sizeof(*sgbuf->addrs), GFP_KERNEL); + if (!sgbuf->pages || !sgbuf->addrs) goto error;
pagep = sgbuf->pages; - chunk = size; + addrp = sgbuf->addrs; + chunk = (PAGE_SIZE - 1) << PAGE_SHIFT; /* to fit in low bits in addrs */ while (size > 0) { chunk = min(size, chunk); - p = do_alloc_pages(dmab->dev.dev, chunk, &addr, wc); + if (sgbuf->use_dma_alloc_coherent) + p = dma_alloc_coherent(dmab->dev.dev, chunk, &addr, DEFAULT_GFP); + else + p = do_alloc_pages(dmab->dev.dev, chunk, &addr, false); if (!p) { if (chunk <= PAGE_SIZE) goto error; @@ -768,17 +798,25 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size) size -= chunk; /* fill pages */ npages = chunk >> PAGE_SHIFT; + *addrp = npages; /* store in lower bits */ curp = virt_to_page(p); - while (npages--) + while (npages--) { *pagep++ = curp++; + *addrp++ |= addr; + addr += PAGE_SIZE; + } }
p = vmap(sgbuf->pages, sgbuf->count, VM_MAP, PAGE_KERNEL); if (!p) goto error; + + if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK) + set_pages_array_wc(sgbuf->pages, sgbuf->count); + dmab->private_data = sgbuf; /* store the first page address for convenience */ - dmab->addr = snd_sgbuf_get_addr(dmab, 0); + dmab->addr = sgbuf->addrs[0] & PAGE_MASK; return p;
error: @@ -788,10 +826,23 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size)
static void snd_dma_sg_fallback_free(struct snd_dma_buffer *dmab) { + struct snd_dma_sg_fallback *sgbuf = dmab->private_data; + + if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK) + set_pages_array_wb(sgbuf->pages, sgbuf->count); vunmap(dmab->area); __snd_dma_sg_fallback_free(dmab, dmab->private_data); }
+static dma_addr_t snd_dma_sg_fallback_get_addr(struct snd_dma_buffer *dmab, + size_t offset) +{ + struct snd_dma_sg_fallback *sgbuf = dmab->private_data; + size_t index = offset >> PAGE_SHIFT; + + return (sgbuf->addrs[index] & PAGE_MASK) | (offset & ~PAGE_MASK); +} + static int snd_dma_sg_fallback_mmap(struct snd_dma_buffer *dmab, struct vm_area_struct *area) { @@ -806,8 +857,8 @@ static const struct snd_malloc_ops snd_dma_sg_fallback_ops = { .alloc = snd_dma_sg_fallback_alloc, .free = snd_dma_sg_fallback_free, .mmap = snd_dma_sg_fallback_mmap, + .get_addr = snd_dma_sg_fallback_get_addr, /* reuse vmalloc helpers */ - .get_addr = snd_dma_vmalloc_get_addr, .get_page = snd_dma_vmalloc_get_page, .get_chunk_size = snd_dma_vmalloc_get_chunk_size, };
From: Eric Auger eric.auger@redhat.com
[ Upstream commit 9526f9a2b762af16be94a72aca5d65c677d28f50 ]
When the vhost iotlb is used along with a guest virtual iommu and the guest gets rebooted, some MISS messages may have been recorded just before the reboot and spuriously executed by the virtual iommu after the reboot.
As vhost does not have any explicit reset user API, VHOST_NET_SET_BACKEND looks a reasonable point where to clear the pending messages, in case the backend is removed.
Export vhost_clear_msg() and call it in vhost_net_set_backend() when fd == -1.
Signed-off-by: Eric Auger eric.auger@redhat.com Suggested-by: Jason Wang jasowang@redhat.com Fixes: 6b1e6cc7855b0 ("vhost: new device IOTLB API") Message-Id: 20230117151518.44725-3-eric.auger@redhat.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/vhost/net.c | 3 +++ drivers/vhost/vhost.c | 3 ++- drivers/vhost/vhost.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 20265393aee7..c7e44d818252 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -1511,6 +1511,9 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) nvq = &n->vqs[index]; mutex_lock(&vq->mutex);
+ if (fd == -1) + vhost_clear_msg(&n->dev); + /* Verify that ring has been setup correctly. */ if (!vhost_vq_access_ok(vq)) { r = -EFAULT; diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 3c2359570df9..547f89a6940f 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -661,7 +661,7 @@ void vhost_dev_stop(struct vhost_dev *dev) } EXPORT_SYMBOL_GPL(vhost_dev_stop);
-static void vhost_clear_msg(struct vhost_dev *dev) +void vhost_clear_msg(struct vhost_dev *dev) { struct vhost_msg_node *node, *n;
@@ -679,6 +679,7 @@ static void vhost_clear_msg(struct vhost_dev *dev)
spin_unlock(&dev->iotlb_lock); } +EXPORT_SYMBOL_GPL(vhost_clear_msg);
void vhost_dev_cleanup(struct vhost_dev *dev) { diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index d9109107af08..790b296271f1 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -181,6 +181,7 @@ long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, void __user *argp); long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp); bool vhost_vq_access_ok(struct vhost_virtqueue *vq); bool vhost_log_access_ok(struct vhost_dev *); +void vhost_clear_msg(struct vhost_dev *dev);
int vhost_get_vq_desc(struct vhost_virtqueue *, struct iovec iov[], unsigned int iov_count,
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit 0e1e4a2238d465199e8f11eb7a779bcb224a0505 ]
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Stable-dep-of: 6dd88fd59da8 ("vhost-scsi: unbreak any layout for response") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kernel/crash_dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index e4ef67e4da0a..a19a2763e8d4 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -153,7 +153,7 @@ int copy_oldmem_kernel(void *dst, unsigned long src, size_t count)
kvec.iov_base = dst; kvec.iov_len = count; - iov_iter_kvec(&iter, WRITE, &kvec, 1, count); + iov_iter_kvec(&iter, READ, &kvec, 1, count); if (copy_oldmem_iter(&iter, src, count) < count) return -EFAULT; return 0;
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit 974c36fb828aeae7b4f9063f94860ae6c5633efd ]
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Stable-dep-of: 6dd88fd59da8 ("vhost-scsi: unbreak any layout for response") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/fsi/fsi-sbefifo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c index 5f93a53846aa..efd4942aa043 100644 --- a/drivers/fsi/fsi-sbefifo.c +++ b/drivers/fsi/fsi-sbefifo.c @@ -659,7 +659,7 @@ static void sbefifo_collect_async_ffdc(struct sbefifo *sbefifo) } ffdc_iov.iov_base = ffdc; ffdc_iov.iov_len = SBEFIFO_MAX_FFDC_SIZE; - iov_iter_kvec(&ffdc_iter, WRITE, &ffdc_iov, 1, SBEFIFO_MAX_FFDC_SIZE); + iov_iter_kvec(&ffdc_iter, READ, &ffdc_iov, 1, SBEFIFO_MAX_FFDC_SIZE); cmd[0] = cpu_to_be32(2); cmd[1] = cpu_to_be32(SBEFIFO_CMD_GET_SBE_FFDC); rc = sbefifo_do_command(sbefifo, cmd, 2, &ffdc_iter); @@ -756,7 +756,7 @@ int sbefifo_submit(struct device *dev, const __be32 *command, size_t cmd_len, rbytes = (*resp_len) * sizeof(__be32); resp_iov.iov_base = response; resp_iov.iov_len = rbytes; - iov_iter_kvec(&resp_iter, WRITE, &resp_iov, 1, rbytes); + iov_iter_kvec(&resp_iter, READ, &resp_iov, 1, rbytes);
/* Perform the command */ rc = mutex_lock_interruptible(&sbefifo->lock); @@ -839,7 +839,7 @@ static ssize_t sbefifo_user_read(struct file *file, char __user *buf, /* Prepare iov iterator */ resp_iov.iov_base = buf; resp_iov.iov_len = len; - iov_iter_init(&resp_iter, WRITE, &resp_iov, 1, len); + iov_iter_init(&resp_iter, READ, &resp_iov, 1, len);
/* Perform the command */ rc = mutex_lock_interruptible(&sbefifo->lock);
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit 355d2c2798e9dc39f6714fa7ef8902c0d4c5350b ]
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Stable-dep-of: 6dd88fd59da8 ("vhost-scsi: unbreak any layout for response") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c index 8546b8816524..88282b288abd 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c @@ -966,7 +966,7 @@ static void rtrs_clt_init_req(struct rtrs_clt_io_req *req, refcount_set(&req->ref, 1); req->mp_policy = clt_path->clt->mp_policy;
- iov_iter_kvec(&iter, READ, vec, 1, usr_len); + iov_iter_kvec(&iter, WRITE, vec, 1, usr_len); len = _copy_from_iter(req->iu->buf, usr_len, &iter); WARN_ON(len != usr_len);
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit 4ba48e1bae5f68af24d8d71d4f28de9eb658af1d ]
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Stable-dep-of: 6dd88fd59da8 ("vhost-scsi: unbreak any layout for response") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/char/zcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 6165e6aae762..83ddac1e5838 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -103,7 +103,7 @@ static inline int memcpy_hsa_kernel(void *dst, unsigned long src, size_t count)
kvec.iov_base = dst; kvec.iov_len = count; - iov_iter_kvec(&iter, WRITE, &kvec, 1, count); + iov_iter_kvec(&iter, READ, &kvec, 1, count); if (memcpy_hsa_iter(&iter, src, count) < count) return -EIO; return 0;
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit 77729412acde120712f5793e9134c2b1cbd1ee02 ]
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Stable-dep-of: 6dd88fd59da8 ("vhost-scsi: unbreak any layout for response") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/mm/maccess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 1571cdcb0c50..753b006c8ea5 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -128,7 +128,7 @@ int memcpy_real(void *dest, unsigned long src, size_t count)
kvec.iov_base = dest; kvec.iov_len = count; - iov_iter_kvec(&iter, WRITE, &kvec, 1, count); + iov_iter_kvec(&iter, READ, &kvec, 1, count); if (memcpy_real_iter(&iter, src, count) < count) return -EFAULT; return 0;
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit b676668d99155e6859d99bbf2df18b3f03851902 ]
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Stable-dep-of: 6dd88fd59da8 ("vhost-scsi: unbreak any layout for response") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_file.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 28aa643be5d5..55935040541b 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -337,7 +337,7 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd, len += sg->length; }
- iov_iter_bvec(&iter, READ, bvec, sgl_nents, len); + iov_iter_bvec(&iter, is_write, bvec, sgl_nents, len); if (is_write) ret = vfs_iter_write(fd, &iter, &pos, 0); else @@ -473,7 +473,7 @@ fd_execute_write_same(struct se_cmd *cmd) len += se_dev->dev_attrib.block_size; }
- iov_iter_bvec(&iter, READ, bvec, nolb, len); + iov_iter_bvec(&iter, WRITE, bvec, nolb, len); ret = vfs_iter_write(fd_dev->fd_file, &iter, &pos, 0);
kfree(bvec);
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit e3bf3df824675ea9cadc3cd2c75d08ee83a6ae26 ]
READ means "data destination", WRITE - "data source".
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Stable-dep-of: 6dd88fd59da8 ("vhost-scsi: unbreak any layout for response") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/vhost/vhost.c | 6 +++--- drivers/vhost/vringh.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 547f89a6940f..c234869d6727 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -833,7 +833,7 @@ static int vhost_copy_to_user(struct vhost_virtqueue *vq, void __user *to, VHOST_ACCESS_WO); if (ret < 0) goto out; - iov_iter_init(&t, WRITE, vq->iotlb_iov, ret, size); + iov_iter_init(&t, READ, vq->iotlb_iov, ret, size); ret = copy_to_iter(from, size, &t); if (ret == size) ret = 0; @@ -872,7 +872,7 @@ static int vhost_copy_from_user(struct vhost_virtqueue *vq, void *to, (unsigned long long) size); goto out; } - iov_iter_init(&f, READ, vq->iotlb_iov, ret, size); + iov_iter_init(&f, WRITE, vq->iotlb_iov, ret, size); ret = copy_from_iter(to, size, &f); if (ret == size) ret = 0; @@ -2136,7 +2136,7 @@ static int get_indirect(struct vhost_virtqueue *vq, vq_err(vq, "Translation failure %d in indirect.\n", ret); return ret; } - iov_iter_init(&from, READ, vq->indirect, ret, len); + iov_iter_init(&from, WRITE, vq->indirect, ret, len); count = len / sizeof desc; /* Buffers are chained via a 16 bit next field, so * we can have at most 2^16 of these. */ diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c index 828c29306565..139c782848c6 100644 --- a/drivers/vhost/vringh.c +++ b/drivers/vhost/vringh.c @@ -1161,7 +1161,7 @@ static inline int copy_from_iotlb(const struct vringh *vrh, void *dst, else if (ret < 0) return ret;
- iov_iter_bvec(&iter, READ, iov, ret, translated); + iov_iter_bvec(&iter, WRITE, iov, ret, translated);
ret = copy_from_iter(dst, translated, &iter); if (ret < 0) @@ -1194,7 +1194,7 @@ static inline int copy_to_iotlb(const struct vringh *vrh, void *dst, else if (ret < 0) return ret;
- iov_iter_bvec(&iter, WRITE, iov, ret, translated); + iov_iter_bvec(&iter, READ, iov, ret, translated);
ret = copy_to_iter(src, translated, &iter); if (ret < 0)
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit fc02f33787d8dd227b54f263eba983d5b249c032 ]
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Stable-dep-of: 6dd88fd59da8 ("vhost-scsi: unbreak any layout for response") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/xen/pvcalls-back.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/xen/pvcalls-back.c b/drivers/xen/pvcalls-back.c index d6f945fd4147..21b9c850a382 100644 --- a/drivers/xen/pvcalls-back.c +++ b/drivers/xen/pvcalls-back.c @@ -129,13 +129,13 @@ static bool pvcalls_conn_back_read(void *opaque) if (masked_prod < masked_cons) { vec[0].iov_base = data->in + masked_prod; vec[0].iov_len = wanted; - iov_iter_kvec(&msg.msg_iter, WRITE, vec, 1, wanted); + iov_iter_kvec(&msg.msg_iter, READ, vec, 1, wanted); } else { vec[0].iov_base = data->in + masked_prod; vec[0].iov_len = array_size - masked_prod; vec[1].iov_base = data->in; vec[1].iov_len = wanted - vec[0].iov_len; - iov_iter_kvec(&msg.msg_iter, WRITE, vec, 2, wanted); + iov_iter_kvec(&msg.msg_iter, READ, vec, 2, wanted); }
atomic_set(&map->read, 0); @@ -188,13 +188,13 @@ static bool pvcalls_conn_back_write(struct sock_mapping *map) if (pvcalls_mask(prod, array_size) > pvcalls_mask(cons, array_size)) { vec[0].iov_base = data->out + pvcalls_mask(cons, array_size); vec[0].iov_len = size; - iov_iter_kvec(&msg.msg_iter, READ, vec, 1, size); + iov_iter_kvec(&msg.msg_iter, WRITE, vec, 1, size); } else { vec[0].iov_base = data->out + pvcalls_mask(cons, array_size); vec[0].iov_len = array_size - pvcalls_mask(cons, array_size); vec[1].iov_base = data->out; vec[1].iov_len = size - vec[0].iov_len; - iov_iter_kvec(&msg.msg_iter, READ, vec, 2, size); + iov_iter_kvec(&msg.msg_iter, WRITE, vec, 2, size); }
atomic_set(&map->write, 0);
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit de4eda9de2d957ef2d6a8365a01e26a435e958cb ]
READ/WRITE proved to be actively confusing - the meanings are "data destination, as used with read(2)" and "data source, as used with write(2)", but people keep interpreting those as "we read data from it" and "we write data to it", i.e. exactly the wrong way.
Call them ITER_DEST and ITER_SOURCE - at least that is harder to misinterpret...
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Stable-dep-of: 6dd88fd59da8 ("vhost-scsi: unbreak any layout for response") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kernel/crash_dump.c | 2 +- arch/s390/mm/maccess.c | 2 +- arch/x86/kernel/cpu/microcode/intel.c | 2 +- arch/x86/kernel/crash_dump_64.c | 2 +- crypto/testmgr.c | 4 ++-- drivers/acpi/pfr_update.c | 2 +- drivers/block/drbd/drbd_main.c | 2 +- drivers/block/drbd/drbd_receiver.c | 2 +- drivers/block/loop.c | 12 ++++++------ drivers/block/nbd.c | 10 +++++----- drivers/char/random.c | 4 ++-- drivers/fsi/fsi-sbefifo.c | 6 +++--- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 2 +- drivers/isdn/mISDN/l1oip_core.c | 2 +- drivers/misc/vmw_vmci/vmci_queue_pair.c | 6 +++--- drivers/net/ppp/ppp_generic.c | 2 +- drivers/nvme/host/tcp.c | 4 ++-- drivers/nvme/target/io-cmd-file.c | 4 ++-- drivers/nvme/target/tcp.c | 2 +- drivers/s390/char/zcore.c | 2 +- drivers/scsi/sg.c | 2 +- drivers/target/iscsi/iscsi_target_util.c | 4 ++-- drivers/target/target_core_file.c | 2 +- drivers/usb/usbip/usbip_common.c | 2 +- drivers/vhost/net.c | 6 +++--- drivers/vhost/scsi.c | 10 +++++----- drivers/vhost/vhost.c | 6 +++--- drivers/vhost/vringh.c | 4 ++-- drivers/vhost/vsock.c | 4 ++-- drivers/xen/pvcalls-back.c | 8 ++++---- fs/9p/vfs_addr.c | 4 ++-- fs/9p/vfs_dir.c | 2 +- fs/9p/xattr.c | 4 ++-- fs/afs/cmservice.c | 2 +- fs/afs/dir.c | 2 +- fs/afs/file.c | 4 ++-- fs/afs/internal.h | 4 ++-- fs/afs/rxrpc.c | 10 +++++----- fs/afs/write.c | 4 ++-- fs/aio.c | 4 ++-- fs/btrfs/ioctl.c | 4 ++-- fs/ceph/addr.c | 4 ++-- fs/ceph/file.c | 4 ++-- fs/cifs/connect.c | 6 +++--- fs/cifs/file.c | 4 ++-- fs/cifs/fscache.c | 4 ++-- fs/cifs/smb2ops.c | 4 ++-- fs/cifs/transport.c | 6 +++--- fs/coredump.c | 2 +- fs/erofs/fscache.c | 6 +++--- fs/fscache/io.c | 2 +- fs/fuse/ioctl.c | 4 ++-- fs/netfs/io.c | 6 +++--- fs/nfs/fscache.c | 4 ++-- fs/nfsd/vfs.c | 4 ++-- fs/ocfs2/cluster/tcp.c | 2 +- fs/orangefs/inode.c | 8 ++++---- fs/proc/vmcore.c | 6 +++--- fs/read_write.c | 12 ++++++------ fs/seq_file.c | 2 +- fs/splice.c | 10 +++++----- include/linux/uio.h | 3 +++ io_uring/net.c | 14 +++++++------- io_uring/rw.c | 10 +++++----- kernel/trace/trace_events_user.c | 2 +- mm/madvise.c | 2 +- mm/page_io.c | 4 ++-- mm/process_vm_access.c | 2 +- net/9p/client.c | 2 +- net/bluetooth/6lowpan.c | 2 +- net/bluetooth/a2mp.c | 2 +- net/bluetooth/smp.c | 2 +- net/ceph/messenger_v1.c | 4 ++-- net/ceph/messenger_v2.c | 14 +++++++------- net/compat.c | 3 ++- net/ipv4/tcp.c | 4 ++-- net/netfilter/ipvs/ip_vs_sync.c | 2 +- net/smc/smc_clc.c | 6 +++--- net/smc/smc_tx.c | 2 +- net/socket.c | 12 ++++++------ net/sunrpc/socklib.c | 6 +++--- net/sunrpc/svcsock.c | 4 ++-- net/sunrpc/xprtsock.c | 6 +++--- net/tipc/topsrv.c | 2 +- net/tls/tls_device.c | 4 ++-- net/xfrm/espintcp.c | 2 +- security/keys/keyctl.c | 4 ++-- 87 files changed, 195 insertions(+), 191 deletions(-)
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index a19a2763e8d4..c13b1455ec8c 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -153,7 +153,7 @@ int copy_oldmem_kernel(void *dst, unsigned long src, size_t count)
kvec.iov_base = dst; kvec.iov_len = count; - iov_iter_kvec(&iter, READ, &kvec, 1, count); + iov_iter_kvec(&iter, ITER_DEST, &kvec, 1, count); if (copy_oldmem_iter(&iter, src, count) < count) return -EFAULT; return 0; diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 753b006c8ea5..4824d1cd33d8 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -128,7 +128,7 @@ int memcpy_real(void *dest, unsigned long src, size_t count)
kvec.iov_base = dest; kvec.iov_len = count; - iov_iter_kvec(&iter, READ, &kvec, 1, count); + iov_iter_kvec(&iter, ITER_DEST, &kvec, 1, count); if (memcpy_real_iter(&iter, src, count) < count) return -EFAULT; return 0; diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 048e38ec99e7..1def66118b03 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -902,7 +902,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device,
kvec.iov_base = (void *)firmware->data; kvec.iov_len = firmware->size; - iov_iter_kvec(&iter, WRITE, &kvec, 1, firmware->size); + iov_iter_kvec(&iter, ITER_SOURCE, &kvec, 1, firmware->size); ret = generic_load_microcode(cpu, &iter);
release_firmware(firmware); diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c index e75bc2f217ff..32d710f7eb84 100644 --- a/arch/x86/kernel/crash_dump_64.c +++ b/arch/x86/kernel/crash_dump_64.c @@ -57,7 +57,7 @@ ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) struct kvec kvec = { .iov_base = buf, .iov_len = count }; struct iov_iter iter;
- iov_iter_kvec(&iter, READ, &kvec, 1, count); + iov_iter_kvec(&iter, ITER_DEST, &kvec, 1, count);
return read_from_oldmem(&iter, count, ppos, cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)); diff --git a/crypto/testmgr.c b/crypto/testmgr.c index bcd059caa1c8..814d2dc87d7e 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -766,7 +766,7 @@ static int build_cipher_test_sglists(struct cipher_test_sglists *tsgls, struct iov_iter input; int err;
- iov_iter_kvec(&input, WRITE, inputs, nr_inputs, src_total_len); + iov_iter_kvec(&input, ITER_SOURCE, inputs, nr_inputs, src_total_len); err = build_test_sglist(&tsgls->src, cfg->src_divs, alignmask, cfg->inplace_mode != OUT_OF_PLACE ? max(dst_total_len, src_total_len) : @@ -1180,7 +1180,7 @@ static int build_hash_sglist(struct test_sglist *tsgl,
kv.iov_base = (void *)vec->plaintext; kv.iov_len = vec->psize; - iov_iter_kvec(&input, WRITE, &kv, 1, vec->psize); + iov_iter_kvec(&input, ITER_SOURCE, &kv, 1, vec->psize); return build_test_sglist(tsgl, cfg->src_divs, alignmask, vec->psize, &input, divs); } diff --git a/drivers/acpi/pfr_update.c b/drivers/acpi/pfr_update.c index 9d2bdc13253a..98267f163e2b 100644 --- a/drivers/acpi/pfr_update.c +++ b/drivers/acpi/pfr_update.c @@ -455,7 +455,7 @@ static ssize_t pfru_write(struct file *file, const char __user *buf,
iov.iov_base = (void __user *)buf; iov.iov_len = len; - iov_iter_init(&iter, WRITE, &iov, 1, len); + iov_iter_init(&iter, ITER_SOURCE, &iov, 1, len);
/* map the communication buffer */ phy_addr = (phys_addr_t)((buf_info.addr_hi << 32) | buf_info.addr_lo); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 677240232684..590d1b50ab5d 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1816,7 +1816,7 @@ int drbd_send(struct drbd_connection *connection, struct socket *sock,
/* THINK if (signal_pending) return ... ? */
- iov_iter_kvec(&msg.msg_iter, WRITE, &iov, 1, size); + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, &iov, 1, size);
if (sock == connection->data.socket) { rcu_read_lock(); diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index ee69d50ba4fd..54010eac6ca9 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -507,7 +507,7 @@ static int drbd_recv_short(struct socket *sock, void *buf, size_t size, int flag struct msghdr msg = { .msg_flags = (flags ? flags : MSG_WAITALL | MSG_NOSIGNAL) }; - iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, size); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, size); return sock_recvmsg(sock, &msg, msg.msg_flags); }
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index d12d3d171ec4..df628e30bca4 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -243,7 +243,7 @@ static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos) struct iov_iter i; ssize_t bw;
- iov_iter_bvec(&i, WRITE, bvec, 1, bvec->bv_len); + iov_iter_bvec(&i, ITER_SOURCE, bvec, 1, bvec->bv_len);
file_start_write(file); bw = vfs_iter_write(file, &i, ppos, 0); @@ -286,7 +286,7 @@ static int lo_read_simple(struct loop_device *lo, struct request *rq, ssize_t len;
rq_for_each_segment(bvec, rq, iter) { - iov_iter_bvec(&i, READ, &bvec, 1, bvec.bv_len); + iov_iter_bvec(&i, ITER_DEST, &bvec, 1, bvec.bv_len); len = vfs_iter_read(lo->lo_backing_file, &i, &pos, 0); if (len < 0) return len; @@ -392,7 +392,7 @@ static void lo_rw_aio_complete(struct kiocb *iocb, long ret) }
static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, - loff_t pos, bool rw) + loff_t pos, int rw) { struct iov_iter iter; struct req_iterator rq_iter; @@ -448,7 +448,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, cmd->iocb.ki_flags = IOCB_DIRECT; cmd->iocb.ki_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0);
- if (rw == WRITE) + if (rw == ITER_SOURCE) ret = call_write_iter(file, &cmd->iocb, &iter); else ret = call_read_iter(file, &cmd->iocb, &iter); @@ -490,12 +490,12 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq) return lo_fallocate(lo, rq, pos, FALLOC_FL_PUNCH_HOLE); case REQ_OP_WRITE: if (cmd->use_aio) - return lo_rw_aio(lo, cmd, pos, WRITE); + return lo_rw_aio(lo, cmd, pos, ITER_SOURCE); else return lo_write_simple(lo, rq, pos); case REQ_OP_READ: if (cmd->use_aio) - return lo_rw_aio(lo, cmd, pos, READ); + return lo_rw_aio(lo, cmd, pos, ITER_DEST); else return lo_read_simple(lo, rq, pos); default: diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 5cffd96ef2d7..e379ccc63c52 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -563,7 +563,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) u32 nbd_cmd_flags = 0; int sent = nsock->sent, skip = 0;
- iov_iter_kvec(&from, WRITE, &iov, 1, sizeof(request)); + iov_iter_kvec(&from, ITER_SOURCE, &iov, 1, sizeof(request));
type = req_to_nbd_cmd_type(req); if (type == U32_MAX) @@ -649,7 +649,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
dev_dbg(nbd_to_dev(nbd), "request %p: sending %d bytes data\n", req, bvec.bv_len); - iov_iter_bvec(&from, WRITE, &bvec, 1, bvec.bv_len); + iov_iter_bvec(&from, ITER_SOURCE, &bvec, 1, bvec.bv_len); if (skip) { if (skip >= iov_iter_count(&from)) { skip -= iov_iter_count(&from); @@ -701,7 +701,7 @@ static int nbd_read_reply(struct nbd_device *nbd, int index, int result;
reply->magic = 0; - iov_iter_kvec(&to, READ, &iov, 1, sizeof(*reply)); + iov_iter_kvec(&to, ITER_DEST, &iov, 1, sizeof(*reply)); result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); if (result < 0) { if (!nbd_disconnected(nbd->config)) @@ -790,7 +790,7 @@ static struct nbd_cmd *nbd_handle_reply(struct nbd_device *nbd, int index, struct iov_iter to;
rq_for_each_segment(bvec, req, iter) { - iov_iter_bvec(&to, READ, &bvec, 1, bvec.bv_len); + iov_iter_bvec(&to, ITER_DEST, &bvec, 1, bvec.bv_len); result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); if (result < 0) { dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n", @@ -1267,7 +1267,7 @@ static void send_disconnects(struct nbd_device *nbd) for (i = 0; i < config->num_connections; i++) { struct nbd_sock *nsock = config->socks[i];
- iov_iter_kvec(&from, WRITE, &iov, 1, sizeof(request)); + iov_iter_kvec(&from, ITER_SOURCE, &iov, 1, sizeof(request)); mutex_lock(&nsock->tx_lock); ret = sock_xmit(nbd, i, 1, &from, 0, NULL); if (ret < 0) diff --git a/drivers/char/random.c b/drivers/char/random.c index f5868dddbb61..5d1c8e1c99b5 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1329,7 +1329,7 @@ SYSCALL_DEFINE3(getrandom, char __user *, ubuf, size_t, len, unsigned int, flags return ret; }
- ret = import_single_range(READ, ubuf, len, &iov, &iter); + ret = import_single_range(ITER_DEST, ubuf, len, &iov, &iter); if (unlikely(ret)) return ret; return get_random_bytes_user(&iter); @@ -1447,7 +1447,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) return -EINVAL; if (get_user(len, p++)) return -EFAULT; - ret = import_single_range(WRITE, p, len, &iov, &iter); + ret = import_single_range(ITER_SOURCE, p, len, &iov, &iter); if (unlikely(ret)) return ret; ret = write_pool_user(&iter); diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c index efd4942aa043..9912b7a6a4b9 100644 --- a/drivers/fsi/fsi-sbefifo.c +++ b/drivers/fsi/fsi-sbefifo.c @@ -659,7 +659,7 @@ static void sbefifo_collect_async_ffdc(struct sbefifo *sbefifo) } ffdc_iov.iov_base = ffdc; ffdc_iov.iov_len = SBEFIFO_MAX_FFDC_SIZE; - iov_iter_kvec(&ffdc_iter, READ, &ffdc_iov, 1, SBEFIFO_MAX_FFDC_SIZE); + iov_iter_kvec(&ffdc_iter, ITER_DEST, &ffdc_iov, 1, SBEFIFO_MAX_FFDC_SIZE); cmd[0] = cpu_to_be32(2); cmd[1] = cpu_to_be32(SBEFIFO_CMD_GET_SBE_FFDC); rc = sbefifo_do_command(sbefifo, cmd, 2, &ffdc_iter); @@ -756,7 +756,7 @@ int sbefifo_submit(struct device *dev, const __be32 *command, size_t cmd_len, rbytes = (*resp_len) * sizeof(__be32); resp_iov.iov_base = response; resp_iov.iov_len = rbytes; - iov_iter_kvec(&resp_iter, READ, &resp_iov, 1, rbytes); + iov_iter_kvec(&resp_iter, ITER_DEST, &resp_iov, 1, rbytes);
/* Perform the command */ rc = mutex_lock_interruptible(&sbefifo->lock); @@ -839,7 +839,7 @@ static ssize_t sbefifo_user_read(struct file *file, char __user *buf, /* Prepare iov iterator */ resp_iov.iov_base = buf; resp_iov.iov_len = len; - iov_iter_init(&resp_iter, READ, &resp_iov, 1, len); + iov_iter_init(&resp_iter, ITER_DEST, &resp_iov, 1, len);
/* Perform the command */ rc = mutex_lock_interruptible(&sbefifo->lock); diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c index 88282b288abd..730f2f1e09bb 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c @@ -966,7 +966,7 @@ static void rtrs_clt_init_req(struct rtrs_clt_io_req *req, refcount_set(&req->ref, 1); req->mp_policy = clt_path->clt->mp_policy;
- iov_iter_kvec(&iter, WRITE, vec, 1, usr_len); + iov_iter_kvec(&iter, ITER_SOURCE, vec, 1, usr_len); len = _copy_from_iter(req->iu->buf, usr_len, &iter); WARN_ON(len != usr_len);
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index a77195e378b7..c24771336f61 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -706,7 +706,7 @@ l1oip_socket_thread(void *data) printk(KERN_DEBUG "%s: socket created and open\n", __func__); while (!signal_pending(current)) { - iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, recvbuf_size); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, recvbuf_size); recvlen = sock_recvmsg(socket, &msg, 0); if (recvlen > 0) { l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen); diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c index 844264e1b88c..73d71c4ec139 100644 --- a/drivers/misc/vmw_vmci/vmci_queue_pair.c +++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c @@ -3044,7 +3044,7 @@ ssize_t vmci_qpair_enqueue(struct vmci_qp *qpair, if (!qpair || !buf) return VMCI_ERROR_INVALID_ARGS;
- iov_iter_kvec(&from, WRITE, &v, 1, buf_size); + iov_iter_kvec(&from, ITER_SOURCE, &v, 1, buf_size);
qp_lock(qpair);
@@ -3088,7 +3088,7 @@ ssize_t vmci_qpair_dequeue(struct vmci_qp *qpair, if (!qpair || !buf) return VMCI_ERROR_INVALID_ARGS;
- iov_iter_kvec(&to, READ, &v, 1, buf_size); + iov_iter_kvec(&to, ITER_DEST, &v, 1, buf_size);
qp_lock(qpair);
@@ -3133,7 +3133,7 @@ ssize_t vmci_qpair_peek(struct vmci_qp *qpair, if (!qpair || !buf) return VMCI_ERROR_INVALID_ARGS;
- iov_iter_kvec(&to, READ, &v, 1, buf_size); + iov_iter_kvec(&to, ITER_DEST, &v, 1, buf_size);
qp_lock(qpair);
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index d4c821c8cf57..1d71f5276241 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -480,7 +480,7 @@ static ssize_t ppp_read(struct file *file, char __user *buf, ret = -EFAULT; iov.iov_base = buf; iov.iov_len = count; - iov_iter_init(&to, READ, &iov, 1, count); + iov_iter_init(&to, ITER_DEST, &iov, 1, count); if (skb_copy_datagram_iter(skb, 0, &to, skb->len)) goto outf; ret = skb->len; diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index eacd445b5333..4c052c261517 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -301,7 +301,7 @@ static inline void nvme_tcp_advance_req(struct nvme_tcp_request *req, if (!iov_iter_count(&req->iter) && req->data_sent < req->data_len) { req->curr_bio = req->curr_bio->bi_next; - nvme_tcp_init_iter(req, WRITE); + nvme_tcp_init_iter(req, ITER_SOURCE); } }
@@ -781,7 +781,7 @@ static int nvme_tcp_recv_data(struct nvme_tcp_queue *queue, struct sk_buff *skb, nvme_tcp_init_recv_ctx(queue); return -EIO; } - nvme_tcp_init_iter(req, READ); + nvme_tcp_init_iter(req, ITER_DEST); }
/* we can read only from what is left in this bio */ diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c index e55ec6fefd7f..871c4f32f443 100644 --- a/drivers/nvme/target/io-cmd-file.c +++ b/drivers/nvme/target/io-cmd-file.c @@ -92,10 +92,10 @@ static ssize_t nvmet_file_submit_bvec(struct nvmet_req *req, loff_t pos, if (req->cmd->rw.control & cpu_to_le16(NVME_RW_FUA)) ki_flags |= IOCB_DSYNC; call_iter = req->ns->file->f_op->write_iter; - rw = WRITE; + rw = ITER_SOURCE; } else { call_iter = req->ns->file->f_op->read_iter; - rw = READ; + rw = ITER_DEST; }
iov_iter_bvec(&iter, rw, req->f.bvec, nr_segs, count); diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 6c1476e086ef..cc05c094de22 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -331,7 +331,7 @@ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd) sg_offset = 0; }
- iov_iter_bvec(&cmd->recv_msg.msg_iter, READ, cmd->iov, + iov_iter_bvec(&cmd->recv_msg.msg_iter, ITER_DEST, cmd->iov, nr_pages, cmd->pdu_len); }
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 83ddac1e5838..a41833557d55 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -103,7 +103,7 @@ static inline int memcpy_hsa_kernel(void *dst, unsigned long src, size_t count)
kvec.iov_base = dst; kvec.iov_len = count; - iov_iter_kvec(&iter, READ, &kvec, 1, count); + iov_iter_kvec(&iter, ITER_DEST, &kvec, 1, count); if (memcpy_hsa_iter(&iter, src, count) < count) return -EIO; return 0; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index ce34a8ad53b4..12344be14232 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1726,7 +1726,7 @@ sg_start_req(Sg_request *srp, unsigned char *cmd) Sg_scatter_hold *rsv_schp = &sfp->reserve; struct request_queue *q = sfp->parentdp->device->request_queue; struct rq_map_data *md, map_data; - int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? WRITE : READ; + int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? ITER_SOURCE : ITER_DEST; struct scsi_cmnd *scmd;
SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp, diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 8d9f21372b67..26dc8ed3045b 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -1225,7 +1225,7 @@ int rx_data( return -1;
memset(&msg, 0, sizeof(struct msghdr)); - iov_iter_kvec(&msg.msg_iter, READ, iov, iov_count, data); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, iov, iov_count, data);
while (msg_data_left(&msg)) { rx_loop = sock_recvmsg(conn->sock, &msg, MSG_WAITALL); @@ -1261,7 +1261,7 @@ int tx_data(
memset(&msg, 0, sizeof(struct msghdr));
- iov_iter_kvec(&msg.msg_iter, WRITE, iov, iov_count, data); + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, iov, iov_count, data);
while (msg_data_left(&msg)) { int tx_loop = sock_sendmsg(conn->sock, &msg); diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 55935040541b..7e81a53dbf3c 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -473,7 +473,7 @@ fd_execute_write_same(struct se_cmd *cmd) len += se_dev->dev_attrib.block_size; }
- iov_iter_bvec(&iter, WRITE, bvec, nolb, len); + iov_iter_bvec(&iter, ITER_SOURCE, bvec, nolb, len); ret = vfs_iter_write(fd_dev->fd_file, &iter, &pos, 0);
kfree(bvec); diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c index 053a2bca4c47..f8b326eed54d 100644 --- a/drivers/usb/usbip/usbip_common.c +++ b/drivers/usb/usbip/usbip_common.c @@ -309,7 +309,7 @@ int usbip_recv(struct socket *sock, void *buf, int size) if (!sock || !buf || !size) return -EINVAL;
- iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, size); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, size);
usbip_dbg_xmit("enter\n");
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index c7e44d818252..4c538b30fd76 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -611,7 +611,7 @@ static size_t init_iov_iter(struct vhost_virtqueue *vq, struct iov_iter *iter, /* Skip header. TODO: support TSO. */ size_t len = iov_length(vq->iov, out);
- iov_iter_init(iter, WRITE, vq->iov, out, len); + iov_iter_init(iter, ITER_SOURCE, vq->iov, out, len); iov_iter_advance(iter, hdr_size);
return iov_iter_count(iter); @@ -1184,14 +1184,14 @@ static void handle_rx(struct vhost_net *net) msg.msg_control = vhost_net_buf_consume(&nvq->rxq); /* On overrun, truncate and discard */ if (unlikely(headcount > UIO_MAXIOV)) { - iov_iter_init(&msg.msg_iter, READ, vq->iov, 1, 1); + iov_iter_init(&msg.msg_iter, ITER_DEST, vq->iov, 1, 1); err = sock->ops->recvmsg(sock, &msg, 1, MSG_DONTWAIT | MSG_TRUNC); pr_debug("Discarded rx packet: len %zd\n", sock_len); continue; } /* We don't need to be notified again. */ - iov_iter_init(&msg.msg_iter, READ, vq->iov, in, vhost_len); + iov_iter_init(&msg.msg_iter, ITER_DEST, vq->iov, in, vhost_len); fixup = msg.msg_iter; if (unlikely((vhost_hlen))) { /* We will supply the header ourselves diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 7ebf106d50c1..dca6346d75b3 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -563,7 +563,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) memcpy(v_rsp.sense, cmd->tvc_sense_buf, se_cmd->scsi_sense_length);
- iov_iter_init(&iov_iter, READ, &cmd->tvc_resp_iov, + iov_iter_init(&iov_iter, ITER_DEST, &cmd->tvc_resp_iov, cmd->tvc_in_iovs, sizeof(v_rsp)); ret = copy_to_iter(&v_rsp, sizeof(v_rsp), &iov_iter); if (likely(ret == sizeof(v_rsp))) { @@ -864,7 +864,7 @@ vhost_scsi_get_desc(struct vhost_scsi *vs, struct vhost_virtqueue *vq, * point at the start of the outgoing WRITE payload, if * DMA_TO_DEVICE is set. */ - iov_iter_init(&vc->out_iter, WRITE, vq->iov, vc->out, vc->out_size); + iov_iter_init(&vc->out_iter, ITER_SOURCE, vq->iov, vc->out, vc->out_size); ret = 0;
done: @@ -1016,7 +1016,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) data_direction = DMA_FROM_DEVICE; exp_data_len = vc.in_size - vc.rsp_size;
- iov_iter_init(&in_iter, READ, &vq->iov[vc.out], vc.in, + iov_iter_init(&in_iter, ITER_DEST, &vq->iov[vc.out], vc.in, vc.rsp_size + exp_data_len); iov_iter_advance(&in_iter, vc.rsp_size); data_iter = in_iter; @@ -1146,7 +1146,7 @@ vhost_scsi_send_tmf_resp(struct vhost_scsi *vs, struct vhost_virtqueue *vq, memset(&rsp, 0, sizeof(rsp)); rsp.response = tmf_resp_code;
- iov_iter_init(&iov_iter, READ, resp_iov, in_iovs, sizeof(rsp)); + iov_iter_init(&iov_iter, ITER_DEST, resp_iov, in_iovs, sizeof(rsp));
ret = copy_to_iter(&rsp, sizeof(rsp), &iov_iter); if (likely(ret == sizeof(rsp))) @@ -1238,7 +1238,7 @@ vhost_scsi_send_an_resp(struct vhost_scsi *vs, memset(&rsp, 0, sizeof(rsp)); /* event_actual = 0 */ rsp.response = VIRTIO_SCSI_S_OK;
- iov_iter_init(&iov_iter, READ, &vq->iov[vc->out], vc->in, sizeof(rsp)); + iov_iter_init(&iov_iter, ITER_DEST, &vq->iov[vc->out], vc->in, sizeof(rsp));
ret = copy_to_iter(&rsp, sizeof(rsp), &iov_iter); if (likely(ret == sizeof(rsp))) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index c234869d6727..43c9770b86e5 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -833,7 +833,7 @@ static int vhost_copy_to_user(struct vhost_virtqueue *vq, void __user *to, VHOST_ACCESS_WO); if (ret < 0) goto out; - iov_iter_init(&t, READ, vq->iotlb_iov, ret, size); + iov_iter_init(&t, ITER_DEST, vq->iotlb_iov, ret, size); ret = copy_to_iter(from, size, &t); if (ret == size) ret = 0; @@ -872,7 +872,7 @@ static int vhost_copy_from_user(struct vhost_virtqueue *vq, void *to, (unsigned long long) size); goto out; } - iov_iter_init(&f, WRITE, vq->iotlb_iov, ret, size); + iov_iter_init(&f, ITER_SOURCE, vq->iotlb_iov, ret, size); ret = copy_from_iter(to, size, &f); if (ret == size) ret = 0; @@ -2136,7 +2136,7 @@ static int get_indirect(struct vhost_virtqueue *vq, vq_err(vq, "Translation failure %d in indirect.\n", ret); return ret; } - iov_iter_init(&from, WRITE, vq->indirect, ret, len); + iov_iter_init(&from, ITER_SOURCE, vq->indirect, ret, len); count = len / sizeof desc; /* Buffers are chained via a 16 bit next field, so * we can have at most 2^16 of these. */ diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c index 139c782848c6..33eb941fcf15 100644 --- a/drivers/vhost/vringh.c +++ b/drivers/vhost/vringh.c @@ -1161,7 +1161,7 @@ static inline int copy_from_iotlb(const struct vringh *vrh, void *dst, else if (ret < 0) return ret;
- iov_iter_bvec(&iter, WRITE, iov, ret, translated); + iov_iter_bvec(&iter, ITER_SOURCE, iov, ret, translated);
ret = copy_from_iter(dst, translated, &iter); if (ret < 0) @@ -1194,7 +1194,7 @@ static inline int copy_to_iotlb(const struct vringh *vrh, void *dst, else if (ret < 0) return ret;
- iov_iter_bvec(&iter, READ, iov, ret, translated); + iov_iter_bvec(&iter, ITER_DEST, iov, ret, translated);
ret = copy_to_iter(src, translated, &iter); if (ret < 0) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index 10a7d23731fe..a2b374372363 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -165,7 +165,7 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock, break; }
- iov_iter_init(&iov_iter, READ, &vq->iov[out], in, iov_len); + iov_iter_init(&iov_iter, ITER_DEST, &vq->iov[out], in, iov_len); payload_len = pkt->len - pkt->off;
/* If the packet is greater than the space available in the @@ -371,7 +371,7 @@ vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq, return NULL;
len = iov_length(vq->iov, out); - iov_iter_init(&iov_iter, WRITE, vq->iov, out, len); + iov_iter_init(&iov_iter, ITER_SOURCE, vq->iov, out, len);
nbytes = copy_from_iter(&pkt->hdr, sizeof(pkt->hdr), &iov_iter); if (nbytes != sizeof(pkt->hdr)) { diff --git a/drivers/xen/pvcalls-back.c b/drivers/xen/pvcalls-back.c index 21b9c850a382..28b2a1fa25ab 100644 --- a/drivers/xen/pvcalls-back.c +++ b/drivers/xen/pvcalls-back.c @@ -129,13 +129,13 @@ static bool pvcalls_conn_back_read(void *opaque) if (masked_prod < masked_cons) { vec[0].iov_base = data->in + masked_prod; vec[0].iov_len = wanted; - iov_iter_kvec(&msg.msg_iter, READ, vec, 1, wanted); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, vec, 1, wanted); } else { vec[0].iov_base = data->in + masked_prod; vec[0].iov_len = array_size - masked_prod; vec[1].iov_base = data->in; vec[1].iov_len = wanted - vec[0].iov_len; - iov_iter_kvec(&msg.msg_iter, READ, vec, 2, wanted); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, vec, 2, wanted); }
atomic_set(&map->read, 0); @@ -188,13 +188,13 @@ static bool pvcalls_conn_back_write(struct sock_mapping *map) if (pvcalls_mask(prod, array_size) > pvcalls_mask(cons, array_size)) { vec[0].iov_base = data->out + pvcalls_mask(cons, array_size); vec[0].iov_len = size; - iov_iter_kvec(&msg.msg_iter, WRITE, vec, 1, size); + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, vec, 1, size); } else { vec[0].iov_base = data->out + pvcalls_mask(cons, array_size); vec[0].iov_len = array_size - pvcalls_mask(cons, array_size); vec[1].iov_base = data->out; vec[1].iov_len = size - vec[0].iov_len; - iov_iter_kvec(&msg.msg_iter, WRITE, vec, 2, size); + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, vec, 2, size); }
atomic_set(&map->write, 0); diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 47b9a1122f34..a19891015f19 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -40,7 +40,7 @@ static void v9fs_issue_read(struct netfs_io_subrequest *subreq) size_t len = subreq->len - subreq->transferred; int total, err;
- iov_iter_xarray(&to, READ, &rreq->mapping->i_pages, pos, len); + iov_iter_xarray(&to, ITER_DEST, &rreq->mapping->i_pages, pos, len);
total = p9_client_read(fid, pos, &to, &err);
@@ -172,7 +172,7 @@ static int v9fs_vfs_write_folio_locked(struct folio *folio)
len = min_t(loff_t, i_size - start, len);
- iov_iter_xarray(&from, WRITE, &folio_mapping(folio)->i_pages, start, len); + iov_iter_xarray(&from, ITER_SOURCE, &folio_mapping(folio)->i_pages, start, len);
/* We should have writeback_fid always set */ BUG_ON(!v9inode->writeback_fid); diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 000fbaae9b18..3bb95adc9619 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c @@ -109,7 +109,7 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx) struct iov_iter to; int n;
- iov_iter_kvec(&to, READ, &kvec, 1, buflen); + iov_iter_kvec(&to, ITER_DEST, &kvec, 1, buflen); n = p9_client_read(file->private_data, ctx->pos, &to, &err); if (err) diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c index 1f9298a4bd42..2807bb63f780 100644 --- a/fs/9p/xattr.c +++ b/fs/9p/xattr.c @@ -24,7 +24,7 @@ ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name, struct iov_iter to; int err;
- iov_iter_kvec(&to, READ, &kvec, 1, buffer_size); + iov_iter_kvec(&to, ITER_DEST, &kvec, 1, buffer_size);
attr_fid = p9_client_xattrwalk(fid, name, &attr_size); if (IS_ERR(attr_fid)) { @@ -109,7 +109,7 @@ int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name, struct iov_iter from; int retval, err;
- iov_iter_kvec(&from, WRITE, &kvec, 1, value_len); + iov_iter_kvec(&from, ITER_SOURCE, &kvec, 1, value_len);
p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu flags = %d\n", name, value_len, flags); diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index 0a090d614e76..7dcd59693a0c 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c @@ -298,7 +298,7 @@ static int afs_deliver_cb_callback(struct afs_call *call) if (call->count2 != call->count && call->count2 != 0) return afs_protocol_error(call, afs_eproto_cb_count); call->iter = &call->def_iter; - iov_iter_discard(&call->def_iter, READ, call->count2 * 3 * 4); + iov_iter_discard(&call->def_iter, ITER_DEST, call->count2 * 3 * 4); call->unmarshall++;
fallthrough; diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 230c2d19116d..104df2964225 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -305,7 +305,7 @@ static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key) req->actual_len = i_size; /* May change */ req->len = nr_pages * PAGE_SIZE; /* We can ask for more than there is */ req->data_version = dvnode->status.data_version; /* May change */ - iov_iter_xarray(&req->def_iter, READ, &dvnode->netfs.inode.i_mapping->i_pages, + iov_iter_xarray(&req->def_iter, ITER_DEST, &dvnode->netfs.inode.i_mapping->i_pages, 0, i_size); req->iter = &req->def_iter;
diff --git a/fs/afs/file.c b/fs/afs/file.c index d1cfb235c4b9..2eeab57df133 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -324,7 +324,7 @@ static void afs_issue_read(struct netfs_io_subrequest *subreq) fsreq->vnode = vnode; fsreq->iter = &fsreq->def_iter;
- iov_iter_xarray(&fsreq->def_iter, READ, + iov_iter_xarray(&fsreq->def_iter, ITER_DEST, &fsreq->vnode->netfs.inode.i_mapping->i_pages, fsreq->pos, fsreq->len);
@@ -346,7 +346,7 @@ static int afs_symlink_read_folio(struct file *file, struct folio *folio) fsreq->len = folio_size(folio); fsreq->vnode = vnode; fsreq->iter = &fsreq->def_iter; - iov_iter_xarray(&fsreq->def_iter, READ, &folio->mapping->i_pages, + iov_iter_xarray(&fsreq->def_iter, ITER_DEST, &folio->mapping->i_pages, fsreq->pos, fsreq->len);
ret = afs_fetch_data(fsreq->vnode, fsreq); diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 723d162078a3..9ba7b68375c9 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -1301,7 +1301,7 @@ static inline void afs_extract_begin(struct afs_call *call, void *buf, size_t si call->iov_len = size; call->kvec[0].iov_base = buf; call->kvec[0].iov_len = size; - iov_iter_kvec(&call->def_iter, READ, call->kvec, 1, size); + iov_iter_kvec(&call->def_iter, ITER_DEST, call->kvec, 1, size); }
static inline void afs_extract_to_tmp(struct afs_call *call) @@ -1319,7 +1319,7 @@ static inline void afs_extract_to_tmp64(struct afs_call *call) static inline void afs_extract_discard(struct afs_call *call, size_t size) { call->iov_len = size; - iov_iter_discard(&call->def_iter, READ, size); + iov_iter_discard(&call->def_iter, ITER_DEST, size); }
static inline void afs_extract_to_buf(struct afs_call *call, size_t size) diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index eccc3cd0cb70..c62939e5ea1f 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c @@ -359,7 +359,7 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
msg.msg_name = NULL; msg.msg_namelen = 0; - iov_iter_kvec(&msg.msg_iter, WRITE, iov, 1, call->request_size); + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, iov, 1, call->request_size); msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = MSG_WAITALL | (call->write_iter ? MSG_MORE : 0); @@ -400,7 +400,7 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp) RX_USER_ABORT, ret, "KSD"); } else { len = 0; - iov_iter_kvec(&msg.msg_iter, READ, NULL, 0, 0); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, NULL, 0, 0); rxrpc_kernel_recv_data(call->net->socket, rxcall, &msg.msg_iter, &len, false, &call->abort_code, &call->service_id); @@ -485,7 +485,7 @@ static void afs_deliver_to_call(struct afs_call *call) ) { if (state == AFS_CALL_SV_AWAIT_ACK) { len = 0; - iov_iter_kvec(&call->def_iter, READ, NULL, 0, 0); + iov_iter_kvec(&call->def_iter, ITER_DEST, NULL, 0, 0); ret = rxrpc_kernel_recv_data(call->net->socket, call->rxcall, &call->def_iter, &len, false, &remote_abort, @@ -822,7 +822,7 @@ void afs_send_empty_reply(struct afs_call *call)
msg.msg_name = NULL; msg.msg_namelen = 0; - iov_iter_kvec(&msg.msg_iter, WRITE, NULL, 0, 0); + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, NULL, 0, 0); msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; @@ -862,7 +862,7 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) iov[0].iov_len = len; msg.msg_name = NULL; msg.msg_namelen = 0; - iov_iter_kvec(&msg.msg_iter, WRITE, iov, 1, len); + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, iov, 1, len); msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; diff --git a/fs/afs/write.c b/fs/afs/write.c index 9ebdd36eaf2f..08fd456dde67 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -609,7 +609,7 @@ static ssize_t afs_write_back_from_locked_folio(struct address_space *mapping, */ afs_write_to_cache(vnode, start, len, i_size, caching);
- iov_iter_xarray(&iter, WRITE, &mapping->i_pages, start, len); + iov_iter_xarray(&iter, ITER_SOURCE, &mapping->i_pages, start, len); ret = afs_store_data(vnode, &iter, start, false); } else { _debug("write discard %x @%llx [%llx]", len, start, i_size); @@ -1000,7 +1000,7 @@ int afs_launder_folio(struct folio *folio) bv[0].bv_page = &folio->page; bv[0].bv_offset = f; bv[0].bv_len = t - f; - iov_iter_bvec(&iter, WRITE, bv, 1, bv[0].bv_len); + iov_iter_bvec(&iter, ITER_SOURCE, bv, 1, bv[0].bv_len);
trace_afs_folio_dirty(vnode, tracepoint_string("launder"), folio); ret = afs_store_data(vnode, &iter, folio_pos(folio) + f, true); diff --git a/fs/aio.c b/fs/aio.c index 5b2ff20ad322..562916d85cba 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -1552,7 +1552,7 @@ static int aio_read(struct kiocb *req, const struct iocb *iocb, if (unlikely(!file->f_op->read_iter)) return -EINVAL;
- ret = aio_setup_rw(READ, iocb, &iovec, vectored, compat, &iter); + ret = aio_setup_rw(ITER_DEST, iocb, &iovec, vectored, compat, &iter); if (ret < 0) return ret; ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter)); @@ -1580,7 +1580,7 @@ static int aio_write(struct kiocb *req, const struct iocb *iocb, if (unlikely(!file->f_op->write_iter)) return -EINVAL;
- ret = aio_setup_rw(WRITE, iocb, &iovec, vectored, compat, &iter); + ret = aio_setup_rw(ITER_SOURCE, iocb, &iovec, vectored, compat, &iter); if (ret < 0) return ret; ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter)); diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index fd1902573cde..c05f16a35bca 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -5283,7 +5283,7 @@ static int btrfs_ioctl_encoded_read(struct file *file, void __user *argp, goto out_acct; }
- ret = import_iovec(READ, args.iov, args.iovcnt, ARRAY_SIZE(iovstack), + ret = import_iovec(ITER_DEST, args.iov, args.iovcnt, ARRAY_SIZE(iovstack), &iov, &iter); if (ret < 0) goto out_acct; @@ -5382,7 +5382,7 @@ static int btrfs_ioctl_encoded_write(struct file *file, void __user *argp, bool if (args.len > args.unencoded_len - args.unencoded_offset) goto out_acct;
- ret = import_iovec(WRITE, args.iov, args.iovcnt, ARRAY_SIZE(iovstack), + ret = import_iovec(ITER_SOURCE, args.iov, args.iovcnt, ARRAY_SIZE(iovstack), &iov, &iter); if (ret < 0) goto out_acct; diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index dcf701b05cc1..61f47debec5a 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -288,7 +288,7 @@ static bool ceph_netfs_issue_op_inline(struct netfs_io_subrequest *subreq) }
len = min_t(size_t, iinfo->inline_len - subreq->start, subreq->len); - iov_iter_xarray(&iter, READ, &rreq->mapping->i_pages, subreq->start, len); + iov_iter_xarray(&iter, ITER_DEST, &rreq->mapping->i_pages, subreq->start, len); err = copy_to_iter(iinfo->inline_data + subreq->start, len, &iter); if (err == 0) err = -EFAULT; @@ -327,7 +327,7 @@ static void ceph_netfs_issue_read(struct netfs_io_subrequest *subreq) }
dout("%s: pos=%llu orig_len=%zu len=%llu\n", __func__, subreq->start, subreq->len, len); - iov_iter_xarray(&iter, READ, &rreq->mapping->i_pages, subreq->start, len); + iov_iter_xarray(&iter, ITER_DEST, &rreq->mapping->i_pages, subreq->start, len); err = iov_iter_get_pages_alloc2(&iter, &pages, len, &page_off); if (err < 0) { dout("%s: iov_ter_get_pages_alloc returned %d\n", __func__, err); diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 04fd34557de8..6f9580defb2b 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -1161,7 +1161,7 @@ static void ceph_aio_complete_req(struct ceph_osd_request *req) aio_req->total_len = rc + zlen; }
- iov_iter_bvec(&i, READ, osd_data->bvec_pos.bvecs, + iov_iter_bvec(&i, ITER_DEST, osd_data->bvec_pos.bvecs, osd_data->num_bvecs, len); iov_iter_advance(&i, rc); iov_iter_zero(zlen, &i); @@ -1400,7 +1400,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, int zlen = min_t(size_t, len - ret, size - pos - ret);
- iov_iter_bvec(&i, READ, bvecs, num_pages, len); + iov_iter_bvec(&i, ITER_DEST, bvecs, num_pages, len); iov_iter_advance(&i, ret); iov_iter_zero(zlen, &i); ret += zlen; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index eab36e4ea130..384c7c0e1088 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -761,7 +761,7 @@ cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, { struct msghdr smb_msg = {}; struct kvec iov = {.iov_base = buf, .iov_len = to_read}; - iov_iter_kvec(&smb_msg.msg_iter, READ, &iov, 1, to_read); + iov_iter_kvec(&smb_msg.msg_iter, ITER_DEST, &iov, 1, to_read);
return cifs_readv_from_socket(server, &smb_msg); } @@ -776,7 +776,7 @@ cifs_discard_from_socket(struct TCP_Server_Info *server, size_t to_read) * and cifs_readv_from_socket sets msg_control and msg_controllen * so little to initialize in struct msghdr */ - iov_iter_discard(&smb_msg.msg_iter, READ, to_read); + iov_iter_discard(&smb_msg.msg_iter, ITER_DEST, to_read);
return cifs_readv_from_socket(server, &smb_msg); } @@ -788,7 +788,7 @@ cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page, struct msghdr smb_msg = {}; struct bio_vec bv = { .bv_page = page, .bv_len = to_read, .bv_offset = page_offset}; - iov_iter_bvec(&smb_msg.msg_iter, READ, &bv, 1, to_read); + iov_iter_bvec(&smb_msg.msg_iter, ITER_DEST, &bv, 1, to_read); return cifs_readv_from_socket(server, &smb_msg); }
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index cd9698209930..209dfc06fd6d 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -3532,7 +3532,7 @@ static ssize_t __cifs_writev( ctx->iter = *from; ctx->len = len; } else { - rc = setup_aio_ctx_iter(ctx, from, WRITE); + rc = setup_aio_ctx_iter(ctx, from, ITER_SOURCE); if (rc) { kref_put(&ctx->refcount, cifs_aio_ctx_release); return rc; @@ -4276,7 +4276,7 @@ static ssize_t __cifs_readv( ctx->iter = *to; ctx->len = len; } else { - rc = setup_aio_ctx_iter(ctx, to, READ); + rc = setup_aio_ctx_iter(ctx, to, ITER_DEST); if (rc) { kref_put(&ctx->refcount, cifs_aio_ctx_release); return rc; diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c index a1751b956318..f6f3a6b75601 100644 --- a/fs/cifs/fscache.c +++ b/fs/cifs/fscache.c @@ -150,7 +150,7 @@ static int fscache_fallback_read_page(struct inode *inode, struct page *page) bvec[0].bv_page = page; bvec[0].bv_offset = 0; bvec[0].bv_len = PAGE_SIZE; - iov_iter_bvec(&iter, READ, bvec, ARRAY_SIZE(bvec), PAGE_SIZE); + iov_iter_bvec(&iter, ITER_DEST, bvec, ARRAY_SIZE(bvec), PAGE_SIZE);
ret = fscache_begin_read_operation(&cres, cookie); if (ret < 0) @@ -180,7 +180,7 @@ static int fscache_fallback_write_page(struct inode *inode, struct page *page, bvec[0].bv_page = page; bvec[0].bv_offset = 0; bvec[0].bv_len = PAGE_SIZE; - iov_iter_bvec(&iter, WRITE, bvec, ARRAY_SIZE(bvec), PAGE_SIZE); + iov_iter_bvec(&iter, ITER_SOURCE, bvec, ARRAY_SIZE(bvec), PAGE_SIZE);
ret = fscache_begin_write_operation(&cres, cookie); if (ret < 0) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 1ff5b6b0e07a..78c2d618eb51 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -4737,13 +4737,13 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, return 0; }
- iov_iter_bvec(&iter, WRITE, bvec, npages, data_len); + iov_iter_bvec(&iter, ITER_SOURCE, bvec, npages, data_len); } else if (buf_len >= data_offset + data_len) { /* read response payload is in buf */ WARN_ONCE(npages > 0, "read data can be either in buf or in pages"); iov.iov_base = buf + data_offset; iov.iov_len = data_len; - iov_iter_kvec(&iter, WRITE, &iov, 1, data_len); + iov_iter_kvec(&iter, ITER_SOURCE, &iov, 1, data_len); } else { /* read response payload cannot be in both buf and pages */ WARN_ONCE(1, "buf can not contain only a part of read data"); diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 575fa8f58342..3851d0aaa288 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -347,7 +347,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, .iov_base = &rfc1002_marker, .iov_len = 4 }; - iov_iter_kvec(&smb_msg.msg_iter, WRITE, &hiov, 1, 4); + iov_iter_kvec(&smb_msg.msg_iter, ITER_SOURCE, &hiov, 1, 4); rc = smb_send_kvec(server, &smb_msg, &sent); if (rc < 0) goto unmask; @@ -368,7 +368,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, size += iov[i].iov_len; }
- iov_iter_kvec(&smb_msg.msg_iter, WRITE, iov, n_vec, size); + iov_iter_kvec(&smb_msg.msg_iter, ITER_SOURCE, iov, n_vec, size);
rc = smb_send_kvec(server, &smb_msg, &sent); if (rc < 0) @@ -384,7 +384,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, rqst_page_get_length(&rqst[j], i, &bvec.bv_len, &bvec.bv_offset);
- iov_iter_bvec(&smb_msg.msg_iter, WRITE, + iov_iter_bvec(&smb_msg.msg_iter, ITER_SOURCE, &bvec, 1, bvec.bv_len); rc = smb_send_kvec(server, &smb_msg, &sent); if (rc < 0) diff --git a/fs/coredump.c b/fs/coredump.c index 7bad7785e8e6..095ed821c8ac 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -853,7 +853,7 @@ static int dump_emit_page(struct coredump_params *cprm, struct page *page) if (dump_interrupted()) return 0; pos = file->f_pos; - iov_iter_bvec(&iter, WRITE, &bvec, 1, PAGE_SIZE); + iov_iter_bvec(&iter, ITER_SOURCE, &bvec, 1, PAGE_SIZE); n = __kernel_write_iter(cprm->file, &iter, &pos); if (n != PAGE_SIZE) return 0; diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index 6a792a513d6b..b04f93bc062a 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -194,7 +194,7 @@ static int erofs_fscache_read_folios_async(struct fscache_cookie *cookie,
atomic_inc(&rreq->nr_outstanding);
- iov_iter_xarray(&iter, READ, &rreq->mapping->i_pages, + iov_iter_xarray(&iter, ITER_DEST, &rreq->mapping->i_pages, start + done, subreq->len);
ret = fscache_read(cres, subreq->start, &iter, @@ -290,7 +290,7 @@ static int erofs_fscache_data_read(struct address_space *mapping, if (IS_ERR(src)) return PTR_ERR(src);
- iov_iter_xarray(&iter, READ, &mapping->i_pages, pos, PAGE_SIZE); + iov_iter_xarray(&iter, ITER_DEST, &mapping->i_pages, pos, PAGE_SIZE); if (copy_to_iter(src + offset, size, &iter) != size) { erofs_put_metabuf(&buf); return -EFAULT; @@ -302,7 +302,7 @@ static int erofs_fscache_data_read(struct address_space *mapping,
if (!(map.m_flags & EROFS_MAP_MAPPED)) { count = len; - iov_iter_xarray(&iter, READ, &mapping->i_pages, pos, count); + iov_iter_xarray(&iter, ITER_DEST, &mapping->i_pages, pos, count); iov_iter_zero(count, &iter); return count; } diff --git a/fs/fscache/io.c b/fs/fscache/io.c index 3af3b08a9bb3..0d2b8dec8f82 100644 --- a/fs/fscache/io.c +++ b/fs/fscache/io.c @@ -286,7 +286,7 @@ void __fscache_write_to_cache(struct fscache_cookie *cookie, * taken into account. */
- iov_iter_xarray(&iter, WRITE, &mapping->i_pages, start, len); + iov_iter_xarray(&iter, ITER_SOURCE, &mapping->i_pages, start, len); fscache_write(cres, start, &iter, fscache_wreq_done, wreq); return;
diff --git a/fs/fuse/ioctl.c b/fs/fuse/ioctl.c index 61d8afcb10a3..fcce94ace2c2 100644 --- a/fs/fuse/ioctl.c +++ b/fs/fuse/ioctl.c @@ -255,7 +255,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, ap.args.in_pages = true;
err = -EFAULT; - iov_iter_init(&ii, WRITE, in_iov, in_iovs, in_size); + iov_iter_init(&ii, ITER_SOURCE, in_iov, in_iovs, in_size); for (i = 0; iov_iter_count(&ii) && !WARN_ON(i >= ap.num_pages); i++) { c = copy_page_from_iter(ap.pages[i], 0, PAGE_SIZE, &ii); if (c != PAGE_SIZE && iov_iter_count(&ii)) @@ -324,7 +324,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, goto out;
err = -EFAULT; - iov_iter_init(&ii, READ, out_iov, out_iovs, transferred); + iov_iter_init(&ii, ITER_DEST, out_iov, out_iovs, transferred); for (i = 0; iov_iter_count(&ii) && !WARN_ON(i >= ap.num_pages); i++) { c = copy_page_to_iter(ap.pages[i], 0, PAGE_SIZE, &ii); if (c != PAGE_SIZE && iov_iter_count(&ii)) diff --git a/fs/netfs/io.c b/fs/netfs/io.c index e374767d1b68..7f753380e047 100644 --- a/fs/netfs/io.c +++ b/fs/netfs/io.c @@ -23,7 +23,7 @@ static void netfs_clear_unread(struct netfs_io_subrequest *subreq) { struct iov_iter iter;
- iov_iter_xarray(&iter, READ, &subreq->rreq->mapping->i_pages, + iov_iter_xarray(&iter, ITER_DEST, &subreq->rreq->mapping->i_pages, subreq->start + subreq->transferred, subreq->len - subreq->transferred); iov_iter_zero(iov_iter_count(&iter), &iter); @@ -49,7 +49,7 @@ static void netfs_read_from_cache(struct netfs_io_request *rreq, struct iov_iter iter;
netfs_stat(&netfs_n_rh_read); - iov_iter_xarray(&iter, READ, &rreq->mapping->i_pages, + iov_iter_xarray(&iter, ITER_DEST, &rreq->mapping->i_pages, subreq->start + subreq->transferred, subreq->len - subreq->transferred);
@@ -208,7 +208,7 @@ static void netfs_rreq_do_write_to_cache(struct netfs_io_request *rreq) continue; }
- iov_iter_xarray(&iter, WRITE, &rreq->mapping->i_pages, + iov_iter_xarray(&iter, ITER_SOURCE, &rreq->mapping->i_pages, subreq->start, subreq->len);
atomic_inc(&rreq->nr_copy_ops); diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index e861d7bae305..e731c00a9fcb 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c @@ -252,7 +252,7 @@ static int fscache_fallback_read_page(struct inode *inode, struct page *page) bvec[0].bv_page = page; bvec[0].bv_offset = 0; bvec[0].bv_len = PAGE_SIZE; - iov_iter_bvec(&iter, READ, bvec, ARRAY_SIZE(bvec), PAGE_SIZE); + iov_iter_bvec(&iter, ITER_DEST, bvec, ARRAY_SIZE(bvec), PAGE_SIZE);
ret = fscache_begin_read_operation(&cres, cookie); if (ret < 0) @@ -282,7 +282,7 @@ static int fscache_fallback_write_page(struct inode *inode, struct page *page, bvec[0].bv_page = page; bvec[0].bv_offset = 0; bvec[0].bv_len = PAGE_SIZE; - iov_iter_bvec(&iter, WRITE, bvec, ARRAY_SIZE(bvec), PAGE_SIZE); + iov_iter_bvec(&iter, ITER_SOURCE, bvec, ARRAY_SIZE(bvec), PAGE_SIZE);
ret = fscache_begin_write_operation(&cres, cookie); if (ret < 0) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 2934ab1d9862..0d49c6bb22eb 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -943,7 +943,7 @@ __be32 nfsd_readv(struct svc_rqst *rqstp, struct svc_fh *fhp, ssize_t host_err;
trace_nfsd_read_vector(rqstp, fhp, offset, *count); - iov_iter_kvec(&iter, READ, vec, vlen, *count); + iov_iter_kvec(&iter, ITER_DEST, vec, vlen, *count); host_err = vfs_iter_read(file, &iter, &ppos, 0); return nfsd_finish_read(rqstp, fhp, file, offset, count, eof, host_err); } @@ -1033,7 +1033,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, if (stable && !use_wgather) flags |= RWF_SYNC;
- iov_iter_kvec(&iter, WRITE, vec, vlen, *cnt); + iov_iter_kvec(&iter, ITER_SOURCE, vec, vlen, *cnt); since = READ_ONCE(file->f_wb_err); if (verf) nfsd_copy_write_verifier(verf, nn); diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index f660c0dbdb63..785cabd71d67 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -900,7 +900,7 @@ static int o2net_recv_tcp_msg(struct socket *sock, void *data, size_t len) { struct kvec vec = { .iov_len = len, .iov_base = data, }; struct msghdr msg = { .msg_flags = MSG_DONTWAIT, }; - iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, len); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, len); return sock_recvmsg(sock, &msg, MSG_DONTWAIT); }
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 7a8c0c6e698d..b3bbb5a5787a 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -53,7 +53,7 @@ static int orangefs_writepage_locked(struct page *page, bv.bv_len = wlen; bv.bv_offset = off % PAGE_SIZE; WARN_ON(wlen == 0); - iov_iter_bvec(&iter, WRITE, &bv, 1, wlen); + iov_iter_bvec(&iter, ITER_SOURCE, &bv, 1, wlen);
ret = wait_for_direct_io(ORANGEFS_IO_WRITE, inode, &off, &iter, wlen, len, wr, NULL, NULL); @@ -112,7 +112,7 @@ static int orangefs_writepages_work(struct orangefs_writepages *ow, else ow->bv[i].bv_offset = 0; } - iov_iter_bvec(&iter, WRITE, ow->bv, ow->npages, ow->len); + iov_iter_bvec(&iter, ITER_SOURCE, ow->bv, ow->npages, ow->len);
WARN_ON(ow->off >= len); if (ow->off + ow->len > len) @@ -270,7 +270,7 @@ static void orangefs_readahead(struct readahead_control *rac) offset = readahead_pos(rac); i_pages = &rac->mapping->i_pages;
- iov_iter_xarray(&iter, READ, i_pages, offset, readahead_length(rac)); + iov_iter_xarray(&iter, ITER_DEST, i_pages, offset, readahead_length(rac));
/* read in the pages. */ if ((ret = wait_for_direct_io(ORANGEFS_IO_READ, inode, @@ -303,7 +303,7 @@ static int orangefs_read_folio(struct file *file, struct folio *folio) bv.bv_page = &folio->page; bv.bv_len = folio_size(folio); bv.bv_offset = 0; - iov_iter_bvec(&iter, READ, &bv, 1, folio_size(folio)); + iov_iter_bvec(&iter, ITER_DEST, &bv, 1, folio_size(folio));
ret = wait_for_direct_io(ORANGEFS_IO_READ, inode, &off, &iter, folio_size(folio), inode->i_size, NULL, NULL, file); diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index f2aa86c421f2..5aa527ca6dbe 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -199,7 +199,7 @@ ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos) struct kvec kvec = { .iov_base = buf, .iov_len = count }; struct iov_iter iter;
- iov_iter_kvec(&iter, READ, &kvec, 1, count); + iov_iter_kvec(&iter, ITER_DEST, &kvec, 1, count);
return read_from_oldmem(&iter, count, ppos, false); } @@ -212,7 +212,7 @@ ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos) struct kvec kvec = { .iov_base = buf, .iov_len = count }; struct iov_iter iter;
- iov_iter_kvec(&iter, READ, &kvec, 1, count); + iov_iter_kvec(&iter, ITER_DEST, &kvec, 1, count);
return read_from_oldmem(&iter, count, ppos, cc_platform_has(CC_ATTR_MEM_ENCRYPT)); @@ -437,7 +437,7 @@ static vm_fault_t mmap_vmcore_fault(struct vm_fault *vmf) offset = (loff_t) index << PAGE_SHIFT; kvec.iov_base = page_address(page); kvec.iov_len = PAGE_SIZE; - iov_iter_kvec(&iter, READ, &kvec, 1, PAGE_SIZE); + iov_iter_kvec(&iter, ITER_DEST, &kvec, 1, PAGE_SIZE);
rc = __read_vmcore(&iter, &offset); if (rc < 0) { diff --git a/fs/read_write.c b/fs/read_write.c index 24b9668d6377..7a2ff6157eda 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -384,7 +384,7 @@ static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, lo
init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = (ppos ? *ppos : 0); - iov_iter_ubuf(&iter, READ, buf, len); + iov_iter_ubuf(&iter, ITER_DEST, buf, len);
ret = call_read_iter(filp, &kiocb, &iter); BUG_ON(ret == -EIOCBQUEUED); @@ -424,7 +424,7 @@ ssize_t __kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
init_sync_kiocb(&kiocb, file); kiocb.ki_pos = pos ? *pos : 0; - iov_iter_kvec(&iter, READ, &iov, 1, iov.iov_len); + iov_iter_kvec(&iter, ITER_DEST, &iov, 1, iov.iov_len); ret = file->f_op->read_iter(&kiocb, &iter); if (ret > 0) { if (pos) @@ -486,7 +486,7 @@ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t
init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = (ppos ? *ppos : 0); - iov_iter_ubuf(&iter, WRITE, (void __user *)buf, len); + iov_iter_ubuf(&iter, ITER_SOURCE, (void __user *)buf, len);
ret = call_write_iter(filp, &kiocb, &iter); BUG_ON(ret == -EIOCBQUEUED); @@ -533,7 +533,7 @@ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t .iov_len = min_t(size_t, count, MAX_RW_COUNT), }; struct iov_iter iter; - iov_iter_kvec(&iter, WRITE, &iov, 1, iov.iov_len); + iov_iter_kvec(&iter, ITER_SOURCE, &iov, 1, iov.iov_len); return __kernel_write_iter(file, &iter, pos); } /* @@ -911,7 +911,7 @@ static ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, struct iov_iter iter; ssize_t ret;
- ret = import_iovec(READ, vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter); + ret = import_iovec(ITER_DEST, vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter); if (ret >= 0) { ret = do_iter_read(file, &iter, pos, flags); kfree(iov); @@ -928,7 +928,7 @@ static ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, struct iov_iter iter; ssize_t ret;
- ret = import_iovec(WRITE, vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter); + ret = import_iovec(ITER_SOURCE, vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter); if (ret >= 0) { file_start_write(file); ret = do_iter_write(file, &iter, pos, flags); diff --git a/fs/seq_file.c b/fs/seq_file.c index 9456a2032224..f5fdaf3b1572 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -156,7 +156,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) ssize_t ret;
init_sync_kiocb(&kiocb, file); - iov_iter_init(&iter, READ, &iov, 1, size); + iov_iter_init(&iter, ITER_DEST, &iov, 1, size);
kiocb.ki_pos = *ppos; ret = seq_read_iter(&kiocb, &iter); diff --git a/fs/splice.c b/fs/splice.c index 0878b852b355..5969b7a1d353 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -303,7 +303,7 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, struct kiocb kiocb; int ret;
- iov_iter_pipe(&to, READ, pipe, len); + iov_iter_pipe(&to, ITER_DEST, pipe, len); init_sync_kiocb(&kiocb, in); kiocb.ki_pos = *ppos; ret = call_read_iter(in, &kiocb, &to); @@ -682,7 +682,7 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out, n++; }
- iov_iter_bvec(&from, WRITE, array, n, sd.total_len - left); + iov_iter_bvec(&from, ITER_SOURCE, array, n, sd.total_len - left); ret = vfs_iter_write(out, &from, &sd.pos, 0); if (ret <= 0) break; @@ -1263,9 +1263,9 @@ static int vmsplice_type(struct fd f, int *type) if (!f.file) return -EBADF; if (f.file->f_mode & FMODE_WRITE) { - *type = WRITE; + *type = ITER_SOURCE; } else if (f.file->f_mode & FMODE_READ) { - *type = READ; + *type = ITER_DEST; } else { fdput(f); return -EBADF; @@ -1314,7 +1314,7 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, uiov,
if (!iov_iter_count(&iter)) error = 0; - else if (iov_iter_rw(&iter) == WRITE) + else if (type == ITER_SOURCE) error = vmsplice_to_pipe(f.file, &iter, flags); else error = vmsplice_to_user(f.file, &iter, flags); diff --git a/include/linux/uio.h b/include/linux/uio.h index 2e3134b14ffd..87fc3d0dda98 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -29,6 +29,9 @@ enum iter_type { ITER_UBUF, };
+#define ITER_SOURCE 1 // == WRITE +#define ITER_DEST 0 // == READ + struct iov_iter_state { size_t iov_offset; size_t count; diff --git a/io_uring/net.c b/io_uring/net.c index 9046e269e5a5..520a73b5a448 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -364,7 +364,7 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags) if (unlikely(!sock)) return -ENOTSOCK;
- ret = import_single_range(WRITE, sr->buf, sr->len, &iov, &msg.msg_iter); + ret = import_single_range(ITER_SOURCE, sr->buf, sr->len, &iov, &msg.msg_iter); if (unlikely(ret)) return ret;
@@ -450,7 +450,7 @@ static int __io_recvmsg_copy_hdr(struct io_kiocb *req, } } else { iomsg->free_iov = iomsg->fast_iov; - ret = __import_iovec(READ, msg.msg_iov, msg.msg_iovlen, UIO_FASTIOV, + ret = __import_iovec(ITER_DEST, msg.msg_iov, msg.msg_iovlen, UIO_FASTIOV, &iomsg->free_iov, &iomsg->msg.msg_iter, false); if (ret > 0) @@ -503,7 +503,7 @@ static int __io_compat_recvmsg_copy_hdr(struct io_kiocb *req, } } else { iomsg->free_iov = iomsg->fast_iov; - ret = __import_iovec(READ, (struct iovec __user *)uiov, msg.msg_iovlen, + ret = __import_iovec(ITER_DEST, (struct iovec __user *)uiov, msg.msg_iovlen, UIO_FASTIOV, &iomsg->free_iov, &iomsg->msg.msg_iter, true); if (ret < 0) @@ -763,7 +763,7 @@ int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags)
kmsg->fast_iov[0].iov_base = buf; kmsg->fast_iov[0].iov_len = len; - iov_iter_init(&kmsg->msg.msg_iter, READ, kmsg->fast_iov, 1, + iov_iter_init(&kmsg->msg.msg_iter, ITER_DEST, kmsg->fast_iov, 1, len); }
@@ -857,7 +857,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags) sr->buf = buf; }
- ret = import_single_range(READ, sr->buf, len, &iov, &msg.msg_iter); + ret = import_single_range(ITER_DEST, sr->buf, len, &iov, &msg.msg_iter); if (unlikely(ret)) goto out_free;
@@ -1097,13 +1097,13 @@ int io_send_zc(struct io_kiocb *req, unsigned int issue_flags) return io_setup_async_addr(req, &__address, issue_flags);
if (zc->flags & IORING_RECVSEND_FIXED_BUF) { - ret = io_import_fixed(WRITE, &msg.msg_iter, req->imu, + ret = io_import_fixed(ITER_SOURCE, &msg.msg_iter, req->imu, (u64)(uintptr_t)zc->buf, zc->len); if (unlikely(ret)) return ret; msg.sg_from_iter = io_sg_from_iter; } else { - ret = import_single_range(WRITE, zc->buf, zc->len, &iov, + ret = import_single_range(ITER_SOURCE, zc->buf, zc->len, &iov, &msg.msg_iter); if (unlikely(ret)) return ret; diff --git a/io_uring/rw.c b/io_uring/rw.c index 6223472095d2..0218fae12edd 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -548,12 +548,12 @@ static inline int io_rw_prep_async(struct io_kiocb *req, int rw)
int io_readv_prep_async(struct io_kiocb *req) { - return io_rw_prep_async(req, READ); + return io_rw_prep_async(req, ITER_DEST); }
int io_writev_prep_async(struct io_kiocb *req) { - return io_rw_prep_async(req, WRITE); + return io_rw_prep_async(req, ITER_SOURCE); }
/* @@ -704,7 +704,7 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags) loff_t *ppos;
if (!req_has_async_data(req)) { - ret = io_import_iovec(READ, req, &iovec, s, issue_flags); + ret = io_import_iovec(ITER_DEST, req, &iovec, s, issue_flags); if (unlikely(ret < 0)) return ret; } else { @@ -716,7 +716,7 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags) * buffers, as we dropped the selected one before retry. */ if (io_do_buffer_select(req)) { - ret = io_import_iovec(READ, req, &iovec, s, issue_flags); + ret = io_import_iovec(ITER_DEST, req, &iovec, s, issue_flags); if (unlikely(ret < 0)) return ret; } @@ -851,7 +851,7 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags) loff_t *ppos;
if (!req_has_async_data(req)) { - ret = io_import_iovec(WRITE, req, &iovec, s, issue_flags); + ret = io_import_iovec(ITER_SOURCE, req, &iovec, s, issue_flags); if (unlikely(ret < 0)) return ret; } else { diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c index 9cb53182bb31..908e8a13c675 100644 --- a/kernel/trace/trace_events_user.c +++ b/kernel/trace/trace_events_user.c @@ -1489,7 +1489,7 @@ static ssize_t user_events_write(struct file *file, const char __user *ubuf, if (unlikely(*ppos != 0)) return -EFAULT;
- if (unlikely(import_single_range(WRITE, (char __user *)ubuf, + if (unlikely(import_single_range(ITER_SOURCE, (char __user *)ubuf, count, &iov, &i))) return -EFAULT;
diff --git a/mm/madvise.c b/mm/madvise.c index b913ba6efc10..d03e149ffe6e 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -1459,7 +1459,7 @@ SYSCALL_DEFINE5(process_madvise, int, pidfd, const struct iovec __user *, vec, goto out; }
- ret = import_iovec(READ, vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter); + ret = import_iovec(ITER_DEST, vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter); if (ret < 0) goto out;
diff --git a/mm/page_io.c b/mm/page_io.c index 2af34dd8fa4d..3a5f921b932e 100644 --- a/mm/page_io.c +++ b/mm/page_io.c @@ -376,7 +376,7 @@ void swap_write_unplug(struct swap_iocb *sio) struct address_space *mapping = sio->iocb.ki_filp->f_mapping; int ret;
- iov_iter_bvec(&from, WRITE, sio->bvec, sio->pages, sio->len); + iov_iter_bvec(&from, ITER_SOURCE, sio->bvec, sio->pages, sio->len); ret = mapping->a_ops->swap_rw(&sio->iocb, &from); if (ret != -EIOCBQUEUED) sio_write_complete(&sio->iocb, ret); @@ -530,7 +530,7 @@ void __swap_read_unplug(struct swap_iocb *sio) struct address_space *mapping = sio->iocb.ki_filp->f_mapping; int ret;
- iov_iter_bvec(&from, READ, sio->bvec, sio->pages, sio->len); + iov_iter_bvec(&from, ITER_DEST, sio->bvec, sio->pages, sio->len); ret = mapping->a_ops->swap_rw(&sio->iocb, &from); if (ret != -EIOCBQUEUED) sio_read_complete(&sio->iocb, ret); diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c index 4bcc11958089..78dfaf9e8990 100644 --- a/mm/process_vm_access.c +++ b/mm/process_vm_access.c @@ -263,7 +263,7 @@ static ssize_t process_vm_rw(pid_t pid, struct iovec *iov_r; struct iov_iter iter; ssize_t rc; - int dir = vm_write ? WRITE : READ; + int dir = vm_write ? ITER_SOURCE : ITER_DEST;
if (flags != 0) return -EINVAL; diff --git a/net/9p/client.c b/net/9p/client.c index b5aa25f82b78..554a4b11f4fe 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -2049,7 +2049,7 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) struct kvec kv = {.iov_base = data, .iov_len = count}; struct iov_iter to;
- iov_iter_kvec(&to, READ, &kv, 1, count); + iov_iter_kvec(&to, ITER_DEST, &kv, 1, count);
p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n", fid->fid, offset, count); diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index c57d643afb10..4eb1b3ced0d2 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -441,7 +441,7 @@ static int send_pkt(struct l2cap_chan *chan, struct sk_buff *skb, iv.iov_len = skb->len;
memset(&msg, 0, sizeof(msg)); - iov_iter_kvec(&msg.msg_iter, WRITE, &iv, 1, skb->len); + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, &iv, 1, skb->len);
err = l2cap_chan_send(chan, &msg, skb->len); if (err > 0) { diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 1fcc482397c3..e7adb8a98cf9 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -56,7 +56,7 @@ static void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *dat
memset(&msg, 0, sizeof(msg));
- iov_iter_kvec(&msg.msg_iter, WRITE, &iv, 1, total_len); + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, &iv, 1, total_len);
l2cap_chan_send(chan, &msg, total_len);
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 11f853d0500f..70663229b3cc 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -605,7 +605,7 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
memset(&msg, 0, sizeof(msg));
- iov_iter_kvec(&msg.msg_iter, WRITE, iv, 2, 1 + len); + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, iv, 2, 1 + len);
l2cap_chan_send(chan, &msg, 1 + len);
diff --git a/net/ceph/messenger_v1.c b/net/ceph/messenger_v1.c index 3ddbde87e4d6..d1787d7d33ef 100644 --- a/net/ceph/messenger_v1.c +++ b/net/ceph/messenger_v1.c @@ -30,7 +30,7 @@ static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len) if (!buf) msg.msg_flags |= MSG_TRUNC;
- iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, len); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, len); r = sock_recvmsg(sock, &msg, msg.msg_flags); if (r == -EAGAIN) r = 0; @@ -49,7 +49,7 @@ static int ceph_tcp_recvpage(struct socket *sock, struct page *page, int r;
BUG_ON(page_offset + length > PAGE_SIZE); - iov_iter_bvec(&msg.msg_iter, READ, &bvec, 1, length); + iov_iter_bvec(&msg.msg_iter, ITER_DEST, &bvec, 1, length); r = sock_recvmsg(sock, &msg, msg.msg_flags); if (r == -EAGAIN) r = 0; diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c index cc8ff81a50b7..3009028c4fa2 100644 --- a/net/ceph/messenger_v2.c +++ b/net/ceph/messenger_v2.c @@ -168,7 +168,7 @@ static int do_try_sendpage(struct socket *sock, struct iov_iter *it) bv.bv_offset, bv.bv_len, CEPH_MSG_FLAGS); } else { - iov_iter_bvec(&msg.msg_iter, WRITE, &bv, 1, bv.bv_len); + iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bv, 1, bv.bv_len); ret = sock_sendmsg(sock, &msg); } if (ret <= 0) { @@ -225,7 +225,7 @@ static void reset_in_kvecs(struct ceph_connection *con) WARN_ON(iov_iter_count(&con->v2.in_iter));
con->v2.in_kvec_cnt = 0; - iov_iter_kvec(&con->v2.in_iter, READ, con->v2.in_kvecs, 0, 0); + iov_iter_kvec(&con->v2.in_iter, ITER_DEST, con->v2.in_kvecs, 0, 0); }
static void set_in_bvec(struct ceph_connection *con, const struct bio_vec *bv) @@ -233,7 +233,7 @@ static void set_in_bvec(struct ceph_connection *con, const struct bio_vec *bv) WARN_ON(iov_iter_count(&con->v2.in_iter));
con->v2.in_bvec = *bv; - iov_iter_bvec(&con->v2.in_iter, READ, &con->v2.in_bvec, 1, bv->bv_len); + iov_iter_bvec(&con->v2.in_iter, ITER_DEST, &con->v2.in_bvec, 1, bv->bv_len); }
static void set_in_skip(struct ceph_connection *con, int len) @@ -241,7 +241,7 @@ static void set_in_skip(struct ceph_connection *con, int len) WARN_ON(iov_iter_count(&con->v2.in_iter));
dout("%s con %p len %d\n", __func__, con, len); - iov_iter_discard(&con->v2.in_iter, READ, len); + iov_iter_discard(&con->v2.in_iter, ITER_DEST, len); }
static void add_out_kvec(struct ceph_connection *con, void *buf, int len) @@ -265,7 +265,7 @@ static void reset_out_kvecs(struct ceph_connection *con)
con->v2.out_kvec_cnt = 0;
- iov_iter_kvec(&con->v2.out_iter, WRITE, con->v2.out_kvecs, 0, 0); + iov_iter_kvec(&con->v2.out_iter, ITER_SOURCE, con->v2.out_kvecs, 0, 0); con->v2.out_iter_sendpage = false; }
@@ -277,7 +277,7 @@ static void set_out_bvec(struct ceph_connection *con, const struct bio_vec *bv,
con->v2.out_bvec = *bv; con->v2.out_iter_sendpage = zerocopy; - iov_iter_bvec(&con->v2.out_iter, WRITE, &con->v2.out_bvec, 1, + iov_iter_bvec(&con->v2.out_iter, ITER_SOURCE, &con->v2.out_bvec, 1, con->v2.out_bvec.bv_len); }
@@ -290,7 +290,7 @@ static void set_out_bvec_zero(struct ceph_connection *con) con->v2.out_bvec.bv_offset = 0; con->v2.out_bvec.bv_len = min(con->v2.out_zero, (int)PAGE_SIZE); con->v2.out_iter_sendpage = true; - iov_iter_bvec(&con->v2.out_iter, WRITE, &con->v2.out_bvec, 1, + iov_iter_bvec(&con->v2.out_iter, ITER_SOURCE, &con->v2.out_bvec, 1, con->v2.out_bvec.bv_len); }
diff --git a/net/compat.c b/net/compat.c index 385f04a6be2f..161b7bea1f62 100644 --- a/net/compat.c +++ b/net/compat.c @@ -95,7 +95,8 @@ int get_compat_msghdr(struct msghdr *kmsg, if (err) return err;
- err = import_iovec(save_addr ? READ : WRITE, compat_ptr(msg.msg_iov), msg.msg_iovlen, + err = import_iovec(save_addr ? ITER_DEST : ITER_SOURCE, + compat_ptr(msg.msg_iov), msg.msg_iovlen, UIO_FASTIOV, iov, &kmsg->msg_iter); return err < 0 ? err : 0; } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ec19ed722453..6667c3538f2a 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2001,7 +2001,7 @@ static int receive_fallback_to_copy(struct sock *sk, if (copy_address != zc->copybuf_address) return -EINVAL;
- err = import_single_range(READ, (void __user *)copy_address, + err = import_single_range(ITER_DEST, (void __user *)copy_address, inq, &iov, &msg.msg_iter); if (err) return err; @@ -2035,7 +2035,7 @@ static int tcp_copy_straggler_data(struct tcp_zerocopy_receive *zc, if (copy_address != zc->copybuf_address) return -EINVAL;
- err = import_single_range(READ, (void __user *)copy_address, + err = import_single_range(ITER_DEST, (void __user *)copy_address, copylen, &iov, &msg.msg_iter); if (err) return err; diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index a56fd0b5a430..4963fec815da 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c @@ -1617,7 +1617,7 @@ ip_vs_receive(struct socket *sock, char *buffer, const size_t buflen) EnterFunction(7);
/* Receive a packet */ - iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, buflen); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, buflen); len = sock_recvmsg(sock, &msg, MSG_DONTWAIT); if (len < 0) return len; diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c index 1472f31480d8..dfb9797f7bc6 100644 --- a/net/smc/smc_clc.c +++ b/net/smc/smc_clc.c @@ -673,7 +673,7 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, */ krflags = MSG_PEEK | MSG_WAITALL; clc_sk->sk_rcvtimeo = timeout; - iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, sizeof(struct smc_clc_msg_hdr)); len = sock_recvmsg(smc->clcsock, &msg, krflags); if (signal_pending(current)) { @@ -720,7 +720,7 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, } else { recvlen = datlen; } - iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, recvlen); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, recvlen); krflags = MSG_WAITALL; len = sock_recvmsg(smc->clcsock, &msg, krflags); if (len < recvlen || !smc_clc_msg_hdr_valid(clcm, check_trl)) { @@ -737,7 +737,7 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen, /* receive remaining proposal message */ recvlen = datlen > SMC_CLC_RECV_BUF_LEN ? SMC_CLC_RECV_BUF_LEN : datlen; - iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, recvlen); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, recvlen); len = sock_recvmsg(smc->clcsock, &msg, krflags); datlen -= len; } diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c index 64dedffe9d26..f4b6a71ac488 100644 --- a/net/smc/smc_tx.c +++ b/net/smc/smc_tx.c @@ -308,7 +308,7 @@ int smc_tx_sendpage(struct smc_sock *smc, struct page *page, int offset,
iov.iov_base = kaddr + offset; iov.iov_len = size; - iov_iter_kvec(&msg.msg_iter, WRITE, &iov, 1, size); + iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, &iov, 1, size); rc = smc_tx_sendmsg(smc, &msg, size); kunmap(page); return rc; diff --git a/net/socket.c b/net/socket.c index 00da9ce3dba0..73463c7c3702 100644 --- a/net/socket.c +++ b/net/socket.c @@ -750,7 +750,7 @@ EXPORT_SYMBOL(sock_sendmsg); int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t size) { - iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size); + iov_iter_kvec(&msg->msg_iter, ITER_SOURCE, vec, num, size); return sock_sendmsg(sock, msg); } EXPORT_SYMBOL(kernel_sendmsg); @@ -776,7 +776,7 @@ int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg, if (!sock->ops->sendmsg_locked) return sock_no_sendmsg_locked(sk, msg, size);
- iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size); + iov_iter_kvec(&msg->msg_iter, ITER_SOURCE, vec, num, size);
return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg)); } @@ -1034,7 +1034,7 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t size, int flags) { msg->msg_control_is_user = false; - iov_iter_kvec(&msg->msg_iter, READ, vec, num, size); + iov_iter_kvec(&msg->msg_iter, ITER_DEST, vec, num, size); return sock_recvmsg(sock, msg, flags); } EXPORT_SYMBOL(kernel_recvmsg); @@ -2092,7 +2092,7 @@ int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags, struct iovec iov; int fput_needed;
- err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter); + err = import_single_range(ITER_SOURCE, buff, len, &iov, &msg.msg_iter); if (unlikely(err)) return err; sock = sockfd_lookup_light(fd, &err, &fput_needed); @@ -2157,7 +2157,7 @@ int __sys_recvfrom(int fd, void __user *ubuf, size_t size, unsigned int flags, int err, err2; int fput_needed;
- err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter); + err = import_single_range(ITER_DEST, ubuf, size, &iov, &msg.msg_iter); if (unlikely(err)) return err; sock = sockfd_lookup_light(fd, &err, &fput_needed); @@ -2417,7 +2417,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, if (err) return err;
- err = import_iovec(save_addr ? READ : WRITE, + err = import_iovec(save_addr ? ITER_DEST : ITER_SOURCE, msg.msg_iov, msg.msg_iovlen, UIO_FASTIOV, iov, &kmsg->msg_iter); return err < 0 ? err : 0; diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c index 71ba4cf513bc..1b2b84feeec6 100644 --- a/net/sunrpc/socklib.c +++ b/net/sunrpc/socklib.c @@ -214,14 +214,14 @@ static inline int xprt_sendmsg(struct socket *sock, struct msghdr *msg, static int xprt_send_kvec(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t seek) { - iov_iter_kvec(&msg->msg_iter, WRITE, vec, 1, vec->iov_len); + iov_iter_kvec(&msg->msg_iter, ITER_SOURCE, vec, 1, vec->iov_len); return xprt_sendmsg(sock, msg, seek); }
static int xprt_send_pagedata(struct socket *sock, struct msghdr *msg, struct xdr_buf *xdr, size_t base) { - iov_iter_bvec(&msg->msg_iter, WRITE, xdr->bvec, xdr_buf_pagecount(xdr), + iov_iter_bvec(&msg->msg_iter, ITER_SOURCE, xdr->bvec, xdr_buf_pagecount(xdr), xdr->page_len + xdr->page_base); return xprt_sendmsg(sock, msg, base + xdr->page_base); } @@ -244,7 +244,7 @@ static int xprt_send_rm_and_kvec(struct socket *sock, struct msghdr *msg, }; size_t len = iov[0].iov_len + iov[1].iov_len;
- iov_iter_kvec(&msg->msg_iter, WRITE, iov, 2, len); + iov_iter_kvec(&msg->msg_iter, ITER_SOURCE, iov, 2, len); return xprt_sendmsg(sock, msg, base); }
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index e833103f4629..815baf308236 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -260,7 +260,7 @@ static ssize_t svc_tcp_read_msg(struct svc_rqst *rqstp, size_t buflen, rqstp->rq_respages = &rqstp->rq_pages[i]; rqstp->rq_next_page = rqstp->rq_respages + 1;
- iov_iter_bvec(&msg.msg_iter, READ, bvec, i, buflen); + iov_iter_bvec(&msg.msg_iter, ITER_DEST, bvec, i, buflen); if (seek) { iov_iter_advance(&msg.msg_iter, seek); buflen -= seek; @@ -874,7 +874,7 @@ static ssize_t svc_tcp_read_marker(struct svc_sock *svsk, want = sizeof(rpc_fraghdr) - svsk->sk_tcplen; iov.iov_base = ((char *)&svsk->sk_marker) + svsk->sk_tcplen; iov.iov_len = want; - iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, want); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, want); len = sock_recvmsg(svsk->sk_sock, &msg, MSG_DONTWAIT); if (len < 0) return len; diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 915b9902f673..b3ab6d9d752e 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -364,7 +364,7 @@ static ssize_t xs_read_kvec(struct socket *sock, struct msghdr *msg, int flags, struct kvec *kvec, size_t count, size_t seek) { - iov_iter_kvec(&msg->msg_iter, READ, kvec, 1, count); + iov_iter_kvec(&msg->msg_iter, ITER_DEST, kvec, 1, count); return xs_sock_recvmsg(sock, msg, flags, seek); }
@@ -373,7 +373,7 @@ xs_read_bvec(struct socket *sock, struct msghdr *msg, int flags, struct bio_vec *bvec, unsigned long nr, size_t count, size_t seek) { - iov_iter_bvec(&msg->msg_iter, READ, bvec, nr, count); + iov_iter_bvec(&msg->msg_iter, ITER_DEST, bvec, nr, count); return xs_sock_recvmsg(sock, msg, flags, seek); }
@@ -381,7 +381,7 @@ static ssize_t xs_read_discard(struct socket *sock, struct msghdr *msg, int flags, size_t count) { - iov_iter_discard(&msg->msg_iter, READ, count); + iov_iter_discard(&msg->msg_iter, ITER_DEST, count); return sock_recvmsg(sock, msg, flags); }
diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c index e3b427a70398..69c88cc03887 100644 --- a/net/tipc/topsrv.c +++ b/net/tipc/topsrv.c @@ -396,7 +396,7 @@ static int tipc_conn_rcv_from_sock(struct tipc_conn *con) iov.iov_base = &s; iov.iov_len = sizeof(s); msg.msg_name = NULL; - iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, iov.iov_len); + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, iov.iov_len); ret = sock_recvmsg(con->sock, &msg, MSG_DONTWAIT); if (ret == -EWOULDBLOCK) return -EWOULDBLOCK; diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index a03d66046ca3..6c593788dc25 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c @@ -620,7 +620,7 @@ int tls_device_sendpage(struct sock *sk, struct page *page, kaddr = kmap(page); iov.iov_base = kaddr + offset; iov.iov_len = size; - iov_iter_kvec(&msg_iter, WRITE, &iov, 1, size); + iov_iter_kvec(&msg_iter, ITER_SOURCE, &iov, 1, size); iter_offset.msg_iter = &msg_iter; rc = tls_push_data(sk, iter_offset, size, flags, TLS_RECORD_TYPE_DATA, NULL); @@ -697,7 +697,7 @@ static int tls_device_push_pending_record(struct sock *sk, int flags) union tls_iter_offset iter; struct iov_iter msg_iter;
- iov_iter_kvec(&msg_iter, WRITE, NULL, 0, 0); + iov_iter_kvec(&msg_iter, ITER_SOURCE, NULL, 0, 0); iter.msg_iter = &msg_iter; return tls_push_data(sk, iter, 0, flags, TLS_RECORD_TYPE_DATA, NULL); } diff --git a/net/xfrm/espintcp.c b/net/xfrm/espintcp.c index 29a540dcb5a7..d6fece1ed982 100644 --- a/net/xfrm/espintcp.c +++ b/net/xfrm/espintcp.c @@ -354,7 +354,7 @@ static int espintcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) *((__be16 *)buf) = cpu_to_be16(msglen); pfx_iov.iov_base = buf; pfx_iov.iov_len = sizeof(buf); - iov_iter_kvec(&pfx_iter, WRITE, &pfx_iov, 1, pfx_iov.iov_len); + iov_iter_kvec(&pfx_iter, ITER_SOURCE, &pfx_iov, 1, pfx_iov.iov_len);
err = sk_msg_memcopy_from_iter(sk, &pfx_iter, &emsg->skmsg, pfx_iov.iov_len); diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 96a92a645216..d54f73c558f7 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1251,7 +1251,7 @@ long keyctl_instantiate_key(key_serial_t id, struct iov_iter from; int ret;
- ret = import_single_range(WRITE, (void __user *)_payload, plen, + ret = import_single_range(ITER_SOURCE, (void __user *)_payload, plen, &iov, &from); if (unlikely(ret)) return ret; @@ -1283,7 +1283,7 @@ long keyctl_instantiate_key_iov(key_serial_t id, if (!_payload_iov) ioc = 0;
- ret = import_iovec(WRITE, _payload_iov, ioc, + ret = import_iovec(ITER_SOURCE, _payload_iov, ioc, ARRAY_SIZE(iovstack), &iov, &from); if (ret < 0) return ret;
From: Jason Wang jasowang@redhat.com
[ Upstream commit 6dd88fd59da84631b5fe5c8176931c38cfa3b265 ]
Al Viro said:
""" Since "vhost/scsi: fix reuse of &vq->iov[out] in response" we have this: cmd->tvc_resp_iov = vq->iov[vc.out]; cmd->tvc_in_iovs = vc.in; combined with iov_iter_init(&iov_iter, ITER_DEST, &cmd->tvc_resp_iov, cmd->tvc_in_iovs, sizeof(v_rsp)); in vhost_scsi_complete_cmd_work(). We used to have ->tvc_resp_iov _pointing_ to vq->iov[vc.out]; back then iov_iter_init() asked to set an iovec-backed iov_iter over the tail of vq->iov[], with length being the amount of iovecs in the tail.
Now we have a copy of one element of that array. Fortunately, the members following it in the containing structure are two non-NULL kernel pointers, so copy_to_iter() will not copy anything beyond the first iovec - kernel pointer is not (on the majority of architectures) going to be accepted by access_ok() in copyout() and it won't be skipped since the "length" (in reality - another non-NULL kernel pointer) won't be zero.
So it's not going to give a guest-to-qemu escalation, but it's definitely a bug. Frankly, my preference would be to verify that the very first iovec is long enough to hold rsp_size. Due to the above, any users that try to give us vq->iov[vc.out].iov_len < sizeof(struct virtio_scsi_cmd_resp) would currently get a failure in vhost_scsi_complete_cmd_work() anyway. """
However, the spec doesn't say anything about the legacy descriptor layout for the respone. So this patch tries to not assume the response to reside in a single separate descriptor which is what commit 79c14141a487 ("vhost/scsi: Convert completion path to use") tries to achieve towards to ANY_LAYOUT.
This is done by allocating and using dedicate resp iov in the command. To be safety, start with UIO_MAXIOV to be consistent with the limitation that we advertise to the vhost_get_vq_desc().
Testing with the hacked virtio-scsi driver that use 1 descriptor for 1 byte in the response.
Reported-by: Al Viro viro@zeniv.linux.org.uk Cc: Benjamin Coddington bcodding@redhat.com Cc: Nicholas Bellinger nab@linux-iscsi.org Fixes: a77ec83a5789 ("vhost/scsi: fix reuse of &vq->iov[out] in response") Signed-off-by: Jason Wang jasowang@redhat.com Message-Id: 20230119073647.76467-1-jasowang@redhat.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Reviewed-by: Stefan Hajnoczi stefanha@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/vhost/scsi.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index dca6346d75b3..d5ecb8876fc9 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -80,7 +80,7 @@ struct vhost_scsi_cmd { struct scatterlist *tvc_prot_sgl; struct page **tvc_upages; /* Pointer to response header iovec */ - struct iovec tvc_resp_iov; + struct iovec *tvc_resp_iov; /* Pointer to vhost_scsi for our device */ struct vhost_scsi *tvc_vhost; /* Pointer to vhost_virtqueue for the cmd */ @@ -563,7 +563,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) memcpy(v_rsp.sense, cmd->tvc_sense_buf, se_cmd->scsi_sense_length);
- iov_iter_init(&iov_iter, ITER_DEST, &cmd->tvc_resp_iov, + iov_iter_init(&iov_iter, ITER_DEST, cmd->tvc_resp_iov, cmd->tvc_in_iovs, sizeof(v_rsp)); ret = copy_to_iter(&v_rsp, sizeof(v_rsp), &iov_iter); if (likely(ret == sizeof(v_rsp))) { @@ -594,6 +594,7 @@ vhost_scsi_get_cmd(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg, struct vhost_scsi_cmd *cmd; struct vhost_scsi_nexus *tv_nexus; struct scatterlist *sg, *prot_sg; + struct iovec *tvc_resp_iov; struct page **pages; int tag;
@@ -613,6 +614,7 @@ vhost_scsi_get_cmd(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg, sg = cmd->tvc_sgl; prot_sg = cmd->tvc_prot_sgl; pages = cmd->tvc_upages; + tvc_resp_iov = cmd->tvc_resp_iov; memset(cmd, 0, sizeof(*cmd)); cmd->tvc_sgl = sg; cmd->tvc_prot_sgl = prot_sg; @@ -625,6 +627,7 @@ vhost_scsi_get_cmd(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg, cmd->tvc_data_direction = data_direction; cmd->tvc_nexus = tv_nexus; cmd->inflight = vhost_scsi_get_inflight(vq); + cmd->tvc_resp_iov = tvc_resp_iov;
memcpy(cmd->tvc_cdb, cdb, VHOST_SCSI_MAX_CDB_SIZE);
@@ -935,7 +938,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) struct iov_iter in_iter, prot_iter, data_iter; u64 tag; u32 exp_data_len, data_direction; - int ret, prot_bytes, c = 0; + int ret, prot_bytes, i, c = 0; u16 lun; u8 task_attr; bool t10_pi = vhost_has_feature(vq, VIRTIO_SCSI_F_T10_PI); @@ -1092,7 +1095,8 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) } cmd->tvc_vhost = vs; cmd->tvc_vq = vq; - cmd->tvc_resp_iov = vq->iov[vc.out]; + for (i = 0; i < vc.in ; i++) + cmd->tvc_resp_iov[i] = vq->iov[vc.out + i]; cmd->tvc_in_iovs = vc.in;
pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n", @@ -1461,6 +1465,7 @@ static void vhost_scsi_destroy_vq_cmds(struct vhost_virtqueue *vq) kfree(tv_cmd->tvc_sgl); kfree(tv_cmd->tvc_prot_sgl); kfree(tv_cmd->tvc_upages); + kfree(tv_cmd->tvc_resp_iov); }
sbitmap_free(&svq->scsi_tags); @@ -1508,6 +1513,14 @@ static int vhost_scsi_setup_vq_cmds(struct vhost_virtqueue *vq, int max_cmds) goto out; }
+ tv_cmd->tvc_resp_iov = kcalloc(UIO_MAXIOV, + sizeof(struct iovec), + GFP_KERNEL); + if (!tv_cmd->tvc_resp_iov) { + pr_err("Unable to allocate tv_cmd->tvc_resp_iov\n"); + goto out; + } + tv_cmd->tvc_prot_sgl = kcalloc(VHOST_SCSI_PREALLOC_PROT_SGLS, sizeof(struct scatterlist), GFP_KERNEL);
From: Dave Ertman david.m.ertman@intel.com
[ Upstream commit a6a0974aae4209d039ba81226ded5246eea14961 ]
The PF controls the set of queues that the RDMA auxiliary_driver requests resources from. The set_channel command will alter that pool and trigger a reconfiguration of the VSI, which breaks RDMA functionality.
Prevent set_channel from executing when RDMA driver bound to auxiliary device.
Adding a locked variable to pass down the call chain to avoid double locking the device_lock.
Fixes: 348048e724a0 ("ice: Implement iidc operations") Signed-off-by: Dave Ertman david.m.ertman@intel.com Tested-by: Gurucharan G gurucharanx.g@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/ice/ice.h | 2 +- drivers/net/ethernet/intel/ice/ice_dcb_lib.c | 23 +++++++++------- drivers/net/ethernet/intel/ice/ice_dcb_lib.h | 4 +-- drivers/net/ethernet/intel/ice/ice_ethtool.c | 28 +++++++++++++++++--- drivers/net/ethernet/intel/ice/ice_main.c | 5 ++-- 5 files changed, 43 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index 001500afc4a6..e04871379baa 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -856,7 +856,7 @@ void ice_set_ethtool_repr_ops(struct net_device *netdev); void ice_set_ethtool_safe_mode_ops(struct net_device *netdev); u16 ice_get_avail_txq_count(struct ice_pf *pf); u16 ice_get_avail_rxq_count(struct ice_pf *pf); -int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx); +int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx, bool locked); void ice_update_vsi_stats(struct ice_vsi *vsi); void ice_update_pf_stats(struct ice_pf *pf); void diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c index add90e75f05c..9aa0437aa598 100644 --- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c @@ -434,7 +434,7 @@ int ice_pf_dcb_cfg(struct ice_pf *pf, struct ice_dcbx_cfg *new_cfg, bool locked) goto out; }
- ice_pf_dcb_recfg(pf); + ice_pf_dcb_recfg(pf, false);
out: /* enable previously downed VSIs */ @@ -724,12 +724,13 @@ static int ice_dcb_noncontig_cfg(struct ice_pf *pf) /** * ice_pf_dcb_recfg - Reconfigure all VEBs and VSIs * @pf: pointer to the PF struct + * @locked: is adev device lock held * * Assumed caller has already disabled all VSIs before * calling this function. Reconfiguring DCB based on * local_dcbx_cfg. */ -void ice_pf_dcb_recfg(struct ice_pf *pf) +void ice_pf_dcb_recfg(struct ice_pf *pf, bool locked) { struct ice_dcbx_cfg *dcbcfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg; struct iidc_event *event; @@ -776,14 +777,16 @@ void ice_pf_dcb_recfg(struct ice_pf *pf) if (vsi->type == ICE_VSI_PF) ice_dcbnl_set_all(vsi); } - /* Notify the AUX drivers that TC change is finished */ - event = kzalloc(sizeof(*event), GFP_KERNEL); - if (!event) - return; + if (!locked) { + /* Notify the AUX drivers that TC change is finished */ + event = kzalloc(sizeof(*event), GFP_KERNEL); + if (!event) + return;
- set_bit(IIDC_EVENT_AFTER_TC_CHANGE, event->type); - ice_send_event_to_aux(pf, event); - kfree(event); + set_bit(IIDC_EVENT_AFTER_TC_CHANGE, event->type); + ice_send_event_to_aux(pf, event); + kfree(event); + } }
/** @@ -1034,7 +1037,7 @@ ice_dcb_process_lldp_set_mib_change(struct ice_pf *pf, }
/* changes in configuration update VSI */ - ice_pf_dcb_recfg(pf); + ice_pf_dcb_recfg(pf, false);
/* enable previously downed VSIs */ ice_dcb_ena_dis_vsi(pf, true, true); diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.h b/drivers/net/ethernet/intel/ice/ice_dcb_lib.h index 4c421c842a13..800879a88c5e 100644 --- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.h +++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.h @@ -23,7 +23,7 @@ u8 ice_dcb_get_tc(struct ice_vsi *vsi, int queue_index); int ice_pf_dcb_cfg(struct ice_pf *pf, struct ice_dcbx_cfg *new_cfg, bool locked); int ice_dcb_bwchk(struct ice_pf *pf, struct ice_dcbx_cfg *dcbcfg); -void ice_pf_dcb_recfg(struct ice_pf *pf); +void ice_pf_dcb_recfg(struct ice_pf *pf, bool locked); void ice_vsi_cfg_dcb_rings(struct ice_vsi *vsi); int ice_init_pf_dcb(struct ice_pf *pf, bool locked); void ice_update_dcb_stats(struct ice_pf *pf); @@ -128,7 +128,7 @@ static inline u8 ice_get_pfc_mode(struct ice_pf *pf) return 0; }
-static inline void ice_pf_dcb_recfg(struct ice_pf *pf) { } +static inline void ice_pf_dcb_recfg(struct ice_pf *pf, bool locked) { } static inline void ice_vsi_cfg_dcb_rings(struct ice_vsi *vsi) { } static inline void ice_update_dcb_stats(struct ice_pf *pf) { } static inline void diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c index b7be84bbe72d..e1f6373a3a2c 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c @@ -3472,7 +3472,9 @@ static int ice_set_channels(struct net_device *dev, struct ethtool_channels *ch) struct ice_vsi *vsi = np->vsi; struct ice_pf *pf = vsi->back; int new_rx = 0, new_tx = 0; + bool locked = false; u32 curr_combined; + int ret = 0;
/* do not support changing channels in Safe Mode */ if (ice_is_safe_mode(pf)) { @@ -3536,15 +3538,33 @@ static int ice_set_channels(struct net_device *dev, struct ethtool_channels *ch) return -EINVAL; }
- ice_vsi_recfg_qs(vsi, new_rx, new_tx); + if (pf->adev) { + mutex_lock(&pf->adev_mutex); + device_lock(&pf->adev->dev); + locked = true; + if (pf->adev->dev.driver) { + netdev_err(dev, "Cannot change channels when RDMA is active\n"); + ret = -EBUSY; + goto adev_unlock; + } + } + + ice_vsi_recfg_qs(vsi, new_rx, new_tx, locked);
- if (!netif_is_rxfh_configured(dev)) - return ice_vsi_set_dflt_rss_lut(vsi, new_rx); + if (!netif_is_rxfh_configured(dev)) { + ret = ice_vsi_set_dflt_rss_lut(vsi, new_rx); + goto adev_unlock; + }
/* Update rss_size due to change in Rx queues */ vsi->rss_size = ice_get_valid_rss_size(&pf->hw, new_rx);
- return 0; +adev_unlock: + if (locked) { + device_unlock(&pf->adev->dev); + mutex_unlock(&pf->adev_mutex); + } + return ret; }
/** diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index ca2898467dcb..1ac5f0018c7e 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -4192,12 +4192,13 @@ bool ice_is_wol_supported(struct ice_hw *hw) * @vsi: VSI being changed * @new_rx: new number of Rx queues * @new_tx: new number of Tx queues + * @locked: is adev device_lock held * * Only change the number of queues if new_tx, or new_rx is non-0. * * Returns 0 on success. */ -int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx) +int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx, bool locked) { struct ice_pf *pf = vsi->back; int err = 0, timeout = 50; @@ -4226,7 +4227,7 @@ int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx)
ice_vsi_close(vsi); ice_vsi_rebuild(vsi, false); - ice_pf_dcb_recfg(pf); + ice_pf_dcb_recfg(pf, locked); ice_vsi_open(vsi); done: clear_bit(ICE_CFG_BUSY, pf->state);
From: Magnus Karlsson magnus.karlsson@intel.com
[ Upstream commit 2ccce20d51faa0178086163ccb6c84a099a87ab4 ]
Make sure that xdp_do_flush() is always executed before napi_complete_done(). This is important for two reasons. First, a redirect to an XSKMAP assumes that a call to xdp_do_redirect() from napi context X on CPU Y will be followed by a xdp_do_flush() from the same napi context and CPU. This is not guaranteed if the napi_complete_done() is executed before xdp_do_flush(), as it tells the napi logic that it is fine to schedule napi context X on another CPU. Details from a production system triggering this bug using the veth driver can be found following the first link below.
The second reason is that the XDP_REDIRECT logic in itself relies on being inside a single NAPI instance through to the xdp_do_flush() call for RCU protection of all in-kernel data structures. Details can be found in the second link below.
Fixes: d1b25b79e162b ("qede: add .ndo_xdp_xmit() and XDP_REDIRECT support") Signed-off-by: Magnus Karlsson magnus.karlsson@intel.com Acked-by: Toke Høiland-Jørgensen toke@redhat.com Link: https://lore.kernel.org/r/20221220185903.1105011-1-sbohrer@cloudflare.com Link: https://lore.kernel.org/all/20210624160609.292325-1-toke@redhat.com/ Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/qlogic/qede/qede_fp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c index 7c2af482192d..cb1746bc0e0c 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_fp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c @@ -1438,6 +1438,10 @@ int qede_poll(struct napi_struct *napi, int budget) rx_work_done = (likely(fp->type & QEDE_FASTPATH_RX) && qede_has_rx_work(fp->rxq)) ? qede_rx_int(fp, budget) : 0; + + if (fp->xdp_xmit & QEDE_XDP_REDIRECT) + xdp_do_flush(); + /* Handle case where we are called by netpoll with a budget of 0 */ if (rx_work_done < budget || !budget) { if (!qede_poll_is_more_work(fp)) { @@ -1457,9 +1461,6 @@ int qede_poll(struct napi_struct *napi, int budget) qede_update_tx_producer(fp->xdp_tx); }
- if (fp->xdp_xmit & QEDE_XDP_REDIRECT) - xdp_do_flush_map(); - return rx_work_done; }
From: Magnus Karlsson magnus.karlsson@intel.com
[ Upstream commit ad7e615f646c9b5b2cf655cdfb9d91a28db4f25a ]
Make sure that xdp_do_flush() is always executed before napi_complete_done(). This is important for two reasons. First, a redirect to an XSKMAP assumes that a call to xdp_do_redirect() from napi context X on CPU Y will be followed by a xdp_do_flush() from the same napi context and CPU. This is not guaranteed if the napi_complete_done() is executed before xdp_do_flush(), as it tells the napi logic that it is fine to schedule napi context X on another CPU. Details from a production system triggering this bug using the veth driver can be found following the first link below.
The second reason is that the XDP_REDIRECT logic in itself relies on being inside a single NAPI instance through to the xdp_do_flush() call for RCU protection of all in-kernel data structures. Details can be found in the second link below.
Fixes: 186b3c998c50 ("virtio-net: support XDP_REDIRECT") Signed-off-by: Magnus Karlsson magnus.karlsson@intel.com Acked-by: Toke Høiland-Jørgensen toke@redhat.com Link: https://lore.kernel.org/r/20221220185903.1105011-1-sbohrer@cloudflare.com Link: https://lore.kernel.org/all/20210624160609.292325-1-toke@redhat.com/ Acked-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/virtio_net.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 3cd15f16090f..ec388932aacf 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1673,13 +1673,13 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
received = virtnet_receive(rq, budget, &xdp_xmit);
+ if (xdp_xmit & VIRTIO_XDP_REDIR) + xdp_do_flush(); + /* Out of packets? */ if (received < budget) virtqueue_napi_complete(napi, rq->vq, received);
- if (xdp_xmit & VIRTIO_XDP_REDIR) - xdp_do_flush(); - if (xdp_xmit & VIRTIO_XDP_TX) { sq = virtnet_xdp_get_sq(vi); if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) {
From: Magnus Karlsson magnus.karlsson@intel.com
[ Upstream commit b534013798b77f81a36f36dafd59bab9de837619 ]
Make sure that xdp_do_flush() is always executed before napi_complete_done(). This is important for two reasons. First, a redirect to an XSKMAP assumes that a call to xdp_do_redirect() from napi context X on CPU Y will be followed by a xdp_do_flush() from the same napi context and CPU. This is not guaranteed if the napi_complete_done() is executed before xdp_do_flush(), as it tells the napi logic that it is fine to schedule napi context X on another CPU. Details from a production system triggering this bug using the veth driver can be found following the first link below.
The second reason is that the XDP_REDIRECT logic in itself relies on being inside a single NAPI instance through to the xdp_do_flush() call for RCU protection of all in-kernel data structures. Details can be found in the second link below.
Fixes: a1e031ffb422 ("dpaa_eth: add XDP_REDIRECT support") Signed-off-by: Magnus Karlsson magnus.karlsson@intel.com Acked-by: Toke Høiland-Jørgensen toke@redhat.com Link: https://lore.kernel.org/r/20221220185903.1105011-1-sbohrer@cloudflare.com Link: https://lore.kernel.org/all/20210624160609.292325-1-toke@redhat.com/ Acked-by: Camelia Groza camelia.groza@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index fc68a32ce2f7..d8fb7d4ebd51 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -2400,6 +2400,9 @@ static int dpaa_eth_poll(struct napi_struct *napi, int budget)
cleaned = qman_p_poll_dqrr(np->p, budget);
+ if (np->xdp_act & XDP_REDIRECT) + xdp_do_flush(); + if (cleaned < budget) { napi_complete_done(napi, cleaned); qman_p_irqsource_add(np->p, QM_PIRQ_DQRI); @@ -2407,9 +2410,6 @@ static int dpaa_eth_poll(struct napi_struct *napi, int budget) qman_p_irqsource_add(np->p, QM_PIRQ_DQRI); }
- if (np->xdp_act & XDP_REDIRECT) - xdp_do_flush(); - return cleaned; }
From: Magnus Karlsson magnus.karlsson@intel.com
[ Upstream commit a3191c4d86c5d3bd35b00dfde6910b88391436a0 ]
Make sure that xdp_do_flush() is always executed before napi_complete_done(). This is important for two reasons. First, a redirect to an XSKMAP assumes that a call to xdp_do_redirect() from napi context X on CPU Y will be followed by a xdp_do_flush() from the same napi context and CPU. This is not guaranteed if the napi_complete_done() is executed before xdp_do_flush(), as it tells the napi logic that it is fine to schedule napi context X on another CPU. Details from a production system triggering this bug using the veth driver can be found following the first link below.
The second reason is that the XDP_REDIRECT logic in itself relies on being inside a single NAPI instance through to the xdp_do_flush() call for RCU protection of all in-kernel data structures. Details can be found in the second link below.
Fixes: d678be1dc1ec ("dpaa2-eth: add XDP_REDIRECT support") Signed-off-by: Magnus Karlsson magnus.karlsson@intel.com Acked-by: Toke Høiland-Jørgensen toke@redhat.com Link: https://lore.kernel.org/r/20221220185903.1105011-1-sbohrer@cloudflare.com Link: https://lore.kernel.org/all/20210624160609.292325-1-toke@redhat.com/ Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index 8d029addddad..6383d9805dac 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -1868,10 +1868,15 @@ static int dpaa2_eth_poll(struct napi_struct *napi, int budget) if (rx_cleaned >= budget || txconf_cleaned >= DPAA2_ETH_TXCONF_PER_NAPI) { work_done = budget; + if (ch->xdp.res & XDP_REDIRECT) + xdp_do_flush(); goto out; } } while (store_cleaned);
+ if (ch->xdp.res & XDP_REDIRECT) + xdp_do_flush(); + /* Update NET DIM with the values for this CDAN */ dpaa2_io_update_net_dim(ch->dpio, ch->stats.frames_per_cdan, ch->stats.bytes_per_cdan); @@ -1902,9 +1907,7 @@ static int dpaa2_eth_poll(struct napi_struct *napi, int budget) txc_fq->dq_bytes = 0; }
- if (ch->xdp.res & XDP_REDIRECT) - xdp_do_flush_map(); - else if (rx_cleaned && ch->xdp.res & XDP_TX) + if (rx_cleaned && ch->xdp.res & XDP_TX) dpaa2_eth_xdp_tx_flush(priv, ch, &priv->fq[flowid]);
return work_done;
From: Alexander Duyck alexanderduyck@fb.com
[ Upstream commit 7d2c89b325874a35564db5630a459966afab04cc ]
GSO should not merge page pool recycled frames with standard reference counted frames. Traditionally this didn't occur, at least not often. However as we start looking at adding support for wireless adapters there becomes the potential to mix the two due to A-MSDU repartitioning frames in the receive path. There are possibly other places where this may have occurred however I suspect they must be few and far between as we have not seen this issue until now.
Fixes: 53e0961da1c7 ("page_pool: add frag page recycling support in page pool") Reported-by: Felix Fietkau nbd@nbd.name Signed-off-by: Alexander Duyck alexanderduyck@fb.com Acked-by: Ilias Apalodimas ilias.apalodimas@linaro.org Reviewed-by: Eric Dumazet edumazet@google.com Link: https://lore.kernel.org/r/167475990764.1934330.11960904198087757911.stgit@lo... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/gro.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/net/core/gro.c b/net/core/gro.c index 1b4abfb9a7a1..352f966cb1da 100644 --- a/net/core/gro.c +++ b/net/core/gro.c @@ -162,6 +162,15 @@ int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb) struct sk_buff *lp; int segs;
+ /* Do not splice page pool based packets w/ non-page pool + * packets. This can result in reference count issues as page + * pool pages will not decrement the reference count and will + * instead be immediately returned to the pool or have frag + * count decremented. + */ + if (p->pp_recycle != skb->pp_recycle) + return -ETOOMANYREFS; + /* pairs with WRITE_ONCE() in netif_set_gro_max_size() */ gro_max_size = READ_ONCE(p->dev->gro_max_size);
From: Íñigo Huguet ihuguet@redhat.com
[ Upstream commit ffffd2454a7a1bc9f7242b12c4cc0b05c12692b4 ]
Recent sfc NICs are TSO capable for some tunnel protocols. However, it was not working properly because the feature was not advertised in hw_enc_features, but in hw_features only.
Setting up a GENEVE tunnel and using iperf3 to send IPv4 and IPv6 traffic to the tunnel show, with tcpdump, that the IPv4 packets still had ~64k size but the IPv6 ones had only ~1500 bytes (they had been segmented by software, not offloaded). With this patch segmentation is offloaded as expected and the traffic is correctly received at the other end.
Fixes: 24b2c3751aa3 ("sfc: advertise encapsulated offloads on EF10") Reported-by: Tianhao Zhao tizhao@redhat.com Signed-off-by: Íñigo Huguet ihuguet@redhat.com Acked-by: Martin Habets habetsm.xilinx@gmail.com Link: https://lore.kernel.org/r/20230125143513.25841-1-ihuguet@redhat.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/sfc/efx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 0556542d7a6b..3a86f1213a05 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1003,8 +1003,11 @@ static int efx_pci_probe_post_io(struct efx_nic *efx) /* Determine netdevice features */ net_dev->features |= (efx->type->offload_features | NETIF_F_SG | NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_RXALL); - if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM)) + if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM)) { net_dev->features |= NETIF_F_TSO6; + if (efx_has_cap(efx, TX_TSO_V2_ENCAP)) + net_dev->hw_enc_features |= NETIF_F_TSO6; + } /* Check whether device supports TSO */ if (!efx->type->tso_versions || !efx->type->tso_versions(efx)) net_dev->features &= ~NETIF_F_ALL_TSO;
From: Andre Kalb andre.kalb@sma.de
[ Upstream commit 422ae7d9c7221e8d4c8526d0f54106307d69d2dc ]
The probe() function is only used for the DP83822 PHY, leaving the private data pointer uninitialized for the smaller DP83825/26 models. While all uses of the private data structure are hidden in 82822 specific callbacks, configuring the interrupt is shared across all models. This causes a NULL pointer dereference on the smaller PHYs as it accesses the private data unchecked. Verifying the pointer avoids that.
Fixes: 5dc39fd5ef35 ("net: phy: DP83822: Add ability to advertise Fiber connection") Signed-off-by: Andre Kalb andre.kalb@sma.de Reviewed-by: Simon Horman simon.horman@corigine.com Link: https://lore.kernel.org/r/Y9FzniUhUtbaGKU7@pc6682 Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/dp83822.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c index b60db8b6f477..267e6fd3d444 100644 --- a/drivers/net/phy/dp83822.c +++ b/drivers/net/phy/dp83822.c @@ -233,7 +233,8 @@ static int dp83822_config_intr(struct phy_device *phydev) DP83822_ENERGY_DET_INT_EN | DP83822_LINK_QUAL_INT_EN);
- if (!dp83822->fx_enabled) + /* Private data pointer is NULL on DP83825/26 */ + if (!dp83822 || !dp83822->fx_enabled) misr_status |= DP83822_ANEG_COMPLETE_INT_EN | DP83822_DUP_MODE_CHANGE_INT_EN | DP83822_SPEED_CHANGED_INT_EN; @@ -253,7 +254,8 @@ static int dp83822_config_intr(struct phy_device *phydev) DP83822_PAGE_RX_INT_EN | DP83822_EEE_ERROR_CHANGE_INT_EN);
- if (!dp83822->fx_enabled) + /* Private data pointer is NULL on DP83825/26 */ + if (!dp83822 || !dp83822->fx_enabled) misr_status |= DP83822_ANEG_ERR_INT_EN | DP83822_WOL_PKT_INT_EN;
From: Kornel Dulęba mindal@semihalf.com
[ Upstream commit e3d6d152a1cbdee25f2e3962009a2751b54e2297 ]
For PCI devices the Runtime PM refcount is incremented twice: 1. During device enumeration with a call to pm_runtime_forbid. 2. Just before a driver probe logic is called. Because of that in order to enable Runtime PM on a given device we have to call both pm_runtime_allow and pm_runtime_put_noidle, once it's ready to be runtime suspended. The former was missing causing the pm refcount to never reach 0.
Fixes: d10b3a695ba0 ("net: wwan: t7xx: Runtime PM") Signed-off-by: Kornel Dulęba mindal@semihalf.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wwan/t7xx/t7xx_pci.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c index 871f2a27a398..226fc1703e90 100644 --- a/drivers/net/wwan/t7xx/t7xx_pci.c +++ b/drivers/net/wwan/t7xx/t7xx_pci.c @@ -121,6 +121,8 @@ void t7xx_pci_pm_init_late(struct t7xx_pci_dev *t7xx_dev) iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR); atomic_set(&t7xx_dev->md_pm_state, MTK_PM_RESUMED);
+ pm_runtime_mark_last_busy(&t7xx_dev->pdev->dev); + pm_runtime_allow(&t7xx_dev->pdev->dev); pm_runtime_put_noidle(&t7xx_dev->pdev->dev); }
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit 337366e02b370d2800110fbc99940f6ddddcbdfa ]
Just to make the code a litter cleaner, there are no functional changes.
Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20221214033155.3455754-3-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe axboe@kernel.dk Stable-dep-of: b600de2d7d3a ("block, bfq: fix uaf for bfqq in bic_set_bfqq()") Signed-off-by: Sasha Levin sashal@kernel.org --- block/bfq-cgroup.c | 8 ++++---- block/bfq-iosched.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c index 7d624a3a3f0f..dfb6d1d8bd46 100644 --- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -718,15 +718,15 @@ static void *__bfq_bic_change_cgroup(struct bfq_data *bfqd, struct bfq_io_cq *bic, struct bfq_group *bfqg) { - struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0); - struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1); + struct bfq_queue *async_bfqq = bic_to_bfqq(bic, false); + struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, true); struct bfq_entity *entity;
if (async_bfqq) { entity = &async_bfqq->entity;
if (entity->sched_data != &bfqg->sched_data) { - bic_set_bfqq(bic, NULL, 0); + bic_set_bfqq(bic, NULL, false); bfq_release_process_ref(bfqd, async_bfqq); } } @@ -762,7 +762,7 @@ static void *__bfq_bic_change_cgroup(struct bfq_data *bfqd, */ bfq_put_cooperator(sync_bfqq); bfq_release_process_ref(bfqd, sync_bfqq); - bic_set_bfqq(bic, NULL, 1); + bic_set_bfqq(bic, NULL, true); } } } diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 7b894df32e32..917939b60ef8 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -3180,7 +3180,7 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, /* * Merge queues (that is, let bic redirect its requests to new_bfqq) */ - bic_set_bfqq(bic, new_bfqq, 1); + bic_set_bfqq(bic, new_bfqq, true); bfq_mark_bfqq_coop(new_bfqq); /* * new_bfqq now belongs to at least two bics (it is a shared queue): @@ -6627,7 +6627,7 @@ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) return bfqq; }
- bic_set_bfqq(bic, NULL, 1); + bic_set_bfqq(bic, NULL, true);
bfq_put_cooperator(bfqq);
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit b600de2d7d3a16f9007fad1bdae82a3951a26af2 ]
After commit 64dc8c732f5c ("block, bfq: fix possible uaf for 'bfqq->bic'"), bic->bfqq will be accessed in bic_set_bfqq(), however, in some context bic->bfqq will be freed, and bic_set_bfqq() is called with the freed bic->bfqq.
Fix the problem by always freeing bfqq after bic_set_bfqq().
Fixes: 64dc8c732f5c ("block, bfq: fix possible uaf for 'bfqq->bic'") Reported-and-tested-by: Shinichiro Kawasaki shinichiro.kawasaki@wdc.com Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20230130014136.591038-1-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/bfq-cgroup.c | 2 +- block/bfq-iosched.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c index dfb6d1d8bd46..60b4299bec8e 100644 --- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -761,8 +761,8 @@ static void *__bfq_bic_change_cgroup(struct bfq_data *bfqd, * request from the old cgroup. */ bfq_put_cooperator(sync_bfqq); - bfq_release_process_ref(bfqd, sync_bfqq); bic_set_bfqq(bic, NULL, true); + bfq_release_process_ref(bfqd, sync_bfqq); } } } diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 917939b60ef8..ff9d23889415 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -5491,9 +5491,11 @@ static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio)
bfqq = bic_to_bfqq(bic, false); if (bfqq) { - bfq_release_process_ref(bfqd, bfqq); + struct bfq_queue *old_bfqq = bfqq; + bfqq = bfq_get_queue(bfqd, bio, false, bic, true); bic_set_bfqq(bic, bfqq, false); + bfq_release_process_ref(bfqd, old_bfqq); }
bfqq = bic_to_bfqq(bic, true);
From: Hyunwoo Kim v4bel@theori.io
[ Upstream commit 611792920925fb088ddccbe2783c7f92fdfb6b64 ]
If you call listen() and accept() on an already connect()ed AF_NETROM socket, accept() can successfully connect. This is because when the peer socket sends data to sendmsg, the skb with its own sk stored in the connected socket's sk->sk_receive_queue is connected, and nr_accept() dequeues the skb waiting in the sk->sk_receive_queue.
As a result, nr_accept() allocates and returns a sock with the sk of the parent AF_NETROM socket.
And here use-after-free can happen through complex race conditions: ``` cpu0 cpu1 1. socket_2 = socket(AF_NETROM) . . listen(socket_2) accepted_socket = accept(socket_2) 2. socket_1 = socket(AF_NETROM) nr_create() // sk refcount : 1 connect(socket_1) 3. write(accepted_socket) nr_sendmsg() nr_output() nr_kick() nr_send_iframe() nr_transmit_buffer() nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() nr_process_rx_frame(sk, skb); // sk : socket_1's sk nr_state3_machine() nr_queue_rx_frame() sock_queue_rcv_skb() sock_queue_rcv_skb_reason() __sock_queue_rcv_skb() __skb_queue_tail(list, skb); // list : socket_1's sk->sk_receive_queue 4. listen(socket_1) nr_listen() uaf_socket = accept(socket_1) nr_accept() skb_dequeue(&sk->sk_receive_queue); 5. close(accepted_socket) nr_release() nr_write_internal(sk, NR_DISCREQ) nr_transmit_buffer() // NR_DISCREQ nr_route_frame() nr_loopback_queue() nr_loopback_timer() nr_rx_frame() // sk : socket_1's sk nr_process_rx_frame() // NR_STATE_3 nr_state3_machine() // NR_DISCREQ nr_disconnect() nr_sk(sk)->state = NR_STATE_0; 6. close(socket_1) // sk refcount : 3 nr_release() // NR_STATE_0 sock_put(sk); // sk refcount : 0 sk_free(sk); close(uaf_socket) nr_release() sock_hold(sk); // UAF ```
KASAN report by syzbot: ``` BUG: KASAN: use-after-free in nr_release+0x66/0x460 net/netrom/af_netrom.c:520 Write of size 4 at addr ffff8880235d8080 by task syz-executor564/5128
Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xd1/0x138 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:306 [inline] print_report+0x15e/0x461 mm/kasan/report.c:417 kasan_report+0xbf/0x1f0 mm/kasan/report.c:517 check_region_inline mm/kasan/generic.c:183 [inline] kasan_check_range+0x141/0x190 mm/kasan/generic.c:189 instrument_atomic_read_write include/linux/instrumented.h:102 [inline] atomic_fetch_add_relaxed include/linux/atomic/atomic-instrumented.h:116 [inline] __refcount_add include/linux/refcount.h:193 [inline] __refcount_inc include/linux/refcount.h:250 [inline] refcount_inc include/linux/refcount.h:267 [inline] sock_hold include/net/sock.h:775 [inline] nr_release+0x66/0x460 net/netrom/af_netrom.c:520 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f6c19e3c9b9 Code: Unable to access opcode bytes at 0x7f6c19e3c98f. RSP: 002b:00007fffd4ba2ce8 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: 0000000000000116 RBX: 0000000000000003 RCX: 00007f6c19e3c9b9 RDX: 0000000000000318 RSI: 00000000200bd000 RDI: 0000000000000006 RBP: 0000000000000003 R08: 000000000000000d R09: 000000000000000d R10: 0000000000000000 R11: 0000000000000246 R12: 000055555566a2c0 R13: 0000000000000011 R14: 0000000000000000 R15: 0000000000000000 </TASK>
Allocated by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 ____kasan_kmalloc mm/kasan/common.c:371 [inline] ____kasan_kmalloc mm/kasan/common.c:330 [inline] __kasan_kmalloc+0xa3/0xb0 mm/kasan/common.c:380 kasan_kmalloc include/linux/kasan.h:211 [inline] __do_kmalloc_node mm/slab_common.c:968 [inline] __kmalloc+0x5a/0xd0 mm/slab_common.c:981 kmalloc include/linux/slab.h:584 [inline] sk_prot_alloc+0x140/0x290 net/core/sock.c:2038 sk_alloc+0x3a/0x7a0 net/core/sock.c:2091 nr_create+0xb6/0x5f0 net/netrom/af_netrom.c:433 __sock_create+0x359/0x790 net/socket.c:1515 sock_create net/socket.c:1566 [inline] __sys_socket_create net/socket.c:1603 [inline] __sys_socket_create net/socket.c:1588 [inline] __sys_socket+0x133/0x250 net/socket.c:1636 __do_sys_socket net/socket.c:1649 [inline] __se_sys_socket net/socket.c:1647 [inline] __x64_sys_socket+0x73/0xb0 net/socket.c:1647 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
Freed by task 5128: kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 kasan_set_track+0x25/0x30 mm/kasan/common.c:52 kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518 ____kasan_slab_free mm/kasan/common.c:236 [inline] ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200 kasan_slab_free include/linux/kasan.h:177 [inline] __cache_free mm/slab.c:3394 [inline] __do_kmem_cache_free mm/slab.c:3580 [inline] __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587 sk_prot_free net/core/sock.c:2074 [inline] __sk_destruct+0x5df/0x750 net/core/sock.c:2166 sk_destruct net/core/sock.c:2181 [inline] __sk_free+0x175/0x460 net/core/sock.c:2192 sk_free+0x7c/0xa0 net/core/sock.c:2203 sock_put include/net/sock.h:1991 [inline] nr_release+0x39e/0x460 net/netrom/af_netrom.c:554 __sock_release+0xcd/0x280 net/socket.c:650 sock_close+0x1c/0x20 net/socket.c:1365 __fput+0x27c/0xa90 fs/file_table.c:320 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xaa8/0x2950 kernel/exit.c:867 do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 get_signal+0x21c3/0x2450 kernel/signal.c:2859 arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd ```
To fix this issue, nr_listen() returns -EINVAL for sockets that successfully nr_connect().
Reported-by: syzbot+caa188bdfc1eeafeb418@syzkaller.appspotmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Hyunwoo Kim v4bel@theori.io 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/netrom/af_netrom.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 6f7f4392cffb..5a4cb796150f 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -400,6 +400,11 @@ static int nr_listen(struct socket *sock, int backlog) struct sock *sk = sock->sk;
lock_sock(sk); + if (sock->state != SS_UNCONNECTED) { + release_sock(sk); + return -EINVAL; + } + if (sk->sk_state != TCP_LISTEN) { memset(&nr_sk(sk)->user_addr, 0, AX25_ADDR_LEN); sk->sk_max_ack_backlog = backlog;
From: Hou Tao houtao1@huawei.com
[ Upstream commit 8226e37d82f43657da34dd770e2b38f20242ada7 ]
The freeing of relinquished volume will wake up the pending volume acquisition by using wake_up_bit(), however it is mismatched with wait_var_event() used in fscache_wait_on_volume_collision() and it will never wake up the waiter in the wait-queue because these two functions operate on different wait-queues.
According to the implementation in fscache_wait_on_volume_collision(), if the wake-up of pending acquisition is delayed longer than 20 seconds (e.g., due to the delay of on-demand fd closing), the first wait_var_event_timeout() will timeout and the following wait_var_event() will hang forever as shown below:
FS-Cache: Potential volume collision new=00000024 old=00000022 ...... INFO: task mount:1148 blocked for more than 122 seconds. Not tainted 6.1.0-rc6+ #1 task:mount state:D stack:0 pid:1148 ppid:1 Call Trace: <TASK> __schedule+0x2f6/0xb80 schedule+0x67/0xe0 fscache_wait_on_volume_collision.cold+0x80/0x82 __fscache_acquire_volume+0x40d/0x4e0 erofs_fscache_register_volume+0x51/0xe0 [erofs] erofs_fscache_register_fs+0x19c/0x240 [erofs] erofs_fc_fill_super+0x746/0xaf0 [erofs] vfs_get_super+0x7d/0x100 get_tree_nodev+0x16/0x20 erofs_fc_get_tree+0x20/0x30 [erofs] vfs_get_tree+0x24/0xb0 path_mount+0x2fa/0xa90 do_mount+0x7c/0xa0 __x64_sys_mount+0x8b/0xe0 do_syscall_64+0x30/0x60 entry_SYSCALL_64_after_hwframe+0x46/0xb0
Considering that wake_up_bit() is more selective, so fix it by using wait_on_bit() instead of wait_var_event() to wait for the freeing of relinquished volume. In addition because waitqueue_active() is used in wake_up_bit() and clear_bit() doesn't imply any memory barrier, use clear_and_wake_up_bit() to add the missing memory barrier between cursor->flags and waitqueue_active().
Fixes: 62ab63352350 ("fscache: Implement volume registration") Reviewed-by: Jingbo Xu jefflexu@linux.alibaba.com Signed-off-by: Hou Tao houtao1@huawei.com Signed-off-by: David Howells dhowells@redhat.com Reviewed-by: Jeff Layton jlayton@kernel.org Link: https://lore.kernel.org/r/20230113115211.2895845-2-houtao@huaweicloud.com/ # v3 Signed-off-by: Sasha Levin sashal@kernel.org --- fs/fscache/volume.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/fs/fscache/volume.c b/fs/fscache/volume.c index ab8ceddf9efa..903af9d85f8b 100644 --- a/fs/fscache/volume.c +++ b/fs/fscache/volume.c @@ -141,13 +141,14 @@ static bool fscache_is_acquire_pending(struct fscache_volume *volume) static void fscache_wait_on_volume_collision(struct fscache_volume *candidate, unsigned int collidee_debug_id) { - wait_var_event_timeout(&candidate->flags, - !fscache_is_acquire_pending(candidate), 20 * HZ); + wait_on_bit_timeout(&candidate->flags, FSCACHE_VOLUME_ACQUIRE_PENDING, + TASK_UNINTERRUPTIBLE, 20 * HZ); if (fscache_is_acquire_pending(candidate)) { pr_notice("Potential volume collision new=%08x old=%08x", candidate->debug_id, collidee_debug_id); fscache_stat(&fscache_n_volumes_collision); - wait_var_event(&candidate->flags, !fscache_is_acquire_pending(candidate)); + wait_on_bit(&candidate->flags, FSCACHE_VOLUME_ACQUIRE_PENDING, + TASK_UNINTERRUPTIBLE); } }
@@ -347,8 +348,8 @@ static void fscache_wake_pending_volume(struct fscache_volume *volume, hlist_bl_for_each_entry(cursor, p, h, hash_link) { if (fscache_volume_same(cursor, volume)) { fscache_see_volume(cursor, fscache_volume_see_hash_wake); - clear_bit(FSCACHE_VOLUME_ACQUIRE_PENDING, &cursor->flags); - wake_up_bit(&cursor->flags, FSCACHE_VOLUME_ACQUIRE_PENDING); + clear_and_wake_up_bit(FSCACHE_VOLUME_ACQUIRE_PENDING, + &cursor->flags); return; } }
From: Shyam Sundar S K Shyam-sundar.S-k@amd.com
[ Upstream commit 3dfe28c936f87373a2b6ada750be4c52c0f249f3 ]
Auto-mode thermal limits should be updated only after receiving the AMT event. But due to a bug in the older commit, these settings were getting applied during the auto-mode init.
Fix this by removing amd_pmf_set_automode() during auto-mode initialization.
Fixes: 3f5571d99524 ("platform/x86/amd/pmf: Add support for Auto mode feature") Suggested-by: Patil Rajesh Reddy Patil.Reddy@amd.com Signed-off-by: Shyam Sundar S K Shyam-sundar.S-k@amd.com Reviewed-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20230125095936.3292883-4-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/amd/pmf/auto-mode.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/platform/x86/amd/pmf/auto-mode.c b/drivers/platform/x86/amd/pmf/auto-mode.c index 644af42e07cf..85ce9ed25b85 100644 --- a/drivers/platform/x86/amd/pmf/auto-mode.c +++ b/drivers/platform/x86/amd/pmf/auto-mode.c @@ -299,7 +299,5 @@ void amd_pmf_deinit_auto_mode(struct amd_pmf_dev *dev) void amd_pmf_init_auto_mode(struct amd_pmf_dev *dev) { amd_pmf_load_defaults_auto_mode(dev); - /* update the thermal limits for Automode */ - amd_pmf_set_automode(dev, config_store.current_mode, NULL); amd_pmf_init_metrics_table(dev); }
From: Shyam Sundar S K Shyam-sundar.S-k@amd.com
[ Upstream commit c5258d39fc4cbed37e20945715e7eb102f26d65b ]
Add helper routine to update the static slider information and remove the duplicate code occurrences after this change.
Signed-off-by: Shyam Sundar S K Shyam-sundar.S-k@amd.com Reviewed-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20230125095936.3292883-2-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Stable-dep-of: 635f79bc73cf ("platform/x86/amd/pmf: Fix to update SPS default pprof thermals") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/amd/pmf/auto-mode.c | 7 +------ drivers/platform/x86/amd/pmf/cnqf.c | 8 ++------ drivers/platform/x86/amd/pmf/pmf.h | 1 + drivers/platform/x86/amd/pmf/sps.c | 20 ++++++++++++++------ 4 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/drivers/platform/x86/amd/pmf/auto-mode.c b/drivers/platform/x86/amd/pmf/auto-mode.c index 85ce9ed25b85..96a8e1832c05 100644 --- a/drivers/platform/x86/amd/pmf/auto-mode.c +++ b/drivers/platform/x86/amd/pmf/auto-mode.c @@ -275,13 +275,8 @@ int amd_pmf_reset_amt(struct amd_pmf_dev *dev) */
if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { - int mode = amd_pmf_get_pprof_modes(dev); - - if (mode < 0) - return mode; - dev_dbg(dev->dev, "resetting AMT thermals\n"); - amd_pmf_update_slider(dev, SLIDER_OP_SET, mode, NULL); + amd_pmf_set_sps_power_limits(dev); } return 0; } diff --git a/drivers/platform/x86/amd/pmf/cnqf.c b/drivers/platform/x86/amd/pmf/cnqf.c index 668c7c0fea83..ef2ac30ff15e 100644 --- a/drivers/platform/x86/amd/pmf/cnqf.c +++ b/drivers/platform/x86/amd/pmf/cnqf.c @@ -307,13 +307,9 @@ static ssize_t cnqf_enable_store(struct device *dev, const char *buf, size_t count) { struct amd_pmf_dev *pdev = dev_get_drvdata(dev); - int mode, result, src; + int result, src; bool input;
- mode = amd_pmf_get_pprof_modes(pdev); - if (mode < 0) - return mode; - result = kstrtobool(buf, &input); if (result) return result; @@ -325,7 +321,7 @@ static ssize_t cnqf_enable_store(struct device *dev, amd_pmf_set_cnqf(pdev, src, config_store.current_mode, NULL); } else { if (is_apmf_func_supported(pdev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) - amd_pmf_update_slider(pdev, SLIDER_OP_SET, mode, NULL); + amd_pmf_set_sps_power_limits(pdev); }
dev_dbg(pdev->dev, "Received CnQF %s\n", input ? "on" : "off"); diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index 84bbe2c6ea61..b5b77a353b96 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -394,6 +394,7 @@ int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev,
int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx); +int amd_pmf_set_sps_power_limits(struct amd_pmf_dev *pmf);
/* Auto Mode Layer */ int apmf_get_auto_mode_def(struct amd_pmf_dev *pdev, struct apmf_auto_mode *data); diff --git a/drivers/platform/x86/amd/pmf/sps.c b/drivers/platform/x86/amd/pmf/sps.c index dba7e36962dc..5f842d6e6db2 100644 --- a/drivers/platform/x86/amd/pmf/sps.c +++ b/drivers/platform/x86/amd/pmf/sps.c @@ -70,6 +70,19 @@ void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx, } }
+int amd_pmf_set_sps_power_limits(struct amd_pmf_dev *pmf) +{ + int mode; + + mode = amd_pmf_get_pprof_modes(pmf); + if (mode < 0) + return mode; + + amd_pmf_update_slider(pmf, SLIDER_OP_SET, mode, NULL); + + return 0; +} + static int amd_pmf_profile_get(struct platform_profile_handler *pprof, enum platform_profile_option *profile) { @@ -105,15 +118,10 @@ static int amd_pmf_profile_set(struct platform_profile_handler *pprof, enum platform_profile_option profile) { struct amd_pmf_dev *pmf = container_of(pprof, struct amd_pmf_dev, pprof); - int mode;
pmf->current_profile = profile; - mode = amd_pmf_get_pprof_modes(pmf); - if (mode < 0) - return mode;
- amd_pmf_update_slider(pmf, SLIDER_OP_SET, mode, NULL); - return 0; + return amd_pmf_set_sps_power_limits(pmf); }
int amd_pmf_init_sps(struct amd_pmf_dev *dev)
From: Shyam Sundar S K Shyam-sundar.S-k@amd.com
[ Upstream commit 635f79bc73cf3d40c4198a20b3a0e7016dd6f0d3 ]
By design PMF static slider will be set to BALANCED during init, but updating to corresponding thermal values from the PMF config store was missed, leading to improper settings getting propagated to PMFW.
Fixes: 4c71ae414474 ("platform/x86/amd/pmf: Add support SPS PMF feature") Suggested-by: Patil Rajesh Reddy Patil.Reddy@amd.com Signed-off-by: Shyam Sundar S K Shyam-sundar.S-k@amd.com Reviewed-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20230125095936.3292883-5-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/amd/pmf/sps.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/platform/x86/amd/pmf/sps.c b/drivers/platform/x86/amd/pmf/sps.c index 5f842d6e6db2..5bccea137bda 100644 --- a/drivers/platform/x86/amd/pmf/sps.c +++ b/drivers/platform/x86/amd/pmf/sps.c @@ -131,6 +131,9 @@ int amd_pmf_init_sps(struct amd_pmf_dev *dev) dev->current_profile = PLATFORM_PROFILE_BALANCED; amd_pmf_load_defaults_sps(dev);
+ /* update SPS balanced power mode thermals */ + amd_pmf_set_sps_power_limits(dev); + dev->pprof.profile_get = amd_pmf_profile_get; dev->pprof.profile_set = amd_pmf_profile_set;
From: Shyam Sundar S K Shyam-sundar.S-k@amd.com
[ Upstream commit 16909aa8c9cc284085f1202c6403ecb9814af812 ]
Add helper routine to check if the current platform profile is balanced mode and remove duplicate code occurrences.
Signed-off-by: Shyam Sundar S K Shyam-sundar.S-k@amd.com Reviewed-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20230125095936.3292883-3-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Stable-dep-of: f21bf62290dd ("platform/x86/amd/pmf: Fix to update SPS thermals when power supply change") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/amd/pmf/cnqf.c | 6 +++--- drivers/platform/x86/amd/pmf/pmf.h | 1 + drivers/platform/x86/amd/pmf/sps.c | 5 +++++ 3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/platform/x86/amd/pmf/cnqf.c b/drivers/platform/x86/amd/pmf/cnqf.c index ef2ac30ff15e..f39275ec5cc9 100644 --- a/drivers/platform/x86/amd/pmf/cnqf.c +++ b/drivers/platform/x86/amd/pmf/cnqf.c @@ -103,7 +103,7 @@ int amd_pmf_trans_cnqf(struct amd_pmf_dev *dev, int socket_power, ktime_t time_l
src = amd_pmf_cnqf_get_power_source(dev);
- if (dev->current_profile == PLATFORM_PROFILE_BALANCED) { + if (is_pprof_balanced(dev)) { amd_pmf_set_cnqf(dev, src, config_store.current_mode, NULL); } else { /* @@ -317,7 +317,7 @@ static ssize_t cnqf_enable_store(struct device *dev, src = amd_pmf_cnqf_get_power_source(pdev); pdev->cnqf_enabled = input;
- if (pdev->cnqf_enabled && pdev->current_profile == PLATFORM_PROFILE_BALANCED) { + if (pdev->cnqf_enabled && is_pprof_balanced(pdev)) { amd_pmf_set_cnqf(pdev, src, config_store.current_mode, NULL); } else { if (is_apmf_func_supported(pdev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) @@ -382,7 +382,7 @@ int amd_pmf_init_cnqf(struct amd_pmf_dev *dev) dev->cnqf_enabled = amd_pmf_check_flags(dev);
/* update the thermal for CnQF */ - if (dev->cnqf_enabled && dev->current_profile == PLATFORM_PROFILE_BALANCED) { + if (dev->cnqf_enabled && is_pprof_balanced(dev)) { src = amd_pmf_cnqf_get_power_source(dev); amd_pmf_set_cnqf(dev, src, config_store.current_mode, NULL); } diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index b5b77a353b96..b94e1a9030f8 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -391,6 +391,7 @@ int amd_pmf_init_sps(struct amd_pmf_dev *dev); void amd_pmf_deinit_sps(struct amd_pmf_dev *dev); int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev, struct apmf_static_slider_granular_output *output); +bool is_pprof_balanced(struct amd_pmf_dev *pmf);
int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx); diff --git a/drivers/platform/x86/amd/pmf/sps.c b/drivers/platform/x86/amd/pmf/sps.c index 5bccea137bda..bed762d47a14 100644 --- a/drivers/platform/x86/amd/pmf/sps.c +++ b/drivers/platform/x86/amd/pmf/sps.c @@ -83,6 +83,11 @@ int amd_pmf_set_sps_power_limits(struct amd_pmf_dev *pmf) return 0; }
+bool is_pprof_balanced(struct amd_pmf_dev *pmf) +{ + return (pmf->current_profile == PLATFORM_PROFILE_BALANCED) ? true : false; +} + static int amd_pmf_profile_get(struct platform_profile_handler *pprof, enum platform_profile_option *profile) {
From: Shyam Sundar S K Shyam-sundar.S-k@amd.com
[ Upstream commit f21bf62290dd4d769594dcf0e6a688783d74f6a0 ]
Every power mode of static power slider has its own AC and DC power settings.
When the power source changes from AC to DC, corresponding DC thermals were not updated from PMF config store and this leads the system to always run on AC power settings.
Fix it by registering with power_supply notifier and apply DC settings upon getting notified by the power_supply handler.
Fixes: da5ce22df5fe ("platform/x86/amd/pmf: Add support for PMF core layer") Suggested-by: Patil Rajesh Reddy Patil.Reddy@amd.com Signed-off-by: Shyam Sundar S K Shyam-sundar.S-k@amd.com Reviewed-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20230125095936.3292883-6-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/amd/pmf/core.c | 23 +++++++++++++++++++++++ drivers/platform/x86/amd/pmf/pmf.h | 1 + 2 files changed, 24 insertions(+)
diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c index a5f5a4bcff6d..c9f7bcef4ac8 100644 --- a/drivers/platform/x86/amd/pmf/core.c +++ b/drivers/platform/x86/amd/pmf/core.c @@ -58,6 +58,25 @@ static bool force_load; module_param(force_load, bool, 0444); MODULE_PARM_DESC(force_load, "Force load this driver on supported older platforms (experimental)");
+static int amd_pmf_pwr_src_notify_call(struct notifier_block *nb, unsigned long event, void *data) +{ + struct amd_pmf_dev *pmf = container_of(nb, struct amd_pmf_dev, pwr_src_notifier); + + if (event != PSY_EVENT_PROP_CHANGED) + return NOTIFY_OK; + + if (is_apmf_func_supported(pmf, APMF_FUNC_AUTO_MODE) || + is_apmf_func_supported(pmf, APMF_FUNC_DYN_SLIDER_DC) || + is_apmf_func_supported(pmf, APMF_FUNC_DYN_SLIDER_AC)) { + if ((pmf->amt_enabled || pmf->cnqf_enabled) && is_pprof_balanced(pmf)) + return NOTIFY_DONE; + } + + amd_pmf_set_sps_power_limits(pmf); + + return NOTIFY_OK; +} + static int current_power_limits_show(struct seq_file *seq, void *unused) { struct amd_pmf_dev *dev = seq->private; @@ -372,6 +391,9 @@ static int amd_pmf_probe(struct platform_device *pdev) apmf_install_handler(dev); amd_pmf_dbgfs_register(dev);
+ dev->pwr_src_notifier.notifier_call = amd_pmf_pwr_src_notify_call; + power_supply_reg_notifier(&dev->pwr_src_notifier); + mutex_init(&dev->lock); mutex_init(&dev->update_mutex); dev_info(dev->dev, "registered PMF device successfully\n"); @@ -383,6 +405,7 @@ static int amd_pmf_remove(struct platform_device *pdev) { struct amd_pmf_dev *dev = platform_get_drvdata(pdev);
+ power_supply_unreg_notifier(&dev->pwr_src_notifier); mutex_destroy(&dev->lock); mutex_destroy(&dev->update_mutex); amd_pmf_deinit_features(dev); diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index b94e1a9030f8..06c30cdc0573 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -169,6 +169,7 @@ struct amd_pmf_dev { struct mutex update_mutex; /* protects race between ACPI handler and metrics thread */ bool cnqf_enabled; bool cnqf_supported; + struct notifier_block pwr_src_notifier; };
struct apmf_sps_prop_granular {
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit e0c40529ff942a985eb0f3dacf18d35ee4dbb03d ]
As soon as the first handler or sysfs file is registered the mutex may get used.
Move the initialization to before any handler registration / sysfs file creation.
Likewise move the destruction of the mutex to after all the de-initialization is done.
Fixes: da5ce22df5fe ("platform/x86/amd/pmf: Add support for PMF core layer") Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230130132554.696025-1-hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/amd/pmf/core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c index c9f7bcef4ac8..da23639071d7 100644 --- a/drivers/platform/x86/amd/pmf/core.c +++ b/drivers/platform/x86/amd/pmf/core.c @@ -385,6 +385,9 @@ static int amd_pmf_probe(struct platform_device *pdev) if (!dev->regbase) return -ENOMEM;
+ mutex_init(&dev->lock); + mutex_init(&dev->update_mutex); + apmf_acpi_init(dev); platform_set_drvdata(pdev, dev); amd_pmf_init_features(dev); @@ -394,8 +397,6 @@ static int amd_pmf_probe(struct platform_device *pdev) dev->pwr_src_notifier.notifier_call = amd_pmf_pwr_src_notify_call; power_supply_reg_notifier(&dev->pwr_src_notifier);
- mutex_init(&dev->lock); - mutex_init(&dev->update_mutex); dev_info(dev->dev, "registered PMF device successfully\n");
return 0; @@ -406,11 +407,11 @@ static int amd_pmf_remove(struct platform_device *pdev) struct amd_pmf_dev *dev = platform_get_drvdata(pdev);
power_supply_unreg_notifier(&dev->pwr_src_notifier); - mutex_destroy(&dev->lock); - mutex_destroy(&dev->update_mutex); amd_pmf_deinit_features(dev); apmf_acpi_deinit(dev); amd_pmf_dbgfs_unregister(dev); + mutex_destroy(&dev->lock); + mutex_destroy(&dev->update_mutex); kfree(dev->buf); return 0; }
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit eebf82012dddbdcb09e4e49d3cdfafb93bc66eb2 ]
Reading the thinklight LED brightnes while the LED is on returns 255 (LED_FULL) but we advertise a max_brightness of 1, so this should be 1 (LED_ON).
Fixes: db5e2a4ca0a7 ("platform/x86: thinkpad_acpi: Fix max_brightness of thinklight") Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230127235723.412864-1-hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/thinkpad_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 7fd735c67a8e..2a48a2d880d8 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -5566,7 +5566,7 @@ static int light_sysfs_set(struct led_classdev *led_cdev,
static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev) { - return (light_get_status() == 1) ? LED_FULL : LED_OFF; + return (light_get_status() == 1) ? LED_ON : LED_OFF; }
static struct tpacpi_led_classdev tpacpi_led_thinklight = {
From: John Harrison John.C.Harrison@Intel.com
[ Upstream commit 87b04e53daf806945c415e94de9f90943d434aed ]
intel_guc_find_hung_context() was not acquiring the correct spinlock before searching the request list. So fix that up. While at it, add some extra whitespace padding for readability.
Fixes: dc0dad365c5e ("drm/i915/guc: Fix for error capture after full GPU reset with GuC") Signed-off-by: John Harrison John.C.Harrison@Intel.com Reviewed-by: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com Acked-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Cc: Matthew Brost matthew.brost@intel.com Cc: Jani Nikula jani.nikula@linux.intel.com Cc: Joonas Lahtinen joonas.lahtinen@linux.intel.com Cc: Rodrigo Vivi rodrigo.vivi@intel.com Cc: Matt Roper matthew.d.roper@intel.com Cc: Umesh Nerlige Ramappa umesh.nerlige.ramappa@intel.com Cc: Michael Cheng michael.cheng@intel.com Cc: Lucas De Marchi lucas.demarchi@intel.com Cc: Tejas Upadhyay tejaskumarx.surendrakumar.upadhyay@intel.com Cc: Chris Wilson chris.p.wilson@intel.com Cc: Bruce Chang yu.bruce.chang@intel.com Cc: Alan Previn alan.previn.teres.alexis@intel.com Cc: Matthew Auld matthew.auld@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230127002842.3169194-2-John.... (cherry picked from commit d1c3717501bcf56536e8b8c1bdaf5cd5357f6bb2) Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index 1a23e901cc66..259162002c3a 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -4587,6 +4587,8 @@ void intel_guc_find_hung_context(struct intel_engine_cs *engine)
xa_lock_irqsave(&guc->context_lookup, flags); xa_for_each(&guc->context_lookup, index, ce) { + bool found; + if (!kref_get_unless_zero(&ce->ref)) continue;
@@ -4603,10 +4605,18 @@ void intel_guc_find_hung_context(struct intel_engine_cs *engine) goto next; }
+ found = false; + spin_lock(&ce->guc_state.lock); list_for_each_entry(rq, &ce->guc_state.requests, sched.link) { if (i915_test_request_state(rq) != I915_REQUEST_ACTIVE) continue;
+ found = true; + break; + } + spin_unlock(&ce->guc_state.lock); + + if (found) { intel_engine_set_hung_context(engine, ce);
/* Can only cope with one hang at a time... */ @@ -4614,6 +4624,7 @@ void intel_guc_find_hung_context(struct intel_engine_cs *engine) xa_lock(&guc->context_lookup); goto done; } + next: intel_context_put(ce); xa_lock(&guc->context_lookup);
From: John Harrison John.C.Harrison@Intel.com
[ Upstream commit 86d8ddc74124c3fdfc139f246ba6da15e45e86e3 ]
When GuC support was added to error capture, the reference counting around the request object was broken. Fix it up.
The context based search manages the spinlocking around the search internally. So it needs to grab the reference count internally as well. The execlist only request based search relies on external locking, so it needs an external reference count but within the spinlock not outside it.
The only other caller of the context based search is the code for dumping engine state to debugfs. That code wasn't previously getting an explicit reference at all as it does everything while holding the execlist specific spinlock. So, that needs updaing as well as that spinlock doesn't help when using GuC submission. Rather than trying to conditionally get/put depending on submission model, just change it to always do the get/put.
v2: Explicitly document adding an extra blank line in some dense code (Andy Shevchenko). Fix multiple potential null pointer derefs in case of no request found (some spotted by Tvrtko, but there was more!). Also fix a leaked request in case of !started and another in __guc_reset_context now that intel_context_find_active_request is actually reference counting the returned request. v3: Add a _get suffix to intel_context_find_active_request now that it grabs a reference (Daniele). v4: Split the intel_guc_find_hung_context change to a separate patch and rename intel_context_find_active_request_get to intel_context_get_active_request (Tvrtko). v5: s/locking/reference counting/ in commit message (Tvrtko)
Fixes: dc0dad365c5e ("drm/i915/guc: Fix for error capture after full GPU reset with GuC") Fixes: 573ba126aef3 ("drm/i915/guc: Capture error state on context reset") Signed-off-by: John Harrison John.C.Harrison@Intel.com Reviewed-by: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com Acked-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Cc: Matthew Brost matthew.brost@intel.com Cc: Jani Nikula jani.nikula@linux.intel.com Cc: Joonas Lahtinen joonas.lahtinen@linux.intel.com Cc: Rodrigo Vivi rodrigo.vivi@intel.com Cc: Andrzej Hajda andrzej.hajda@intel.com Cc: Matthew Auld matthew.auld@intel.com Cc: Matt Roper matthew.d.roper@intel.com Cc: Umesh Nerlige Ramappa umesh.nerlige.ramappa@intel.com Cc: Michael Cheng michael.cheng@intel.com Cc: Lucas De Marchi lucas.demarchi@intel.com Cc: Tejas Upadhyay tejaskumarx.surendrakumar.upadhyay@intel.com Cc: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: Aravind Iddamsetty aravind.iddamsetty@intel.com Cc: Alan Previn alan.previn.teres.alexis@intel.com Cc: Bruce Chang yu.bruce.chang@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230127002842.3169194-3-John.... (cherry picked from commit 3700e353781e27f1bc7222f51f2cc36cbeb9b4ec) Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/gt/intel_context.c | 4 +++- drivers/gpu/drm/i915/gt/intel_context.h | 3 +-- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 6 +++++- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 3 ++- drivers/gpu/drm/i915/i915_gpu_error.c | 13 ++++++------- 5 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index e94365b08f1e..2aa63ec521b8 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -528,7 +528,7 @@ struct i915_request *intel_context_create_request(struct intel_context *ce) return rq; }
-struct i915_request *intel_context_find_active_request(struct intel_context *ce) +struct i915_request *intel_context_get_active_request(struct intel_context *ce) { struct intel_context *parent = intel_context_to_parent(ce); struct i915_request *rq, *active = NULL; @@ -552,6 +552,8 @@ struct i915_request *intel_context_find_active_request(struct intel_context *ce)
active = rq; } + if (active) + active = i915_request_get_rcu(active); spin_unlock_irqrestore(&parent->guc_state.lock, flags);
return active; diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h index be09fb2e883a..4ab6c8ddd6ec 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.h +++ b/drivers/gpu/drm/i915/gt/intel_context.h @@ -268,8 +268,7 @@ int intel_context_prepare_remote_request(struct intel_context *ce,
struct i915_request *intel_context_create_request(struct intel_context *ce);
-struct i915_request * -intel_context_find_active_request(struct intel_context *ce); +struct i915_request *intel_context_get_active_request(struct intel_context *ce);
static inline bool intel_context_is_barrier(const struct intel_context *ce) { diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index fcbccd8d244e..4327c6d91ce9 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -2201,9 +2201,11 @@ static void engine_dump_active_requests(struct intel_engine_cs *engine, struct d if (guc) { ce = intel_engine_get_hung_context(engine); if (ce) - hung_rq = intel_context_find_active_request(ce); + hung_rq = intel_context_get_active_request(ce); } else { hung_rq = intel_engine_execlist_find_hung_request(engine); + if (hung_rq) + hung_rq = i915_request_get_rcu(hung_rq); }
if (hung_rq) @@ -2214,6 +2216,8 @@ static void engine_dump_active_requests(struct intel_engine_cs *engine, struct d else intel_engine_dump_active_requests(&engine->sched_engine->requests, hung_rq, m); + if (hung_rq) + i915_request_put(hung_rq); }
void intel_engine_dump(struct intel_engine_cs *engine, diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index 259162002c3a..0ec07dad1dcf 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -1685,7 +1685,7 @@ static void __guc_reset_context(struct intel_context *ce, intel_engine_mask_t st goto next_context;
guilty = false; - rq = intel_context_find_active_request(ce); + rq = intel_context_get_active_request(ce); if (!rq) { head = ce->ring->tail; goto out_replay; @@ -1698,6 +1698,7 @@ static void __guc_reset_context(struct intel_context *ce, intel_engine_mask_t st head = intel_ring_wrap(ce->ring, rq->head);
__i915_request_reset(rq, guilty); + i915_request_put(rq); out_replay: guc_reset_state(ce, head, guilty); next_context: diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 9ea2fe34e7d3..a8ee4cd2ff16 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1603,7 +1603,7 @@ capture_engine(struct intel_engine_cs *engine, ce = intel_engine_get_hung_context(engine); if (ce) { intel_engine_clear_hung_context(engine); - rq = intel_context_find_active_request(ce); + rq = intel_context_get_active_request(ce); if (!rq || !i915_request_started(rq)) goto no_request_capture; } else { @@ -1614,21 +1614,18 @@ capture_engine(struct intel_engine_cs *engine, if (!intel_uc_uses_guc_submission(&engine->gt->uc)) { spin_lock_irqsave(&engine->sched_engine->lock, flags); rq = intel_engine_execlist_find_hung_request(engine); + if (rq) + rq = i915_request_get_rcu(rq); spin_unlock_irqrestore(&engine->sched_engine->lock, flags); } } - if (rq) - rq = i915_request_get_rcu(rq); - if (!rq) goto no_request_capture;
capture = intel_engine_coredump_add_request(ee, rq, ATOMIC_MAYFAIL); - if (!capture) { - i915_request_put(rq); + if (!capture) goto no_request_capture; - } if (dump_flags & CORE_DUMP_FLAG_IS_GUC_CAPTURE) intel_guc_capture_get_matching_node(engine->gt, ee, ce);
@@ -1638,6 +1635,8 @@ capture_engine(struct intel_engine_cs *engine, return ee;
no_request_capture: + if (rq) + i915_request_put(rq); kfree(ee); return NULL; }
From: John Harrison John.C.Harrison@Intel.com
[ Upstream commit 5bc4b43d5c6c9692ddc7b96116650cdf9406f3da ]
The debugfs dump of requests was confused about what state requires the execlist lock versus the GuC lock. There was also a bunch of duplicated messy code between it and the error capture code.
So refactor the hung request search into a re-usable function. And reduce the span of the execlist state lock to only the execlist specific code paths. In order to do that, also move the report of hold count (which is an execlist only concept) from the top level dump function to the lower level execlist specific function. Also, move the execlist specific code into the execlist source file.
v2: Rename some functions and move to more appropriate files (Daniele). v3: Rename new execlist dump function (Daniele)
Fixes: dc0dad365c5e ("drm/i915/guc: Fix for error capture after full GPU reset with GuC") Signed-off-by: John Harrison John.C.Harrison@Intel.com Reviewed-by: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com Acked-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Cc: Matthew Brost matthew.brost@intel.com Cc: Jani Nikula jani.nikula@linux.intel.com Cc: Joonas Lahtinen joonas.lahtinen@linux.intel.com Cc: Rodrigo Vivi rodrigo.vivi@intel.com Cc: Matt Roper matthew.d.roper@intel.com Cc: Umesh Nerlige Ramappa umesh.nerlige.ramappa@intel.com Cc: Michael Cheng michael.cheng@intel.com Cc: Lucas De Marchi lucas.demarchi@intel.com Cc: Bruce Chang yu.bruce.chang@intel.com Cc: Alan Previn alan.previn.teres.alexis@intel.com Cc: Matthew Auld matthew.auld@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230127002842.3169194-4-John.... (cherry picked from commit a4be3dca53172d9d2091e4b474fb795c81ed3d6c) Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/gt/intel_engine.h | 4 +- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 74 +++++++++---------- .../drm/i915/gt/intel_execlists_submission.c | 27 +++++++ .../drm/i915/gt/intel_execlists_submission.h | 4 + drivers/gpu/drm/i915/i915_gpu_error.c | 26 +------ 5 files changed, 73 insertions(+), 62 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h index cbc8b857d5f7..7a4504ea35c3 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine.h +++ b/drivers/gpu/drm/i915/gt/intel_engine.h @@ -248,8 +248,8 @@ void intel_engine_dump_active_requests(struct list_head *requests, ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine, ktime_t *now);
-struct i915_request * -intel_engine_execlist_find_hung_request(struct intel_engine_cs *engine); +void intel_engine_get_hung_entity(struct intel_engine_cs *engine, + struct intel_context **ce, struct i915_request **rq);
u32 intel_engine_context_size(struct intel_gt *gt, u8 class); struct intel_context * diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 4327c6d91ce9..b458547e1fc6 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -2078,17 +2078,6 @@ static void print_request_ring(struct drm_printer *m, struct i915_request *rq) } }
-static unsigned long list_count(struct list_head *list) -{ - struct list_head *pos; - unsigned long count = 0; - - list_for_each(pos, list) - count++; - - return count; -} - static unsigned long read_ul(void *p, size_t x) { return *(unsigned long *)(p + x); @@ -2180,11 +2169,11 @@ void intel_engine_dump_active_requests(struct list_head *requests, } }
-static void engine_dump_active_requests(struct intel_engine_cs *engine, struct drm_printer *m) +static void engine_dump_active_requests(struct intel_engine_cs *engine, + struct drm_printer *m) { + struct intel_context *hung_ce = NULL; struct i915_request *hung_rq = NULL; - struct intel_context *ce; - bool guc;
/* * No need for an engine->irq_seqno_barrier() before the seqno reads. @@ -2193,29 +2182,20 @@ static void engine_dump_active_requests(struct intel_engine_cs *engine, struct d * But the intention here is just to report an instantaneous snapshot * so that's fine. */ - lockdep_assert_held(&engine->sched_engine->lock); + intel_engine_get_hung_entity(engine, &hung_ce, &hung_rq);
drm_printf(m, "\tRequests:\n");
- guc = intel_uc_uses_guc_submission(&engine->gt->uc); - if (guc) { - ce = intel_engine_get_hung_context(engine); - if (ce) - hung_rq = intel_context_get_active_request(ce); - } else { - hung_rq = intel_engine_execlist_find_hung_request(engine); - if (hung_rq) - hung_rq = i915_request_get_rcu(hung_rq); - } - if (hung_rq) engine_dump_request(hung_rq, m, "\t\thung"); + else if (hung_ce) + drm_printf(m, "\t\tGot hung ce but no hung rq!\n");
- if (guc) + if (intel_uc_uses_guc_submission(&engine->gt->uc)) intel_guc_dump_active_requests(engine, hung_rq, m); else - intel_engine_dump_active_requests(&engine->sched_engine->requests, - hung_rq, m); + intel_execlists_dump_active_requests(engine, hung_rq, m); + if (hung_rq) i915_request_put(hung_rq); } @@ -2227,7 +2207,6 @@ void intel_engine_dump(struct intel_engine_cs *engine, struct i915_gpu_error * const error = &engine->i915->gpu_error; struct i915_request *rq; intel_wakeref_t wakeref; - unsigned long flags; ktime_t dummy;
if (header) { @@ -2264,13 +2243,8 @@ void intel_engine_dump(struct intel_engine_cs *engine, i915_reset_count(error)); print_properties(engine, m);
- spin_lock_irqsave(&engine->sched_engine->lock, flags); engine_dump_active_requests(engine, m);
- drm_printf(m, "\tOn hold?: %lu\n", - list_count(&engine->sched_engine->hold)); - spin_unlock_irqrestore(&engine->sched_engine->lock, flags); - drm_printf(m, "\tMMIO base: 0x%08x\n", engine->mmio_base); wakeref = intel_runtime_pm_get_if_in_use(engine->uncore->rpm); if (wakeref) { @@ -2316,8 +2290,7 @@ intel_engine_create_virtual(struct intel_engine_cs **siblings, return siblings[0]->cops->create_virtual(siblings, count, flags); }
-struct i915_request * -intel_engine_execlist_find_hung_request(struct intel_engine_cs *engine) +static struct i915_request *engine_execlist_find_hung_request(struct intel_engine_cs *engine) { struct i915_request *request, *active = NULL;
@@ -2369,6 +2342,33 @@ intel_engine_execlist_find_hung_request(struct intel_engine_cs *engine) return active; }
+void intel_engine_get_hung_entity(struct intel_engine_cs *engine, + struct intel_context **ce, struct i915_request **rq) +{ + unsigned long flags; + + *ce = intel_engine_get_hung_context(engine); + if (*ce) { + intel_engine_clear_hung_context(engine); + + *rq = intel_context_get_active_request(*ce); + return; + } + + /* + * Getting here with GuC enabled means it is a forced error capture + * with no actual hang. So, no need to attempt the execlist search. + */ + if (intel_uc_uses_guc_submission(&engine->gt->uc)) + return; + + spin_lock_irqsave(&engine->sched_engine->lock, flags); + *rq = engine_execlist_find_hung_request(engine); + if (*rq) + *rq = i915_request_get_rcu(*rq); + spin_unlock_irqrestore(&engine->sched_engine->lock, flags); +} + void xehp_enable_ccs_engines(struct intel_engine_cs *engine) { /* diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c index c718e6dc40b5..bfd1ffc71a48 100644 --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -4144,6 +4144,33 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, spin_unlock_irqrestore(&sched_engine->lock, flags); }
+static unsigned long list_count(struct list_head *list) +{ + struct list_head *pos; + unsigned long count = 0; + + list_for_each(pos, list) + count++; + + return count; +} + +void intel_execlists_dump_active_requests(struct intel_engine_cs *engine, + struct i915_request *hung_rq, + struct drm_printer *m) +{ + unsigned long flags; + + spin_lock_irqsave(&engine->sched_engine->lock, flags); + + intel_engine_dump_active_requests(&engine->sched_engine->requests, hung_rq, m); + + drm_printf(m, "\tOn hold?: %lu\n", + list_count(&engine->sched_engine->hold)); + + spin_unlock_irqrestore(&engine->sched_engine->lock, flags); +} + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "selftest_execlists.c" #endif diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.h b/drivers/gpu/drm/i915/gt/intel_execlists_submission.h index a1aa92c983a5..d2c7d45ea062 100644 --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.h +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.h @@ -32,6 +32,10 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, int indent), unsigned int max);
+void intel_execlists_dump_active_requests(struct intel_engine_cs *engine, + struct i915_request *hung_rq, + struct drm_printer *m); + bool intel_engine_in_execlists_submission_mode(const struct intel_engine_cs *engine);
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index a8ee4cd2ff16..847b9e6af1a1 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1592,35 +1592,15 @@ capture_engine(struct intel_engine_cs *engine, { struct intel_engine_capture_vma *capture = NULL; struct intel_engine_coredump *ee; - struct intel_context *ce; + struct intel_context *ce = NULL; struct i915_request *rq = NULL; - unsigned long flags;
ee = intel_engine_coredump_alloc(engine, ALLOW_FAIL, dump_flags); if (!ee) return NULL;
- ce = intel_engine_get_hung_context(engine); - if (ce) { - intel_engine_clear_hung_context(engine); - rq = intel_context_get_active_request(ce); - if (!rq || !i915_request_started(rq)) - goto no_request_capture; - } else { - /* - * Getting here with GuC enabled means it is a forced error capture - * with no actual hang. So, no need to attempt the execlist search. - */ - if (!intel_uc_uses_guc_submission(&engine->gt->uc)) { - spin_lock_irqsave(&engine->sched_engine->lock, flags); - rq = intel_engine_execlist_find_hung_request(engine); - if (rq) - rq = i915_request_get_rcu(rq); - spin_unlock_irqrestore(&engine->sched_engine->lock, - flags); - } - } - if (!rq) + intel_engine_get_hung_entity(engine, &ce, &rq); + if (!rq || !i915_request_started(rq)) goto no_request_capture;
capture = intel_engine_coredump_add_request(ee, rq, ATOMIC_MAYFAIL);
From: Chaitanya Kumar Borah chaitanya.kumar.borah@intel.com
[ Upstream commit 47a2bd9d985bfdb55900f313603619fc9234f317 ]
Fix typo for reference clock from 24400 to 24000.
Bspec: 55409 Fixes: 626426ff9ce4 ("drm/i915/adl_p: Add cdclk support for ADL-P") Reviewed-by: Matt Roper matthew.d.roper@intel.com Signed-off-by: Chaitanya Kumar Borah chaitanya.kumar.borah@intel.com Signed-off-by: Jani Nikula jani.nikula@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230112094131.550252-1-chaita... (cherry picked from commit 2b6f7e39ccae065abfbe3b6e562ec95ccad09f1e) Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/display/intel_cdclk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index ed05070b7307..92925f0f7239 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1323,7 +1323,7 @@ static const struct intel_cdclk_vals adlp_cdclk_table[] = { { .refclk = 24000, .cdclk = 192000, .divider = 2, .ratio = 16 }, { .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 }, { .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 46 }, - { .refclk = 24400, .cdclk = 648000, .divider = 2, .ratio = 54 }, + { .refclk = 24000, .cdclk = 648000, .divider = 2, .ratio = 54 },
{ .refclk = 38400, .cdclk = 179200, .divider = 3, .ratio = 14 }, { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 10 },
From: Pietro Borrello borrello@diag.uniroma1.it
[ Upstream commit ffe2a22562444720b05bdfeb999c03e810d84cbb ]
tls_is_tx_ready() checks that list_first_entry() does not return NULL. This condition can never happen. For empty lists, list_first_entry() returns the list_entry() of the head, which is a type confusion. Use list_first_entry_or_null() which returns NULL in case of empty lists.
Fixes: a42055e8d2c3 ("net/tls: Add support for async encryption of records for performance") Signed-off-by: Pietro Borrello borrello@diag.uniroma1.it Link: https://lore.kernel.org/r/20230128-list-entry-null-check-tls-v1-1-525bbfe6f0... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/tls/tls_sw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 9ed978634125..a83d2b4275fa 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -2427,7 +2427,7 @@ static bool tls_is_tx_ready(struct tls_sw_context_tx *ctx) { struct tls_rec *rec;
- rec = list_first_entry(&ctx->tx_list, struct tls_rec, list); + rec = list_first_entry_or_null(&ctx->tx_list, struct tls_rec, list); if (!rec) return false;
From: Takashi Sakamoto o-takashi@sakamocchi.jp
[ Upstream commit c7a806d9ce6757ff56078674916e53bd859f242d ]
Smatch static analysis tool detects that acquired lock is not released in hwdep device when condition branch is passed due to no event. It is unlikely to occur, while fulfilling is preferable for better coding.
Reported-by: Dan Carpenter error27@gmail.com Fixes: 634ec0b2906e ("ALSA: firewire-motu: notify event for parameter change in register DSP model") Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp Link: https://lore.kernel.org/r/20230130141540.102854-1-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/firewire/motu/motu-hwdep.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/sound/firewire/motu/motu-hwdep.c b/sound/firewire/motu/motu-hwdep.c index a900fc0e7644..88d1f4b56e4b 100644 --- a/sound/firewire/motu/motu-hwdep.c +++ b/sound/firewire/motu/motu-hwdep.c @@ -87,6 +87,10 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, return -EFAULT;
count = consumed; + } else { + spin_unlock_irq(&motu->lock); + + count = 0; }
return count;
From: Florian Westphal fw@strlen.de
[ Upstream commit 2b272bb558f1d3a5aa95ed8a82253786fd1a48ba ]
When using a xfrm interface in a bridged setup (the outgoing device is bridged), the incoming packets in the xfrm interface are only tracked in the outgoing direction.
$ brctl show bridge name interfaces br_eth1 eth1
$ conntrack -L tcp 115 SYN_SENT src=192... dst=192... [UNREPLIED] ...
If br_netfilter is enabled, the first (encrypted) packet is received onR eth1, conntrack hooks are called from br_netfilter emulation which allocates nf_bridge info for this skb.
If the packet is for local machine, skb gets passed up the ip stack. The skb passes through ip prerouting a second time. br_netfilter ip_sabotage_in supresses the re-invocation of the hooks.
After this, skb gets decrypted in xfrm layer and appears in network stack a second time (after decryption).
Then, ip_sabotage_in is called again and suppresses netfilter hook invocation, even though the bridge layer never called them for the plaintext incarnation of the packet.
Free the bridge info after the first suppression to avoid this.
I was unable to figure out where the regression comes from, as far as i can see br_netfilter always had this problem; i did not expect that skb is looped again with different headers.
Fixes: c4b0e771f906 ("netfilter: avoid using skb->nf_bridge directly") Reported-and-tested-by: Wolfgang Nothdurft wolfgang@linogate.de 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 --- net/bridge/br_netfilter_hooks.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c index f20f4373ff40..9554abcfd5b4 100644 --- a/net/bridge/br_netfilter_hooks.c +++ b/net/bridge/br_netfilter_hooks.c @@ -871,6 +871,7 @@ static unsigned int ip_sabotage_in(void *priv, if (nf_bridge && !nf_bridge->in_prerouting && !netif_is_l3_master(skb->dev) && !netif_is_l3_slave(skb->dev)) { + nf_bridge_info_free(skb); state->okfn(state->net, state->sk, skb); return NF_STOLEN; }
From: Liu Xiaodong xiaodong.liu@intel.com
[ Upstream commit 29baef789c838bd5c02f50c88adbbc6b955aaf61 ]
When validating drafted SPDK ublk target, in a case that assigning large queue depth to multiqueue ublk device, ublk target would run into a weird incorrect state. During rounds of review and debug, An overflow bug was found in ublk driver.
In ublk_cmd.h, UBLK_MAX_QUEUE_DEPTH is 4096 which means each ublk queue depth can be set as large as 4096. But when setting qd for a ublk device, sizeof(struct ublk_queue) + depth * sizeof(struct ublk_io) will be larger than 65535 if qd is larger than 2728. Then queue_size is overflowed, and ublk_get_queue() references a wrong pointer position. The wrong content of ublk_queue elements will lead to out-of-bounds memory access.
Extend queue_size in ublk_device as "unsigned int".
Signed-off-by: Liu Xiaodong xiaodong.liu@intel.com Fixes: 71f28f3136af ("ublk_drv: add io_uring based userspace block driver") Reviewed-by: Ming Lei ming.lei@redhat.com Link: https://lore.kernel.org/r/20230131070552.115067-1-xiaodong.liu@intel.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ublk_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index e54693204630..6368b56eacf1 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -137,7 +137,7 @@ struct ublk_device {
char *__queues;
- unsigned short queue_size; + unsigned int queue_size; struct ublksrv_ctrl_dev_info dev_info;
struct blk_mq_tag_set tag_set;
From: Brendan Higgins brendan.higgins@linux.dev
[ Upstream commit 254c71374a70051a043676b67ba4f7ad392b5fe6 ]
Looks like kunit_test_init_section_suites(...) was messed up in a merge conflict. This fixes it.
kunit_test_init_section_suites(...) was not updated to avoid the extra level of indirection when .kunit_test_suites was flattened. Given no-one was actively using it, this went unnoticed for a long period of time.
Fixes: e5857d396f35 ("kunit: flatten kunit_suite*** to kunit_suite** in .kunit_test_suites") Signed-off-by: Brendan Higgins brendan.higgins@linux.dev Signed-off-by: David Gow davidgow@google.com Tested-by: Martin Fernandez martin.fernandez@eclypsium.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/kunit/test.h | 1 - 1 file changed, 1 deletion(-)
diff --git a/include/kunit/test.h b/include/kunit/test.h index b1ab6b32216d..ebcdbddf8344 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -299,7 +299,6 @@ static inline int kunit_run_all_tests(void) */ #define kunit_test_init_section_suites(__suites...) \ __kunit_test_suites(CONCATENATE(__UNIQUE_ID(array), _probe), \ - CONCATENATE(__UNIQUE_ID(suites), _probe), \ ##__suites)
#define kunit_test_init_section_suite(suite) \
From: Fedor Pchelkin pchelkin@ispras.ru
[ Upstream commit 72e544b1b28325fe78a4687b980871a7e4101f76 ]
While mounting a corrupted filesystem, a signed integer '*xattr_ids' can become less than zero. This leads to the incorrect computation of 'len' and 'indexes' values which can cause null-ptr-deref in copy_bio_to_actor() or out-of-bounds accesses in the next sanity checks inside squashfs_read_xattr_id_table().
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Link: https://lkml.kernel.org/r/20230117105226.329303-2-pchelkin@ispras.ru Fixes: 506220d2ba21 ("squashfs: add more sanity checks in xattr id lookup") Reported-by: syzbot+082fa4af80a5bb1a9843@syzkaller.appspotmail.com Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru Signed-off-by: Alexey Khoroshilov khoroshilov@ispras.ru Cc: Phillip Lougher phillip@squashfs.org.uk Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/squashfs/xattr_id.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/squashfs/xattr_id.c b/fs/squashfs/xattr_id.c index 087cab8c78f4..f6d78cbc3e74 100644 --- a/fs/squashfs/xattr_id.c +++ b/fs/squashfs/xattr_id.c @@ -76,7 +76,7 @@ __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 table_start, /* Sanity check values */
/* there is always at least one xattr id */ - if (*xattr_ids == 0) + if (*xattr_ids <= 0) return ERR_PTR(-EINVAL);
len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids);
From: Wei Yang richard.weiyang@gmail.com
[ Upstream commit ab6ef70a8b0d314c2160af70b0de984664d675e0 ]
We should get pivots boundary by type. Fixes a potential overindexing of mt_pivots[].
Link: https://lkml.kernel.org/r/20221112234308.23823-1-richard.weiyang@gmail.com Fixes: 54a611b60590 ("Maple Tree: add new data structure") Signed-off-by: Wei Yang richard.weiyang@gmail.com Reviewed-by: Liam R. Howlett Liam.Howlett@oracle.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/maple_tree.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/maple_tree.c b/lib/maple_tree.c index fe21bf276d91..5bfaae60ed8b 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -665,12 +665,13 @@ static inline unsigned long mte_pivot(const struct maple_enode *mn, unsigned char piv) { struct maple_node *node = mte_to_node(mn); + enum maple_type type = mte_node_type(mn);
- if (piv >= mt_pivots[piv]) { + if (piv >= mt_pivots[type]) { WARN_ON(1); return 0; } - switch (mte_node_type(mn)) { + switch (type) { case maple_arange_64: return node->ma64.pivot[piv]; case maple_range_64:
From: Xin Long lucien.xin@gmail.com
[ Upstream commit 8f35ae17ef565a605de5f409e04bcd49a55d7646 ]
It tries to avoid the frequently hb_timer refresh in commit ba6f5e33bdbb ("sctp: avoid refreshing heartbeat timer too often"), and it only allows mod_timer when the new expires is after hb_timer.expires. It means even a much shorter interval for hb timer gets applied, it will have to wait until the current hb timer to time out.
In sctp_do_8_2_transport_strike(), when a transport enters PF state, it expects to update the hb timer to resend a heartbeat every rto after calling sctp_transport_reset_hb_timer(), which will not work as the change mentioned above.
The frequently hb_timer refresh was caused by sctp_transport_reset_timers() called in sctp_outq_flush() and it was already removed in the commit above. So we don't have to check hb_timer.expires when resetting hb_timer as it is now not called very often.
Fixes: ba6f5e33bdbb ("sctp: avoid refreshing heartbeat timer too often") Signed-off-by: Xin Long lucien.xin@gmail.com Acked-by: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Link: https://lore.kernel.org/r/d958c06985713ec84049a2d5664879802710179a.167509593... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/sctp/transport.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index f8fd98784977..b3f1a91e9a07 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -196,9 +196,7 @@ void sctp_transport_reset_hb_timer(struct sctp_transport *transport)
/* When a data chunk is sent, reset the heartbeat interval. */ expires = jiffies + sctp_transport_timeout(transport); - if ((time_before(transport->hb_timer.expires, expires) || - !timer_pending(&transport->hb_timer)) && - !mod_timer(&transport->hb_timer, + if (!mod_timer(&transport->hb_timer, expires + prandom_u32_max(transport->rto))) sctp_transport_hold(transport); }
From: Chris Healy healych@amazon.com
[ Upstream commit afc2336f89dc0fc0ef25b92366814524b0fd90fb ]
The Meson G12A Internal PHY does not support standard IEEE MMD extended register access, therefore add generic dummy stubs to fail the read and write MMD calls. This is necessary to prevent the core PHY code from erroneously believing that EEE is supported by this PHY even though this PHY does not support EEE, as MMD register access returns all FFFFs.
Fixes: 5c3407abb338 ("net: phy: meson-gxl: add g12a support") Reviewed-by: Heiner Kallweit hkallweit1@gmail.com Signed-off-by: Chris Healy healych@amazon.com Reviewed-by: Jerome Brunet jbrunet@baylibre.com Link: https://lore.kernel.org/r/20230130231402.471493-1-cphealy@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/meson-gxl.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c index c49062ad72c6..5e41658b1e2f 100644 --- a/drivers/net/phy/meson-gxl.c +++ b/drivers/net/phy/meson-gxl.c @@ -271,6 +271,8 @@ static struct phy_driver meson_gxl_phy[] = { .handle_interrupt = meson_gxl_handle_interrupt, .suspend = genphy_suspend, .resume = genphy_resume, + .read_mmd = genphy_read_mmd_unsupported, + .write_mmd = genphy_write_mmd_unsupported, }, };
From: Stephen Boyd swboyd@chromium.org
[ Upstream commit a3ee9e0b57f8ecca02d1c16fad4941e09bfe2941 ]
The unprepare sequence has started to fail after moving to panel bridge code in the msm drm driver (commit 007ac0262b0d ("drm/msm/dsi: switch to DRM_PANEL_BRIDGE")). You'll see messages like this in the kernel logs:
panel-boe-tv101wum-nl6 ae94000.dsi.0: failed to set panel off: -22
This is because boe_panel_enter_sleep_mode() needs an operating DSI link to set the panel into sleep mode. Performing those writes in the unprepare phase of bridge ops is too late, because the link has already been torn down by the DSI controller in post_disable, i.e. the PHY has been disabled, etc. See dsi_mgr_bridge_post_disable() for more details on the DSI .
Split the unprepare function into a disable part and an unprepare part. For now, just the DSI writes to enter sleep mode are put in the disable function. This fixes the panel off routine and keeps the panel happy.
My Wormdingler has an integrated touchscreen that stops responding to touch if the panel is only half disabled too. This patch fixes it. And finally, this saves power when the screen is off because without this fix the regulators for the panel are left enabled when nothing is being displayed on the screen.
Fixes: 007ac0262b0d ("drm/msm/dsi: switch to DRM_PANEL_BRIDGE") Fixes: a869b9db7adf ("drm/panel: support for boe tv101wum-nl6 wuxga dsi video mode panel") Cc: yangcong yangcong5@huaqin.corp-partner.google.com Cc: Douglas Anderson dianders@chromium.org Cc: Jitao Shi jitao.shi@mediatek.com Cc: Sam Ravnborg sam@ravnborg.org Cc: Rob Clark robdclark@chromium.org Cc: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Stephen Boyd swboyd@chromium.org Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Douglas Anderson dianders@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20230106030108.2542081-1-swboy... (cherry picked from commit c913cd5489930abbb557ef144a333846286754c3) Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c index 857a2f0420d7..c924f1124ebc 100644 --- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c @@ -1193,14 +1193,11 @@ static int boe_panel_enter_sleep_mode(struct boe_panel *boe) return 0; }
-static int boe_panel_unprepare(struct drm_panel *panel) +static int boe_panel_disable(struct drm_panel *panel) { struct boe_panel *boe = to_boe_panel(panel); int ret;
- if (!boe->prepared) - return 0; - ret = boe_panel_enter_sleep_mode(boe); if (ret < 0) { dev_err(panel->dev, "failed to set panel off: %d\n", ret); @@ -1209,6 +1206,16 @@ static int boe_panel_unprepare(struct drm_panel *panel)
msleep(150);
+ return 0; +} + +static int boe_panel_unprepare(struct drm_panel *panel) +{ + struct boe_panel *boe = to_boe_panel(panel); + + if (!boe->prepared) + return 0; + if (boe->desc->discharge_on_disable) { regulator_disable(boe->avee); regulator_disable(boe->avdd); @@ -1528,6 +1535,7 @@ static enum drm_panel_orientation boe_panel_get_orientation(struct drm_panel *pa }
static const struct drm_panel_funcs boe_panel_funcs = { + .disable = boe_panel_disable, .unprepare = boe_panel_unprepare, .prepare = boe_panel_prepare, .enable = boe_panel_enable,
From: Thomas Winter Thomas.Winter@alliedtelesis.co.nz
[ Upstream commit 23ca0c2c93406bdb1150659e720bda1cec1fad04 ]
For our point-to-point GRE tunnels, they have IN6_ADDR_GEN_MODE_NONE when they are created then we set IN6_ADDR_GEN_MODE_EUI64 when they come up to generate the IPv6 link local address for the interface. Recently we found that they were no longer generating IPv6 addresses. This issue would also have affected SIT tunnels.
Commit e5dd729460ca changed the code path so that GRE tunnels generate an IPv6 address based on the tunnel source address. It also changed the code path so GRE tunnels don't call addrconf_addr_gen in addrconf_dev_config which is called by addrconf_sysctl_addr_gen_mode when the IN6_ADDR_GEN_MODE is changed.
This patch aims to fix this issue by moving the code in addrconf_notify which calls the addr gen for GRE and SIT into a separate function and calling it in the places that expect the IPv6 address to be generated.
The previous addrconf_dev_config is renamed to addrconf_eth_config since it only expected eth type interfaces and follows the addrconf_gre/sit_config format.
A part of this changes means that the loopback address will be attempted to be configured when changing addr_gen_mode for lo. This should not be a problem because the address should exist anyway and if does already exist then no error is produced.
Fixes: e5dd729460ca ("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address") Signed-off-by: Thomas Winter Thomas.Winter@alliedtelesis.co.nz Reviewed-by: David Ahern dsahern@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv6/addrconf.c | 49 +++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 22 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 9c3f5202a97b..eaecaf2ffe00 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3447,6 +3447,30 @@ static void addrconf_gre_config(struct net_device *dev) } #endif
+static void addrconf_init_auto_addrs(struct net_device *dev) +{ + switch (dev->type) { +#if IS_ENABLED(CONFIG_IPV6_SIT) + case ARPHRD_SIT: + addrconf_sit_config(dev); + break; +#endif +#if IS_ENABLED(CONFIG_NET_IPGRE) || IS_ENABLED(CONFIG_IPV6_GRE) + case ARPHRD_IP6GRE: + case ARPHRD_IPGRE: + addrconf_gre_config(dev); + break; +#endif + case ARPHRD_LOOPBACK: + init_loopback(dev); + break; + + default: + addrconf_dev_config(dev); + break; + } +} + static int fixup_permanent_addr(struct net *net, struct inet6_dev *idev, struct inet6_ifaddr *ifp) @@ -3615,26 +3639,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, run_pending = 1; }
- switch (dev->type) { -#if IS_ENABLED(CONFIG_IPV6_SIT) - case ARPHRD_SIT: - addrconf_sit_config(dev); - break; -#endif -#if IS_ENABLED(CONFIG_NET_IPGRE) || IS_ENABLED(CONFIG_IPV6_GRE) - case ARPHRD_IP6GRE: - case ARPHRD_IPGRE: - addrconf_gre_config(dev); - break; -#endif - case ARPHRD_LOOPBACK: - init_loopback(dev); - break; - - default: - addrconf_dev_config(dev); - break; - } + addrconf_init_auto_addrs(dev);
if (!IS_ERR_OR_NULL(idev)) { if (run_pending) @@ -6397,7 +6402,7 @@ static int addrconf_sysctl_addr_gen_mode(struct ctl_table *ctl, int write,
if (idev->cnf.addr_gen_mode != new_val) { idev->cnf.addr_gen_mode = new_val; - addrconf_dev_config(idev->dev); + addrconf_init_auto_addrs(idev->dev); } } else if (&net->ipv6.devconf_all->addr_gen_mode == ctl->data) { struct net_device *dev; @@ -6408,7 +6413,7 @@ static int addrconf_sysctl_addr_gen_mode(struct ctl_table *ctl, int write, if (idev && idev->cnf.addr_gen_mode != new_val) { idev->cnf.addr_gen_mode = new_val; - addrconf_dev_config(idev->dev); + addrconf_init_auto_addrs(idev->dev); } } }
From: Thomas Winter Thomas.Winter@alliedtelesis.co.nz
[ Upstream commit 30e2291f61f93f7132c060190f8360df52644ec1 ]
We recently found that our non-point-to-point tunnels were not generating any IPv6 link local address and instead generating an IPv6 compat address, breaking IPv6 communication on the tunnel.
Previously, addrconf_gre_config always would call addrconf_addr_gen and generate a EUI64 link local address for the tunnel. Then commit e5dd729460ca changed the code path so that add_v4_addrs is called but this only generates a compat IPv6 address for non-point-to-point tunnels.
I assume the compat address is specifically for SIT tunnels so have kept that only for SIT - GRE tunnels now always generate link local addresses.
Fixes: e5dd729460ca ("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address") Signed-off-by: Thomas Winter Thomas.Winter@alliedtelesis.co.nz Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv6/addrconf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index eaecaf2ffe00..e6c7edcf6834 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3127,17 +3127,17 @@ static void add_v4_addrs(struct inet6_dev *idev) offset = sizeof(struct in6_addr) - 4; memcpy(&addr.s6_addr32[3], idev->dev->dev_addr + offset, 4);
- if (idev->dev->flags&IFF_POINTOPOINT) { + if (!(idev->dev->flags & IFF_POINTOPOINT) && idev->dev->type == ARPHRD_SIT) { + scope = IPV6_ADDR_COMPATv4; + plen = 96; + pflags |= RTF_NONEXTHOP; + } else { if (idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_NONE) return;
addr.s6_addr32[0] = htonl(0xfe800000); scope = IFA_LINK; plen = 64; - } else { - scope = IPV6_ADDR_COMPATv4; - plen = 96; - pflags |= RTF_NONEXTHOP; }
if (addr.s6_addr32[3]) {
From: Guo Ren guoren@linux.alibaba.com
[ Upstream commit 87f48c7ccc73afc78630530d9af51f458f58cab8 ]
The kernel would panic when probed for an illegal position. eg:
(CONFIG_RISCV_ISA_C=n)
echo 'p:hello kernel_clone+0x16 a0=%a0' >> kprobe_events echo 1 > events/kprobes/hello/enable cat trace
Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: __do_sys_newfstatat+0xb8/0xb8 CPU: 0 PID: 111 Comm: sh Not tainted 6.2.0-rc1-00027-g2d398fe49a4d #490 Hardware name: riscv-virtio,qemu (DT) Call Trace: [<ffffffff80007268>] dump_backtrace+0x38/0x48 [<ffffffff80c5e83c>] show_stack+0x50/0x68 [<ffffffff80c6da28>] dump_stack_lvl+0x60/0x84 [<ffffffff80c6da6c>] dump_stack+0x20/0x30 [<ffffffff80c5ecf4>] panic+0x160/0x374 [<ffffffff80c6db94>] generic_handle_arch_irq+0x0/0xa8 [<ffffffff802deeb0>] sys_newstat+0x0/0x30 [<ffffffff800158c0>] sys_clone+0x20/0x30 [<ffffffff800039e8>] ret_from_syscall+0x0/0x4 ---[ end Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: __do_sys_newfstatat+0xb8/0xb8 ]---
That is because the kprobe's ebreak instruction broke the kernel's original code. The user should guarantee the correction of the probe position, but it couldn't make the kernel panic.
This patch adds arch_check_kprobe in arch_prepare_kprobe to prevent an illegal position (Such as the middle of an instruction).
Fixes: c22b0bcb1dd0 ("riscv: Add kprobes supported") Signed-off-by: Guo Ren guoren@linux.alibaba.com Signed-off-by: Guo Ren guoren@kernel.org Reviewed-by: Björn Töpel bjorn@kernel.org Link: https://lore.kernel.org/r/20230201040604.3390509-1-guoren@kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/kernel/probes/kprobes.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/arch/riscv/kernel/probes/kprobes.c b/arch/riscv/kernel/probes/kprobes.c index e6e950b7cf32..388ecada500c 100644 --- a/arch/riscv/kernel/probes/kprobes.c +++ b/arch/riscv/kernel/probes/kprobes.c @@ -48,6 +48,21 @@ static void __kprobes arch_simulate_insn(struct kprobe *p, struct pt_regs *regs) post_kprobe_handler(p, kcb, regs); }
+static bool __kprobes arch_check_kprobe(struct kprobe *p) +{ + unsigned long tmp = (unsigned long)p->addr - p->offset; + unsigned long addr = (unsigned long)p->addr; + + while (tmp <= addr) { + if (tmp == addr) + return true; + + tmp += GET_INSN_LENGTH(*(u16 *)tmp); + } + + return false; +} + int __kprobes arch_prepare_kprobe(struct kprobe *p) { unsigned long probe_addr = (unsigned long)p->addr; @@ -55,6 +70,9 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) if (probe_addr & 0x1) return -EILSEQ;
+ if (!arch_check_kprobe(p)) + return -EILSEQ; + /* copy instruction */ p->opcode = *p->addr;
From: Tom Rix trix@redhat.com
[ Upstream commit a2df8463e15c10a8a882090f3d7a760fdb7b189d ]
clang static analysis reports drivers/net/ethernet/intel/igc/igc_ptp.c:673:3: warning: The left operand of '+' is a garbage value [core.UndefinedBinaryOperatorResult] ktime_add_ns(shhwtstamps.hwtstamp, adjust); ^ ~~~~~~~~~~~~~~~~~~~~
igc_ptp_systim_to_hwtstamp() silently returns without setting the hwtstamp if the mac type is unknown. This should be treated as an error.
Fixes: 81b055205e8b ("igc: Add support for RX timestamping") Signed-off-by: Tom Rix trix@redhat.com Reviewed-by: Simon Horman simon.horman@corigine.com Acked-by: Sasha Neftin sasha.neftin@intel.com Tested-by: Naama Meir naamax.meir@linux.intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Link: https://lore.kernel.org/r/20230131215437.1528994-1-anthony.l.nguyen@intel.co... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/igc/igc_ptp.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c index c34734d432e0..4e10ced736db 100644 --- a/drivers/net/ethernet/intel/igc/igc_ptp.c +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c @@ -417,10 +417,12 @@ static int igc_ptp_verify_pin(struct ptp_clock_info *ptp, unsigned int pin, * * We need to convert the system time value stored in the RX/TXSTMP registers * into a hwtstamp which can be used by the upper level timestamping functions. + * + * Returns 0 on success. **/ -static void igc_ptp_systim_to_hwtstamp(struct igc_adapter *adapter, - struct skb_shared_hwtstamps *hwtstamps, - u64 systim) +static int igc_ptp_systim_to_hwtstamp(struct igc_adapter *adapter, + struct skb_shared_hwtstamps *hwtstamps, + u64 systim) { switch (adapter->hw.mac.type) { case igc_i225: @@ -430,8 +432,9 @@ static void igc_ptp_systim_to_hwtstamp(struct igc_adapter *adapter, systim & 0xFFFFFFFF); break; default: - break; + return -EINVAL; } + return 0; }
/** @@ -652,7 +655,8 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter)
regval = rd32(IGC_TXSTMPL); regval |= (u64)rd32(IGC_TXSTMPH) << 32; - igc_ptp_systim_to_hwtstamp(adapter, &shhwtstamps, regval); + if (igc_ptp_systim_to_hwtstamp(adapter, &shhwtstamps, regval)) + return;
switch (adapter->link_speed) { case SPEED_10:
From: Ratheesh Kannoth rkannoth@marvell.com
[ Upstream commit 917d5e04d4dd2bbbf36fc6976ba442e284ccc42d ]
Exact match feature is only available in CN10K-B. Unregister exact match devlink entry only for this silicon variant.
Fixes: 87e4ea29b030 ("octeontx2-af: Debugsfs support for exact match.") Signed-off-by: Ratheesh Kannoth rkannoth@marvell.com Reviewed-by: Leon Romanovsky leonro@nvidia.com Link: https://lore.kernel.org/r/20230131061659.1025137-1-rkannoth@marvell.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../marvell/octeontx2/af/rvu_devlink.c | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c index 88dee589cb21..dc7bd2ce78f7 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c @@ -1500,6 +1500,9 @@ static const struct devlink_param rvu_af_dl_params[] = { BIT(DEVLINK_PARAM_CMODE_RUNTIME), rvu_af_dl_dwrr_mtu_get, rvu_af_dl_dwrr_mtu_set, rvu_af_dl_dwrr_mtu_validate), +}; + +static const struct devlink_param rvu_af_dl_param_exact_match[] = { DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE, "npc_exact_feature_disable", DEVLINK_PARAM_TYPE_STRING, BIT(DEVLINK_PARAM_CMODE_RUNTIME), @@ -1563,7 +1566,6 @@ int rvu_register_dl(struct rvu *rvu) { struct rvu_devlink *rvu_dl; struct devlink *dl; - size_t size; int err;
dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink), @@ -1585,21 +1587,32 @@ int rvu_register_dl(struct rvu *rvu) goto err_dl_health; }
+ err = devlink_params_register(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params)); + if (err) { + dev_err(rvu->dev, + "devlink params register failed with error %d", err); + goto err_dl_health; + } + /* Register exact match devlink only for CN10K-B */ - size = ARRAY_SIZE(rvu_af_dl_params); if (!rvu_npc_exact_has_match_table(rvu)) - size -= 1; + goto done;
- err = devlink_params_register(dl, rvu_af_dl_params, size); + err = devlink_params_register(dl, rvu_af_dl_param_exact_match, + ARRAY_SIZE(rvu_af_dl_param_exact_match)); if (err) { dev_err(rvu->dev, - "devlink params register failed with error %d", err); - goto err_dl_health; + "devlink exact match params register failed with error %d", err); + goto err_dl_exact_match; }
+done: devlink_register(dl); return 0;
+err_dl_exact_match: + devlink_params_unregister(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params)); + err_dl_health: rvu_health_reporters_destroy(rvu); devlink_free(dl); @@ -1612,8 +1625,14 @@ void rvu_unregister_dl(struct rvu *rvu) struct devlink *dl = rvu_dl->dl;
devlink_unregister(dl); - devlink_params_unregister(dl, rvu_af_dl_params, - ARRAY_SIZE(rvu_af_dl_params)); + + devlink_params_unregister(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params)); + + /* Unregister exact match devlink only for CN10K-B */ + if (rvu_npc_exact_has_match_table(rvu)) + devlink_params_unregister(dl, rvu_af_dl_param_exact_match, + ARRAY_SIZE(rvu_af_dl_param_exact_match)); + rvu_health_reporters_destroy(rvu); devlink_free(dl); }
From: Ziyang Xuan william.xuanziyang@huawei.com
[ Upstream commit d0553680f94c49bbe0e39eb50d033ba563b4212d ]
The conclusion "j1939_session_deactivate() should be called with a session ref-count of at least 2" is incorrect. In some concurrent scenarios, j1939_session_deactivate can be called with the session ref-count less than 2. But there is not any problem because it will check the session active state before session putting in j1939_session_deactivate_locked().
Here is the concurrent scenario of the problem reported by syzbot and my reproduction log.
cpu0 cpu1 j1939_xtp_rx_eoma j1939_xtp_rx_abort_one j1939_session_get_by_addr [kref == 2] j1939_session_get_by_addr [kref == 3] j1939_session_deactivate [kref == 2] j1939_session_put [kref == 1] j1939_session_completed j1939_session_deactivate WARN_ON_ONCE(kref < 2)
===================================================== WARNING: CPU: 1 PID: 21 at net/can/j1939/transport.c:1088 j1939_session_deactivate+0x5f/0x70 CPU: 1 PID: 21 Comm: ksoftirqd/1 Not tainted 5.14.0-rc7+ #32 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1 04/01/2014 RIP: 0010:j1939_session_deactivate+0x5f/0x70 Call Trace: j1939_session_deactivate_activate_next+0x11/0x28 j1939_xtp_rx_eoma+0x12a/0x180 j1939_tp_recv+0x4a2/0x510 j1939_can_recv+0x226/0x380 can_rcv_filter+0xf8/0x220 can_receive+0x102/0x220 ? process_backlog+0xf0/0x2c0 can_rcv+0x53/0xf0 __netif_receive_skb_one_core+0x67/0x90 ? process_backlog+0x97/0x2c0 __netif_receive_skb+0x22/0x80
Fixes: 0c71437dd50d ("can: j1939: j1939_session_deactivate(): clarify lifetime of session object") Reported-by: syzbot+9981a614060dcee6eeca@syzkaller.appspotmail.com Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Acked-by: Oleksij Rempel o.rempel@pengutronix.de Link: https://lore.kernel.org/all/20210906094200.95868-1-william.xuanziyang@huawei... Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- net/can/j1939/transport.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c index 55f29c9f9e08..4177e9617070 100644 --- a/net/can/j1939/transport.c +++ b/net/can/j1939/transport.c @@ -1092,10 +1092,6 @@ static bool j1939_session_deactivate(struct j1939_session *session) bool active;
j1939_session_list_lock(priv); - /* This function should be called with a session ref-count of at - * least 2. - */ - WARN_ON_ONCE(kref_read(&session->kref) < 2); active = j1939_session_deactivate_locked(session); j1939_session_list_unlock(priv);
From: Oliver Hartkopp socketcan@hartkopp.net
[ Upstream commit 3793301cbaa4a62d83e21f685307da7671f812ab ]
A CAN XL device is always capable to process CAN FD frames. The former check when sending CAN FD frames relied on the existence of a CAN FD device and did not check for a CAN XL device that would be correct too.
With this patch the CAN FD feature is enabled automatically when CAN XL is switched on - and CAN FD cannot be switch off while CAN XL is enabled.
This precondition also leads to a clean up and reduction of checks in the hot path in raw_rcv() and raw_sendmsg(). Some conditions are reordered to handle simple checks first.
changes since v1: https://lore.kernel.org/all/20230131091012.50553-1-socketcan@hartkopp.net - fixed typo: devive -> device changes since v2: https://lore.kernel.org/all/20230131091824.51026-1-socketcan@hartkopp.net/ - reorder checks in if statements to handle simple checks first
Fixes: 626332696d75 ("can: raw: add CAN XL support") Signed-off-by: Oliver Hartkopp socketcan@hartkopp.net Link: https://lore.kernel.org/all/20230131105613.55228-1-socketcan@hartkopp.net Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- net/can/raw.c | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-)
diff --git a/net/can/raw.c b/net/can/raw.c index 3eb7d3e2b541..4abab2c3011a 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -132,8 +132,8 @@ static void raw_rcv(struct sk_buff *oskb, void *data) return;
/* make sure to not pass oversized frames to the socket */ - if ((can_is_canfd_skb(oskb) && !ro->fd_frames && !ro->xl_frames) || - (can_is_canxl_skb(oskb) && !ro->xl_frames)) + if ((!ro->fd_frames && can_is_canfd_skb(oskb)) || + (!ro->xl_frames && can_is_canxl_skb(oskb))) return;
/* eliminate multiple filter matches for the same skb */ @@ -670,6 +670,11 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, if (copy_from_sockptr(&ro->fd_frames, optval, optlen)) return -EFAULT;
+ /* Enabling CAN XL includes CAN FD */ + if (ro->xl_frames && !ro->fd_frames) { + ro->fd_frames = ro->xl_frames; + return -EINVAL; + } break;
case CAN_RAW_XL_FRAMES: @@ -679,6 +684,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, if (copy_from_sockptr(&ro->xl_frames, optval, optlen)) return -EFAULT;
+ /* Enabling CAN XL includes CAN FD */ + if (ro->xl_frames) + ro->fd_frames = ro->xl_frames; break;
case CAN_RAW_JOIN_FILTERS: @@ -786,6 +794,25 @@ static int raw_getsockopt(struct socket *sock, int level, int optname, return 0; }
+static bool raw_bad_txframe(struct raw_sock *ro, struct sk_buff *skb, int mtu) +{ + /* Classical CAN -> no checks for flags and device capabilities */ + if (can_is_can_skb(skb)) + return false; + + /* CAN FD -> needs to be enabled and a CAN FD or CAN XL device */ + if (ro->fd_frames && can_is_canfd_skb(skb) && + (mtu == CANFD_MTU || can_is_canxl_dev_mtu(mtu))) + return false; + + /* CAN XL -> needs to be enabled and a CAN XL device */ + if (ro->xl_frames && can_is_canxl_skb(skb) && + can_is_canxl_dev_mtu(mtu)) + return false; + + return true; +} + static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) { struct sock *sk = sock->sk; @@ -833,20 +860,8 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) goto free_skb;
err = -EINVAL; - if (ro->xl_frames && can_is_canxl_dev_mtu(dev->mtu)) { - /* CAN XL, CAN FD and Classical CAN */ - if (!can_is_canxl_skb(skb) && !can_is_canfd_skb(skb) && - !can_is_can_skb(skb)) - goto free_skb; - } else if (ro->fd_frames && dev->mtu == CANFD_MTU) { - /* CAN FD and Classical CAN */ - if (!can_is_canfd_skb(skb) && !can_is_can_skb(skb)) - goto free_skb; - } else { - /* Classical CAN */ - if (!can_is_can_skb(skb)) - goto free_skb; - } + if (raw_bad_txframe(ro, skb, dev->mtu)) + goto free_skb;
sockcm_init(&sockc, sk); if (msg->msg_controllen) {
From: Marc Kleine-Budde mkl@pengutronix.de
[ Upstream commit 1613fff7a32e1d9e2ac09db73feba0e71a188445 ]
If the a new ring layout is set, the max coalesced frames for RX and TX are re-calculated, too. Add the missing assignment of the newly calculated TX max coalesced frames.
Fixes: 656fc12ddaf8 ("can: mcp251xfd: add TX IRQ coalescing ethtool support") Link: https://lore.kernel.org/all/20230130154334.1578518-1-mkl@pengutronix.de Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c index 3585f02575df..57eeb066a945 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ethtool.c @@ -48,6 +48,7 @@ mcp251xfd_ring_set_ringparam(struct net_device *ndev, priv->rx_obj_num = layout.cur_rx; priv->rx_obj_num_coalesce_irq = layout.rx_coalesce; priv->tx->obj_num = layout.cur_tx; + priv->tx_obj_num_coalesce_irq = layout.tx_coalesce;
return 0; }
From: Damien Le Moal damien.lemoal@opensource.wdc.com
[ Upstream commit 69f2c9346313ba3d3dfa4091ff99df26c67c9021 ]
Commit 2dc0b46b5ea3 ("libata: sata_down_spd_limit should return if driver has not recorded sstatus speed") changed the behavior of sata_down_spd_limit() to return doing nothing if a drive does not report a current link speed, to avoid reducing the link speed to the lowest 1.5 Gbps speed.
However, the change assumed that a speed was recorded before probing (e.g. before a suspend/resume) and set in link->sata_spd. This causes problems with adapters/drives combination failing to establish a link speed during probe autonegotiation. One example reported of this problem is an mvebu adapter with a 3Gbps port-multiplier box: autonegotiation fails, leaving no recorded link speed and no reported current link speed. Probe retries also fail as no action is taken by sata_set_spd() after each retry.
Fix this by returning early in sata_down_spd_limit() only if we do have a recorded link speed, that is, if link->sata_spd is not 0. With this fix, a failed probe not leading to a recorded link speed is retried at the lower 1.5 Gbps speed, with the link speed potentially increased later on the second revalidate of the device if the device reports that it supports higher link speeds.
Reported-by: Marius Dinu marius@psihoexpert.ro Fixes: 2dc0b46b5ea3 ("libata: sata_down_spd_limit should return if driver has not recorded sstatus speed") Reviewed-by: Niklas Cassel niklas.cassel@wdc.com Tested-by: Marius Dinu marius@psihoexpert.ro Signed-off-by: Damien Le Moal damien.lemoal@opensource.wdc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index d3ce5c383f3a..26a75f5cce95 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3108,7 +3108,7 @@ int sata_down_spd_limit(struct ata_link *link, u32 spd_limit) */ if (spd > 1) mask &= (1 << (spd - 1)) - 1; - else + else if (link->sata_spd) return -EINVAL;
/* were we already at the bottom? */
From: Andrei Gherzan andrei.gherzan@canonical.com
[ Upstream commit c03c80e3a03ffb4f790901d60797e9810539d946 ]
This change fixes the following compiler warning:
/usr/include/x86_64-linux-gnu/bits/error.h:40:5: warning: ‘gso_size’ may be used uninitialized [-Wmaybe-uninitialized] 40 | __error_noreturn (__status, __errnum, __format, __va_arg_pack ()); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ udpgso_bench_rx.c: In function ‘main’: udpgso_bench_rx.c:253:23: note: ‘gso_size’ was declared here 253 | int ret, len, gso_size, budget = 256;
Fixes: 3327a9c46352 ("selftests: add functionals test for UDP GRO") Signed-off-by: Andrei Gherzan andrei.gherzan@canonical.com Reviewed-by: Willem de Bruijn willemb@google.com Link: https://lore.kernel.org/r/20230201001612.515730-1-andrei.gherzan@canonical.c... Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/udpgso_bench_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/udpgso_bench_rx.c b/tools/testing/selftests/net/udpgso_bench_rx.c index 6a193425c367..d0895bd1933f 100644 --- a/tools/testing/selftests/net/udpgso_bench_rx.c +++ b/tools/testing/selftests/net/udpgso_bench_rx.c @@ -250,7 +250,7 @@ static int recv_msg(int fd, char *buf, int len, int *gso_size) static void do_flush_udp(int fd) { static char rbuf[ETH_MAX_MTU]; - int ret, len, gso_size, budget = 256; + int ret, len, gso_size = 0, budget = 256;
len = cfg_read_all ? sizeof(rbuf) : 0; while (budget--) {
From: Andrei Gherzan andrei.gherzan@canonical.com
[ Upstream commit db9b47ee9f5f375ab0c5daeb20321c75b4fa657d ]
Leaving unrecognized arguments buried in the output, can easily hide a CLI/script typo. Avoid this by exiting when wrong arguments are provided to the udpgso_bench test programs.
Fixes: 3a687bef148d ("selftests: udp gso benchmark") Signed-off-by: Andrei Gherzan andrei.gherzan@canonical.com Cc: Willem de Bruijn willemb@google.com Reviewed-by: Willem de Bruijn willemb@google.com Link: https://lore.kernel.org/r/20230201001612.515730-2-andrei.gherzan@canonical.c... Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/udpgso_bench_rx.c | 2 ++ tools/testing/selftests/net/udpgso_bench_tx.c | 2 ++ 2 files changed, 4 insertions(+)
diff --git a/tools/testing/selftests/net/udpgso_bench_rx.c b/tools/testing/selftests/net/udpgso_bench_rx.c index d0895bd1933f..4058c7451e70 100644 --- a/tools/testing/selftests/net/udpgso_bench_rx.c +++ b/tools/testing/selftests/net/udpgso_bench_rx.c @@ -336,6 +336,8 @@ static void parse_opts(int argc, char **argv) cfg_verify = true; cfg_read_all = true; break; + default: + exit(1); } }
diff --git a/tools/testing/selftests/net/udpgso_bench_tx.c b/tools/testing/selftests/net/udpgso_bench_tx.c index f1fdaa270291..b47b5c32039f 100644 --- a/tools/testing/selftests/net/udpgso_bench_tx.c +++ b/tools/testing/selftests/net/udpgso_bench_tx.c @@ -490,6 +490,8 @@ static void parse_opts(int argc, char **argv) case 'z': cfg_zerocopy = true; break; + default: + exit(1); } }
From: Andrei Gherzan andrei.gherzan@canonical.com
[ Upstream commit dafe93b9ee21028d625dce347118b82659652eff ]
"udpgro_bench.sh" invokes udpgso_bench_rx/udpgso_bench_tx programs subsequently and while doing so, there is a chance that the rx one is not ready to accept socket connections. This racing bug could fail the test with at least one of the following:
./udpgso_bench_tx: connect: Connection refused ./udpgso_bench_tx: sendmsg: Connection refused ./udpgso_bench_tx: write: Connection refused
This change addresses this by making udpgro_bench.sh wait for the rx program to be ready before firing off the tx one - up to a 10s timeout.
Fixes: 3a687bef148d ("selftests: udp gso benchmark") Signed-off-by: Andrei Gherzan andrei.gherzan@canonical.com Cc: Paolo Abeni pabeni@redhat.com Cc: Willem de Bruijn willemb@google.com Reviewed-by: Willem de Bruijn willemb@google.com Link: https://lore.kernel.org/r/20230201001612.515730-3-andrei.gherzan@canonical.c... Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/udpgso_bench.sh | 24 +++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/net/udpgso_bench.sh b/tools/testing/selftests/net/udpgso_bench.sh index dc932fd65363..640bc43452fa 100755 --- a/tools/testing/selftests/net/udpgso_bench.sh +++ b/tools/testing/selftests/net/udpgso_bench.sh @@ -7,6 +7,7 @@ readonly GREEN='\033[0;92m' readonly YELLOW='\033[0;33m' readonly RED='\033[0;31m' readonly NC='\033[0m' # No Color +readonly TESTPORT=8000
readonly KSFT_PASS=0 readonly KSFT_FAIL=1 @@ -56,11 +57,26 @@ trap wake_children EXIT
run_one() { local -r args=$@ + local nr_socks=0 + local i=0 + local -r timeout=10 + + ./udpgso_bench_rx -p "$TESTPORT" & + ./udpgso_bench_rx -p "$TESTPORT" -t & + + # Wait for the above test program to get ready to receive connections. + while [ "$i" -lt "$timeout" ]; do + nr_socks="$(ss -lnHi | grep -c "*:${TESTPORT}")" + [ "$nr_socks" -eq 2 ] && break + i=$((i + 1)) + sleep 1 + done + if [ "$nr_socks" -ne 2 ]; then + echo "timed out while waiting for udpgso_bench_rx" + exit 1 + fi
- ./udpgso_bench_rx & - ./udpgso_bench_rx -t & - - ./udpgso_bench_tx ${args} + ./udpgso_bench_tx -p "$TESTPORT" ${args} }
run_in_netns() {
From: Andrei Gherzan andrei.gherzan@canonical.com
[ Upstream commit 329c9cd769c2e306957df031efff656c40922c76 ]
The test tool can check that the zerocopy number of completions value is valid taking into consideration the number of datagram send calls. This can catch the system into a state where the datagrams are still in the system (for example in a qdisk, waiting for the network interface to return a completion notification, etc).
This change adds a retry logic of computing the number of completions up to a configurable (via CLI) timeout (default: 2 seconds).
Fixes: 79ebc3c26010 ("net/udpgso_bench_tx: options to exercise TX CMSG") Signed-off-by: Andrei Gherzan andrei.gherzan@canonical.com Cc: Willem de Bruijn willemb@google.com Cc: Paolo Abeni pabeni@redhat.com Reviewed-by: Willem de Bruijn willemb@google.com Link: https://lore.kernel.org/r/20230201001612.515730-4-andrei.gherzan@canonical.c... Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/udpgso_bench_tx.c | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/net/udpgso_bench_tx.c b/tools/testing/selftests/net/udpgso_bench_tx.c index b47b5c32039f..477392715a9a 100644 --- a/tools/testing/selftests/net/udpgso_bench_tx.c +++ b/tools/testing/selftests/net/udpgso_bench_tx.c @@ -62,6 +62,7 @@ static int cfg_payload_len = (1472 * 42); static int cfg_port = 8000; static int cfg_runtime_ms = -1; static bool cfg_poll; +static int cfg_poll_loop_timeout_ms = 2000; static bool cfg_segment; static bool cfg_sendmmsg; static bool cfg_tcp; @@ -235,16 +236,17 @@ static void flush_errqueue_recv(int fd) } }
-static void flush_errqueue(int fd, const bool do_poll) +static void flush_errqueue(int fd, const bool do_poll, + unsigned long poll_timeout, const bool poll_err) { if (do_poll) { struct pollfd fds = {0}; int ret;
fds.fd = fd; - ret = poll(&fds, 1, 500); + ret = poll(&fds, 1, poll_timeout); if (ret == 0) { - if (cfg_verbose) + if ((cfg_verbose) && (poll_err)) fprintf(stderr, "poll timeout\n"); } else if (ret < 0) { error(1, errno, "poll"); @@ -254,6 +256,20 @@ static void flush_errqueue(int fd, const bool do_poll) flush_errqueue_recv(fd); }
+static void flush_errqueue_retry(int fd, unsigned long num_sends) +{ + unsigned long tnow, tstop; + bool first_try = true; + + tnow = gettimeofday_ms(); + tstop = tnow + cfg_poll_loop_timeout_ms; + do { + flush_errqueue(fd, true, tstop - tnow, first_try); + first_try = false; + tnow = gettimeofday_ms(); + } while ((stat_zcopies != num_sends) && (tnow < tstop)); +} + static int send_tcp(int fd, char *data) { int ret, done = 0, count = 0; @@ -413,7 +429,8 @@ static int send_udp_segment(int fd, char *data)
static void usage(const char *filepath) { - error(1, 0, "Usage: %s [-46acmHPtTuvz] [-C cpu] [-D dst ip] [-l secs] [-M messagenr] [-p port] [-s sendsize] [-S gsosize]", + error(1, 0, "Usage: %s [-46acmHPtTuvz] [-C cpu] [-D dst ip] [-l secs] " + "[-L secs] [-M messagenr] [-p port] [-s sendsize] [-S gsosize]", filepath); }
@@ -423,7 +440,7 @@ static void parse_opts(int argc, char **argv) int max_len, hdrlen; int c;
- while ((c = getopt(argc, argv, "46acC:D:Hl:mM:p:s:PS:tTuvz")) != -1) { + while ((c = getopt(argc, argv, "46acC:D:Hl:L:mM:p:s:PS:tTuvz")) != -1) { switch (c) { case '4': if (cfg_family != PF_UNSPEC) @@ -452,6 +469,9 @@ static void parse_opts(int argc, char **argv) case 'l': cfg_runtime_ms = strtoul(optarg, NULL, 10) * 1000; break; + case 'L': + cfg_poll_loop_timeout_ms = strtoul(optarg, NULL, 10) * 1000; + break; case 'm': cfg_sendmmsg = true; break; @@ -679,7 +699,7 @@ int main(int argc, char **argv) num_sends += send_udp(fd, buf[i]); num_msgs++; if ((cfg_zerocopy && ((num_msgs & 0xF) == 0)) || cfg_tx_tstamp) - flush_errqueue(fd, cfg_poll); + flush_errqueue(fd, cfg_poll, 500, true);
if (cfg_msg_nr && num_msgs >= cfg_msg_nr) break; @@ -698,7 +718,7 @@ int main(int argc, char **argv) } while (!interrupted && (cfg_runtime_ms == -1 || tnow < tstop));
if (cfg_zerocopy || cfg_tx_tstamp) - flush_errqueue(fd, true); + flush_errqueue_retry(fd, num_sends);
if (close(fd)) error(1, errno, "close");
From: Parav Pandit parav@nvidia.com
[ Upstream commit 63b114042d8a9c02d9939889177c36dbdb17a588 ]
Cited commit in fixes tag frees rxq xdp info while RQ NAPI is still enabled and packet processing may be ongoing.
Follow the mirror sequence of open() in the stop() callback. This ensures that when rxq info is unregistered, no rx packet processing is ongoing.
Fixes: 754b8a21a96d ("virtio_net: setup xdp_rxq_info") Acked-by: Michael S. Tsirkin mst@redhat.com Reviewed-by: Jiri Pirko jiri@nvidia.com Signed-off-by: Parav Pandit parav@nvidia.com Link: https://lore.kernel.org/r/20230202163516.12559-1-parav@nvidia.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/virtio_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index ec388932aacf..20b1b34a092a 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -2154,8 +2154,8 @@ static int virtnet_close(struct net_device *dev) cancel_delayed_work_sync(&vi->refill);
for (i = 0; i < vi->max_queue_pairs; i++) { - xdp_rxq_info_unreg(&vi->rq[i].xdp_rxq); napi_disable(&vi->rq[i].napi); + xdp_rxq_info_unreg(&vi->rq[i].xdp_rxq); virtnet_napi_tx_disable(&vi->sq[i].napi); }
From: Fedor Pchelkin pchelkin@ispras.ru
[ Upstream commit 0c598aed445eb45b0ee7ba405f7ece99ee349c30 ]
Syzkaller reports a memory leak of new_flow in ovs_flow_cmd_new() as it is not freed when an allocation of a key fails.
BUG: memory leak unreferenced object 0xffff888116668000 (size 632): comm "syz-executor231", pid 1090, jiffies 4294844701 (age 18.871s) 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: [<00000000defa3494>] kmem_cache_zalloc include/linux/slab.h:654 [inline] [<00000000defa3494>] ovs_flow_alloc+0x19/0x180 net/openvswitch/flow_table.c:77 [<00000000c67d8873>] ovs_flow_cmd_new+0x1de/0xd40 net/openvswitch/datapath.c:957 [<0000000010a539a8>] genl_family_rcv_msg_doit+0x22d/0x330 net/netlink/genetlink.c:739 [<00000000dff3302d>] genl_family_rcv_msg net/netlink/genetlink.c:783 [inline] [<00000000dff3302d>] genl_rcv_msg+0x328/0x590 net/netlink/genetlink.c:800 [<000000000286dd87>] netlink_rcv_skb+0x153/0x430 net/netlink/af_netlink.c:2515 [<0000000061fed410>] genl_rcv+0x24/0x40 net/netlink/genetlink.c:811 [<000000009dc0f111>] netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline] [<000000009dc0f111>] netlink_unicast+0x545/0x7f0 net/netlink/af_netlink.c:1339 [<000000004a5ee816>] netlink_sendmsg+0x8e7/0xde0 net/netlink/af_netlink.c:1934 [<00000000482b476f>] sock_sendmsg_nosec net/socket.c:651 [inline] [<00000000482b476f>] sock_sendmsg+0x152/0x190 net/socket.c:671 [<00000000698574ba>] ____sys_sendmsg+0x70a/0x870 net/socket.c:2356 [<00000000d28d9e11>] ___sys_sendmsg+0xf3/0x170 net/socket.c:2410 [<0000000083ba9120>] __sys_sendmsg+0xe5/0x1b0 net/socket.c:2439 [<00000000c00628f8>] do_syscall_64+0x30/0x40 arch/x86/entry/common.c:46 [<000000004abfdcf4>] entry_SYSCALL_64_after_hwframe+0x61/0xc6
To fix this the patch rearranges the goto labels to reflect the order of object allocations and adds appropriate goto statements on the error paths.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: 68bb10101e6b ("openvswitch: Fix flow lookup to use unmasked key") Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru Signed-off-by: Alexey Khoroshilov khoroshilov@ispras.ru Acked-by: Eelco Chaudron echaudro@redhat.com Reviewed-by: Simon Horman simon.horman@corigine.com Link: https://lore.kernel.org/r/20230201210218.361970-1-pchelkin@ispras.ru Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/openvswitch/datapath.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index fa0f1952d763..5920fdca1287 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -979,14 +979,14 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info) key = kzalloc(sizeof(*key), GFP_KERNEL); if (!key) { error = -ENOMEM; - goto err_kfree_key; + goto err_kfree_flow; }
ovs_match_init(&match, key, false, &mask); error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY], a[OVS_FLOW_ATTR_MASK], log); if (error) - goto err_kfree_flow; + goto err_kfree_key;
ovs_flow_mask_key(&new_flow->key, key, true, &mask);
@@ -994,14 +994,14 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info) error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID], key, log); if (error) - goto err_kfree_flow; + goto err_kfree_key;
/* Validate actions. */ error = ovs_nla_copy_actions(net, a[OVS_FLOW_ATTR_ACTIONS], &new_flow->key, &acts, log); if (error) { OVS_NLERR(log, "Flow actions may not be safe on all matching packets."); - goto err_kfree_flow; + goto err_kfree_key; }
reply = ovs_flow_cmd_alloc_info(acts, &new_flow->id, info, false, @@ -1101,10 +1101,10 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info) kfree_skb(reply); err_kfree_acts: ovs_nla_free_flow_actions(acts); -err_kfree_flow: - ovs_flow_free(new_flow, false); err_kfree_key: kfree(key); +err_kfree_flow: + ovs_flow_free(new_flow, false); error: return error; }
From: Anton Gusev aagusev@ispras.ru
[ Upstream commit 966d47e1f27c45507c5df82b2a2157e5a4fd3909 ]
When iterating on a linked list, a result of memremap is dereferenced without checking it for NULL.
This patch adds a check that falls back on allocating a new page in case memremap doesn't succeed.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 18df7577adae ("efi/memreserve: deal with memreserve entries in unmapped memory") Signed-off-by: Anton Gusev aagusev@ispras.ru [ardb: return -ENOMEM instead of breaking out of the loop] Signed-off-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/efi/efi.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 033aac6be7da..b43e5e6ddaf6 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -984,6 +984,8 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) /* first try to find a slot in an existing linked list entry */ for (prsv = efi_memreserve_root->next; prsv; ) { rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB); + if (!rsv) + return -ENOMEM; index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size); if (index < rsv->size) { rsv->entry[index].base = addr;
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 08279468a294d8c996a657ecc9e51bd5c084c75d ]
On 32-bit architectures with 64-bit resource_size_t, sp_rtc_probe() causes a compiler warning:
drivers/rtc/rtc-sunplus.c: In function 'sp_rtc_probe': drivers/rtc/rtc-sunplus.c:243:33: error: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=] 243 | dev_dbg(&plat_dev->dev, "res = 0x%x, reg_base = 0x%lx\n", | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The best way to print a resource is the special %pR format string, and similarly to print a pointer we can use %p and avoid the cast.
Fixes: fad6cbe9b2b4 ("rtc: Add driver for RTC in Sunplus SP7021") Signed-off-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20230117172450.2938962-1-arnd@kernel.org Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-sunplus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/rtc-sunplus.c b/drivers/rtc/rtc-sunplus.c index e8e2ab1103fc..4b578e4d44f6 100644 --- a/drivers/rtc/rtc-sunplus.c +++ b/drivers/rtc/rtc-sunplus.c @@ -240,8 +240,8 @@ static int sp_rtc_probe(struct platform_device *plat_dev) if (IS_ERR(sp_rtc->reg_base)) return dev_err_probe(&plat_dev->dev, PTR_ERR(sp_rtc->reg_base), "%s devm_ioremap_resource fail\n", RTC_REG_NAME); - dev_dbg(&plat_dev->dev, "res = 0x%x, reg_base = 0x%lx\n", - sp_rtc->res->start, (unsigned long)sp_rtc->reg_base); + dev_dbg(&plat_dev->dev, "res = %pR, reg_base = %p\n", + sp_rtc->res, sp_rtc->reg_base);
sp_rtc->irq = platform_get_irq(plat_dev, 0); if (sp_rtc->irq < 0)
From: Jan Luebbe jlu@pengutronix.de
[ Upstream commit b1c3d2beed8ef3699fab106340e33a79052df116 ]
When CONFIG_MODULE_SIG_KEY is PKCS#11 URI (pkcs11:*) and contains a semicolon, signing_key.x509 fails to build:
certs/extract-cert pkcs11:token=foo;object=bar;pin-value=1111 certs/signing_key.x509 Usage: extract-cert <source> <dest>
Add quotes to the extract-cert argument to avoid splitting by the shell.
This approach was suggested by Masahiro Yamada masahiroy@kernel.org.
Fixes: 129ab0d2d9f3 ("kbuild: do not quote string values in include/config/auto.conf") Signed-off-by: Jan Luebbe jlu@pengutronix.de Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- certs/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/certs/Makefile b/certs/Makefile index 9486ed924731..799ad7b9e68a 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -23,8 +23,8 @@ $(obj)/blacklist_hash_list: $(CONFIG_SYSTEM_BLACKLIST_HASH_LIST) FORCE targets += blacklist_hash_list
quiet_cmd_extract_certs = CERT $@ - cmd_extract_certs = $(obj)/extract-cert $(extract-cert-in) $@ -extract-cert-in = $(or $(filter-out $(obj)/extract-cert, $(real-prereqs)),"") + cmd_extract_certs = $(obj)/extract-cert "$(extract-cert-in)" $@ +extract-cert-in = $(filter-out $(obj)/extract-cert, $(real-prereqs))
$(obj)/system_certificates.o: $(obj)/x509_certificate_list
From: Jan Luebbe jlu@pengutronix.de
[ Upstream commit 22e46f6480e83bcf49b6d5e6b66c81872c97a902 ]
When CONFIG_MODULE_SIG_KEY is PKCS#11 URI (pkcs11:*), signing of modules fails:
scripts/sign-file sha256 /.../linux/pkcs11:token=foo;object=bar;pin-value=1111 certs/signing_key.x509 /.../kernel/crypto/tcrypt.ko Usage: scripts/sign-file [-dp] <hash algo> <key> <x509> <module> [<dest>] scripts/sign-file -s <raw sig> <hash algo> <x509> <module> [<dest>]
First, we need to avoid adding the $(srctree)/ prefix to the URL.
Second, since the kconfig string values no longer include quotes, we need to add them again when passing a PKCS#11 URI to sign-file. This avoids splitting by the shell if the URI contains semicolons.
Fixes: 4db9c2e3d055 ("kbuild: stop using config_filename in scripts/Makefile.modsign") Fixes: 129ab0d2d9f3 ("kbuild: do not quote string values in include/config/auto.conf") Signed-off-by: Jan Luebbe jlu@pengutronix.de Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/Makefile.modinst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index a4c987c23750..10df89b9ef67 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -66,9 +66,13 @@ endif # Don't stop modules_install even if we can't sign external modules. # ifeq ($(CONFIG_MODULE_SIG_ALL),y) +ifeq ($(filter pkcs11:%, $(CONFIG_MODULE_SIG_KEY)),) sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(srctree)/)$(CONFIG_MODULE_SIG_KEY) +else +sig-key := $(CONFIG_MODULE_SIG_KEY) +endif quiet_cmd_sign = SIGN $@ - cmd_sign = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(sig-key) certs/signing_key.x509 $@ \ + cmd_sign = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) "$(sig-key)" certs/signing_key.x509 $@ \ $(if $(KBUILD_EXTMOD),|| true) else quiet_cmd_sign :=
From: Basavaraj Natikar Basavaraj.Natikar@amd.com
[ Upstream commit 2ece0930ac5662bccce0ba4c59b84c98d2437200 ]
Add additional supported PCI IDs for latest AMD NAVI GPU card which has an integrated Type-C controller and designware I2C with PCI interface.
Signed-off-by: Basavaraj Natikar Basavaraj.Natikar@amd.com Tested-by: Sanath S Sanath.S@amd.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Jarkko Nikula jarkko.nikula@linux.intel.com Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-designware-pcidrv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index e499f96506c5..782fe1ef3ca1 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -396,6 +396,8 @@ static const struct pci_device_id i2_designware_pci_ids[] = { { PCI_VDEVICE(ATI, 0x73a4), navi_amd }, { PCI_VDEVICE(ATI, 0x73e4), navi_amd }, { PCI_VDEVICE(ATI, 0x73c4), navi_amd }, + { PCI_VDEVICE(ATI, 0x7444), navi_amd }, + { PCI_VDEVICE(ATI, 0x7464), navi_amd }, { 0,} }; MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids);
From: Stefan Wahren stefan.wahren@i2se.com
[ Upstream commit 78a4471fa1a76a8bef4919105de67660a89a1e9b ]
During boot of I2SE Duckbill the kernel log contains a confusing error:
Failed to request dma
This is caused by i2c-mxs tries to request a not yet available DMA channel (-EPROBE_DEFER). So suppress this message by using dev_err_probe().
Signed-off-by: Stefan Wahren stefan.wahren@i2se.com Reviewed-by: Fabio Estevam festevam@gmail.com Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-mxs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 5af5cffc444e..d113bed79545 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -826,8 +826,8 @@ static int mxs_i2c_probe(struct platform_device *pdev) /* Setup the DMA */ i2c->dmach = dma_request_chan(dev, "rx-tx"); if (IS_ERR(i2c->dmach)) { - dev_err(dev, "Failed to request dma\n"); - return PTR_ERR(i2c->dmach); + return dev_err_probe(dev, PTR_ERR(i2c->dmach), + "Failed to request dma\n"); }
platform_set_drvdata(pdev, i2c);
From: Maurizio Lombardi mlombard@redhat.com
[ Upstream commit 84ed64b1a7a7fcd507598dee7708c1f225123711 ]
Calling spin_lock_irqsave() does not disable the interrupts on realtime kernels, remove the warning and replace assert_spin_locked() with lockdep_assert_held().
Signed-off-by: Maurizio Lombardi mlombard@redhat.com Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20230110125310.55884-1-mlombard@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_tmr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index bac111456fa1..2b95b4550a63 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -73,8 +73,8 @@ static bool __target_check_io_state(struct se_cmd *se_cmd, { struct se_session *sess = se_cmd->se_sess;
- assert_spin_locked(&sess->sess_cmd_lock); - WARN_ON_ONCE(!irqs_disabled()); + lockdep_assert_held(&sess->sess_cmd_lock); + /* * If command already reached CMD_T_COMPLETE state within * target_complete_cmd() or CMD_T_FABRIC_STOP due to shutdown,
From: Yair Podemsky ypodemsk@redhat.com
[ Upstream commit 5f5cc9ed992cbab6361f198966f0edba5fc52688 ]
Once disable_freq_invariance_work is called the scale_freq_tick function will not compute or update the arch_freq_scale values. However the scheduler will still read these values and use them. The result is that the scheduler might perform unfair decisions based on stale values.
This patch adds the step of setting the arch_freq_scale values for all cpus to the default (max) value SCHED_CAPACITY_SCALE, Once all cpus have the same arch_freq_scale value the scaling is meaningless.
Signed-off-by: Yair Podemsky ypodemsk@redhat.com Signed-off-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra peterz@infradead.org Link: https://lore.kernel.org/r/20230110160206.75912-1-ypodemsk@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/aperfmperf.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c index 1f60a2b27936..fdbb5f07448f 100644 --- a/arch/x86/kernel/cpu/aperfmperf.c +++ b/arch/x86/kernel/cpu/aperfmperf.c @@ -330,7 +330,16 @@ static void __init bp_init_freq_invariance(void)
static void disable_freq_invariance_workfn(struct work_struct *work) { + int cpu; + static_branch_disable(&arch_scale_freq_key); + + /* + * Set arch_freq_scale to a default value on all cpus + * This negates the effect of scaling + */ + for_each_possible_cpu(cpu) + per_cpu(arch_freq_scale, cpu) = SCHED_CAPACITY_SCALE; }
static DECLARE_WORK(disable_freq_invariance_work,
From: Kan Liang kan.liang@linux.intel.com
[ Upstream commit 6795e558e9cc6123c24e2100a2ebe88e58a792bc ]
From core PMU's perspective, Emerald Rapids is the same as the Sapphire
Rapids. The only difference is the event list, which will be supported in the perf tool later.
Signed-off-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Ingo Molnar mingo@kernel.org Link: https://lore.kernel.org/r/20230106160449.3566477-1-kan.liang@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/intel/core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 1b92bf05fd65..5a1d0ea402e4 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -6342,6 +6342,7 @@ __init int intel_pmu_init(void) break;
case INTEL_FAM6_SAPPHIRERAPIDS_X: + case INTEL_FAM6_EMERALDRAPIDS_X: pmem = true; x86_pmu.late_ack = true; memcpy(hw_cache_event_ids, spr_hw_cache_event_ids, sizeof(hw_cache_event_ids));
From: Kan Liang kan.liang@linux.intel.com
[ Upstream commit 5a8a05f165fb18d37526062419774d9088c2a9b9 ]
From the perspective of Intel cstate residency counters,
Emerald Rapids is the same as the Sapphire Rapids and Ice Lake. Add Emerald Rapids model.
Signed-off-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Ingo Molnar mingo@kernel.org Link: https://lore.kernel.org/r/20230106160449.3566477-2-kan.liang@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/intel/cstate.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 3019fb1926e3..551741e79e03 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c @@ -677,6 +677,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &icx_cstates), X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &icx_cstates), X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &icx_cstates), + X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &icx_cstates),
X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, &icl_cstates), X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, &icl_cstates),
From: Mike Christie michael.christie@oracle.com
[ Upstream commit 6f1d64b13097e85abda0f91b5638000afc5f9a06 ]
Bug report and analysis from Ding Hui.
During iSCSI session logout, if another task accesses the shost ipaddress attr, we can get a KASAN UAF report like this:
[ 276.942144] BUG: KASAN: use-after-free in _raw_spin_lock_bh+0x78/0xe0 [ 276.942535] Write of size 4 at addr ffff8881053b45b8 by task cat/4088 [ 276.943511] CPU: 2 PID: 4088 Comm: cat Tainted: G E 6.1.0-rc8+ #3 [ 276.943997] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020 [ 276.944470] Call Trace: [ 276.944943] <TASK> [ 276.945397] dump_stack_lvl+0x34/0x48 [ 276.945887] print_address_description.constprop.0+0x86/0x1e7 [ 276.946421] print_report+0x36/0x4f [ 276.947358] kasan_report+0xad/0x130 [ 276.948234] kasan_check_range+0x35/0x1c0 [ 276.948674] _raw_spin_lock_bh+0x78/0xe0 [ 276.949989] iscsi_sw_tcp_host_get_param+0xad/0x2e0 [iscsi_tcp] [ 276.951765] show_host_param_ISCSI_HOST_PARAM_IPADDRESS+0xe9/0x130 [scsi_transport_iscsi] [ 276.952185] dev_attr_show+0x3f/0x80 [ 276.953005] sysfs_kf_seq_show+0x1fb/0x3e0 [ 276.953401] seq_read_iter+0x402/0x1020 [ 276.954260] vfs_read+0x532/0x7b0 [ 276.955113] ksys_read+0xed/0x1c0 [ 276.955952] do_syscall_64+0x38/0x90 [ 276.956347] entry_SYSCALL_64_after_hwframe+0x63/0xcd [ 276.956769] RIP: 0033:0x7f5d3a679222 [ 276.957161] Code: c0 e9 b2 fe ff ff 50 48 8d 3d 32 c0 0b 00 e8 a5 fe 01 00 0f 1f 44 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 <48> 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 ec 28 48 89 54 24 [ 276.958009] RSP: 002b:00007ffc864d16a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 [ 276.958431] RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007f5d3a679222 [ 276.958857] RDX: 0000000000020000 RSI: 00007f5d3a4fe000 RDI: 0000000000000003 [ 276.959281] RBP: 00007f5d3a4fe000 R08: 00000000ffffffff R09: 0000000000000000 [ 276.959682] R10: 0000000000000022 R11: 0000000000000246 R12: 0000000000020000 [ 276.960126] R13: 0000000000000003 R14: 0000000000000000 R15: 0000557a26dada58 [ 276.960536] </TASK> [ 276.961357] Allocated by task 2209: [ 276.961756] kasan_save_stack+0x1e/0x40 [ 276.962170] kasan_set_track+0x21/0x30 [ 276.962557] __kasan_kmalloc+0x7e/0x90 [ 276.962923] __kmalloc+0x5b/0x140 [ 276.963308] iscsi_alloc_session+0x28/0x840 [scsi_transport_iscsi] [ 276.963712] iscsi_session_setup+0xda/0xba0 [libiscsi] [ 276.964078] iscsi_sw_tcp_session_create+0x1fd/0x330 [iscsi_tcp] [ 276.964431] iscsi_if_create_session.isra.0+0x50/0x260 [scsi_transport_iscsi] [ 276.964793] iscsi_if_recv_msg+0xc5a/0x2660 [scsi_transport_iscsi] [ 276.965153] iscsi_if_rx+0x198/0x4b0 [scsi_transport_iscsi] [ 276.965546] netlink_unicast+0x4d5/0x7b0 [ 276.965905] netlink_sendmsg+0x78d/0xc30 [ 276.966236] sock_sendmsg+0xe5/0x120 [ 276.966576] ____sys_sendmsg+0x5fe/0x860 [ 276.966923] ___sys_sendmsg+0xe0/0x170 [ 276.967300] __sys_sendmsg+0xc8/0x170 [ 276.967666] do_syscall_64+0x38/0x90 [ 276.968028] entry_SYSCALL_64_after_hwframe+0x63/0xcd [ 276.968773] Freed by task 2209: [ 276.969111] kasan_save_stack+0x1e/0x40 [ 276.969449] kasan_set_track+0x21/0x30 [ 276.969789] kasan_save_free_info+0x2a/0x50 [ 276.970146] __kasan_slab_free+0x106/0x190 [ 276.970470] __kmem_cache_free+0x133/0x270 [ 276.970816] device_release+0x98/0x210 [ 276.971145] kobject_cleanup+0x101/0x360 [ 276.971462] iscsi_session_teardown+0x3fb/0x530 [libiscsi] [ 276.971775] iscsi_sw_tcp_session_destroy+0xd8/0x130 [iscsi_tcp] [ 276.972143] iscsi_if_recv_msg+0x1bf1/0x2660 [scsi_transport_iscsi] [ 276.972485] iscsi_if_rx+0x198/0x4b0 [scsi_transport_iscsi] [ 276.972808] netlink_unicast+0x4d5/0x7b0 [ 276.973201] netlink_sendmsg+0x78d/0xc30 [ 276.973544] sock_sendmsg+0xe5/0x120 [ 276.973864] ____sys_sendmsg+0x5fe/0x860 [ 276.974248] ___sys_sendmsg+0xe0/0x170 [ 276.974583] __sys_sendmsg+0xc8/0x170 [ 276.974891] do_syscall_64+0x38/0x90 [ 276.975216] entry_SYSCALL_64_after_hwframe+0x63/0xcd
We can easily reproduce by two tasks: 1. while :; do iscsiadm -m node --login; iscsiadm -m node --logout; done 2. while :; do cat \ /sys/devices/platform/host*/iscsi_host/host*/ipaddress; done
iscsid | cat --------------------------------+--------------------------------------- |- iscsi_sw_tcp_session_destroy | |- iscsi_session_teardown | |- device_release | |- iscsi_session_release ||- dev_attr_show |- kfree | |- show_host_param_ | ISCSI_HOST_PARAM_IPADDRESS | |- iscsi_sw_tcp_host_get_param | |- r/w tcp_sw_host->session (UAF) |- iscsi_host_remove | |- iscsi_host_free |
Fix the above bug by splitting the session removal into 2 parts:
1. removal from iSCSI class which includes sysfs and removal from host tracking.
2. freeing of session.
During iscsi_tcp host and session removal we can remove the session from sysfs then remove the host from sysfs. At this point we know userspace is not accessing the kernel via sysfs so we can free the session and host.
Link: https://lore.kernel.org/r/20230117193937.21244-2-michael.christie@oracle.com Signed-off-by: Mike Christie michael.christie@oracle.com Reviewed-by: Lee Duncan lduncan@suse.com Acked-by: Ding Hui dinghui@sangfor.com.cn Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/iscsi_tcp.c | 11 +++++++++-- drivers/scsi/libiscsi.c | 38 +++++++++++++++++++++++++++++++------- include/scsi/libiscsi.h | 2 ++ 3 files changed, 42 insertions(+), 9 deletions(-)
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 5fb1f364e815..9c0c8f34ef67 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -982,10 +982,17 @@ static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session) if (WARN_ON_ONCE(session->leadconn)) return;
+ iscsi_session_remove(cls_session); + /* + * Our get_host_param needs to access the session, so remove the + * host from sysfs before freeing the session to make sure userspace + * is no longer accessing the callout. + */ + iscsi_host_remove(shost, false); + iscsi_tcp_r2tpool_free(cls_session->dd_data); - iscsi_session_teardown(cls_session);
- iscsi_host_remove(shost, false); + iscsi_session_free(cls_session); iscsi_host_free(shost); }
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index d95f4bcdeb2e..6e811d753cb1 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -3104,17 +3104,32 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, } EXPORT_SYMBOL_GPL(iscsi_session_setup);
-/** - * iscsi_session_teardown - destroy session, host, and cls_session - * @cls_session: iscsi session +/* + * issi_session_remove - Remove session from iSCSI class. */ -void iscsi_session_teardown(struct iscsi_cls_session *cls_session) +void iscsi_session_remove(struct iscsi_cls_session *cls_session) { struct iscsi_session *session = cls_session->dd_data; - struct module *owner = cls_session->transport->owner; struct Scsi_Host *shost = session->host;
iscsi_remove_session(cls_session); + /* + * host removal only has to wait for its children to be removed from + * sysfs, and iscsi_tcp needs to do iscsi_host_remove before freeing + * the session, so drop the session count here. + */ + iscsi_host_dec_session_cnt(shost); +} +EXPORT_SYMBOL_GPL(iscsi_session_remove); + +/** + * iscsi_session_free - Free iscsi session and it's resources + * @cls_session: iscsi session + */ +void iscsi_session_free(struct iscsi_cls_session *cls_session) +{ + struct iscsi_session *session = cls_session->dd_data; + struct module *owner = cls_session->transport->owner;
iscsi_pool_free(&session->cmdpool); kfree(session->password); @@ -3132,10 +3147,19 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) kfree(session->discovery_parent_type);
iscsi_free_session(cls_session); - - iscsi_host_dec_session_cnt(shost); module_put(owner); } +EXPORT_SYMBOL_GPL(iscsi_session_free); + +/** + * iscsi_session_teardown - destroy session and cls_session + * @cls_session: iscsi session + */ +void iscsi_session_teardown(struct iscsi_cls_session *cls_session) +{ + iscsi_session_remove(cls_session); + iscsi_session_free(cls_session); +} EXPORT_SYMBOL_GPL(iscsi_session_teardown);
/** diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 654cc3918c94..7fb3cb787df4 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -422,6 +422,8 @@ extern int iscsi_host_get_max_scsi_cmds(struct Scsi_Host *shost, extern struct iscsi_cls_session * iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost, uint16_t, int, int, uint32_t, unsigned int); +void iscsi_session_remove(struct iscsi_cls_session *cls_session); +void iscsi_session_free(struct iscsi_cls_session *cls_session); extern void iscsi_session_teardown(struct iscsi_cls_session *); extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
From: Mike Christie michael.christie@oracle.com
[ Upstream commit f484a794e4ee2a9ce61f52a78e810ac45f3fe3b3 ]
If during iscsi_sw_tcp_session_create() iscsi_tcp_r2tpool_alloc() fails, userspace could be accessing the host's ipaddress attr. If we then free the session via iscsi_session_teardown() while userspace is still accessing the session we will hit a use after free bug.
Set the tcp_sw_host->session after we have completed session creation and can no longer fail.
Link: https://lore.kernel.org/r/20230117193937.21244-3-michael.christie@oracle.com Signed-off-by: Mike Christie michael.christie@oracle.com Reviewed-by: Lee Duncan lduncan@suse.com Acked-by: Ding Hui dinghui@sangfor.com.cn Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/iscsi_tcp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 9c0c8f34ef67..c3ad04ad66e0 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -848,7 +848,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param, char *buf) { struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost); - struct iscsi_session *session = tcp_sw_host->session; + struct iscsi_session *session; struct iscsi_conn *conn; struct iscsi_tcp_conn *tcp_conn; struct iscsi_sw_tcp_conn *tcp_sw_conn; @@ -858,6 +858,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost,
switch (param) { case ISCSI_HOST_PARAM_IPADDRESS: + session = tcp_sw_host->session; if (!session) return -ENOTCONN;
@@ -958,11 +959,13 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, if (!cls_session) goto remove_host; session = cls_session->dd_data; - tcp_sw_host = iscsi_host_priv(shost); - tcp_sw_host->session = session;
if (iscsi_tcp_r2tpool_alloc(session)) goto remove_session; + + /* We are now fully setup so expose the session to sysfs. */ + tcp_sw_host = iscsi_host_priv(shost); + tcp_sw_host->session = session; return cls_session;
remove_session:
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 0582d984793d30442da88fe458674502bad1ad29 ]
Fix multiple W=1 kernel-doc warnings in i2c-rk3x.c:
drivers/i2c/busses/i2c-rk3x.c:83: warning: missing initial short description on line: * struct i2c_spec_values: drivers/i2c/busses/i2c-rk3x.c:139: warning: missing initial short description on line: * struct rk3x_i2c_calced_timings: drivers/i2c/busses/i2c-rk3x.c:162: warning: missing initial short description on line: * struct rk3x_i2c_soc_data: drivers/i2c/busses/i2c-rk3x.c:242: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Generate a START condition, which triggers a REG_INT_START interrupt. drivers/i2c/busses/i2c-rk3x.c:261: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Generate a STOP condition, which triggers a REG_INT_STOP interrupt. drivers/i2c/busses/i2c-rk3x.c:304: warning: expecting prototype for Setup a read according to i2c(). Prototype was for rk3x_i2c_prepare_read() instead drivers/i2c/busses/i2c-rk3x.c:335: warning: expecting prototype for Fill the transmit buffer with data from i2c(). Prototype was for rk3x_i2c_fill_transmit_buf() instead drivers/i2c/busses/i2c-rk3x.c:535: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Get timing values of I2C specification drivers/i2c/busses/i2c-rk3x.c:552: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Calculate divider values for desired SCL frequency drivers/i2c/busses/i2c-rk3x.c:713: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Calculate timing values for desired SCL frequency drivers/i2c/busses/i2c-rk3x.c:963: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Setup I2C registers for an I2C operation specified by msgs, num.
Signed-off-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-rk3x.c | 44 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c index d1658ed76562..b31cf4f18f85 100644 --- a/drivers/i2c/busses/i2c-rk3x.c +++ b/drivers/i2c/busses/i2c-rk3x.c @@ -80,7 +80,7 @@ enum { #define DEFAULT_SCL_RATE (100 * 1000) /* Hz */
/** - * struct i2c_spec_values: + * struct i2c_spec_values - I2C specification values for various modes * @min_hold_start_ns: min hold time (repeated) START condition * @min_low_ns: min LOW period of the SCL clock * @min_high_ns: min HIGH period of the SCL cloc @@ -136,7 +136,7 @@ static const struct i2c_spec_values fast_mode_plus_spec = { };
/** - * struct rk3x_i2c_calced_timings: + * struct rk3x_i2c_calced_timings - calculated V1 timings * @div_low: Divider output for low * @div_high: Divider output for high * @tuning: Used to adjust setup/hold data time, @@ -159,7 +159,7 @@ enum rk3x_i2c_state { };
/** - * struct rk3x_i2c_soc_data: + * struct rk3x_i2c_soc_data - SOC-specific data * @grf_offset: offset inside the grf regmap for setting the i2c type * @calc_timings: Callback function for i2c timing information calculated */ @@ -239,7 +239,8 @@ static inline void rk3x_i2c_clean_ipd(struct rk3x_i2c *i2c) }
/** - * Generate a START condition, which triggers a REG_INT_START interrupt. + * rk3x_i2c_start - Generate a START condition, which triggers a REG_INT_START interrupt. + * @i2c: target controller data */ static void rk3x_i2c_start(struct rk3x_i2c *i2c) { @@ -258,8 +259,8 @@ static void rk3x_i2c_start(struct rk3x_i2c *i2c) }
/** - * Generate a STOP condition, which triggers a REG_INT_STOP interrupt. - * + * rk3x_i2c_stop - Generate a STOP condition, which triggers a REG_INT_STOP interrupt. + * @i2c: target controller data * @error: Error code to return in rk3x_i2c_xfer */ static void rk3x_i2c_stop(struct rk3x_i2c *i2c, int error) @@ -298,7 +299,8 @@ static void rk3x_i2c_stop(struct rk3x_i2c *i2c, int error) }
/** - * Setup a read according to i2c->msg + * rk3x_i2c_prepare_read - Setup a read according to i2c->msg + * @i2c: target controller data */ static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c) { @@ -329,7 +331,8 @@ static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c) }
/** - * Fill the transmit buffer with data from i2c->msg + * rk3x_i2c_fill_transmit_buf - Fill the transmit buffer with data from i2c->msg + * @i2c: target controller data */ static void rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c) { @@ -532,11 +535,10 @@ static irqreturn_t rk3x_i2c_irq(int irqno, void *dev_id) }
/** - * Get timing values of I2C specification - * + * rk3x_i2c_get_spec - Get timing values of I2C specification * @speed: Desired SCL frequency * - * Returns: Matched i2c spec values. + * Return: Matched i2c_spec_values. */ static const struct i2c_spec_values *rk3x_i2c_get_spec(unsigned int speed) { @@ -549,13 +551,12 @@ static const struct i2c_spec_values *rk3x_i2c_get_spec(unsigned int speed) }
/** - * Calculate divider values for desired SCL frequency - * + * rk3x_i2c_v0_calc_timings - Calculate divider values for desired SCL frequency * @clk_rate: I2C input clock rate * @t: Known I2C timing information * @t_calc: Caculated rk3x private timings that would be written into regs * - * Returns: 0 on success, -EINVAL if the goal SCL rate is too slow. In that case + * Return: %0 on success, -%EINVAL if the goal SCL rate is too slow. In that case * a best-effort divider value is returned in divs. If the target rate is * too high, we silently use the highest possible rate. */ @@ -710,13 +711,12 @@ static int rk3x_i2c_v0_calc_timings(unsigned long clk_rate, }
/** - * Calculate timing values for desired SCL frequency - * + * rk3x_i2c_v1_calc_timings - Calculate timing values for desired SCL frequency * @clk_rate: I2C input clock rate * @t: Known I2C timing information * @t_calc: Caculated rk3x private timings that would be written into regs * - * Returns: 0 on success, -EINVAL if the goal SCL rate is too slow. In that case + * Return: %0 on success, -%EINVAL if the goal SCL rate is too slow. In that case * a best-effort divider value is returned in divs. If the target rate is * too high, we silently use the highest possible rate. * The following formulas are v1's method to calculate timings. @@ -960,14 +960,14 @@ static int rk3x_i2c_clk_notifier_cb(struct notifier_block *nb, unsigned long }
/** - * Setup I2C registers for an I2C operation specified by msgs, num. - * - * Must be called with i2c->lock held. - * + * rk3x_i2c_setup - Setup I2C registers for an I2C operation specified by msgs, num. + * @i2c: target controller data * @msgs: I2C msgs to process * @num: Number of msgs * - * returns: Number of I2C msgs processed or negative in case of error + * Must be called with i2c->lock held. + * + * Return: Number of I2C msgs processed or negative in case of error */ static int rk3x_i2c_setup(struct rk3x_i2c *i2c, struct i2c_msg *msgs, int num) {
From: Andreas Gruenbacher agruenba@redhat.com
[ Upstream commit 95ecbd0f162fc06ef4c4045a66f653f47b62a2d3 ]
Commit b2b0a5e97855 switched from generic_writepages() to filemap_fdatawrite_wbc() in gfs2_ail1_start_one() on the path to replacing ->writepage() with ->writepages() and eventually eliminating the former. Function gfs2_ail1_start_one() is called from gfs2_log_flush(), our main function for flushing the filesystem log.
Unfortunately, at least as implemented today, ->writepage() and ->writepages() are entirely different operations for journaled data inodes: while the former creates and submits transactions covering the data to be written, the latter flushes dirty buffers out to disk.
With gfs2_ail1_start_one() now calling ->writepages(), we end up creating filesystem transactions while we are in the course of a log flush, which immediately deadlocks on the sdp->sd_log_flush_lock semaphore.
Work around that by going back to how things used to work before commit b2b0a5e97855 for now; figuring out a superior solution will take time we don't have available right now. However ...
Since the removal of generic_writepages() is imminent, open-code it here. We're already inside a blk_start_plug() ... blk_finish_plug() section here, so skip that part of the original generic_writepages().
This reverts commit b2b0a5e978552e348f85ad9c7568b630a5ede659.
Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Acked-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- fs/gfs2/log.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 723639376ae2..61323deb80bc 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -80,6 +80,15 @@ void gfs2_remove_from_ail(struct gfs2_bufdata *bd) brelse(bd->bd_bh); }
+static int __gfs2_writepage(struct page *page, struct writeback_control *wbc, + void *data) +{ + struct address_space *mapping = data; + int ret = mapping->a_ops->writepage(page, wbc); + mapping_set_error(mapping, ret); + return ret; +} + /** * gfs2_ail1_start_one - Start I/O on a transaction * @sdp: The superblock @@ -131,7 +140,7 @@ __acquires(&sdp->sd_ail_lock) if (!mapping) continue; spin_unlock(&sdp->sd_ail_lock); - ret = filemap_fdatawrite_wbc(mapping, wbc); + ret = write_cache_pages(mapping, wbc, __gfs2_writepage, mapping); if (need_resched()) { blk_finish_plug(plug); cond_resched();
From: Nathan Chancellor nathan@kernel.org
[ Upstream commit 27b5de622ea3fe0ad5a31a0ebd9f7a0a276932d1 ]
LLVM 16 will have support for this flag so move it out of the GCC-only block to allow LLVM builds to take advantage of it.
Signed-off-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Tested-by: Nick Desaulniers ndesaulniers@google.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://github.com/ClangBuiltLinux/linux/issues/1665 Link: https://github.com/llvm/llvm-project/commit/6f867f9102838ebe314c1f3661fdf957... Link: https://lore.kernel.org/r/20230120165826.2469302-1-nathan@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 415a5d138de4..3419ffa2a350 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -14,13 +14,13 @@ endif
ifdef CONFIG_CC_IS_GCC RETPOLINE_CFLAGS := $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register) -RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix) RETPOLINE_VDSO_CFLAGS := $(call cc-option,-mindirect-branch=thunk-inline -mindirect-branch-register) endif ifdef CONFIG_CC_IS_CLANG RETPOLINE_CFLAGS := -mretpoline-external-thunk RETPOLINE_VDSO_CFLAGS := -mretpoline endif +RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix)
ifdef CONFIG_RETHUNK RETHUNK_CFLAGS := -mfunction-return=thunk-extern
From: Koba Ko koba.ko@canonical.com
[ Upstream commit 83bcf3e52e9cfc727df33f1055ef0618c91719d0 ]
Some platforms send the speaker-mute key from EC. dell-wmi can't recognize it.
Add a new keymap for KEY_MUTE in type 0x0010 table.
Signed-off-by: Koba Ko koba.ko@canonical.com Link: https://lore.kernel.org/r/20230117123436.200440-1-koba.ko@canonical.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/dell/dell-wmi-base.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/platform/x86/dell/dell-wmi-base.c b/drivers/platform/x86/dell/dell-wmi-base.c index 0a259a27459f..502783a7adb1 100644 --- a/drivers/platform/x86/dell/dell-wmi-base.c +++ b/drivers/platform/x86/dell/dell-wmi-base.c @@ -261,6 +261,9 @@ static const struct key_entry dell_wmi_keymap_type_0010[] = { { KE_KEY, 0x57, { KEY_BRIGHTNESSDOWN } }, { KE_KEY, 0x58, { KEY_BRIGHTNESSUP } },
+ /*Speaker Mute*/ + { KE_KEY, 0x109, { KEY_MUTE} }, + /* Mic mute */ { KE_KEY, 0x150, { KEY_MICMUTE } },
From: Rishit Bansal rishitbansal0@gmail.com
[ Upstream commit 3ee5447b2048c8389ed899838a40b40180d50906 ]
Add support to map the "HP Omen Key" to KEY_PROG2. Laptops in the HP Omen Series open the HP Omen Command Center application on windows. But, on linux it fails with the following message from the hp-wmi driver:
[ 5143.415714] hp_wmi: Unknown event_id - 29 - 0x21a5
Also adds support to map Fn+Esc to KEY_FN_ESC. This currently throws the following message on the hp-wmi driver:
[ 6082.143785] hp_wmi: Unknown key code - 0x21a7
There is also a "Win-Lock" key on HP Omen Laptops which supports Enabling and Disabling the Windows key, which trigger commands 0x21a4 and 0x121a4 respectively, but I wasn't able to find any KEY in input.h to map this to.
Signed-off-by: Rishit Bansal rishitbansal0@gmail.com Link: https://lore.kernel.org/r/20230120221214.24426-1-rishitbansal0@gmail.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/hp-wmi.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 0a99058be813..4a3851332ef2 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -90,6 +90,7 @@ enum hp_wmi_event_ids { HPWMI_PEAKSHIFT_PERIOD = 0x0F, HPWMI_BATTERY_CHARGE_PERIOD = 0x10, HPWMI_SANITIZATION_MODE = 0x17, + HPWMI_OMEN_KEY = 0x1D, HPWMI_SMART_EXPERIENCE_APP = 0x21, };
@@ -216,6 +217,8 @@ static const struct key_entry hp_wmi_keymap[] = { { KE_KEY, 0x213b, { KEY_INFO } }, { KE_KEY, 0x2169, { KEY_ROTATE_DISPLAY } }, { KE_KEY, 0x216a, { KEY_SETUP } }, + { KE_KEY, 0x21a5, { KEY_PROG2 } }, /* HP Omen Key */ + { KE_KEY, 0x21a7, { KEY_FN_ESC } }, { KE_KEY, 0x21a9, { KEY_TOUCHPAD_OFF } }, { KE_KEY, 0x121a9, { KEY_TOUCHPAD_ON } }, { KE_KEY, 0x231b, { KEY_HELP } }, @@ -810,6 +813,7 @@ static void hp_wmi_notify(u32 value, void *context) case HPWMI_SMART_ADAPTER: break; case HPWMI_BEZEL_BUTTON: + case HPWMI_OMEN_KEY: key_code = hp_wmi_read_int(HPWMI_HOTKEY_QUERY); if (key_code < 0) break;
From: Kevin Kuriakose kevinmkuriakose@gmail.com
[ Upstream commit a410429a3b7e748a9db9f357e71e2e085a21c902 ]
To the best of my knowledge this is the same board as the B450M DS3H-CF, but with an added WiFi card. Name obtained using dmidecode, tested with force_load on v6.1.6
Signed-off-by: Kevin Kuriakose kevinmkuriakose@gmail.com Acked-by: Thomas Weißschuh linux@weissschuh.net Link: https://lore.kernel.org/r/20230119150925.31962-1-kevinmkuriakose@gmail.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/gigabyte-wmi.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/platform/x86/gigabyte-wmi.c b/drivers/platform/x86/gigabyte-wmi.c index 5e7e6659a849..322cfaeda17b 100644 --- a/drivers/platform/x86/gigabyte-wmi.c +++ b/drivers/platform/x86/gigabyte-wmi.c @@ -141,6 +141,7 @@ static u8 gigabyte_wmi_detect_sensor_usability(struct wmi_device *wdev)
static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = { DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M DS3H-CF"), + DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M DS3H WIFI-CF"), DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M S2H V2"), DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE AX V2"), DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE"),
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 8e60615e8932167057b363c11a7835da7f007106 ]
By default when the system is configured for low power idle in the FADT the keyboard is set up as a wake source. This matches the behavior that Windows uses for Modern Standby as well.
It has been reported that a variety of AMD based designs there are spurious wakeups are happening where two IRQ sources are active.
For example: ``` PM: Triggering wakeup from IRQ 9 PM: Triggering wakeup from IRQ 1 ```
In these designs IRQ 9 is the ACPI SCI and IRQ 1 is the keyboard. One way to trigger this problem is to suspend the laptop and then unplug the AC adapter. The SOC will be in a hardware sleep state and plugging in the AC adapter returns control to the kernel's s2idle loop.
Normally if just IRQ 9 was active the s2idle loop would advance any EC transactions and no other IRQ being active would cause the s2idle loop to put the SOC back into hardware sleep state.
When this bug occurred IRQ 1 is also active even if no keyboard activity occurred. This causes the s2idle loop to break and the system to wake.
This is a platform firmware bug triggering IRQ1 without keyboard activity. This occurs in Windows as well, but Windows will enter "SW DRIPS" and then with no activity enters back into "HW DRIPS" (hardware sleep state).
This issue affects Renoir, Lucienne, Cezanne, and Barcelo platforms. It does not happen on newer systems such as Mendocino or Rembrandt.
It's been fixed in newer platform firmware. To avoid triggering the bug on older systems check the SMU F/W version and adjust the policy at suspend time for s2idle wakeup from keyboard on these systems. A lot of thought and experimentation has been given around the timing of disabling IRQ1, and to make it work the "suspend" PM callback is restored.
Reported-by: Kai-Heng Feng kai.heng.feng@canonical.com Reported-by: Xaver Hugl xaver.hugl@gmail.com Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2115 Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1951 Signed-off-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20230120191519.15926-1-mario.limonciello@amd.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/amd/pmc.c | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c index 8d924986381b..be1b49824edb 100644 --- a/drivers/platform/x86/amd/pmc.c +++ b/drivers/platform/x86/amd/pmc.c @@ -22,6 +22,7 @@ #include <linux/pci.h> #include <linux/platform_device.h> #include <linux/rtc.h> +#include <linux/serio.h> #include <linux/suspend.h> #include <linux/seq_file.h> #include <linux/uaccess.h> @@ -653,6 +654,33 @@ static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev) return -EINVAL; }
+static int amd_pmc_czn_wa_irq1(struct amd_pmc_dev *pdev) +{ + struct device *d; + int rc; + + if (!pdev->major) { + rc = amd_pmc_get_smu_version(pdev); + if (rc) + return rc; + } + + if (pdev->major > 64 || (pdev->major == 64 && pdev->minor > 65)) + return 0; + + d = bus_find_device_by_name(&serio_bus, NULL, "serio0"); + if (!d) + return 0; + if (device_may_wakeup(d)) { + dev_info_once(d, "Disabling IRQ1 wakeup source to avoid platform firmware bug\n"); + disable_irq_wake(1); + device_set_wakeup_enable(d, false); + } + put_device(d); + + return 0; +} + static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg) { struct rtc_device *rtc_device; @@ -782,6 +810,25 @@ static struct acpi_s2idle_dev_ops amd_pmc_s2idle_dev_ops = { .check = amd_pmc_s2idle_check, .restore = amd_pmc_s2idle_restore, }; + +static int __maybe_unused amd_pmc_suspend_handler(struct device *dev) +{ + struct amd_pmc_dev *pdev = dev_get_drvdata(dev); + + if (pdev->cpu_id == AMD_CPU_ID_CZN) { + int rc = amd_pmc_czn_wa_irq1(pdev); + + if (rc) { + dev_err(pdev->dev, "failed to adjust keyboard wakeup: %d\n", rc); + return rc; + } + } + + return 0; +} + +static SIMPLE_DEV_PM_OPS(amd_pmc_pm, amd_pmc_suspend_handler, NULL); + #endif
static const struct pci_device_id pmc_pci_ids[] = { @@ -980,6 +1027,9 @@ static struct platform_driver amd_pmc_driver = { .name = "amd_pmc", .acpi_match_table = amd_pmc_acpi_ids, .dev_groups = pmc_groups, +#ifdef CONFIG_SUSPEND + .pm = &amd_pmc_pm, +#endif }, .probe = amd_pmc_probe, .remove = amd_pmc_remove,
From: Hyunwoo Kim v4bel@theori.io
[ Upstream commit f2b0b5210f67c56a3bcdf92ff665fb285d6e0067 ]
When listen() and accept() are called on an x25 socket that connect() succeeds, accept() succeeds immediately. This is because x25_connect() queues the skb to sk->sk_receive_queue, and x25_accept() dequeues it.
This creates a child socket with the sk of the parent x25 socket, which can cause confusion.
Fix x25_listen() to return -EINVAL if the socket has already been successfully connect()ed to avoid this issue.
Signed-off-by: Hyunwoo Kim v4bel@theori.io Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/x25/af_x25.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 3b55502b2965..5c7ad301d742 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -482,6 +482,12 @@ static int x25_listen(struct socket *sock, int backlog) int rc = -EOPNOTSUPP;
lock_sock(sk); + if (sock->state != SS_UNCONNECTED) { + rc = -EINVAL; + release_sock(sk); + return rc; + } + if (sk->sk_state != TCP_LISTEN) { memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN); sk->sk_max_ack_backlog = backlog;
From: Aurabindo Pillai aurabindo.pillai@amd.com
[ Upstream commit 4b069553246f993c4221e382d0d0ae34f5ba730e ]
[Why&How] Switching between certain modes that are freesync video modes and those are not freesync video modes result in timing not changing as seen by the monitor due to incorrect timing being driven.
The issue is fixed by ensuring that when a non freesync video mode is set, we reset the freesync status on the crtc.
Reviewed-by: Nicholas Kazlauskas Nicholas.Kazlauskas@amd.com Acked-by: Alan Liu HaoPing.Liu@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: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 85bd1f18259c..b425ec00817c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8784,6 +8784,13 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, if (!dm_old_crtc_state->stream) goto skip_modeset;
+ /* Unset freesync video if it was active before */ + if (dm_old_crtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED) { + dm_new_crtc_state->freesync_config.state = VRR_STATE_INACTIVE; + dm_new_crtc_state->freesync_config.fixed_refresh_in_uhz = 0; + } + + /* Now check if we should set freesync video mode */ if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream && is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state)) {
From: Kees Cook keescook@chromium.org
[ Upstream commit be0d8f48ad97f5b775b0af3310343f676dbf318a ]
struct bkey has internal padding in a union, but it isn't always named the same (e.g. key ## _pad, key_p, etc). This makes it extremely hard for the compiler to reason about the available size of copies done against such keys. Use unsafe_memcpy() for now, to silence the many run-time false positive warnings:
memcpy: detected field-spanning write (size 264) of single field "&i->j" at drivers/md/bcache/journal.c:152 (size 240) memcpy: detected field-spanning write (size 24) of single field "&b->key" at drivers/md/bcache/btree.c:939 (size 16) memcpy: detected field-spanning write (size 24) of single field "&temp.key" at drivers/md/bcache/extents.c:428 (size 16)
Reported-by: Alexandre Pereira alexpereira@disroot.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=216785 Acked-by: Coly Li colyli@suse.de Cc: Kent Overstreet kent.overstreet@gmail.com Cc: linux-bcache@vger.kernel.org Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20230106060229.never.047-kees@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/bcache_ondisk.h | 3 ++- drivers/md/bcache/journal.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/md/bcache/bcache_ondisk.h b/drivers/md/bcache/bcache_ondisk.h index 97413586195b..f96034e0ba4f 100644 --- a/drivers/md/bcache/bcache_ondisk.h +++ b/drivers/md/bcache/bcache_ondisk.h @@ -106,7 +106,8 @@ static inline unsigned long bkey_bytes(const struct bkey *k) return bkey_u64s(k) * sizeof(__u64); }
-#define bkey_copy(_dest, _src) memcpy(_dest, _src, bkey_bytes(_src)) +#define bkey_copy(_dest, _src) unsafe_memcpy(_dest, _src, bkey_bytes(_src), \ + /* bkey is always padded */)
static inline void bkey_copy_key(struct bkey *dest, const struct bkey *src) { diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index e5da469a4235..c182c21de2e8 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c @@ -149,7 +149,8 @@ reread: left = ca->sb.bucket_size - offset; bytes, GFP_KERNEL); if (!i) return -ENOMEM; - memcpy(&i->j, j, bytes); + unsafe_memcpy(&i->j, j, bytes, + /* "bytes" was calculated by set_bytes() above */); /* Add to the location after 'where' points to */ list_add(&i->list, where); ret = 1;
From: Olivier Moysan olivier.moysan@foss.st.com
[ Upstream commit cc3304052a89ab6ac887ed9224420a27e3d354e1 ]
When STM32 DFSDM driver is built as module, no modalias information is available. This prevents module to be loaded by udev. Add MODULE_DEVICE_TABLE() to fill module aliases.
Fixes: e2e6771c6462 ("IIO: ADC: add STM32 DFSDM sigma delta ADC support") Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com Link: https://lore.kernel.org/r/20221202152848.45585-1-olivier.moysan@foss.st.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/stm32-dfsdm-adc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c index 6d21ea84fa82..a428bdb567d5 100644 --- a/drivers/iio/adc/stm32-dfsdm-adc.c +++ b/drivers/iio/adc/stm32-dfsdm-adc.c @@ -1520,6 +1520,7 @@ static const struct of_device_id stm32_dfsdm_adc_match[] = { }, {} }; +MODULE_DEVICE_TABLE(of, stm32_dfsdm_adc_match);
static int stm32_dfsdm_adc_probe(struct platform_device *pdev) {
From: Neil Armstrong neil.armstrong@linaro.org
[ Upstream commit eb320f76e31dc835b9f57f04af1a2353b13bb7d8 ]
With vbus override enabled when in OTG dr_mode, Host<->Peripheral switch now works on SM8550, otherwise the DWC3 seems to be stuck in Host mode only.
Fixes: a4333c3a6ba9 ("usb: dwc3: Add Qualcomm DWC3 glue driver") Reviewed-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://lore.kernel.org/r/20230123-topic-sm8550-upstream-dwc3-qcom-otg-v2-1-... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/dwc3-qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index b0a0351d2d8b..959fc925ca7c 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -901,7 +901,7 @@ static int dwc3_qcom_probe(struct platform_device *pdev) qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev);
/* enable vbus override for device mode */ - if (qcom->mode == USB_DR_MODE_PERIPHERAL) + if (qcom->mode != USB_DR_MODE_HOST) dwc3_qcom_vbus_override_enable(qcom, true);
/* register extcon to override sw_vbus on Vbus change later */
From: Udipto Goswami quic_ugoswami@quicinc.com
[ Upstream commit 921deb9da15851425ccbb6ee409dc2fd8fbdfe6b ]
__ffs_ep0_queue_wait executes holding the spinlock of &ffs->ev.waitq.lock and unlocks it after the assignments to usb_request are done. However in the code if the request is already NULL we bail out returning -EINVAL but never unlocked the spinlock.
Fix this by adding spin_unlock_irq &ffs->ev.waitq.lock before returning.
Fixes: 6a19da111057 ("usb: gadget: f_fs: Prevent race during ffs_ep0_queue_wait") Reviewed-by: John Keeping john@metanate.com Signed-off-by: Udipto Goswami quic_ugoswami@quicinc.com Link: https://lore.kernel.org/r/20230124091149.18647-1-quic_ugoswami@quicinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_fs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 523a961b910b..8ad354741380 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -279,8 +279,10 @@ static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len) struct usb_request *req = ffs->ep0req; int ret;
- if (!req) + if (!req) { + spin_unlock_irq(&ffs->ev.waitq.lock); return -EINVAL; + }
req->zero = len < le16_to_cpu(ffs->ev.setup.wLength);
From: George Kennedy george.kennedy@oracle.com
[ Upstream commit 226fae124b2dac217ea5436060d623ff3385bc34 ]
After a call to console_unlock() in vcs_read() the vc_data struct can be freed by vc_deallocate(). Because of that, the struct vc_data pointer load must be done at the top of while loop in vcs_read() to avoid a UAF when vcs_size() is called.
Syzkaller reported a UAF in vcs_size().
BUG: KASAN: use-after-free in vcs_size (drivers/tty/vt/vc_screen.c:215) Read of size 4 at addr ffff8881137479a8 by task 4a005ed81e27e65/1537
CPU: 0 PID: 1537 Comm: 4a005ed81e27e65 Not tainted 6.2.0-rc5 #1 Hardware name: Red Hat KVM, BIOS 1.15.0-2.module Call Trace: <TASK> __asan_report_load4_noabort (mm/kasan/report_generic.c:350) vcs_size (drivers/tty/vt/vc_screen.c:215) vcs_read (drivers/tty/vt/vc_screen.c:415) vfs_read (fs/read_write.c:468 fs/read_write.c:450) ... </TASK>
Allocated by task 1191: ... kmalloc_trace (mm/slab_common.c:1069) vc_allocate (./include/linux/slab.h:580 ./include/linux/slab.h:720 drivers/tty/vt/vt.c:1128 drivers/tty/vt/vt.c:1108) con_install (drivers/tty/vt/vt.c:3383) tty_init_dev (drivers/tty/tty_io.c:1301 drivers/tty/tty_io.c:1413 drivers/tty/tty_io.c:1390) tty_open (drivers/tty/tty_io.c:2080 drivers/tty/tty_io.c:2126) chrdev_open (fs/char_dev.c:415) do_dentry_open (fs/open.c:883) vfs_open (fs/open.c:1014) ...
Freed by task 1548: ... kfree (mm/slab_common.c:1021) vc_port_destruct (drivers/tty/vt/vt.c:1094) tty_port_destructor (drivers/tty/tty_port.c:296) tty_port_put (drivers/tty/tty_port.c:312) vt_disallocate_all (drivers/tty/vt/vt_ioctl.c:662 (discriminator 2)) vt_ioctl (drivers/tty/vt/vt_ioctl.c:903) tty_ioctl (drivers/tty/tty_io.c:2776) ...
The buggy address belongs to the object at ffff888113747800 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 424 bytes inside of 1024-byte region [ffff888113747800, ffff888113747c00)
The buggy address belongs to the physical page: page:00000000b3fe6c7c refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x113740 head:00000000b3fe6c7c order:3 compound_mapcount:0 subpages_mapcount:0 compound_pincount:0 anon flags: 0x17ffffc0010200(slab|head|node=0|zone=2|lastcpupid=0x1fffff) raw: 0017ffffc0010200 ffff888100042dc0 0000000000000000 dead000000000001 raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff888113747880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888113747900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff888113747980: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^ ffff888113747a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888113747a80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== Disabling lock debugging due to kernel taint
Fixes: ac751efa6a0d ("console: rename acquire/release_console_sem() to console_lock/unlock()") Reported-by: syzkaller syzkaller@googlegroups.com Suggested-by: Jiri Slaby jirislaby@kernel.org Signed-off-by: George Kennedy george.kennedy@oracle.com Link: https://lore.kernel.org/r/1674577014-12374-1-git-send-email-george.kennedy@o... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/vt/vc_screen.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 1850bacdb5b0..f566eb1839dc 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -386,10 +386,6 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
uni_mode = use_unicode(inode); attr = use_attributes(inode); - ret = -ENXIO; - vc = vcs_vc(inode, &viewed); - if (!vc) - goto unlock_out;
ret = -EINVAL; if (pos < 0) @@ -407,6 +403,11 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) unsigned int this_round, skip = 0; int size;
+ ret = -ENXIO; + vc = vcs_vc(inode, &viewed); + if (!vc) + goto unlock_out; + /* Check whether we are above size each round, * as copy_to_user at the end of this loop * could sleep.
From: Samuel Thibault samuel.thibault@ens-lyon.org
commit 2b09d5d364986f724f17001ccfe4126b9b43a0be upstream.
blit_x and blit_y are u32, so fbcon currently cannot support fonts larger than 32x32.
The 32x32 case also needs shifting an unsigned int, to properly set bit 31, otherwise we get "UBSAN: shift-out-of-bounds in fbcon_set_font", as reported on:
http://lore.kernel.org/all/IA1PR07MB98308653E259A6F2CE94A4AFABCE9@IA1PR07MB9... Kernel Branch: 6.2.0-rc5-next-20230124 Kernel config: https://drive.google.com/file/d/1F-LszDAizEEH0ZX0HcSR06v5q8FPl2Uv/view?usp=s... Reproducer: https://drive.google.com/file/d/1mP1jcLBY7vWCNM60OMf-ogw-urQRjNrm/view?usp=s...
Reported-by: Sanan Hasanov sanan.hasanov@Knights.ucf.edu Signed-off-by: Samuel Thibault samuel.thibault@ens-lyon.org Fixes: 2d2699d98492 ("fbcon: font setting should check limitation of driver") Cc: stable@vger.kernel.org Tested-by: Miko Larsson mikoxyzzz@gmail.com Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/video/fbdev/core/fbcon.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2495,9 +2495,12 @@ static int fbcon_set_font(struct vc_data h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres)) return -EINVAL;
+ if (font->width > 32 || font->height > 32) + return -EINVAL; + /* Make sure drawing engine can handle the font */ - if (!(info->pixmap.blit_x & (1 << (font->width - 1))) || - !(info->pixmap.blit_y & (1 << (font->height - 1)))) + if (!(info->pixmap.blit_x & BIT(font->width - 1)) || + !(info->pixmap.blit_y & BIT(font->height - 1))) return -EINVAL;
/* Make sure driver can handle the font length */
From: Waiman Long longman@redhat.com
commit e5ae8803847b80fe9d744a3174abe2b7bfed222a upstream.
It was found that the check to see if a partition could use up all the cpus from the parent cpuset in update_parent_subparts_cpumask() was incorrect. As a result, it is possible to leave parent with no effective cpu left even if there are tasks in the parent cpuset. This can lead to system panic as reported in [1].
Fix this probem by updating the check to fail the enabling the partition if parent's effective_cpus is a subset of the child's cpus_allowed.
Also record the error code when an error happens in update_prstate() and add a test case where parent partition and child have the same cpu list and parent has task. Enabling partition in the child will fail in this case.
[1] https://www.spinics.net/lists/cgroups/msg36254.html
Fixes: f0af1bfc27b5 ("cgroup/cpuset: Relax constraints to partition & cpus changes") Cc: stable@vger.kernel.org # v6.1 Reported-by: Srinivas Pandruvada srinivas.pandruvada@intel.com Signed-off-by: Waiman Long longman@redhat.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/cgroup/cpuset.c | 3 ++- tools/testing/selftests/cgroup/test_cpuset_prs.sh | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
--- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -1342,7 +1342,7 @@ static int update_parent_subparts_cpumas * A parent can be left with no CPU as long as there is no * task directly associated with the parent partition. */ - if (!cpumask_intersects(cs->cpus_allowed, parent->effective_cpus) && + if (cpumask_subset(parent->effective_cpus, cs->cpus_allowed) && partition_is_populated(parent, cs)) return PERR_NOCPUS;
@@ -2320,6 +2320,7 @@ out: new_prs = -new_prs; spin_lock_irq(&callback_lock); cs->partition_root_state = new_prs; + WRITE_ONCE(cs->prs_err, err); spin_unlock_irq(&callback_lock); /* * Update child cpusets, if present. --- a/tools/testing/selftests/cgroup/test_cpuset_prs.sh +++ b/tools/testing/selftests/cgroup/test_cpuset_prs.sh @@ -254,6 +254,7 @@ TEST_MATRIX=( # Taking away all CPUs from parent or itself if there are tasks # will make the partition invalid. " S+ C2-3:P1:S+ C3:P1 . . T C2-3 . . 0 A1:2-3,A2:2-3 A1:P1,A2:P-1" + " S+ C3:P1:S+ C3 . . T P1 . . 0 A1:3,A2:3 A1:P1,A2:P-1" " S+ $SETUP_A123_PARTITIONS . T:C2-3 . . . 0 A1:2-3,A2:2-3,A3:3 A1:P1,A2:P-1,A3:P-1" " S+ $SETUP_A123_PARTITIONS . T:C2-3:C1-3 . . . 0 A1:1,A2:2,A3:3 A1:P1,A2:P1,A3:P1"
From: Michael Kelley mikelley@microsoft.com
commit 99f1c46011cc0feb47d4f4f7bee70a0341442d14 upstream.
netvsc_dma_map() and netvsc_dma_unmap() currently check the cp_partial flag and adjust the page_count so that pagebuf entries for the RNDIS portion of the message are skipped when it has already been copied into a send buffer. But this adjustment has already been made by code in netvsc_send(). The duplicate adjustment causes some pagebuf entries to not be mapped. In a normal VM, this doesn't break anything because the mapping doesn’t change the PFN. But in a Confidential VM, dma_map_single() does bounce buffering and provides a different PFN. Failing to do the mapping causes the wrong PFN to be passed to Hyper-V, and various errors ensue.
Fix this by removing the duplicate adjustment in netvsc_dma_map() and netvsc_dma_unmap().
Fixes: 846da38de0e8 ("net: netvsc: Add Isolation VM support for netvsc driver") Cc: stable@vger.kernel.org Signed-off-by: Michael Kelley mikelley@microsoft.com Reviewed-by: Haiyang Zhang haiyangz@microsoft.com Link: https://lore.kernel.org/r/1675135986-254490-1-git-send-email-mikelley@micros... Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/hyperv/netvsc.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
--- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -987,9 +987,6 @@ static void netvsc_copy_to_send_buf(stru void netvsc_dma_unmap(struct hv_device *hv_dev, struct hv_netvsc_packet *packet) { - u32 page_count = packet->cp_partial ? - packet->page_buf_cnt - packet->rmsg_pgcnt : - packet->page_buf_cnt; int i;
if (!hv_is_isolation_supported()) @@ -998,7 +995,7 @@ void netvsc_dma_unmap(struct hv_device * if (!packet->dma_range) return;
- for (i = 0; i < page_count; i++) + for (i = 0; i < packet->page_buf_cnt; i++) dma_unmap_single(&hv_dev->device, packet->dma_range[i].dma, packet->dma_range[i].mapping_size, DMA_TO_DEVICE); @@ -1028,9 +1025,7 @@ static int netvsc_dma_map(struct hv_devi struct hv_netvsc_packet *packet, struct hv_page_buffer *pb) { - u32 page_count = packet->cp_partial ? - packet->page_buf_cnt - packet->rmsg_pgcnt : - packet->page_buf_cnt; + u32 page_count = packet->page_buf_cnt; dma_addr_t dma; int i;
From: Fabio Estevam festevam@denx.de
commit 1febf88ef907b142fdde34f7c64ed3535d9339e4 upstream.
Currently, when resetting the USB modem via AT commands, the modem is no longer re-connected.
This problem is caused by the incorrect description of the USB_OTG2_OC pad. It should have pull-up enabled, hysteresis enabled and the property 'over-current-active-low' should be passed.
With this change, the USB modem can be successfully re-connected after a reset.
Cc: stable@vger.kernel.org Fixes: 9ac0ae97e349 ("ARM: dts: imx7d-smegw01: Add support for i.MX7D SMEGW01 board") Signed-off-by: Fabio Estevam festevam@denx.de Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/boot/dts/imx7d-smegw01.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/imx7d-smegw01.dts b/arch/arm/boot/dts/imx7d-smegw01.dts index 546268b8d0b1..c0f00f5db11e 100644 --- a/arch/arm/boot/dts/imx7d-smegw01.dts +++ b/arch/arm/boot/dts/imx7d-smegw01.dts @@ -198,6 +198,7 @@ &usbotg2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usbotg2>; + over-current-active-low; dr_mode = "host"; status = "okay"; }; @@ -374,7 +375,7 @@
pinctrl_usbotg2: usbotg2grp { fsl,pins = < - MX7D_PAD_UART3_RTS_B__USB_OTG2_OC 0x04 + MX7D_PAD_UART3_RTS_B__USB_OTG2_OC 0x5c >; };
From: Natalia Petrova n.petrova@fintech.ru
commit 29de68c2b32ce58d64dea496d281e25ad0f551bd upstream.
Function radix_tree_insert() returns errors if the node hasn't been initialized and added to the tree.
"kfree(node)" and return value "NULL" of node_get() help to avoid using unclear node in other calls.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Cc: stable@vger.kernel.org # 5.7 Fixes: 0c2204a4ad71 ("net: qrtr: Migrate nameservice to kernel from userspace") Signed-off-by: Natalia Petrova n.petrova@fintech.ru Reviewed-by: Simon Horman simon.horman@corigine.com Reviewed-by: Manivannan Sadhasivam mani@kernel.org Link: https://lore.kernel.org/r/20230125134831.8090-1-n.petrova@fintech.ru Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/qrtr/ns.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -83,7 +83,10 @@ static struct qrtr_node *node_get(unsign
node->id = node_id;
- radix_tree_insert(&nodes, node_id, node); + if (radix_tree_insert(&nodes, node_id, node)) { + kfree(node); + return NULL; + }
return node; }
From: Oliver Hartkopp socketcan@hartkopp.net
commit 4f027cba8216f42a18b544842efab134f8b1f9f4 upstream.
The timer for the transmission of isotp PDUs formerly had two functions: 1. send two consecutive frames with a given time gap 2. monitor the timeouts for flow control frames and the echo frames
This led to larger txstate checks and potentially to a problem discovered by syzbot which enabled the panic_on_warn feature while testing.
The former 'txtimer' function is split into 'txfrtimer' and 'txtimer' to handle the two above functionalities with separate timer callbacks.
The two simplified timers now run in one-shot mode and make the state transitions (especially with isotp_rcv_echo) better understandable.
Fixes: 866337865f37 ("can: isotp: fix tx state handling for echo tx processing") Reported-by: syzbot+5aed6c3aaba661f5b917@syzkaller.appspotmail.com Cc: stable@vger.kernel.org # >= v6.0 Signed-off-by: Oliver Hartkopp socketcan@hartkopp.net Link: https://lore.kernel.org/all/20230104145701.2422-1-socketcan@hartkopp.net Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/can/isotp.c | 65 ++++++++++++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 36 deletions(-)
--- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -140,7 +140,7 @@ struct isotp_sock { canid_t rxid; ktime_t tx_gap; ktime_t lastrxcf_tstamp; - struct hrtimer rxtimer, txtimer; + struct hrtimer rxtimer, txtimer, txfrtimer; struct can_isotp_options opt; struct can_isotp_fc_options rxfc, txfc; struct can_isotp_ll_options ll; @@ -871,7 +871,7 @@ static void isotp_rcv_echo(struct sk_buf }
/* start timer to send next consecutive frame with correct delay */ - hrtimer_start(&so->txtimer, so->tx_gap, HRTIMER_MODE_REL_SOFT); + hrtimer_start(&so->txfrtimer, so->tx_gap, HRTIMER_MODE_REL_SOFT); }
static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer) @@ -879,49 +879,39 @@ static enum hrtimer_restart isotp_tx_tim struct isotp_sock *so = container_of(hrtimer, struct isotp_sock, txtimer); struct sock *sk = &so->sk; - enum hrtimer_restart restart = HRTIMER_NORESTART;
- switch (so->tx.state) { - case ISOTP_SENDING: + /* don't handle timeouts in IDLE state */ + if (so->tx.state == ISOTP_IDLE) + return HRTIMER_NORESTART;
- /* cfecho should be consumed by isotp_rcv_echo() here */ - if (!so->cfecho) { - /* start timeout for unlikely lost echo skb */ - hrtimer_set_expires(&so->txtimer, - ktime_add(ktime_get(), - ktime_set(ISOTP_ECHO_TIMEOUT, 0))); - restart = HRTIMER_RESTART; + /* we did not get any flow control or echo frame in time */
- /* push out the next consecutive frame */ - isotp_send_cframe(so); - break; - } - - /* cfecho has not been cleared in isotp_rcv_echo() */ - pr_notice_once("can-isotp: cfecho %08X timeout\n", so->cfecho); - fallthrough; + /* report 'communication error on send' */ + sk->sk_err = ECOMM; + if (!sock_flag(sk, SOCK_DEAD)) + sk_error_report(sk);
- case ISOTP_WAIT_FC: - case ISOTP_WAIT_FIRST_FC: + /* reset tx state */ + so->tx.state = ISOTP_IDLE; + wake_up_interruptible(&so->wait);
- /* we did not get any flow control frame in time */ + return HRTIMER_NORESTART; +}
- /* report 'communication error on send' */ - sk->sk_err = ECOMM; - if (!sock_flag(sk, SOCK_DEAD)) - sk_error_report(sk); +static enum hrtimer_restart isotp_txfr_timer_handler(struct hrtimer *hrtimer) +{ + struct isotp_sock *so = container_of(hrtimer, struct isotp_sock, + txfrtimer);
- /* reset tx state */ - so->tx.state = ISOTP_IDLE; - wake_up_interruptible(&so->wait); - break; + /* start echo timeout handling and cover below protocol error */ + hrtimer_start(&so->txtimer, ktime_set(ISOTP_ECHO_TIMEOUT, 0), + HRTIMER_MODE_REL_SOFT);
- default: - WARN_ONCE(1, "can-isotp: tx timer state %08X cfecho %08X\n", - so->tx.state, so->cfecho); - } + /* cfecho should be consumed by isotp_rcv_echo() here */ + if (so->tx.state == ISOTP_SENDING && !so->cfecho) + isotp_send_cframe(so);
- return restart; + return HRTIMER_NORESTART; }
static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) @@ -1194,6 +1184,7 @@ static int isotp_release(struct socket * } }
+ hrtimer_cancel(&so->txfrtimer); hrtimer_cancel(&so->txtimer); hrtimer_cancel(&so->rxtimer);
@@ -1597,6 +1588,8 @@ static int isotp_init(struct sock *sk) so->rxtimer.function = isotp_rx_timer_handler; hrtimer_init(&so->txtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); so->txtimer.function = isotp_tx_timer_handler; + hrtimer_init(&so->txfrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); + so->txfrtimer.function = isotp_txfr_timer_handler;
init_waitqueue_head(&so->wait); spin_lock_init(&so->rx_lock);
From: Oliver Hartkopp socketcan@hartkopp.net
commit 823b2e42720f96f277940c37ea438b7c5ead51a4 upstream.
When wait_event_interruptible() has been interrupted by a signal the tx.state value might not be ISOTP_IDLE. Force the state machines into idle state to inhibit the timer handlers to continue working.
Fixes: 866337865f37 ("can: isotp: fix tx state handling for echo tx processing") Cc: stable@vger.kernel.org Signed-off-by: Oliver Hartkopp socketcan@hartkopp.net Link: https://lore.kernel.org/all/20230112192347.1944-1-socketcan@hartkopp.net Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/can/isotp.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/net/can/isotp.c +++ b/net/can/isotp.c @@ -1152,6 +1152,10 @@ static int isotp_release(struct socket * /* wait for complete transmission of current pdu */ wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+ /* force state machines to be idle also when a signal occurred */ + so->tx.state = ISOTP_IDLE; + so->rx.state = ISOTP_IDLE; + spin_lock(&isotp_notifier_lock); while (isotp_busy_notifier == so) { spin_unlock(&isotp_notifier_lock);
From: Alexander Egorenkov egorenar@linux.ibm.com
commit fe8973a3ad0905cb9ba2d42db42ed51de14737df upstream.
With CONFIG_VMAP_STACK=y the stack is allocated from the vmalloc space. Data passed to a hardware or a hypervisor interface that requires V=R can no longer be allocated on the stack.
Use kmalloc() to get memory for a diag288 command.
Signed-off-by: Alexander Egorenkov egorenar@linux.ibm.com Reviewed-by: Heiko Carstens hca@linux.ibm.com Cc: stable@vger.kernel.org Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/watchdog/diag288_wdt.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
--- a/drivers/watchdog/diag288_wdt.c +++ b/drivers/watchdog/diag288_wdt.c @@ -268,12 +268,21 @@ static int __init diag288_init(void) char ebc_begin[] = { 194, 197, 199, 201, 213 }; + char *ebc_cmd;
watchdog_set_nowayout(&wdt_dev, nowayout_info);
if (MACHINE_IS_VM) { - if (__diag288_vm(WDT_FUNC_INIT, 15, - ebc_begin, sizeof(ebc_begin)) != 0) { + ebc_cmd = kmalloc(sizeof(ebc_begin), GFP_KERNEL); + if (!ebc_cmd) { + pr_err("The watchdog cannot be initialized\n"); + return -ENOMEM; + } + memcpy(ebc_cmd, ebc_begin, sizeof(ebc_begin)); + ret = __diag288_vm(WDT_FUNC_INIT, 15, + ebc_cmd, sizeof(ebc_begin)); + kfree(ebc_cmd); + if (ret != 0) { pr_err("The watchdog cannot be initialized\n"); return -EINVAL; }
From: Alexander Egorenkov egorenar@linux.ibm.com
commit 32e40f9506b9e32917eb73154f93037b443124d1 upstream.
The DIAG 288 statement consumes an EBCDIC string the address of which is passed in a register. Use a "memory" clobber to tell the compiler that memory is accessed within the inline assembly.
Signed-off-by: Alexander Egorenkov egorenar@linux.ibm.com Reviewed-by: Heiko Carstens hca@linux.ibm.com Cc: stable@vger.kernel.org Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/watchdog/diag288_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/watchdog/diag288_wdt.c +++ b/drivers/watchdog/diag288_wdt.c @@ -86,7 +86,7 @@ static int __diag288(unsigned int func, "1:\n" EX_TABLE(0b, 1b) : "+d" (err) : "d"(__func), "d"(__timeout), - "d"(__action), "d"(__len) : "1", "cc"); + "d"(__action), "d"(__len) : "1", "cc", "memory"); return err; }
From: Victor Shyba victor1984@riseup.net
commit 6a28a25d358079b7d0d144689f850aecacf63cba upstream.
Same issue as SP513-54N: Headset microphone does not work without ALC255_FIXUP_ACER_MIC_NO_PRESENCE fixup.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=211853 Cc: stable@vger.kernel.org Signed-off-by: Victor Shyba victor1984@riseup.net Link: https://lore.kernel.org/r/20230123222129.17589-1-victor1984@riseup.net Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9202,6 +9202,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x1025, 0x142b, "Acer Swift SF314-42", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1025, 0x1466, "Acer Aspire A515-56", ALC255_FIXUP_ACER_HEADPHONE_AND_MIC), + SND_PCI_QUIRK(0x1025, 0x1534, "Acer Predator PH315-54", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x1028, 0x053c, "Dell Latitude E5430", ALC292_FIXUP_DELL_E7X), SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
From: Jeremy Szu jeremy.szu@canonical.com
commit 858c54152658ccd4e305c1e12d3cc6825bc90504 upstream.
There is a HP platform needs ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED quirk to make mic-mute/audio-mute/speaker working.
Signed-off-by: Jeremy Szu jeremy.szu@canonical.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230118115446.14902-1-jeremy.szu@canonical.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9433,6 +9433,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8b92, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
commit 100c94ffde489ee11e23400f2a07b236144b048f upstream.
Correct reversed values used in min/max rates, leading to incorrect playback constraints.
Cc: stable@vger.kernel.org Fixes: 43b8c7dc85a1 ("ASoC: codecs: add wsa883x amplifier support") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20230124123049.285395-1-krzysztof.kozlowski@linaro... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/codecs/wsa883x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index 966ba4909204..58fdb4e9fd97 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -1359,8 +1359,8 @@ static struct snd_soc_dai_driver wsa883x_dais[] = { .stream_name = "SPKR Playback", .rates = WSA883X_RATES | WSA883X_FRAC_RATES, .formats = WSA883X_FORMATS, - .rate_max = 8000, - .rate_min = 352800, + .rate_min = 8000, + .rate_max = 352800, .channels_min = 1, .channels_max = 1, },
From: Bard Liao yung-chuan.liao@linux.intel.com
commit 7d2a67e02549c4b1feaac4d8b4151bf46424a047 upstream.
We should unprepare the widget if its use_count = 1.
Fixes: 9862dcf70245 ("ASoC: SOF: don't unprepare widget used other pipelines") Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Rander Wang rander.wang@intel.com Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Link: https://lore.kernel.org/r/20230118101255.29139-2-peter.ujfalusi@linux.intel.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/sof/sof-audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 7306a2649857..e52ef62ce7a3 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -272,7 +272,7 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg struct snd_soc_dapm_path *p;
/* return if the widget is in use or if it is already unprepared */ - if (!swidget->prepared || swidget->use_count > 1) + if (!swidget->prepared || swidget->use_count > 0) return;
if (widget_ops[widget->id].ipc_unprepare)
From: Ranjani Sridharan ranjani.sridharan@linux.intel.com
commit 0ad84b11f2f8dd19d62d0b2ffd95ece897e6c3dc upstream.
Skip preparing/unpreparing widgets if the swidget pointer is NULL. This will be true in the case of virtual widgets in topology that were added for reusing the legacy HDA machine driver with SOF.
Fixes: 9862dcf70245 ("ASoC: SOF: don't unprepare widget used other pipelines") Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Rander Wang rander.wang@intel.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Tested-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Link: https://lore.kernel.org/r/20230118101255.29139-3-peter.ujfalusi@linux.intel.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/sof/sof-audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -272,7 +272,7 @@ sof_unprepare_widgets_in_path(struct snd struct snd_soc_dapm_path *p;
/* return if the widget is in use or if it is already unprepared */ - if (!swidget->prepared || swidget->use_count > 0) + if (!swidget || !swidget->prepared || swidget->use_count > 0) return;
if (widget_ops[widget->id].ipc_unprepare) @@ -303,7 +303,7 @@ sof_prepare_widgets_in_path(struct snd_s struct snd_soc_dapm_path *p; int ret;
- if (!widget_ops[widget->id].ipc_prepare || swidget->prepared) + if (!swidget || !widget_ops[widget->id].ipc_prepare || swidget->prepared) goto sink_prepare;
/* prepare the source widget */
From: Bard Liao yung-chuan.liao@linux.intel.com
commit cc755b4377b0520d594ae573497cf0824baea648 upstream.
The existing code return when a widget doesn't need to prepare/unprepare. This will prevent widgets in the sink path from being prepared/unprepared.
Cc: stable@vger.kernel.org # 6.1 Link: https://github.com/thesofproject/linux/issues/4021 Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Rander Wang rander.wang@intel.com Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Link: https://lore.kernel.org/r/20230118101255.29139-4-peter.ujfalusi@linux.intel.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/sof/sof-audio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 8c114e6a23c6..ff716bfbcb67 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -271,9 +271,9 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg struct snd_sof_widget *swidget = widget->dobj.private; struct snd_soc_dapm_path *p;
- /* return if the widget is in use or if it is already unprepared */ + /* skip if the widget is in use or if it is already unprepared */ if (!swidget || !swidget->prepared || swidget->use_count > 0) - return; + goto sink_unprepare;
if (widget_ops[widget->id].ipc_unprepare) /* unprepare the source widget */ @@ -281,6 +281,7 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg
swidget->prepared = false;
+sink_unprepare: /* unprepare all widgets in the sink paths */ snd_soc_dapm_widget_for_each_sink_path(widget, p) { if (!p->walking && p->sink->dobj.private) {
From: Ard Biesheuvel ardb@kernel.org
commit 636ab417a7aec4ee993916e688eb5c5977570836 upstream.
UEFI v2.10 introduces version 2 of the memory attributes table, which turns the reserved field into a flags field, but is compatible with version 1 in all other respects. So let's not complain about version 2 if we encounter it.
Cc: stable@vger.kernel.org Signed-off-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/firmware/efi/memattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/firmware/efi/memattr.c +++ b/drivers/firmware/efi/memattr.c @@ -33,7 +33,7 @@ int __init efi_memattr_init(void) return -ENOMEM; }
- if (tbl->version > 1) { + if (tbl->version > 2) { pr_warn("Unexpected EFI Memory Attributes table version %d\n", tbl->version); goto unmap;
From: Shanker Donthineni sdonthineni@nvidia.com
commit 101ca8d05913b7d1e6e8b9dd792193d4082fff86 upstream.
The current implementation of rtc-efi is expecting all the 4 time services GET{SET}_TIME{WAKEUP} must be supported by UEFI firmware. As per the EFI_RT_PROPERTIES_TABLE, the platform specific implementations can choose to enable selective time services based on the RTC device capabilities.
This patch does the following changes to provide GET/SET RTC services on platforms that do not support the WAKEUP feature.
1) Relax time services cap check when creating a platform device. 2) Clear RTC_FEATURE_ALARM bit in the absence of WAKEUP services. 3) Conditional alarm entries in '/proc/driver/rtc'.
Cc: stable@vger.kernel.org # v6.0+ Signed-off-by: Shanker Donthineni sdonthineni@nvidia.com Link: https://lore.kernel.org/r/20230102230630.192911-1-sdonthineni@nvidia.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/rtc/rtc-efi.c | 48 +++++++++++++++++++++++++++--------------------- include/linux/efi.h | 3 ++- 2 files changed, 29 insertions(+), 22 deletions(-)
--- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c @@ -188,9 +188,10 @@ static int efi_set_time(struct device *d
static int efi_procfs(struct device *dev, struct seq_file *seq) { - efi_time_t eft, alm; - efi_time_cap_t cap; - efi_bool_t enabled, pending; + efi_time_t eft, alm; + efi_time_cap_t cap; + efi_bool_t enabled, pending; + struct rtc_device *rtc = dev_get_drvdata(dev);
memset(&eft, 0, sizeof(eft)); memset(&alm, 0, sizeof(alm)); @@ -213,23 +214,25 @@ static int efi_procfs(struct device *dev /* XXX fixme: convert to string? */ seq_printf(seq, "Timezone\t: %u\n", eft.timezone);
- seq_printf(seq, - "Alarm Time\t: %u:%u:%u.%09u\n" - "Alarm Date\t: %u-%u-%u\n" - "Alarm Daylight\t: %u\n" - "Enabled\t\t: %s\n" - "Pending\t\t: %s\n", - alm.hour, alm.minute, alm.second, alm.nanosecond, - alm.year, alm.month, alm.day, - alm.daylight, - enabled == 1 ? "yes" : "no", - pending == 1 ? "yes" : "no"); - - if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE) - seq_puts(seq, "Timezone\t: unspecified\n"); - else - /* XXX fixme: convert to string? */ - seq_printf(seq, "Timezone\t: %u\n", alm.timezone); + if (test_bit(RTC_FEATURE_ALARM, rtc->features)) { + seq_printf(seq, + "Alarm Time\t: %u:%u:%u.%09u\n" + "Alarm Date\t: %u-%u-%u\n" + "Alarm Daylight\t: %u\n" + "Enabled\t\t: %s\n" + "Pending\t\t: %s\n", + alm.hour, alm.minute, alm.second, alm.nanosecond, + alm.year, alm.month, alm.day, + alm.daylight, + enabled == 1 ? "yes" : "no", + pending == 1 ? "yes" : "no"); + + if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE) + seq_puts(seq, "Timezone\t: unspecified\n"); + else + /* XXX fixme: convert to string? */ + seq_printf(seq, "Timezone\t: %u\n", alm.timezone); + }
/* * now prints the capabilities @@ -269,7 +272,10 @@ static int __init efi_rtc_probe(struct p
rtc->ops = &efi_rtc_ops; clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); - set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->features); + if (efi_rt_services_supported(EFI_RT_SUPPORTED_WAKEUP_SERVICES)) + set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->features); + else + clear_bit(RTC_FEATURE_ALARM, rtc->features);
return devm_rtc_register_device(rtc); } --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -668,7 +668,8 @@ extern struct efi {
#define EFI_RT_SUPPORTED_ALL 0x3fff
-#define EFI_RT_SUPPORTED_TIME_SERVICES 0x000f +#define EFI_RT_SUPPORTED_TIME_SERVICES 0x0003 +#define EFI_RT_SUPPORTED_WAKEUP_SERVICES 0x000c #define EFI_RT_SUPPORTED_VARIABLE_SERVICES 0x0070
extern struct mm_struct efi_mm;
From: Dmitry Perchanov dmitry.perchanov@intel.com
commit f7b23d1c35d8b8de1425bdfccaefd01f3b7c9d1c upstream.
Return value should be zero for success. This was forgotten for timestamp feature. Verified on RealSense cameras.
Fixes: a96cd0f901ee ("iio: accel: hid-sensor-accel-3d: Add timestamp") Signed-off-by: Dmitry Perchanov dmitry.perchanov@intel.com Link: https://lore.kernel.org/r/a6dc426498221c81fa71045b41adf782ebd42136.camel@int... Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/accel/hid-sensor-accel-3d.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -280,6 +280,7 @@ static int accel_3d_capture_sample(struc hid_sensor_convert_timestamp( &accel_state->common_attributes, *(int64_t *)raw_data); + ret = 0; break; default: break;
From: Dmitry Perchanov dmitry.perchanov@intel.com
commit eb50cd5bfdac61627a5026566cf3b90ced7b141c upstream.
Return value should be zero for success. This was forgotten for timestamp feature. Verified on RealSense cameras.
Fixes: 4648cbd8fb92 ("iio: hid-sensor-gyro-3d: Add timestamp channel") Signed-off-by: Dmitry Perchanov dmitry.perchanov@intel.com Link: https://lore.kernel.org/r/7c1809dc74eb2f58a20595f4d02e76934f8e9219.camel@int... Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/gyro/hid-sensor-gyro-3d.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -231,6 +231,7 @@ static int gyro_3d_capture_sample(struct gyro_state->timestamp = hid_sensor_convert_timestamp(&gyro_state->common_attributes, *(s64 *)raw_data); + ret = 0; break; default: break;
From: Marco Pagani marpagan@redhat.com
commit 6794ed0cfcc6ce737240eccc48b3e8190df36703 upstream.
The clang-analyzer reported a warning: "Value stored to 'ret' is never read".
Fix the return value check if devm_krealloc() fails to resize ams_channels.
Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver") Signed-off-by: Marco Pagani marpagan@redhat.com Acked-by: Michal Simek michal.simek@amd.com Link: https://lore.kernel.org/r/20221125113112.219290-1-marpagan@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/adc/xilinx-ams.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/adc/xilinx-ams.c +++ b/drivers/iio/adc/xilinx-ams.c @@ -1329,7 +1329,7 @@ static int ams_parse_firmware(struct iio
dev_channels = devm_krealloc(dev, ams_channels, dev_size, GFP_KERNEL); if (!dev_channels) - ret = -ENOMEM; + return -ENOMEM;
indio_dev->channels = dev_channels; indio_dev->num_channels = num_channels;
From: Xiongfeng Wang wangxiongfeng2@huawei.com
commit cbd3a0153cd18a2cbef6bf3cf31bb406c3fc9f55 upstream.
of_get_parent() will return a device_node pointer with refcount incremented. We need to use of_node_put() on it when done. Add the missing of_node_put() in the error path of berlin2_adc_probe();
Fixes: 70f1937911ca ("iio: adc: add support for Berlin") Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Link: https://lore.kernel.org/r/20221129020316.191731-1-wangxiongfeng2@huawei.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/adc/berlin2-adc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/iio/adc/berlin2-adc.c +++ b/drivers/iio/adc/berlin2-adc.c @@ -298,8 +298,10 @@ static int berlin2_adc_probe(struct plat int ret;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv)); - if (!indio_dev) + if (!indio_dev) { + of_node_put(parent_np); return -ENOMEM; + }
priv = iio_priv(indio_dev);
From: Frank Li Frank.Li@nxp.com
commit 0fc3562a993c3dc41d1177b3983d9300d0db1d4d upstream.
irq flood happen when run cat /sys/bus/iio/devices/iio:device0/in_voltage1_raw
imx8qxp_adc_read_raw() { ... enable irq /* adc start */ writel(1, adc->regs + IMX8QXP_ADR_ADC_SWTRIG); ^^^^ trigger irq flood. wait_for_completion_interruptible_timeout(); readl(adc->regs + IMX8QXP_ADR_ADC_RESFIFO); ^^^^ clear irq here. ... }
There is only FIFO watermark interrupt at this ADC controller. IRQ line will be assert until software read data from FIFO. So IRQ flood happen during wait_for_completion_interruptible_timeout().
Move FIFO read into irq handle to avoid irq flood.
Fixes: 1e23dcaa1a9f ("iio: imx8qxp-adc: Add driver support for NXP IMX8QXP ADC") Cc: stable@vger.kernel.org
Signed-off-by: Frank Li Frank.Li@nxp.com Reviewed-by: Cai Huoqing cai.huoqing@linux.dev Reviewed-by: Haibo Chen haibo.chen@nxp.com Link: https://lore.kernel.org/r/20221201140110.2653501-1-Frank.Li@nxp.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/adc/imx8qxp-adc.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/imx8qxp-adc.c b/drivers/iio/adc/imx8qxp-adc.c index 36777b827165..f5a0fc9e64c5 100644 --- a/drivers/iio/adc/imx8qxp-adc.c +++ b/drivers/iio/adc/imx8qxp-adc.c @@ -86,6 +86,8 @@
#define IMX8QXP_ADC_TIMEOUT msecs_to_jiffies(100)
+#define IMX8QXP_ADC_MAX_FIFO_SIZE 16 + struct imx8qxp_adc { struct device *dev; void __iomem *regs; @@ -95,6 +97,7 @@ struct imx8qxp_adc { /* Serialise ADC channel reads */ struct mutex lock; struct completion completion; + u32 fifo[IMX8QXP_ADC_MAX_FIFO_SIZE]; };
#define IMX8QXP_ADC_CHAN(_idx) { \ @@ -238,8 +241,7 @@ static int imx8qxp_adc_read_raw(struct iio_dev *indio_dev, return ret; }
- *val = FIELD_GET(IMX8QXP_ADC_RESFIFO_VAL_MASK, - readl(adc->regs + IMX8QXP_ADR_ADC_RESFIFO)); + *val = adc->fifo[0];
mutex_unlock(&adc->lock); return IIO_VAL_INT; @@ -265,10 +267,15 @@ static irqreturn_t imx8qxp_adc_isr(int irq, void *dev_id) { struct imx8qxp_adc *adc = dev_id; u32 fifo_count; + int i;
fifo_count = FIELD_GET(IMX8QXP_ADC_FCTRL_FCOUNT_MASK, readl(adc->regs + IMX8QXP_ADR_ADC_FCTRL));
+ for (i = 0; i < fifo_count; i++) + adc->fifo[i] = FIELD_GET(IMX8QXP_ADC_RESFIFO_VAL_MASK, + readl_relaxed(adc->regs + IMX8QXP_ADR_ADC_RESFIFO)); + if (fifo_count) complete(&adc->completion);
From: Andreas Kemnade andreas@kemnade.info
commit f804bd0dc28683a93a60f271aaefb2fc5b0853dd upstream.
Some inputs need to be wired up to produce proper measurements, without this change only near zero values are reported.
Signed-off-by: Andreas Kemnade andreas@kemnade.info Fixes: 1696f36482e70 ("iio: twl6030-gpadc: TWL6030, TWL6032 GPADC driver") Link: https://lore.kernel.org/r/20221201181635.3522962-1-andreas@kemnade.info Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/adc/twl6030-gpadc.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
--- a/drivers/iio/adc/twl6030-gpadc.c +++ b/drivers/iio/adc/twl6030-gpadc.c @@ -57,6 +57,18 @@ #define TWL6030_GPADCS BIT(1) #define TWL6030_GPADCR BIT(0)
+#define USB_VBUS_CTRL_SET 0x04 +#define USB_ID_CTRL_SET 0x06 + +#define TWL6030_MISC1 0xE4 +#define VBUS_MEAS 0x01 +#define ID_MEAS 0x01 + +#define VAC_MEAS 0x04 +#define VBAT_MEAS 0x02 +#define BB_MEAS 0x01 + + /** * struct twl6030_chnl_calib - channel calibration * @gain: slope coefficient for ideal curve @@ -927,6 +939,26 @@ static int twl6030_gpadc_probe(struct pl return ret; }
+ ret = twl_i2c_write_u8(TWL_MODULE_USB, VBUS_MEAS, USB_VBUS_CTRL_SET); + if (ret < 0) { + dev_err(dev, "failed to wire up inputs\n"); + return ret; + } + + ret = twl_i2c_write_u8(TWL_MODULE_USB, ID_MEAS, USB_ID_CTRL_SET); + if (ret < 0) { + dev_err(dev, "failed to wire up inputs\n"); + return ret; + } + + ret = twl_i2c_write_u8(TWL6030_MODULE_ID0, + VBAT_MEAS | BB_MEAS | BB_MEAS, + TWL6030_MISC1); + if (ret < 0) { + dev_err(dev, "failed to wire up inputs\n"); + return ret; + } + indio_dev->name = DRIVER_NAME; indio_dev->info = &twl6030_gpadc_iio_info; indio_dev->modes = INDIO_DIRECT_MODE;
From: Kai-Heng Feng kai.heng.feng@canonical.com
commit ee3c5b644a0fdcfed27515a39fb2dd3a016704c1 upstream.
Commit c1e62062ff54 ("iio: light: cm32181: Handle CM3218 ACPI devices with 2 I2C resources") creates a second client for the actual I2C address, but the "struct device" passed to PM ops is the first I2C client that can't talk to the sensor.
That means the I2C transfers in both suspend and resume routines can fail and blocking the whole suspend process.
Instead of using the first client for I2C transfer, use the I2C client stored in the cm32181 private struct so the PM ops can get the correct I2C client to really talk to the sensor device.
Fixes: 68c1b3dd5c48 ("iio: light: cm32181: Add PM support") BugLink: https://bugs.launchpad.net/bugs/1988346 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2152281 Tested-by: Wahaj wahajaved@protonmail.com Signed-off-by: Kai-Heng Feng kai.heng.feng@canonical.com Reviewed-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20230118170422.339619-1-kai.heng.feng@canonical.co... Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/light/cm32181.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c index 001055d09750..b1674a5bfa36 100644 --- a/drivers/iio/light/cm32181.c +++ b/drivers/iio/light/cm32181.c @@ -440,6 +440,8 @@ static int cm32181_probe(struct i2c_client *client) if (!indio_dev) return -ENOMEM;
+ i2c_set_clientdata(client, indio_dev); + /* * Some ACPI systems list 2 I2C resources for the CM3218 sensor, the * SMBus Alert Response Address (ARA, 0x0c) and the actual I2C address. @@ -460,8 +462,6 @@ static int cm32181_probe(struct i2c_client *client) return PTR_ERR(client); }
- i2c_set_clientdata(client, indio_dev); - cm32181 = iio_priv(indio_dev); cm32181->client = client; cm32181->dev = dev; @@ -490,7 +490,8 @@ static int cm32181_probe(struct i2c_client *client)
static int cm32181_suspend(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); + struct cm32181_chip *cm32181 = iio_priv(dev_get_drvdata(dev)); + struct i2c_client *client = cm32181->client;
return i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD, CM32181_CMD_ALS_DISABLE); @@ -498,8 +499,8 @@ static int cm32181_suspend(struct device *dev)
static int cm32181_resume(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); struct cm32181_chip *cm32181 = iio_priv(dev_get_drvdata(dev)); + struct i2c_client *client = cm32181->client;
return i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD, cm32181->conf_regs[CM32181_REG_ADDR_CMD]);
From: Carlos Song carlos.song@nxp.com
commit 9d61c1820598a5ea474576ed55318a6dadee37ed upstream.
When device is in active mode, it fails to set an ACCEL full-scale range(2g/4g/8g) in FXOS8700_XYZ_DATA_CFG. This is not align with the datasheet, but it is a fxos8700 chip behavior.
Keep the device in standby mode before setting ACCEL full-scale range into FXOS8700_XYZ_DATA_CFG in chip initialization phase and setting scale phase.
Fixes: 84e5ddd5c46e ("iio: imu: Add support for the FXOS8700 IMU") Signed-off-by: Carlos Song carlos.song@nxp.com Link: https://lore.kernel.org/r/20221208071911.2405922-6-carlos.song@nxp.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/imu/fxos8700_core.c | 41 +++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-)
--- a/drivers/iio/imu/fxos8700_core.c +++ b/drivers/iio/imu/fxos8700_core.c @@ -345,7 +345,8 @@ static int fxos8700_set_active_mode(stru static int fxos8700_set_scale(struct fxos8700_data *data, enum fxos8700_sensor t, int uscale) { - int i; + int i, ret, val; + bool active_mode; static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale); struct device *dev = regmap_get_device(data->regmap);
@@ -354,6 +355,25 @@ static int fxos8700_set_scale(struct fxo return -EINVAL; }
+ /* + * When device is in active mode, it failed to set an ACCEL + * full-scale range(2g/4g/8g) in FXOS8700_XYZ_DATA_CFG. + * This is not align with the datasheet, but it is a fxos8700 + * chip behavier. Set the device in standby mode before setting + * an ACCEL full-scale range. + */ + ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val); + if (ret) + return ret; + + active_mode = val & FXOS8700_ACTIVE; + if (active_mode) { + ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, + val & ~FXOS8700_ACTIVE); + if (ret) + return ret; + } + for (i = 0; i < scale_num; i++) if (fxos8700_accel_scale[i].uscale == uscale) break; @@ -361,8 +381,12 @@ static int fxos8700_set_scale(struct fxo if (i == scale_num) return -EINVAL;
- return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, + ret = regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, fxos8700_accel_scale[i].bits); + if (ret) + return ret; + return regmap_write(data->regmap, FXOS8700_CTRL_REG1, + active_mode); }
static int fxos8700_get_scale(struct fxos8700_data *data, @@ -592,14 +616,17 @@ static int fxos8700_chip_init(struct fxo if (ret) return ret;
- /* Max ODR (800Hz individual or 400Hz hybrid), active mode */ - ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1, - FXOS8700_CTRL_ODR_MAX | FXOS8700_ACTIVE); + /* + * Set max full-scale range (+/-8G) for ACCEL sensor in chip + * initialization then activate the device. + */ + ret = regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G); if (ret) return ret;
- /* Set for max full-scale range (+/-8G) */ - return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G); + /* Max ODR (800Hz individual or 400Hz hybrid), active mode */ + return regmap_write(data->regmap, FXOS8700_CTRL_REG1, + FXOS8700_CTRL_ODR_MAX | FXOS8700_ACTIVE); }
static void fxos8700_chip_uninit(void *data)
From: Carlos Song carlos.song@nxp.com
commit 37a94d86d7050665d6d01378b2c916c28e454f10 upstream.
The length of ACCEL and MAGN 3-axis channels output data is 6 byte individually. However block only read 3 bytes data into buffer from ACCEL or MAGN output data registers every time. It causes an incomplete ACCEL and MAGN channels readback.
Set correct value count for regmap_bulk_read to get 6 bytes ACCEL and MAGN channels readback.
Fixes: 84e5ddd5c46e ("iio: imu: Add support for the FXOS8700 IMU") Signed-off-by: Carlos Song carlos.song@nxp.com Link: https://lore.kernel.org/r/20221208071911.2405922-4-carlos.song@nxp.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/imu/fxos8700_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/imu/fxos8700_core.c +++ b/drivers/iio/imu/fxos8700_core.c @@ -425,7 +425,7 @@ static int fxos8700_get_data(struct fxos
/* Block read 6 bytes of device output registers to avoid data loss */ ret = regmap_bulk_read(data->regmap, base, data->buf, - FXOS8700_DATA_BUF_SIZE); + sizeof(data->buf)); if (ret) return ret;
From: Carlos Song carlos.song@nxp.com
commit a53f945879c0cb9de3a4c05a665f5157884b5208 upstream.
ACCEL output data registers contain the X-axis, Y-axis, and Z-axis 14-bit left-justified sample data and MAGN output data registers contain the X-axis, Y-axis, and Z-axis 16-bit sample data. The ACCEL raw register output data should be divided by 4 before sent to userspace.
Apply a 2 bits signed right shift to the raw data from ACCEL output data register but keep that from MAGN sensor as the origin.
Fixes: 84e5ddd5c46e ("iio: imu: Add support for the FXOS8700 IMU") Signed-off-by: Carlos Song carlos.song@nxp.com Link: https://lore.kernel.org/r/20221208071911.2405922-5-carlos.song@nxp.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/imu/fxos8700_core.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
--- a/drivers/iio/imu/fxos8700_core.c +++ b/drivers/iio/imu/fxos8700_core.c @@ -418,6 +418,7 @@ static int fxos8700_get_data(struct fxos int axis, int *val) { u8 base, reg; + s16 tmp; int ret; enum fxos8700_sensor type = fxos8700_to_sensor(chan_type);
@@ -432,8 +433,33 @@ static int fxos8700_get_data(struct fxos /* Convert axis to buffer index */ reg = axis - IIO_MOD_X;
+ /* + * Convert to native endianness. The accel data and magn data + * are signed, so a forced type conversion is needed. + */ + tmp = be16_to_cpu(data->buf[reg]); + + /* + * ACCEL output data registers contain the X-axis, Y-axis, and Z-axis + * 14-bit left-justified sample data and MAGN output data registers + * contain the X-axis, Y-axis, and Z-axis 16-bit sample data. Apply + * a signed 2 bits right shift to the readback raw data from ACCEL + * output data register and keep that from MAGN sensor as the origin. + * Value should be extended to 32 bit. + */ + switch (chan_type) { + case IIO_ACCEL: + tmp = tmp >> 2; + break; + case IIO_MAGN: + /* Nothing to do */ + break; + default: + return -EINVAL; + } + /* Convert to native endianness */ - *val = sign_extend32(be16_to_cpu(data->buf[reg]), 15); + *val = sign_extend32(tmp, 15);
return 0; }
From: Carlos Song carlos.song@nxp.com
commit 429e1e8ec696e0e7a0742904e3dc2f83b7b23dfb upstream.
FXOS8700 is an IMU sensor with ACCEL sensor and MAGN sensor. Sensor type is indexed by corresponding channel type in a switch. IIO_ANGL_VEL channel type mapped to MAGN sensor has caused confusion.
Fix the mapping label of "IIO_MAGN" channel type instead of "IIO_ANGL_VEL" channel type to MAGN sensor.
Fixes: 84e5ddd5c46e ("iio: imu: Add support for the FXOS8700 IMU") Signed-off-by: Carlos Song carlos.song@nxp.com Link: https://lore.kernel.org/r/20221208071911.2405922-2-carlos.song@nxp.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/imu/fxos8700_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/imu/fxos8700_core.c +++ b/drivers/iio/imu/fxos8700_core.c @@ -320,7 +320,7 @@ static enum fxos8700_sensor fxos8700_to_ switch (iio_type) { case IIO_ACCEL: return FXOS8700_ACCEL; - case IIO_ANGL_VEL: + case IIO_MAGN: return FXOS8700_MAGN; default: return -EINVAL;
From: Carlos Song carlos.song@nxp.com
commit c68b44bc7d9b1469774a1c985ee71d2cbc5ebef5 upstream.
Because ACCEL and MAGN channels data register base address is swapped the accelerometer and magnetometer channels readback is swapped.
Fixes: 84e5ddd5c46e ("iio: imu: Add support for the FXOS8700 IMU") Signed-off-by: Carlos Song carlos.song@nxp.com Link: https://lore.kernel.org/r/20221208071911.2405922-3-carlos.song@nxp.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/imu/fxos8700_core.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
--- a/drivers/iio/imu/fxos8700_core.c +++ b/drivers/iio/imu/fxos8700_core.c @@ -420,9 +420,22 @@ static int fxos8700_get_data(struct fxos u8 base, reg; s16 tmp; int ret; - enum fxos8700_sensor type = fxos8700_to_sensor(chan_type);
- base = type ? FXOS8700_OUT_X_MSB : FXOS8700_M_OUT_X_MSB; + /* + * Different register base addresses varies with channel types. + * This bug hasn't been noticed before because using an enum is + * really hard to read. Use an a switch statement to take over that. + */ + switch (chan_type) { + case IIO_ACCEL: + base = FXOS8700_OUT_X_MSB; + break; + case IIO_MAGN: + base = FXOS8700_M_OUT_X_MSB; + break; + default: + return -EINVAL; + }
/* Block read 6 bytes of device output registers to avoid data loss */ ret = regmap_bulk_read(data->regmap, base, data->buf,
From: Carlos Song carlos.song@nxp.com
commit 78ad6864e9e012cdba7c353d044d21ffcfd5f34b upstream.
The absence of a correct offset leads an incorrect ODR mode readback after use a hexadecimal number to mark the value from FXOS8700_CTRL_REG1.
Get ODR mode by field mask and FIELD_GET clearly and conveniently. And attach other additional fix for keeping the original code logic and a good readability.
Fixes: 84e5ddd5c46e ("iio: imu: Add support for the FXOS8700 IMU") Signed-off-by: Carlos Song carlos.song@nxp.com Link: https://lore.kernel.org/r/20230118074227.1665098-2-carlos.song@nxp.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/imu/fxos8700_core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/iio/imu/fxos8700_core.c +++ b/drivers/iio/imu/fxos8700_core.c @@ -10,6 +10,7 @@ #include <linux/regmap.h> #include <linux/acpi.h> #include <linux/bitops.h> +#include <linux/bitfield.h>
#include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -144,9 +145,9 @@ #define FXOS8700_NVM_DATA_BNK0 0xa7
/* Bit definitions for FXOS8700_CTRL_REG1 */ -#define FXOS8700_CTRL_ODR_MSK 0x38 #define FXOS8700_CTRL_ODR_MAX 0x00 #define FXOS8700_CTRL_ODR_MIN GENMASK(4, 3) +#define FXOS8700_CTRL_ODR_MSK GENMASK(5, 3)
/* Bit definitions for FXOS8700_M_CTRL_REG1 */ #define FXOS8700_HMS_MASK GENMASK(1, 0) @@ -508,10 +509,9 @@ static int fxos8700_set_odr(struct fxos8 if (i >= odr_num) return -EINVAL;
- return regmap_update_bits(data->regmap, - FXOS8700_CTRL_REG1, - FXOS8700_CTRL_ODR_MSK + FXOS8700_ACTIVE, - fxos8700_odr[i].bits << 3 | active_mode); + val &= ~FXOS8700_CTRL_ODR_MSK; + val |= FIELD_PREP(FXOS8700_CTRL_ODR_MSK, fxos8700_odr[i].bits) | FXOS8700_ACTIVE; + return regmap_write(data->regmap, FXOS8700_CTRL_REG1, val); }
static int fxos8700_get_odr(struct fxos8700_data *data, enum fxos8700_sensor t, @@ -524,7 +524,7 @@ static int fxos8700_get_odr(struct fxos8 if (ret) return ret;
- val &= FXOS8700_CTRL_ODR_MSK; + val = FIELD_GET(FXOS8700_CTRL_ODR_MSK, val);
for (i = 0; i < odr_num; i++) if (val == fxos8700_odr[i].bits)
From: Carlos Song carlos.song@nxp.com
commit eb6d8f8705bc19141bac81d8161461f9e256948a upstream.
The absence of correct offset leads a failed initialization ODR mode assignment.
Select MAX ODR mode as the initialization ODR mode by field mask and FIELD_PREP.
Fixes: 84e5ddd5c46e ("iio: imu: Add support for the FXOS8700 IMU") Signed-off-by: Carlos Song carlos.song@nxp.com Link: https://lore.kernel.org/r/20230118074227.1665098-3-carlos.song@nxp.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/imu/fxos8700_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/iio/imu/fxos8700_core.c +++ b/drivers/iio/imu/fxos8700_core.c @@ -664,8 +664,10 @@ static int fxos8700_chip_init(struct fxo return ret;
/* Max ODR (800Hz individual or 400Hz hybrid), active mode */ - return regmap_write(data->regmap, FXOS8700_CTRL_REG1, - FXOS8700_CTRL_ODR_MAX | FXOS8700_ACTIVE); + return regmap_update_bits(data->regmap, FXOS8700_CTRL_REG1, + FXOS8700_CTRL_ODR_MSK | FXOS8700_ACTIVE, + FIELD_PREP(FXOS8700_CTRL_ODR_MSK, FXOS8700_CTRL_ODR_MAX) | + FXOS8700_ACTIVE); }
static void fxos8700_chip_uninit(void *data)
From: Carlos Song carlos.song@nxp.com
commit ff5e2cd92ffda9a25ffa2cbdb3a0cf17650172a6 upstream.
FXOS8700_CTRL_ODR_MIN is not used but value is probably wrong.
Remove it for a good readability.
Fixes: 84e5ddd5c46e ("iio: imu: Add support for the FXOS8700 IMU") Signed-off-by: Carlos Song carlos.song@nxp.com Link: https://lore.kernel.org/r/20230118074227.1665098-4-carlos.song@nxp.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/imu/fxos8700_core.c | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/iio/imu/fxos8700_core.c +++ b/drivers/iio/imu/fxos8700_core.c @@ -146,7 +146,6 @@
/* Bit definitions for FXOS8700_CTRL_REG1 */ #define FXOS8700_CTRL_ODR_MAX 0x00 -#define FXOS8700_CTRL_ODR_MIN GENMASK(4, 3) #define FXOS8700_CTRL_ODR_MSK GENMASK(5, 3)
/* Bit definitions for FXOS8700_M_CTRL_REG1 */
From: Carlos Song carlos.song@nxp.com
commit 2acd031347f645871959a799238a7caf6803aa18 upstream.
+/-1200uT is a MAGN sensor full measurement range. Magnetometer scale is the magnetic sensitivity parameter. It is referenced as 0.1uT according to datasheet and magnetometer channel unit is Gauss in sysfs-bus-iio documentation. Gauss and uTesla unit conversion relationship as follows: 0.1uT = 0.001Gs.
Set magnetometer scale and available magnetometer scale as fixed 0.001Gs.
Fixes: 84e5ddd5c46e ("iio: imu: Add support for the FXOS8700 IMU") Signed-off-by: Carlos Song carlos.song@nxp.com Link: https://lore.kernel.org/r/20230118074227.1665098-5-carlos.song@nxp.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/imu/fxos8700_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/iio/imu/fxos8700_core.c +++ b/drivers/iio/imu/fxos8700_core.c @@ -351,7 +351,7 @@ static int fxos8700_set_scale(struct fxo struct device *dev = regmap_get_device(data->regmap);
if (t == FXOS8700_MAGN) { - dev_err(dev, "Magnetometer scale is locked at 1200uT\n"); + dev_err(dev, "Magnetometer scale is locked at 0.001Gs\n"); return -EINVAL; }
@@ -396,7 +396,7 @@ static int fxos8700_get_scale(struct fxo static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
if (t == FXOS8700_MAGN) { - *uscale = 1200; /* Magnetometer is locked at 1200uT */ + *uscale = 1000; /* Magnetometer is locked at 0.001Gs */ return 0; }
@@ -588,7 +588,7 @@ static IIO_CONST_ATTR(in_accel_sampling_ static IIO_CONST_ATTR(in_magn_sampling_frequency_available, "1.5625 6.25 12.5 50 100 200 400 800"); static IIO_CONST_ATTR(in_accel_scale_available, "0.000244 0.000488 0.000976"); -static IIO_CONST_ATTR(in_magn_scale_available, "0.000001200"); +static IIO_CONST_ATTR(in_magn_scale_available, "0.001000");
static struct attribute *fxos8700_attrs[] = { &iio_const_attr_in_accel_sampling_frequency_available.dev_attr.attr,
From: Jiasheng Jiang jiasheng@iscas.ac.cn
commit b0576ade3aaf24b376ea1a4406ae138e2a22b0c0 upstream.
Add the check for the return value of kzalloc in order to avoid NULL pointer dereference.
Fixes: 6e977eaa8280 ("nvmem: brcm_nvram: parse NVRAM content into NVMEM cells") Cc: stable@vger.kernel.org Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20230127104015.23839-2-srinivas.kandagatla@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvmem/brcm_nvram.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/nvmem/brcm_nvram.c +++ b/drivers/nvmem/brcm_nvram.c @@ -97,6 +97,9 @@ static int brcm_nvram_parse(struct brcm_ len = le32_to_cpu(header.len);
data = kzalloc(len, GFP_KERNEL); + if (!data) + return -ENOMEM; + memcpy_fromio(data, priv->base, len); data[len - 1] = '\0';
From: Samuel Holland samuel@sholland.org
commit c151d5ed8e8fe0474bd61dce7f2076ca5916c683 upstream.
The SID SRAM on at least some SoCs (A64 and D1) returns different values when read with bus cycles narrower than 32 bits. This is not immediately obvious, because memcpy_fromio() uses word-size accesses as long as enough data is being copied.
The vendor driver always uses 32-bit MMIO reads, so do the same here. This is faster than the register-based method, which is currently used as a workaround on A64. And it fixes the values returned on D1, where the SRAM method was being used.
The special case for the last word is needed to maintain .word_size == 1 for sysfs ABI compatibility, as noted previously in commit de2a3eaea552 ("nvmem: sunxi_sid: Optimize register read-out method").
Fixes: 07ae4fde9efa ("nvmem: sunxi_sid: Add support for D1 variant") Cc: stable@vger.kernel.org Tested-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Samuel Holland samuel@sholland.org Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20230127104015.23839-3-srinivas.kandagatla@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvmem/sunxi_sid.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c index 5750e1f4bcdb..92dfe4cb10e3 100644 --- a/drivers/nvmem/sunxi_sid.c +++ b/drivers/nvmem/sunxi_sid.c @@ -41,8 +41,21 @@ static int sunxi_sid_read(void *context, unsigned int offset, void *val, size_t bytes) { struct sunxi_sid *sid = context; + u32 word; + + /* .stride = 4 so offset is guaranteed to be aligned */ + __ioread32_copy(val, sid->base + sid->value_offset + offset, bytes / 4);
- memcpy_fromio(val, sid->base + sid->value_offset + offset, bytes); + val += round_down(bytes, 4); + offset += round_down(bytes, 4); + bytes = bytes % 4; + + if (!bytes) + return 0; + + /* Handle any trailing bytes */ + word = readl_relaxed(sid->base + sid->value_offset + offset); + memcpy(val, &word, bytes);
return 0; }
From: Johan Hovold johan+linaro@kernel.org
commit 1ca7fca349316231bbaa68d16f819a08d683c5a7 upstream.
Add the missing module device table so that the driver can be autoloaded when built as a module.
Fixes: 40ce9798794f ("nvmem: add QTI SDAM driver") Cc: stable@vger.kernel.org # 5.6 Reviewed-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Johan Hovold johan+linaro@kernel.org Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20230127104015.23839-11-srinivas.kandagatla@linaro... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvmem/qcom-spmi-sdam.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/nvmem/qcom-spmi-sdam.c b/drivers/nvmem/qcom-spmi-sdam.c index 4fcb63507ecd..8499892044b7 100644 --- a/drivers/nvmem/qcom-spmi-sdam.c +++ b/drivers/nvmem/qcom-spmi-sdam.c @@ -166,6 +166,7 @@ static const struct of_device_id sdam_match_table[] = { { .compatible = "qcom,spmi-sdam" }, {}, }; +MODULE_DEVICE_TABLE(of, sdam_match_table);
static struct platform_driver sdam_driver = { .driver = {
From: Helge Deller deller@gmx.de
commit 5d1335dabb3c493a3d6d5b233953b6ac7b6c1ff2 upstream.
There is an off-by-one if the printed string includes a new-line char.
Cc: stable@vger.kernel.org Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/kernel/firmware.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -1303,7 +1303,7 @@ static char iodc_dbuf[4096] __page_align */ int pdc_iodc_print(const unsigned char *str, unsigned count) { - unsigned int i; + unsigned int i, found = 0; unsigned long flags;
count = min_t(unsigned int, count, sizeof(iodc_dbuf)); @@ -1315,6 +1315,7 @@ int pdc_iodc_print(const unsigned char * iodc_dbuf[i+0] = '\r'; iodc_dbuf[i+1] = '\n'; i += 2; + found = 1; goto print; default: iodc_dbuf[i] = str[i]; @@ -1330,7 +1331,7 @@ print: __pa(pdc_result), 0, __pa(iodc_dbuf), i, 0); spin_unlock_irqrestore(&pdc_lock, flags);
- return i; + return i - found; }
#if !defined(BOOTLOADER)
From: Helge Deller deller@gmx.de
commit 3f0c17809a098d3f0c1ec83f1fb3ca61638d3dcd upstream.
Prefer usage of the PRIV_USER constant over the hard-coded value to set the lowest 2 bits for the userspace privilege.
Signed-off-by: Helge Deller deller@gmx.de Cc: stable@vger.kernel.org # 5.16+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/kernel/ptrace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -166,7 +166,7 @@ long arch_ptrace(struct task_struct *chi addr >= sizeof(struct pt_regs)) break; if (addr == PT_IAOQ0 || addr == PT_IAOQ1) { - data |= 3; /* ensure userspace privilege */ + data |= PRIV_USER; /* ensure userspace privilege */ } if ((addr >= PT_GR1 && addr <= PT_GR31) || addr == PT_IAOQ0 || addr == PT_IAOQ1 || @@ -285,7 +285,7 @@ long compat_arch_ptrace(struct task_stru if (addr >= sizeof(struct pt_regs)) break; if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) { - data |= 3; /* ensure userspace privilege */ + data |= PRIV_USER; /* ensure userspace privilege */ } if (addr >= PT_FR0 && addr <= PT_FR31 + 4) { /* Special case, fp regs are 64 bits anyway */ @@ -483,7 +483,7 @@ static void set_reg(struct pt_regs *regs case RI(iaoq[0]): case RI(iaoq[1]): /* set 2 lowest bits to ensure userspace privilege: */ - regs->iaoq[num - RI(iaoq[0])] = val | 3; + regs->iaoq[num - RI(iaoq[0])] = val | PRIV_USER; return; case RI(sar): regs->sar = val; return;
From: Helge Deller deller@gmx.de
commit 316f1f42b5cc1d95124c1f0387c867c1ba7b6d0e upstream.
Wire up the missing ptrace requests PTRACE_GETREGS, PTRACE_SETREGS, PTRACE_GETFPREGS and PTRACE_SETFPREGS when running 32-bit applications on 64-bit kernels.
Signed-off-by: Helge Deller deller@gmx.de Cc: stable@vger.kernel.org # 4.7+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/kernel/ptrace.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
--- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -126,6 +126,12 @@ long arch_ptrace(struct task_struct *chi unsigned long tmp; long ret = -EIO;
+ unsigned long user_regs_struct_size = sizeof(struct user_regs_struct); +#ifdef CONFIG_64BIT + if (is_compat_task()) + user_regs_struct_size /= 2; +#endif + switch (request) {
/* Read the word at location addr in the USER area. For ptraced @@ -181,14 +187,14 @@ long arch_ptrace(struct task_struct *chi return copy_regset_to_user(child, task_user_regset_view(current), REGSET_GENERAL, - 0, sizeof(struct user_regs_struct), + 0, user_regs_struct_size, datap);
case PTRACE_SETREGS: /* Set all gp regs in the child. */ return copy_regset_from_user(child, task_user_regset_view(current), REGSET_GENERAL, - 0, sizeof(struct user_regs_struct), + 0, user_regs_struct_size, datap);
case PTRACE_GETFPREGS: /* Get the child FPU state. */ @@ -302,6 +308,11 @@ long compat_arch_ptrace(struct task_stru } } break; + case PTRACE_GETREGS: + case PTRACE_SETREGS: + case PTRACE_GETFPREGS: + case PTRACE_SETFPREGS: + return arch_ptrace(child, request, addr, data);
default: ret = compat_ptrace_request(child, request, addr, data);
From: Andreas Schwab schwab@suse.de
commit 2f394c0e7d1129a35156e492bc8f445fb20f43ac upstream.
GCC 13 will enable -fasynchronous-unwind-tables by default on riscv. In the kernel, we don't have any use for unwind tables yet, so disable them. More importantly, the .eh_frame section brings relocations (R_RISC_32_PCREL, R_RISCV_SET{6,8,16}, R_RISCV_SUB{6,8,16}) into modules that we are not prepared to handle.
Signed-off-by: Andreas Schwab schwab@suse.de Link: https://lore.kernel.org/r/mvmzg9xybqu.fsf@suse.de Cc: stable@vger.kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/Makefile | 3 +++ 1 file changed, 3 insertions(+)
--- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -80,6 +80,9 @@ ifeq ($(CONFIG_PERF_EVENTS),y) KBUILD_CFLAGS += -fno-omit-frame-pointer endif
+# Avoid generating .eh_frame sections. +KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables + KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax) KBUILD_AFLAGS_MODULE += $(call as-option,-Wa$(comma)-mno-relax)
From: Isaac J. Manjarres isaacmanjarres@google.com
commit 8ef852f1cb426a5812aee700d3b4297aaa426acc upstream.
This reverts commit 972fa3a7c17c9d60212e32ecc0205dc585b1e769.
Kmemleak operates by periodically scanning memory regions for pointers to allocated memory blocks to determine if they are leaked or not. However, reserved memory regions can be used for DMA transactions between a device and a CPU, and thus, wouldn't contain pointers to allocated memory blocks, making them inappropriate for kmemleak to scan. Thus, revert this commit.
Link: https://lkml.kernel.org/r/20230124230254.295589-1-isaacmanjarres@google.com Fixes: 972fa3a7c17c9 ("mm: kmemleak: alloc gray object for reserved region with direct map") Signed-off-by: Isaac J. Manjarres isaacmanjarres@google.com Acked-by: Catalin Marinas catalin.marinas@arm.com Cc: Calvin Zhang calvinzhang.cool@gmail.com Cc: Frank Rowand frowand.list@gmail.com Cc: Rob Herring robh+dt@kernel.org Cc: Saravana Kannan saravanak@google.com Cc: stable@vger.kernel.org [5.17+] Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/of/fdt.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index f08b25195ae7..d1a68b6d03b3 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -26,7 +26,6 @@ #include <linux/serial_core.h> #include <linux/sysfs.h> #include <linux/random.h> -#include <linux/kmemleak.h>
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */ #include <asm/page.h> @@ -525,12 +524,9 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, size = dt_mem_next_cell(dt_root_size_cells, &prop);
if (size && - early_init_dt_reserve_memory(base, size, nomap) == 0) { + early_init_dt_reserve_memory(base, size, nomap) == 0) pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n", uname, &base, (unsigned long)(size / SZ_1M)); - if (!nomap) - kmemleak_alloc_phys(base, size, 0); - } else pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", uname, &base, (unsigned long)(size / SZ_1M));
From: Yu Zhao yuzhao@google.com
commit de08eaa6156405f2e9369f06ba5afae0e4ab3b62 upstream.
lru_gen_migrate_mm() assumes lru_gen_add_mm() runs prior to itself. This isn't true for the following scenario:
CPU 1 CPU 2
clone() cgroup_can_fork() cgroup_procs_write() cgroup_post_fork() task_lock() lru_gen_migrate_mm() task_unlock() task_lock() lru_gen_add_mm() task_unlock()
And when the above happens, kernel crashes because of linked list corruption (mm_struct->lru_gen.list).
Link: https://lore.kernel.org/r/20230115134651.30028-1-msizanoen@qtmlabs.xyz/ Link: https://lkml.kernel.org/r/20230116034405.2960276-1-yuzhao@google.com Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks") Signed-off-by: Yu Zhao yuzhao@google.com Reported-by: msizanoen msizanoen@qtmlabs.xyz Tested-by: msizanoen msizanoen@qtmlabs.xyz Cc: stable@vger.kernel.org [6.1+] Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/vmscan.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -3290,13 +3290,16 @@ void lru_gen_migrate_mm(struct mm_struct if (mem_cgroup_disabled()) return;
+ /* migration can happen before addition */ + if (!mm->lru_gen.memcg) + return; + rcu_read_lock(); memcg = mem_cgroup_from_task(task); rcu_read_unlock(); if (memcg == mm->lru_gen.memcg) return;
- VM_WARN_ON_ONCE(!mm->lru_gen.memcg); VM_WARN_ON_ONCE(list_empty(&mm->lru_gen.list));
lru_gen_del_mm(mm);
From: Mike Kravetz mike.kravetz@oracle.com
commit 3489dbb696d25602aea8c3e669a6d43b76bd5358 upstream.
Patch series "Fixes for hugetlb mapcount at most 1 for shared PMDs".
This issue of mapcount in hugetlb pages referenced by shared PMDs was discussed in [1]. The following two patches address user visible behavior caused by this issue.
[1] https://lore.kernel.org/linux-mm/Y9BF+OCdWnCSilEu@monkey/
This patch (of 2):
A hugetlb page will have a mapcount of 1 if mapped by multiple processes via a shared PMD. This is because only the first process increases the map count, and subsequent processes just add the shared PMD page to their page table.
page_mapcount is being used to decide if a hugetlb page is shared or private in /proc/PID/smaps. Pages referenced via a shared PMD were incorrectly being counted as private.
To fix, check for a shared PMD if mapcount is 1. If a shared PMD is found count the hugetlb page as shared. A new helper to check for a shared PMD is added.
[akpm@linux-foundation.org: simplification, per David] [akpm@linux-foundation.org: hugetlb.h: include page_ref.h for page_count()] Link: https://lkml.kernel.org/r/20230126222721.222195-2-mike.kravetz@oracle.com Fixes: 25ee01a2fca0 ("mm: hugetlb: proc: add hugetlb-related fields to /proc/PID/smaps") Signed-off-by: Mike Kravetz mike.kravetz@oracle.com Acked-by: Peter Xu peterx@redhat.com Cc: David Hildenbrand david@redhat.com Cc: James Houghton jthoughton@google.com Cc: Matthew Wilcox willy@infradead.org Cc: Michal Hocko mhocko@suse.com Cc: Muchun Song songmuchun@bytedance.com Cc: Naoya Horiguchi naoya.horiguchi@linux.dev Cc: Vishal Moola (Oracle) vishal.moola@gmail.com Cc: Yang Shi shy828301@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/proc/task_mmu.c | 4 +--- include/linux/hugetlb.h | 13 +++++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-)
--- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -737,9 +737,7 @@ static int smaps_hugetlb_range(pte_t *pt page = pfn_swap_entry_to_page(swpent); } if (page) { - int mapcount = page_mapcount(page); - - if (mapcount >= 2) + if (page_mapcount(page) >= 2 || hugetlb_pmd_shared(pte)) mss->shared_hugetlb += huge_page_size(hstate_vma(vma)); else mss->private_hugetlb += huge_page_size(hstate_vma(vma)); --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -7,6 +7,7 @@ #include <linux/fs.h> #include <linux/hugetlb_inline.h> #include <linux/cgroup.h> +#include <linux/page_ref.h> #include <linux/list.h> #include <linux/kref.h> #include <linux/pgtable.h> @@ -1182,6 +1183,18 @@ static inline __init void hugetlb_cma_re } #endif
+#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE +static inline bool hugetlb_pmd_shared(pte_t *pte) +{ + return page_count(virt_to_page(pte)) > 1; +} +#else +static inline bool hugetlb_pmd_shared(pte_t *pte) +{ + return false; +} +#endif + bool want_pmd_share(struct vm_area_struct *vma, unsigned long addr);
#ifndef __HAVE_ARCH_FLUSH_HUGETLB_TLB_RANGE
From: Kefeng Wang wangkefeng.wang@huawei.com
commit ac86f547ca1002aec2ef66b9e64d03f45bbbfbb9 upstream.
As commit 18365225f044 ("hwpoison, memcg: forcibly uncharge LRU pages"), hwpoison will forcibly uncharg a LRU hwpoisoned page, the folio_memcg could be NULl, then, mem_cgroup_track_foreign_dirty_slowpath() could occurs a NULL pointer dereference, let's do not record the foreign writebacks for folio memcg is null in mem_cgroup_track_foreign_dirty() to fix it.
Link: https://lkml.kernel.org/r/20230129040945.180629-1-wangkefeng.wang@huawei.com Fixes: 97b27821b485 ("writeback, memcg: Implement foreign dirty flushing") Signed-off-by: Kefeng Wang wangkefeng.wang@huawei.com Reported-by: Ma Wupeng mawupeng1@huawei.com Tested-by: Miko Larsson mikoxyzzz@gmail.com Acked-by: Michal Hocko mhocko@suse.com Cc: Jan Kara jack@suse.cz Cc: Jens Axboe axboe@kernel.dk Cc: Kefeng Wang wangkefeng.wang@huawei.com Cc: Ma Wupeng mawupeng1@huawei.com Cc: Naoya Horiguchi naoya.horiguchi@nec.com Cc: Shakeel Butt shakeelb@google.com Cc: Tejun Heo tj@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 --- include/linux/memcontrol.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -1655,10 +1655,13 @@ void mem_cgroup_track_foreign_dirty_slow static inline void mem_cgroup_track_foreign_dirty(struct folio *folio, struct bdi_writeback *wb) { + struct mem_cgroup *memcg; + if (mem_cgroup_disabled()) return;
- if (unlikely(&folio_memcg(folio)->css != wb->memcg_css)) + memcg = folio_memcg(folio); + if (unlikely(memcg && &memcg->css != wb->memcg_css)) mem_cgroup_track_foreign_dirty_slowpath(folio, wb); }
From: Pratham Pratap quic_ppratap@quicinc.com
commit 2fa89458af9993fab8054daf827f38881e2ad473 upstream.
Currently connect/disconnect of USB cable calls afunc_bind and eventually increments the bNumEndpoints. Performing multiple plugin/plugout will increment bNumEndpoints incorrectly, and on the next plug-in it leads to invalid configuration of descriptor and hence enumeration fails.
Fix this by resetting the value of bNumEndpoints to 1 on every afunc_bind call.
Fixes: 40c73b30546e ("usb: gadget: f_uac2: add adaptive sync support for capture") Cc: stable stable@kernel.org Signed-off-by: Pratham Pratap quic_ppratap@quicinc.com Signed-off-by: Prashanth K quic_prashk@quicinc.com Link: https://lore.kernel.org/r/1674631645-28888-1-git-send-email-quic_prashk@quic... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/gadget/function/f_uac2.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -1142,6 +1142,7 @@ afunc_bind(struct usb_configuration *cfg } std_as_out_if0_desc.bInterfaceNumber = ret; std_as_out_if1_desc.bInterfaceNumber = ret; + std_as_out_if1_desc.bNumEndpoints = 1; uac2->as_out_intf = ret; uac2->as_out_alt = 0;
From: Heikki Krogerus heikki.krogerus@linux.intel.com
commit f82060da749c611ed427523b6d1605d87338aac1 upstream.
This will fix null pointer dereference that was caused by the driver attempting to resume ports that were not yet registered.
Fixes: e0dced9c7d47 ("usb: typec: ucsi: Resume in separate work") Cc: stable@vger.kernel.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=216697 Signed-off-by: Heikki Krogerus heikki.krogerus@linux.intel.com Link: https://lore.kernel.org/r/20230131141518.78215-1-heikki.krogerus@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/typec/ucsi/ucsi.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -1269,6 +1269,9 @@ err_unregister: con->port = NULL; }
+ kfree(ucsi->connector); + ucsi->connector = NULL; + err_reset: memset(&ucsi->cap, 0, sizeof(ucsi->cap)); ucsi_reset_ppm(ucsi); @@ -1300,7 +1303,8 @@ static void ucsi_resume_work(struct work
int ucsi_resume(struct ucsi *ucsi) { - queue_work(system_long_wq, &ucsi->resume_work); + if (ucsi->connector) + queue_work(system_long_wq, &ucsi->resume_work); return 0; } EXPORT_SYMBOL_GPL(ucsi_resume); @@ -1420,6 +1424,9 @@ void ucsi_unregister(struct ucsi *ucsi) /* Disable notifications */ ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
+ if (!ucsi->connector) + return; + for (i = 0; i < ucsi->cap.num_connectors; i++) { cancel_work_sync(&ucsi->connector[i].work); ucsi_unregister_partner(&ucsi->connector[i]);
From: Aaro Koskinen aaro.koskinen@iki.fi
commit 30d09b3131f5b1b9d54ad9b7ee171a45e21362b3 upstream.
Before the commit fc274c1e9973 ("USB: gadget: Add a new bus for gadgets") gadget driver.bus was unused. For whatever reason, many UDC drivers set this field explicitly to NULL in udc_start(). With the newly added gadget bus, doing this will crash the driver during the attach.
The problem was first reported, fixed and tested with OMAP UDC and g_ether. Other drivers are changed based on code analysis only.
Fixes: fc274c1e9973 ("USB: gadget: Add a new bus for gadgets") Cc: stable stable@kernel.org Signed-off-by: Aaro Koskinen aaro.koskinen@iki.fi Acked-by: Alan Stern stern@rowland.harvard.edu Link: https://lore.kernel.org/r/20230201220125.GD2415@darkstar.musicnaut.iki.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/gadget/udc/bcm63xx_udc.c | 1 - drivers/usb/gadget/udc/fotg210-udc.c | 1 - drivers/usb/gadget/udc/fsl_qe_udc.c | 1 - drivers/usb/gadget/udc/fsl_udc_core.c | 1 - drivers/usb/gadget/udc/fusb300_udc.c | 1 - drivers/usb/gadget/udc/goku_udc.c | 1 - drivers/usb/gadget/udc/gr_udc.c | 1 - drivers/usb/gadget/udc/m66592-udc.c | 1 - drivers/usb/gadget/udc/max3420_udc.c | 1 - drivers/usb/gadget/udc/mv_u3d_core.c | 1 - drivers/usb/gadget/udc/mv_udc_core.c | 1 - drivers/usb/gadget/udc/net2272.c | 1 - drivers/usb/gadget/udc/net2280.c | 1 - drivers/usb/gadget/udc/omap_udc.c | 1 - drivers/usb/gadget/udc/pch_udc.c | 1 - drivers/usb/gadget/udc/snps_udc_core.c | 1 - 16 files changed, 16 deletions(-)
--- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -1830,7 +1830,6 @@ static int bcm63xx_udc_start(struct usb_ bcm63xx_select_phy_mode(udc, true);
udc->driver = driver; - driver->driver.bus = NULL; udc->gadget.dev.of_node = udc->dev->of_node;
spin_unlock_irqrestore(&udc->lock, flags); --- a/drivers/usb/gadget/udc/fotg210-udc.c +++ b/drivers/usb/gadget/udc/fotg210-udc.c @@ -1009,7 +1009,6 @@ static int fotg210_udc_start(struct usb_ u32 value;
/* hook up the driver */ - driver->driver.bus = NULL; fotg210->driver = driver;
/* enable device global interrupt */ --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -2285,7 +2285,6 @@ static int fsl_qe_start(struct usb_gadge /* lock is needed but whether should use this lock or another */ spin_lock_irqsave(&udc->lock, flags);
- driver->driver.bus = NULL; /* hook up the driver */ udc->driver = driver; udc->gadget.speed = driver->max_speed; --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -1943,7 +1943,6 @@ static int fsl_udc_start(struct usb_gadg /* lock is needed but whether should use this lock or another */ spin_lock_irqsave(&udc_controller->lock, flags);
- driver->driver.bus = NULL; /* hook up the driver */ udc_controller->driver = driver; spin_unlock_irqrestore(&udc_controller->lock, flags); --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c @@ -1311,7 +1311,6 @@ static int fusb300_udc_start(struct usb_ struct fusb300 *fusb300 = to_fusb300(g);
/* hook up the driver */ - driver->driver.bus = NULL; fusb300->driver = driver;
return 0; --- a/drivers/usb/gadget/udc/goku_udc.c +++ b/drivers/usb/gadget/udc/goku_udc.c @@ -1375,7 +1375,6 @@ static int goku_udc_start(struct usb_gad struct goku_udc *dev = to_goku_udc(g);
/* hook up the driver */ - driver->driver.bus = NULL; dev->driver = driver;
/* --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -1906,7 +1906,6 @@ static int gr_udc_start(struct usb_gadge spin_lock(&dev->lock);
/* Hook up the driver */ - driver->driver.bus = NULL; dev->driver = driver;
/* Get ready for host detection */ --- a/drivers/usb/gadget/udc/m66592-udc.c +++ b/drivers/usb/gadget/udc/m66592-udc.c @@ -1454,7 +1454,6 @@ static int m66592_udc_start(struct usb_g struct m66592 *m66592 = to_m66592(g);
/* hook up the driver */ - driver->driver.bus = NULL; m66592->driver = driver;
m66592_bset(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); --- a/drivers/usb/gadget/udc/max3420_udc.c +++ b/drivers/usb/gadget/udc/max3420_udc.c @@ -1108,7 +1108,6 @@ static int max3420_udc_start(struct usb_
spin_lock_irqsave(&udc->lock, flags); /* hook up the driver */ - driver->driver.bus = NULL; udc->driver = driver; udc->gadget.speed = USB_SPEED_FULL;
--- a/drivers/usb/gadget/udc/mv_u3d_core.c +++ b/drivers/usb/gadget/udc/mv_u3d_core.c @@ -1243,7 +1243,6 @@ static int mv_u3d_start(struct usb_gadge }
/* hook up the driver ... */ - driver->driver.bus = NULL; u3d->driver = driver;
u3d->ep0_dir = USB_DIR_OUT; --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c @@ -1359,7 +1359,6 @@ static int mv_udc_start(struct usb_gadge spin_lock_irqsave(&udc->lock, flags);
/* hook up the driver ... */ - driver->driver.bus = NULL; udc->driver = driver;
udc->usb_state = USB_STATE_ATTACHED; --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -1451,7 +1451,6 @@ static int net2272_start(struct usb_gadg dev->ep[i].irqs = 0; /* hook up the driver ... */ dev->softconnect = 1; - driver->driver.bus = NULL; dev->driver = driver;
/* ... then enable host detection and ep0; and we're ready --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -2423,7 +2423,6 @@ static int net2280_start(struct usb_gadg dev->ep[i].irqs = 0;
/* hook up the driver ... */ - driver->driver.bus = NULL; dev->driver = driver;
retval = device_create_file(&dev->pdev->dev, &dev_attr_function); --- a/drivers/usb/gadget/udc/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c @@ -2066,7 +2066,6 @@ static int omap_udc_start(struct usb_gad udc->softconnect = 1;
/* hook up the driver */ - driver->driver.bus = NULL; udc->driver = driver; spin_unlock_irqrestore(&udc->lock, flags);
--- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -2908,7 +2908,6 @@ static int pch_udc_start(struct usb_gadg { struct pch_udc_dev *dev = to_pch_udc(g);
- driver->driver.bus = NULL; dev->driver = driver;
/* get ready for ep0 traffic */ --- a/drivers/usb/gadget/udc/snps_udc_core.c +++ b/drivers/usb/gadget/udc/snps_udc_core.c @@ -1933,7 +1933,6 @@ static int amd5536_udc_start(struct usb_ struct udc *dev = to_amd5536_udc(g); u32 tmp;
- driver->driver.bus = NULL; dev->driver = driver;
/* Some gadget drivers use both ep0 directions.
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
commit d83d7ed260283560700d4034a80baad46620481b upstream.
When calling debugfs_lookup() the result must have dput() called on it, otherwise the memory will leak over time. To make things simpler, just call debugfs_lookup_and_remove() instead which handles all of the logic at once.
Cc: Thomas Gleixner tglx@linutronix.de Cc: stable stable@kernel.org Reviewed-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20230202151554.2310273-1-gregkh@linuxfoundation.or... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/irq/irqdomain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1915,7 +1915,7 @@ static void debugfs_add_domain_dir(struc
static void debugfs_remove_domain_dir(struct irq_domain *d) { - debugfs_remove(debugfs_lookup(d->name, domain_dir)); + debugfs_lookup_and_remove(d->name, domain_dir); }
void __init irq_domain_debugfs_init(struct dentry *root)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
commit 6dfb0771429a63db8561d44147f2bb76f93e1c86 upstream.
When calling debugfs_lookup() the result must have dput() called on it, otherwise the memory will leak over time. To make things simpler, just call debugfs_lookup_and_remove() instead which handles all of the logic at once.
Cc: "K. Y. Srinivasan" kys@microsoft.com Cc: Haiyang Zhang haiyangz@microsoft.com Cc: Wei Liu wei.liu@kernel.org Cc: Dexuan Cui decui@microsoft.com Fixes: d180e0a1be6c ("Drivers: hv: Create debugfs file with hyper-v balloon usage information") Cc: stable stable@kernel.org Reviewed-by: Michael Kelley mikelley@microsoft.com Link: https://lore.kernel.org/r/20230202140918.2289522-1-gregkh@linuxfoundation.or... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hv/hv_balloon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/hv/hv_balloon.c +++ b/drivers/hv/hv_balloon.c @@ -1911,7 +1911,7 @@ static void hv_balloon_debugfs_init(str
static void hv_balloon_debugfs_exit(struct hv_dynmem_device *b) { - debugfs_remove(debugfs_lookup("hv-balloon", NULL)); + debugfs_lookup_and_remove("hv-balloon", NULL); }
#else
From: Joerg Roedel jroedel@suse.de
commit 9d2c7203ffdb846399b82b0660563c89e918c751 upstream.
In kernels compiled with CONFIG_PARAVIRT=n, the compiler re-orders the DR7 read in exc_nmi() to happen before the call to sev_es_ist_enter().
This is problematic when running as an SEV-ES guest because in this environment the DR7 read might cause a #VC exception, and taking #VC exceptions is not safe in exc_nmi() before sev_es_ist_enter() has run.
The result is stack recursion if the NMI was caused on the #VC IST stack, because a subsequent #VC exception in the NMI handler will overwrite the stack frame of the interrupted #VC handler.
As there are no compiler barriers affecting the ordering of DR7 reads/writes, make the accesses to this register volatile, forbidding the compiler to re-order them.
[ bp: Massage text, make them volatile too, to make sure some aggressive compiler optimization pass doesn't discard them. ]
Fixes: 315562c9af3d ("x86/sev-es: Adjust #VC IST Stack on entering NMI handler") Reported-by: Alexey Kardashevskiy aik@amd.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230127035616.508966-1-aik@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/include/asm/debugreg.h | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)
--- a/arch/x86/include/asm/debugreg.h +++ b/arch/x86/include/asm/debugreg.h @@ -39,7 +39,20 @@ static __always_inline unsigned long nat asm("mov %%db6, %0" :"=r" (val)); break; case 7: - asm("mov %%db7, %0" :"=r" (val)); + /* + * Apply __FORCE_ORDER to DR7 reads to forbid re-ordering them + * with other code. + * + * This is needed because a DR7 access can cause a #VC exception + * when running under SEV-ES. Taking a #VC exception is not a + * safe thing to do just anywhere in the entry code and + * re-ordering might place the access into an unsafe location. + * + * This happened in the NMI handler, where the DR7 read was + * re-ordered to happen before the call to sev_es_ist_enter(), + * causing stack recursion. + */ + asm volatile("mov %%db7, %0" : "=r" (val) : __FORCE_ORDER); break; default: BUG(); @@ -66,7 +79,16 @@ static __always_inline void native_set_d asm("mov %0, %%db6" ::"r" (value)); break; case 7: - asm("mov %0, %%db7" ::"r" (value)); + /* + * Apply __FORCE_ORDER to DR7 writes to forbid re-ordering them + * with other code. + * + * While is didn't happen with a DR7 write (see the DR7 read + * comment above which explains where it happened), add the + * __FORCE_ORDER here too to avoid similar problems in the + * future. + */ + asm volatile("mov %0, %%db7" ::"r" (value), __FORCE_ORDER); break; default: BUG();
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
commit 60ce26d10e5850f33cc76fce52f5377045e75a15 upstream.
Handle probe error rollbacks properly to avoid leaks.
Fixes: 5cd339b370e2 ("fpga: m10bmc-sec: add max10 secure update functions") Reviewed-by: Matthew Gerlach matthew.gerlach@linux.intel.com Reviewed-by: Russ Weight russell.h.weight@intel.com Reviewed-by: Marco Pagani marpagan@redhat.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Cc: stable@vger.kernel.org Acked-by: Xu Yilun yilun.xu@intel.com Link: https://lore.kernel.org/r/20221214144952.8392-1-ilpo.jarvinen@linux.intel.co... Signed-off-by: Xu Yilun yilun.xu@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/fpga/intel-m10-bmc-sec-update.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/fpga/intel-m10-bmc-sec-update.c b/drivers/fpga/intel-m10-bmc-sec-update.c index 79d48852825e..03f1bd81c434 100644 --- a/drivers/fpga/intel-m10-bmc-sec-update.c +++ b/drivers/fpga/intel-m10-bmc-sec-update.c @@ -574,20 +574,27 @@ static int m10bmc_sec_probe(struct platform_device *pdev) len = scnprintf(buf, SEC_UPDATE_LEN_MAX, "secure-update%d", sec->fw_name_id); sec->fw_name = kmemdup_nul(buf, len, GFP_KERNEL); - if (!sec->fw_name) - return -ENOMEM; + if (!sec->fw_name) { + ret = -ENOMEM; + goto fw_name_fail; + }
fwl = firmware_upload_register(THIS_MODULE, sec->dev, sec->fw_name, &m10bmc_ops, sec); if (IS_ERR(fwl)) { dev_err(sec->dev, "Firmware Upload driver failed to start\n"); - kfree(sec->fw_name); - xa_erase(&fw_upload_xa, sec->fw_name_id); - return PTR_ERR(fwl); + ret = PTR_ERR(fwl); + goto fw_uploader_fail; }
sec->fwl = fwl; return 0; + +fw_uploader_fail: + kfree(sec->fw_name); +fw_name_fail: + xa_erase(&fw_upload_xa, sec->fw_name_id); + return ret; }
static int m10bmc_sec_remove(struct platform_device *pdev)
From: Zheng Yongjun zhengyongjun3@huawei.com
commit 65ea840afd508194b0ee903256162aa87e46ec30 upstream.
In case of error, the function stratix10_svc_allocate_memory() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR().
Fixes: e7eef1d7633a ("fpga: add intel stratix10 soc fpga manager driver") Signed-off-by: Zheng Yongjun zhengyongjun3@huawei.com Reviewed-by: Russ Weight russell.h.weight@intel.com Cc: stable@vger.kernel.org Acked-by: Xu Yilun yilun.xu@intel.com Link: https://lore.kernel.org/r/20221126071430.19540-1-zhengyongjun3@huawei.com Signed-off-by: Xu Yilun yilun.xu@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/fpga/stratix10-soc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/fpga/stratix10-soc.c +++ b/drivers/fpga/stratix10-soc.c @@ -213,9 +213,9 @@ static int s10_ops_write_init(struct fpg /* Allocate buffers from the service layer's pool. */ for (i = 0; i < NUM_SVC_BUFS; i++) { kbuf = stratix10_svc_allocate_memory(priv->chan, SVC_BUF_SIZE); - if (!kbuf) { + if (IS_ERR(kbuf)) { s10_free_buffers(mgr); - ret = -ENOMEM; + ret = PTR_ERR(kbuf); goto init_done; }
From: Peter Xu peterx@redhat.com
commit 49d6d7fb631345b0f2957a7c4be24ad63903150f upstream.
Patch series "mm: Fixes on pte markers".
Patch 1 resolves the syzkiller report from Pengfei.
Patch 2 further harden pte markers when used with the recent swapin error markers. The major case is we should persist a swapin error marker after fork(), so child shouldn't read a corrupted page.
This patch (of 2):
When fork(), dst_vma is not guaranteed to have VM_UFFD_WP even if src may have it and has pte marker installed. The warning is improper along with the comment. The right thing is to inherit the pte marker when needed, or keep the dst pte empty.
A vague guess is this happened by an accident when there's the prior patch to introduce src/dst vma into this helper during the uffd-wp feature got developed and I probably messed up in the rebase, since if we replace dst_vma with src_vma the warning & comment it all makes sense too.
Hugetlb did exactly the right here (copy_hugetlb_page_range()). Fix the general path.
Reproducer:
https://github.com/xupengfe/syzkaller_logs/blob/main/221208_115556_copy_page...
Bugzilla report: https://bugzilla.kernel.org/show_bug.cgi?id=216808
Link: https://lkml.kernel.org/r/20221214200453.1772655-1-peterx@redhat.com Link: https://lkml.kernel.org/r/20221214200453.1772655-2-peterx@redhat.com Fixes: c56d1b62cce8 ("mm/shmem: handle uffd-wp during fork()") Signed-off-by: Peter Xu peterx@redhat.com Reported-by: Pengfei Xu pengfei.xu@intel.com Acked-by: David Hildenbrand david@redhat.com Reviewed-by: Miaohe Lin linmiaohe@huawei.com Cc: Andrea Arcangeli aarcange@redhat.com Cc: "Huang, Ying" ying.huang@intel.com Cc: Nadav Amit nadav.amit@gmail.com Cc: stable@vger.kernel.org # 5.19+ Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/memory.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
--- a/mm/memory.c +++ b/mm/memory.c @@ -875,12 +875,8 @@ copy_nonpresent_pte(struct mm_struct *ds return -EBUSY; return -ENOENT; } else if (is_pte_marker_entry(entry)) { - /* - * We're copying the pgtable should only because dst_vma has - * uffd-wp enabled, do sanity check. - */ - WARN_ON_ONCE(!userfaultfd_wp(dst_vma)); - set_pte_at(dst_mm, addr, dst_pte, pte); + if (userfaultfd_wp(dst_vma)) + set_pte_at(dst_mm, addr, dst_pte, pte); return 0; } if (!userfaultfd_wp(dst_vma))
From: Longlong Xia xialonglong1@huawei.com
commit 7717fc1a12f88701573f9ed897cc4f6699c661e3 upstream.
The softlockup still occurs in get_swap_pages() under memory pressure. 64 CPU cores, 64GB memory, and 28 zram devices, the disksize of each zram device is 50MB with same priority as si. Use the stress-ng tool to increase memory pressure, causing the system to oom frequently.
The plist_for_each_entry_safe() loops in get_swap_pages() could reach tens of thousands of times to find available space (extreme case: cond_resched() is not called in scan_swap_map_slots()). Let's add cond_resched() into get_swap_pages() when failed to find available space to avoid softlockup.
Link: https://lkml.kernel.org/r/20230128094757.1060525-1-xialonglong1@huawei.com Signed-off-by: Longlong Xia xialonglong1@huawei.com Reviewed-by: "Huang, Ying" ying.huang@intel.com Cc: Chen Wandun chenwandun@huawei.com Cc: Huang Ying ying.huang@intel.com Cc: Kefeng Wang wangkefeng.wang@huawei.com Cc: Nanyong Sun sunnanyong@huawei.com Cc: Hugh Dickins hughd@google.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/swapfile.c | 1 + 1 file changed, 1 insertion(+)
--- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -1101,6 +1101,7 @@ start_over: goto check_out; pr_debug("scan_swap_map of si %d failed to find offset\n", si->type); + cond_resched();
spin_lock(&swap_avail_lock); nextsi:
From: Jann Horn jannh@google.com
commit 023f47a8250c6bdb4aebe744db4bf7f73414028b upstream.
If an ->anon_vma is attached to the VMA, collapse_and_free_pmd() requires it to be locked.
Page table traversal is allowed under any one of the mmap lock, the anon_vma lock (if the VMA is associated with an anon_vma), and the mapping lock (if the VMA is associated with a mapping); and so to be able to remove page tables, we must hold all three of them. retract_page_tables() bails out if an ->anon_vma is attached, but does this check before holding the mmap lock (as the comment above the check explains).
If we racily merged an existing ->anon_vma (shared with a child process) from a neighboring VMA, subsequent rmap traversals on pages belonging to the child will be able to see the page tables that we are concurrently removing while assuming that nothing else can access them.
Repeat the ->anon_vma check once we hold the mmap lock to ensure that there really is no concurrent page table access.
Hitting this bug causes a lockdep warning in collapse_and_free_pmd(), in the line "lockdep_assert_held_write(&vma->anon_vma->root->rwsem)". It can also lead to use-after-free access.
Link: https://lore.kernel.org/linux-mm/CAG48ez3434wZBKFFbdx4M9j6eUwSUVPd4dxhzW_k_P... Link: https://lkml.kernel.org/r/20230111133351.807024-1-jannh@google.com Fixes: f3f0e1d2150b ("khugepaged: add support of collapse for tmpfs/shmem pages") Signed-off-by: Jann Horn jannh@google.com Reported-by: Zach O'Keefe zokeefe@google.com Acked-by: Kirill A. Shutemov kirill.shutemov@intel.linux.com Reviewed-by: Yang Shi shy828301@gmail.com Cc: David Hildenbrand david@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/khugepaged.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
--- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -1649,7 +1649,7 @@ static int retract_page_tables(struct ad * has higher cost too. It would also probably require locking * the anon_vma. */ - if (vma->anon_vma) { + if (READ_ONCE(vma->anon_vma)) { result = SCAN_PAGE_ANON; goto next; } @@ -1678,6 +1678,18 @@ static int retract_page_tables(struct ad if ((cc->is_khugepaged || is_target) && mmap_write_trylock(mm)) { /* + * Re-check whether we have an ->anon_vma, because + * collapse_and_free_pmd() requires that either no + * ->anon_vma exists or the anon_vma is locked. + * We already checked ->anon_vma above, but that check + * is racy because ->anon_vma can be populated under the + * mmap lock in read mode. + */ + if (vma->anon_vma) { + result = SCAN_PAGE_ANON; + goto unlock_next; + } + /* * When a vma is registered with uffd-wp, we can't * recycle the pmd pgtable because there can be pte * markers installed. Skip it only, so the rest mm/vma
From: Vlastimil Babka vbabka@suse.cz
commit d014cd7c1c358edc3ea82ebf327a036a42ed0164 upstream.
Fabian has reported another regression in 6.1 due to ca3d76b0aa80 ("mm: add merging after mremap resize"). The problem is that vma_merge() can fail when vma has a vm_ops->close() method, causing is_mergeable_vma() test to be negative. This was happening for vma mapping a file from fuse-overlayfs, which does have the method. But when we are simply expanding the vma, we never remove it due to the "merge" with the added area, so the test should not prevent the expansion.
As a quick fix, check for such vmas and expand them using vma_adjust() directly as was done before commit ca3d76b0aa80. For a more robust long term solution we should try to limit the check for vma_ops->close only to cases that actually result in vma removal, so that no merge would be prevented unnecessarily.
[akpm@linux-foundation.org: fix indenting whitespace, reflow comment] Link: https://lkml.kernel.org/r/20230117101939.9753-1-vbabka@suse.cz Fixes: ca3d76b0aa80 ("mm: add merging after mremap resize") Signed-off-by: Vlastimil Babka vbabka@suse.cz Reported-by: Fabian Vogt fvogt@suse.com Link: https://bugzilla.suse.com/show_bug.cgi?id=1206359#c35 Tested-by: Fabian Vogt fvogt@suse.com Cc: Jakub Matěna matenajakub@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/mremap.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/mm/mremap.c b/mm/mremap.c index fe587c5d6591..930f65c315c0 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -1027,16 +1027,29 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, }
/* - * Function vma_merge() is called on the extension we are adding to - * the already existing vma, vma_merge() will merge this extension with - * the already existing vma (expand operation itself) and possibly also - * with the next vma if it becomes adjacent to the expanded vma and - * otherwise compatible. + * Function vma_merge() is called on the extension we + * are adding to the already existing vma, vma_merge() + * will merge this extension with the already existing + * vma (expand operation itself) and possibly also with + * the next vma if it becomes adjacent to the expanded + * vma and otherwise compatible. + * + * However, vma_merge() can currently fail due to + * is_mergeable_vma() check for vm_ops->close (see the + * comment there). Yet this should not prevent vma + * expanding, so perform a simple expand for such vma. + * Ideally the check for close op should be only done + * when a vma would be actually removed due to a merge. */ - vma = vma_merge(mm, vma, extension_start, extension_end, + if (!vma->vm_ops || !vma->vm_ops->close) { + vma = vma_merge(mm, vma, extension_start, extension_end, vma->vm_flags, vma->anon_vma, vma->vm_file, extension_pgoff, vma_policy(vma), vma->vm_userfaultfd_ctx, anon_vma_name(vma)); + } else if (vma_adjust(vma, vma->vm_start, addr + new_len, + vma->vm_pgoff, NULL)) { + vma = NULL; + } if (!vma) { vm_unacct_memory(pages); ret = -ENOMEM;
From: Zach O'Keefe zokeefe@google.com
commit edb5d0cf5525357652aff6eacd9850b8ced07143 upstream.
In commit 34488399fa08 ("mm/madvise: add file and shmem support to MADV_COLLAPSE") we make the following change to find_pmd_or_thp_or_none():
- if (!pmd_present(pmde)) - return SCAN_PMD_NULL; + if (pmd_none(pmde)) + return SCAN_PMD_NONE;
This was for-use by MADV_COLLAPSE file/shmem codepaths, where MADV_COLLAPSE might identify a pte-mapped hugepage, only to have khugepaged race-in, free the pte table, and clear the pmd. Such codepaths include:
A) If we find a suitably-aligned compound page of order HPAGE_PMD_ORDER already in the pagecache. B) In retract_page_tables(), if we fail to grab mmap_lock for the target mm/address.
In these cases, collapse_pte_mapped_thp() really does expect a none (not just !present) pmd, and we want to suitably identify that case separate from the case where no pmd is found, or it's a bad-pmd (of course, many things could happen once we drop mmap_lock, and the pmd could plausibly undergo multiple transitions due to intervening fault, split, etc). Regardless, the code is prepared install a huge-pmd only when the existing pmd entry is either a genuine pte-table-mapping-pmd, or the none-pmd.
However, the commit introduces a logical hole; namely, that we've allowed !none- && !huge- && !bad-pmds to be classified as genuine pte-table-mapping-pmds. One such example that could leak through are swap entries. The pmd values aren't checked again before use in pte_offset_map_lock(), which is expecting nothing less than a genuine pte-table-mapping-pmd.
We want to put back the !pmd_present() check (below the pmd_none() check), but need to be careful to deal with subtleties in pmd transitions and treatments by various arch.
The issue is that __split_huge_pmd_locked() temporarily clears the present bit (or otherwise marks the entry as invalid), but pmd_present() and pmd_trans_huge() still need to return true while the pmd is in this transitory state. For example, x86's pmd_present() also checks the _PAGE_PSE , riscv's version also checks the _PAGE_LEAF bit, and arm64 also checks a PMD_PRESENT_INVALID bit.
Covering all 4 cases for x86 (all checks done on the same pmd value):
1) pmd_present() && pmd_trans_huge() All we actually know here is that the PSE bit is set. Either: a) We aren't racing with __split_huge_page(), and PRESENT or PROTNONE is set. => huge-pmd b) We are currently racing with __split_huge_page(). The danger here is that we proceed as-if we have a huge-pmd, but really we are looking at a pte-mapping-pmd. So, what is the risk of this danger?
The only relevant path is:
madvise_collapse() -> collapse_pte_mapped_thp()
Where we might just incorrectly report back "success", when really the memory isn't pmd-backed. This is fine, since split could happen immediately after (actually) successful madvise_collapse(). So, it should be safe to just assume huge-pmd here.
2) pmd_present() && !pmd_trans_huge() Either: a) PSE not set and either PRESENT or PROTNONE is. => pte-table-mapping pmd (or PROT_NONE) b) devmap. This routine can be called immediately after unlocking/locking mmap_lock -- or called with no locks held (see khugepaged_scan_mm_slot()), so previous VMA checks have since been invalidated.
3) !pmd_present() && pmd_trans_huge() Not possible.
4) !pmd_present() && !pmd_trans_huge() Neither PRESENT nor PROTNONE set => not present
I've checked all archs that implement pmd_trans_huge() (arm64, riscv, powerpc, longarch, x86, mips, s390) and this logic roughly translates (though devmap treatment is unique to x86 and powerpc, and (3) doesn't necessarily hold in general -- but that doesn't matter since !pmd_present() always takes failure path).
Also, add a comment above find_pmd_or_thp_or_none() to help future travelers reason about the validity of the code; namely, the possible mutations that might happen out from under us, depending on how mmap_lock is held (if at all).
Link: https://lkml.kernel.org/r/20230125225358.2576151-1-zokeefe@google.com Fixes: 34488399fa08 ("mm/madvise: add file and shmem support to MADV_COLLAPSE") Signed-off-by: Zach O'Keefe zokeefe@google.com Reported-by: Hugh Dickins hughd@google.com Reviewed-by: Yang Shi shy828301@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/khugepaged.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c index 935aa8b71d1c..90acfea40c13 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -847,6 +847,10 @@ static int hugepage_vma_revalidate(struct mm_struct *mm, unsigned long address, return SCAN_SUCCEED; }
+/* + * See pmd_trans_unstable() for how the result may change out from + * underneath us, even if we hold mmap_lock in read. + */ static int find_pmd_or_thp_or_none(struct mm_struct *mm, unsigned long address, pmd_t **pmd) @@ -865,8 +869,12 @@ static int find_pmd_or_thp_or_none(struct mm_struct *mm, #endif if (pmd_none(pmde)) return SCAN_PMD_NONE; + if (!pmd_present(pmde)) + return SCAN_PMD_NULL; if (pmd_trans_huge(pmde)) return SCAN_PMD_MAPPED; + if (pmd_devmap(pmde)) + return SCAN_PMD_NULL; if (pmd_bad(pmde)) return SCAN_PMD_NULL; return SCAN_SUCCEED;
From: Matthew Wilcox (Oracle) willy@infradead.org
commit 88d7b12068b95731c280af8ce88e8ee9561f96de upstream.
We already round down the address in kunmap_local_indexed() which is the other implementation of __kunmap_local(). The only implementation of kunmap_flush_on_unmap() is PA-RISC which is expecting a page-aligned address. This may be causing PA-RISC to be flushing the wrong addresses currently.
Link: https://lkml.kernel.org/r/20230126200727.1680362-1-willy@infradead.org Signed-off-by: Matthew Wilcox (Oracle) willy@infradead.org Fixes: 298fa1ad5571 ("highmem: Provide generic variant of kmap_atomic*") Reviewed-by: Ira Weiny ira.weiny@intel.com Cc: "Fabio M. De Francesco" fmdefrancesco@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Thomas Gleixner tglx@linutronix.de Cc: Helge Deller deller@gmx.de Cc: Alexander Potapenko glider@google.com Cc: Andrey Konovalov andreyknvl@gmail.com Cc: Bagas Sanjaya bagasdotme@gmail.com Cc: David Sterba dsterba@suse.com Cc: Kees Cook keescook@chromium.org Cc: Sebastian Andrzej Siewior bigeasy@linutronix.de Cc: Tony Luck tony.luck@intel.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/highmem-internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/include/linux/highmem-internal.h +++ b/include/linux/highmem-internal.h @@ -200,7 +200,7 @@ static inline void *kmap_local_pfn(unsig static inline void __kunmap_local(const void *addr) { #ifdef ARCH_HAS_FLUSH_ON_KUNMAP - kunmap_flush_on_unmap(addr); + kunmap_flush_on_unmap(PTR_ALIGN_DOWN(addr, PAGE_SIZE)); #endif }
@@ -227,7 +227,7 @@ static inline void *kmap_atomic_pfn(unsi static inline void __kunmap_atomic(const void *addr) { #ifdef ARCH_HAS_FLUSH_ON_KUNMAP - kunmap_flush_on_unmap(addr); + kunmap_flush_on_unmap(PTR_ALIGN_DOWN(addr, PAGE_SIZE)); #endif pagefault_enable(); if (IS_ENABLED(CONFIG_PREEMPT_RT))
From: James Morse james.morse@arm.com
commit 6f28a2613497fc587e347afa99fa2c52230678a7 upstream.
Since commit aa06a9bd8533 ("ia64: fix clock_getres(CLOCK_MONOTONIC) to report ITC frequency"), gcc 10.1.0 fails to build ia64 with the gnomic: | ../arch/ia64/kernel/sys_ia64.c: In function 'ia64_clock_getres': | ../arch/ia64/kernel/sys_ia64.c:189:3: error: a label can only be part of a statement and a declaration is not a statement | 189 | s64 tick_ns = DIV_ROUND_UP(NSEC_PER_SEC, local_cpu_data->itc_freq);
This line appears immediately after a case label in a switch.
Move the declarations out of the case, to the top of the function.
Link: https://lkml.kernel.org/r/20230117151632.393836-1-james.morse@arm.com Fixes: aa06a9bd8533 ("ia64: fix clock_getres(CLOCK_MONOTONIC) to report ITC frequency") Signed-off-by: James Morse james.morse@arm.com Reviewed-by: Sergei Trofimovich slyich@gmail.com Cc: Émeric Maschino emeric.maschino@gmail.com Cc: matoro matoro_mailinglist_kernel@matoro.tk Cc: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de 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/kernel/sys_ia64.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index f6a502e8f02c..6e948d015332 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c @@ -170,6 +170,9 @@ ia64_mremap (unsigned long addr, unsigned long old_len, unsigned long new_len, u asmlinkage long ia64_clock_getres(const clockid_t which_clock, struct __kernel_timespec __user *tp) { + struct timespec64 rtn_tp; + s64 tick_ns; + /* * ia64's clock_gettime() syscall is implemented as a vdso call * fsys_clock_gettime(). Currently it handles only @@ -185,8 +188,8 @@ ia64_clock_getres(const clockid_t which_clock, struct __kernel_timespec __user * switch (which_clock) { case CLOCK_REALTIME: case CLOCK_MONOTONIC: - s64 tick_ns = DIV_ROUND_UP(NSEC_PER_SEC, local_cpu_data->itc_freq); - struct timespec64 rtn_tp = ns_to_timespec64(tick_ns); + tick_ns = DIV_ROUND_UP(NSEC_PER_SEC, local_cpu_data->itc_freq); + rtn_tp = ns_to_timespec64(tick_ns); return put_timespec64(&rtn_tp, tp); }
From: Phillip Lougher phillip@squashfs.org.uk
commit f65c4bbbd682b0877b669828b4e033b8d5d0a2dc upstream.
A Sysbot [1] corrupted filesystem exposes two flaws in the handling and sanity checking of the xattr_ids count in the filesystem. Both of these flaws cause computation overflow due to incorrect typing.
In the corrupted filesystem the xattr_ids value is 4294967071, which stored in a signed variable becomes the negative number -225.
Flaw 1 (64-bit systems only):
The signed integer xattr_ids variable causes sign extension.
This causes variable overflow in the SQUASHFS_XATTR_*(A) macros. The variable is first multiplied by sizeof(struct squashfs_xattr_id) where the type of the sizeof operator is "unsigned long".
On a 64-bit system this is 64-bits in size, and causes the negative number to be sign extended and widened to 64-bits and then become unsigned. This produces the very large number 18446744073709548016 or 2^64 - 3600. This number when rounded up by SQUASHFS_METADATA_SIZE - 1 (8191 bytes) and divided by SQUASHFS_METADATA_SIZE overflows and produces a length of 0 (stored in len).
Flaw 2 (32-bit systems only):
On a 32-bit system the integer variable is not widened by the unsigned long type of the sizeof operator (32-bits), and the signedness of the variable has no effect due it always being treated as unsigned.
The above corrupted xattr_ids value of 4294967071, when multiplied overflows and produces the number 4294963696 or 2^32 - 3400. This number when rounded up by SQUASHFS_METADATA_SIZE - 1 (8191 bytes) and divided by SQUASHFS_METADATA_SIZE overflows again and produces a length of 0.
The effect of the 0 length computation:
In conjunction with the corrupted xattr_ids field, the filesystem also has a corrupted xattr_table_start value, where it matches the end of filesystem value of 850.
This causes the following sanity check code to fail because the incorrectly computed len of 0 matches the incorrect size of the table reported by the superblock (0 bytes).
len = SQUASHFS_XATTR_BLOCK_BYTES(*xattr_ids); indexes = SQUASHFS_XATTR_BLOCKS(*xattr_ids);
/* * The computed size of the index table (len bytes) should exactly * match the table start and end points */ start = table_start + sizeof(*id_table); end = msblk->bytes_used;
if (len != (end - start)) return ERR_PTR(-EINVAL);
Changing the xattr_ids variable to be "usigned int" fixes the flaw on a 64-bit system. This relies on the fact the computation is widened by the unsigned long type of the sizeof operator.
Casting the variable to u64 in the above macro fixes this flaw on a 32-bit system.
It also means 64-bit systems do not implicitly rely on the type of the sizeof operator to widen the computation.
[1] https://lore.kernel.org/lkml/000000000000cd44f005f1a0f17f@google.com/
Link: https://lkml.kernel.org/r/20230127061842.10965-1-phillip@squashfs.org.uk Fixes: 506220d2ba21 ("squashfs: add more sanity checks in xattr id lookup") Signed-off-by: Phillip Lougher phillip@squashfs.org.uk Reported-by: syzbot+082fa4af80a5bb1a9843@syzkaller.appspotmail.com Cc: Alexey Khoroshilov khoroshilov@ispras.ru Cc: Fedor Pchelkin pchelkin@ispras.ru Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/squashfs/squashfs_fs.h | 2 +- fs/squashfs/squashfs_fs_sb.h | 2 +- fs/squashfs/xattr.h | 4 ++-- fs/squashfs/xattr_id.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-)
--- a/fs/squashfs/squashfs_fs.h +++ b/fs/squashfs/squashfs_fs.h @@ -183,7 +183,7 @@ static inline int squashfs_block_size(__ #define SQUASHFS_ID_BLOCK_BYTES(A) (SQUASHFS_ID_BLOCKS(A) *\ sizeof(u64)) /* xattr id lookup table defines */ -#define SQUASHFS_XATTR_BYTES(A) ((A) * sizeof(struct squashfs_xattr_id)) +#define SQUASHFS_XATTR_BYTES(A) (((u64) (A)) * sizeof(struct squashfs_xattr_id))
#define SQUASHFS_XATTR_BLOCK(A) (SQUASHFS_XATTR_BYTES(A) / \ SQUASHFS_METADATA_SIZE) --- a/fs/squashfs/squashfs_fs_sb.h +++ b/fs/squashfs/squashfs_fs_sb.h @@ -63,7 +63,7 @@ struct squashfs_sb_info { long long bytes_used; unsigned int inodes; unsigned int fragments; - int xattr_ids; + unsigned int xattr_ids; unsigned int ids; bool panic_on_errors; }; --- a/fs/squashfs/xattr.h +++ b/fs/squashfs/xattr.h @@ -10,12 +10,12 @@
#ifdef CONFIG_SQUASHFS_XATTR extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64, - u64 *, int *); + u64 *, unsigned int *); extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *, unsigned int *, unsigned long long *); #else static inline __le64 *squashfs_read_xattr_id_table(struct super_block *sb, - u64 start, u64 *xattr_table_start, int *xattr_ids) + u64 start, u64 *xattr_table_start, unsigned int *xattr_ids) { struct squashfs_xattr_id_table *id_table;
--- a/fs/squashfs/xattr_id.c +++ b/fs/squashfs/xattr_id.c @@ -56,7 +56,7 @@ int squashfs_xattr_lookup(struct super_b * Read uncompressed xattr id lookup table indexes from disk into memory */ __le64 *squashfs_read_xattr_id_table(struct super_block *sb, u64 table_start, - u64 *xattr_table_start, int *xattr_ids) + u64 *xattr_table_start, unsigned int *xattr_ids) { struct squashfs_sb_info *msblk = sb->s_fs_info; unsigned int len, indexes;
From: Liam Howlett liam.howlett@oracle.com
commit 7327e8111adb315423035fb5233533016dfd3f2e upstream.
mas_empty_area_rev() was not correctly validating the start of a gap against the lower limit. This could lead to the range starting lower than the requested minimum.
Fix the issue by better validating a gap once one is found.
This commit also adds tests to the maple tree test suite for this issue and tests the mas_empty_area() function for similar bound checking.
Link: https://lkml.kernel.org/r/20230111200136.1851322-1-Liam.Howlett@oracle.com Link: https://bugzilla.kernel.org/show_bug.cgi?id=216911 Fixes: 54a611b60590 ("Maple Tree: add new data structure") Signed-off-by: Liam R. Howlett Liam.Howlett@oracle.com Reported-by: amanieu@gmail.com Link: https://lore.kernel.org/linux-mm/0b9f5425-08d4-8013-aa4c-e620c3b10bb2@leemhu... Tested-by: Holger Hoffsttte holger@applied-asynchrony.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- lib/maple_tree.c | 17 ++++----- lib/test_maple_tree.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 9 deletions(-)
--- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -4883,7 +4883,7 @@ static bool mas_rev_awalk(struct ma_stat unsigned long *pivots, *gaps; void __rcu **slots; unsigned long gap = 0; - unsigned long max, min, index; + unsigned long max, min; unsigned char offset;
if (unlikely(mas_is_err(mas))) @@ -4905,8 +4905,7 @@ static bool mas_rev_awalk(struct ma_stat min = mas_safe_min(mas, pivots, --offset);
max = mas_safe_pivot(mas, pivots, offset, type); - index = mas->index; - while (index <= max) { + while (mas->index <= max) { gap = 0; if (gaps) gap = gaps[offset]; @@ -4937,10 +4936,8 @@ static bool mas_rev_awalk(struct ma_stat min = mas_safe_min(mas, pivots, offset); }
- if (unlikely(index > max)) { - mas_set_err(mas, -EBUSY); - return false; - } + if (unlikely((mas->index > max) || (size - 1 > max - mas->index))) + goto no_space;
if (unlikely(ma_is_leaf(type))) { mas->offset = offset; @@ -4957,9 +4954,11 @@ static bool mas_rev_awalk(struct ma_stat return false;
ascend: - if (mte_is_root(mas->node)) - mas_set_err(mas, -EBUSY); + if (!mte_is_root(mas->node)) + return false;
+no_space: + mas_set_err(mas, -EBUSY); return false; }
--- a/lib/test_maple_tree.c +++ b/lib/test_maple_tree.c @@ -2517,6 +2517,91 @@ static noinline void check_bnode_min_spa mt_set_non_kernel(0); }
+static noinline void check_empty_area_window(struct maple_tree *mt) +{ + unsigned long i, nr_entries = 20; + MA_STATE(mas, mt, 0, 0); + + for (i = 1; i <= nr_entries; i++) + mtree_store_range(mt, i*10, i*10 + 9, + xa_mk_value(i), GFP_KERNEL); + + /* Create another hole besides the one at 0 */ + mtree_store_range(mt, 160, 169, NULL, GFP_KERNEL); + + /* Check lower bounds that don't fit */ + rcu_read_lock(); + MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 90, 10) != -EBUSY); + + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area_rev(&mas, 6, 90, 5) != -EBUSY); + + /* Check lower bound that does fit */ + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 90, 5) != 0); + MT_BUG_ON(mt, mas.index != 5); + MT_BUG_ON(mt, mas.last != 9); + rcu_read_unlock(); + + /* Check one gap that doesn't fit and one that does */ + rcu_read_lock(); + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area_rev(&mas, 5, 217, 9) != 0); + MT_BUG_ON(mt, mas.index != 161); + MT_BUG_ON(mt, mas.last != 169); + + /* Check one gap that does fit above the min */ + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 218, 3) != 0); + MT_BUG_ON(mt, mas.index != 216); + MT_BUG_ON(mt, mas.last != 218); + + /* Check size that doesn't fit any gap */ + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 218, 16) != -EBUSY); + + /* + * Check size that doesn't fit the lower end of the window but + * does fit the gap + */ + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area_rev(&mas, 167, 200, 4) != -EBUSY); + + /* + * Check size that doesn't fit the upper end of the window but + * does fit the gap + */ + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area_rev(&mas, 100, 162, 4) != -EBUSY); + + /* Check mas_empty_area forward */ + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 9) != 0); + MT_BUG_ON(mt, mas.index != 0); + MT_BUG_ON(mt, mas.last != 8); + + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 4) != 0); + MT_BUG_ON(mt, mas.index != 0); + MT_BUG_ON(mt, mas.last != 3); + + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area(&mas, 0, 100, 11) != -EBUSY); + + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area(&mas, 5, 100, 6) != -EBUSY); + + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area(&mas, 0, 8, 10) != -EBUSY); + + mas_reset(&mas); + mas_empty_area(&mas, 100, 165, 3); + + mas_reset(&mas); + MT_BUG_ON(mt, mas_empty_area(&mas, 100, 163, 6) != -EBUSY); + rcu_read_unlock(); +} + static DEFINE_MTREE(tree); static int maple_tree_seed(void) { @@ -2765,6 +2850,10 @@ static int maple_tree_seed(void) check_bnode_min_spanning(&tree); mtree_destroy(&tree);
+ mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); + check_empty_area_window(&tree); + mtree_destroy(&tree); + #if defined(BENCH) skip: #endif
From: Mike Kravetz mike.kravetz@oracle.com
commit 73bdf65ea74857d7fb2ec3067a3cec0e261b1462 upstream.
migrate_pages/mempolicy semantics state that CAP_SYS_NICE is required to move pages shared with another process to a different node. page_mapcount
1 is being used to determine if a hugetlb page is shared. However, a
hugetlb page will have a mapcount of 1 if mapped by multiple processes via a shared PMD. As a result, hugetlb pages shared by multiple processes and mapped with a shared PMD can be moved by a process without CAP_SYS_NICE.
To fix, check for a shared PMD if mapcount is 1. If a shared PMD is found consider the page shared.
Link: https://lkml.kernel.org/r/20230126222721.222195-3-mike.kravetz@oracle.com Fixes: e2d8cf405525 ("migrate: add hugepage migration code to migrate_pages()") Signed-off-by: Mike Kravetz mike.kravetz@oracle.com Acked-by: Peter Xu peterx@redhat.com Acked-by: David Hildenbrand david@redhat.com Cc: James Houghton jthoughton@google.com Cc: Matthew Wilcox willy@infradead.org Cc: Michal Hocko mhocko@suse.com Cc: Muchun Song songmuchun@bytedance.com Cc: Naoya Horiguchi naoya.horiguchi@linux.dev Cc: Vishal Moola (Oracle) vishal.moola@gmail.com Cc: Yang Shi shy828301@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/mempolicy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -600,7 +600,8 @@ static int queue_pages_hugetlb(pte_t *pt
/* With MPOL_MF_MOVE, we migrate only unshared hugepage. */ if (flags & (MPOL_MF_MOVE_ALL) || - (flags & MPOL_MF_MOVE && page_mapcount(page) == 1)) { + (flags & MPOL_MF_MOVE && page_mapcount(page) == 1 && + !hugetlb_pmd_shared(pte))) { if (isolate_hugetlb(page, qp->pagelist) && (flags & MPOL_MF_STRICT)) /*
From: Danilo Krummrich dakr@redhat.com
commit d2ceea0eb6e17bb37d8b85cb4c16797c0d683d1c upstream.
In dma_fence_allocate_private_stub() set the signaling bit of the newly allocated private stub fence rather than the signaling bit of the shared dma_fence_stub.
Cc: stable@vger.kernel.org # v6.1 Fixes: c85d00d4fd8b ("dma-buf: set signaling bit for the stub fence") Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Danilo Krummrich dakr@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20230126002844.339593-1-dakr@r... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/dma-buf/dma-fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 406b4e26f538..0de0482cd36e 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -167,7 +167,7 @@ struct dma_fence *dma_fence_allocate_private_stub(void) 0, 0);
set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, - &dma_fence_stub.flags); + &fence->flags);
dma_fence_signal(fence);
From: Marek Vasut marex@denx.de
commit 3f6c02fa712bd453871877fe1d1969625617471e upstream.
Requesting an interrupt with IRQF_ONESHOT will run the primary handler in the hard-IRQ context even in the force-threaded mode. The force-threaded mode is used by PREEMPT_RT in order to avoid acquiring sleeping locks (spinlock_t) in hard-IRQ context. This combination makes it impossible and leads to "sleeping while atomic" warnings.
Use one interrupt handler for both handlers (primary and secondary) and drop the IRQF_ONESHOT flag which is not needed.
Fixes: e359b4411c283 ("serial: stm32: fix threaded interrupt handling") Reviewed-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Tested-by: Valentin Caron valentin.caron@foss.st.com # V3 Signed-off-by: Marek Vasut marex@denx.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230120160332.57930-1-marex@denx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/stm32-usart.c | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-)
--- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -798,25 +798,11 @@ static irqreturn_t stm32_usart_interrupt spin_unlock(&port->lock); }
- if (stm32_usart_rx_dma_enabled(port)) - return IRQ_WAKE_THREAD; - else - return IRQ_HANDLED; -} - -static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr) -{ - struct uart_port *port = ptr; - struct tty_port *tport = &port->state->port; - struct stm32_port *stm32_port = to_stm32_port(port); - unsigned int size; - unsigned long flags; - /* Receiver timeout irq for DMA RX */ - if (!stm32_port->throttled) { - spin_lock_irqsave(&port->lock, flags); + if (stm32_usart_rx_dma_enabled(port) && !stm32_port->throttled) { + spin_lock(&port->lock); size = stm32_usart_receive_chars(port, false); - uart_unlock_and_check_sysrq_irqrestore(port, flags); + uart_unlock_and_check_sysrq(port); if (size) tty_flip_buffer_push(tport); } @@ -1016,10 +1002,8 @@ static int stm32_usart_startup(struct ua u32 val; int ret;
- ret = request_threaded_irq(port->irq, stm32_usart_interrupt, - stm32_usart_threaded_interrupt, - IRQF_ONESHOT | IRQF_NO_SUSPEND, - name, port); + ret = request_irq(port->irq, stm32_usart_interrupt, + IRQF_NO_SUSPEND, name, port); if (ret) return ret;
@@ -1602,13 +1586,6 @@ static int stm32_usart_of_dma_rx_probe(s struct dma_slave_config config; int ret;
- /* - * Using DMA and threaded handler for the console could lead to - * deadlocks. - */ - if (uart_console(port)) - return -ENODEV; - stm32port->rx_buf = dma_alloc_coherent(dev, RX_BUF_L, &stm32port->rx_dma_buf, GFP_KERNEL);
From: Rob Clark robdclark@chromium.org
commit 41d419382ec7e257e54b7b6ff0d3623aafb1316d upstream.
Adding the vm to the vm_xa table makes it visible to userspace, which could try to race with us to close the vm. So we need to take our extra reference before putting it in the table.
Signed-off-by: Rob Clark robdclark@chromium.org Reviewed-by: Matthew Auld matthew.auld@intel.com Fixes: 9ec8795e7d91 ("drm/i915: Drop __rcu from gem_context->vm") Cc: stable@vger.kernel.org # v5.16+ Signed-off-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230119173321.2825472-1-robdc... (cherry picked from commit 99343c46d4e2b34c285d3d5f68ff04274c2f9fb4) Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/gem/i915_gem_context.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index 6250de9b9196..e4b78ab4773b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -1861,11 +1861,19 @@ static int get_ppgtt(struct drm_i915_file_private *file_priv, vm = ctx->vm; GEM_BUG_ON(!vm);
+ /* + * Get a reference for the allocated handle. Once the handle is + * visible in the vm_xa table, userspace could try to close it + * from under our feet, so we need to hold the extra reference + * first. + */ + i915_vm_get(vm); + err = xa_alloc(&file_priv->vm_xa, &id, vm, xa_limit_32b, GFP_KERNEL); - if (err) + if (err) { + i915_vm_put(vm); return err; - - i915_vm_get(vm); + }
GEM_BUG_ON(id == 0); /* reserved for invalid/unassigned ppgtt */ args->value = id;
From: Rob Clark robdclark@chromium.org
commit 7057a8f126f14f14b040faecfa220fd27c6c2f85 upstream.
A userspace with multiple threads racing I915_GEM_SET_TILING to set the tiling to I915_TILING_NONE could trigger a double free of the bit_17 bitmask. (Or conversely leak memory on the transition to tiled.) Move allocation/free'ing of the bitmask within the section protected by the obj lock.
Signed-off-by: Rob Clark robdclark@chromium.org Fixes: 2850748ef876 ("drm/i915: Pull i915_vma_pin under the vm->mutex") Cc: stable@vger.kernel.org # v5.5+ [tursulin: Correct fixes tag and added cc stable.] Reviewed-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Signed-off-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230127200550.3531984-1-robdc... (cherry picked from commit 10e0cbaaf1104f449d695c80bcacf930dcd3c42e) Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/gem/i915_gem_tiling.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/i915/gem/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_tiling.c @@ -305,10 +305,6 @@ i915_gem_object_set_tiling(struct drm_i9 spin_unlock(&obj->vma.lock);
obj->tiling_and_stride = tiling | stride; - i915_gem_object_unlock(obj); - - /* Force the fence to be reacquired for GTT access */ - i915_gem_object_release_mmap_gtt(obj);
/* Try to preallocate memory required to save swizzling on put-pages */ if (i915_gem_object_needs_bit17_swizzle(obj)) { @@ -321,6 +317,11 @@ i915_gem_object_set_tiling(struct drm_i9 obj->bit_17 = NULL; }
+ i915_gem_object_unlock(obj); + + /* Force the fence to be reacquired for GTT access */ + i915_gem_object_release_mmap_gtt(obj); + return 0; }
From: Mario Limonciello mario.limonciello@amd.com
commit 5048fa1ebf89d03cf0ceca13fab8f800399e9ee3 upstream.
A mistake has been made on some boards with NBIO 4.3.0 where some NBIO registers aren't properly set by the hardware.
Ensure that they're set during initialization.
Cc: Natikar Basavaraj Basavaraj.Natikar@amd.com Tested-by: Satyanarayana ReddyTVN Satyanarayana.ReddyTVN@amd.com Tested-by: Rutvij Gajjar Rutvij.Gajjar@amd.com Signed-off-by: Mario Limonciello mario.limonciello@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org # 6.1.x Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c b/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c index 15eb3658d70e..09fdcd20cb91 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c @@ -337,7 +337,13 @@ const struct nbio_hdp_flush_reg nbio_v4_3_hdp_flush_reg = {
static void nbio_v4_3_init_registers(struct amdgpu_device *adev) { - return; + if (adev->ip_versions[NBIO_HWIP][0] == IP_VERSION(4, 3, 0)) { + uint32_t data; + + data = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF2_STRAP2); + data &= ~RCC_DEV0_EPF2_STRAP2__STRAP_NO_SOFT_RESET_DEV0_F2_MASK; + WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF2_STRAP2, data); + } }
static u32 nbio_v4_3_get_rom_offset(struct amdgpu_device *adev)
From: Tim Huang tim.huang@amd.com
commit 1538709c9f1c207d30afd95ea41b3aeb973f67e7 upstream.
PMFW will handle the features disablement properly for gpu reset case, driver involvement may cause some unexpected issues.
Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Tim Huang tim.huang@amd.com Reviewed-by: Yifan Zhang yifan1.zhang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -1499,6 +1499,20 @@ static int smu_disable_dpms(struct smu_c }
/* + * For SMU 13.0.4/11, PMFW will handle the features disablement properly + * for gpu reset case. Driver involvement is unnecessary. + */ + if (amdgpu_in_reset(adev)) { + switch (adev->ip_versions[MP1_HWIP][0]) { + case IP_VERSION(13, 0, 4): + case IP_VERSION(13, 0, 11): + return 0; + default: + break; + } + } + + /* * For gpu reset, runpm and hibernation through BACO, * BACO feature has to be kept enabled. */
From: Graham Sider Graham.Sider@amd.com
commit ed8e793c65e4c6633e8577e40d574da8a56d2e0f upstream.
SQ_WAVE_INST_DW0 isn't present on gfx11 compared to gfx10, so update wave data type to signify a difference.
Signed-off-by: Graham Sider Graham.Sider@amd.com Reviewed-by: Mukul Joshi Mukul.Joshi@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org # 6.1.x Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index b9b57a66e113..66eb102cd88f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -790,8 +790,8 @@ static void gfx_v11_0_read_wave_data(struct amdgpu_device *adev, uint32_t simd, * zero here */ WARN_ON(simd != 0);
- /* type 2 wave data */ - dst[(*no_fields)++] = 2; + /* type 3 wave data */ + dst[(*no_fields)++] = 3; dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_STATUS); dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_PC_LO); dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_PC_HI);
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
commit 3bd747c7ea13cb145f0d84444e00df928b0842d9 upstream.
The error path for wp_gpio attempts to free the IDA nvmem->id, but this has yet to be assigned, so will always be zero - leaking the ID allocated by ida_alloc(). Fix this by moving the initialisation of nvmem->id earlier.
Fixes: f7d8d7dcd978 ("nvmem: fix memory leak in error path") Cc: stable@vger.kernel.org Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20230127104015.23839-4-srinivas.kandagatla@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvmem/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -770,6 +770,8 @@ struct nvmem_device *nvmem_register(cons return ERR_PTR(rval); }
+ nvmem->id = rval; + if (config->wp_gpio) nvmem->wp_gpio = config->wp_gpio; else if (!config->ignore_wp) @@ -785,7 +787,6 @@ struct nvmem_device *nvmem_register(cons kref_init(&nvmem->refcnt); INIT_LIST_HEAD(&nvmem->cells);
- nvmem->id = rval; nvmem->owner = config->owner; if (!nvmem->owner && config->dev->driver) nvmem->owner = config->dev->driver->owner;
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
commit 569653f022a29a1a44ea9de5308b657228303fa5 upstream.
No one provides wp_gpio, so let's remove it to avoid issues with the nvmem core putting this gpio.
Cc: stable@vger.kernel.org Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20230127104015.23839-5-srinivas.kandagatla@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvmem/core.c | 4 +--- include/linux/nvmem-provider.h | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-)
--- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -772,9 +772,7 @@ struct nvmem_device *nvmem_register(cons
nvmem->id = rval;
- if (config->wp_gpio) - nvmem->wp_gpio = config->wp_gpio; - else if (!config->ignore_wp) + if (!config->ignore_wp) nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp", GPIOD_OUT_HIGH); if (IS_ERR(nvmem->wp_gpio)) { --- a/include/linux/nvmem-provider.h +++ b/include/linux/nvmem-provider.h @@ -70,7 +70,6 @@ struct nvmem_keepout { * @word_size: Minimum read/write access granularity. * @stride: Minimum read/write access stride. * @priv: User context passed to read/write callbacks. - * @wp-gpio: Write protect pin * @ignore_wp: Write Protect pin is managed by the provider. * * Note: A default "nvmem<id>" name will be assigned to the device if @@ -85,7 +84,6 @@ struct nvmem_config { const char *name; int id; struct module *owner; - struct gpio_desc *wp_gpio; const struct nvmem_cell_info *cells; int ncells; const struct nvmem_keepout *keepout;
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
commit 560181d3ace61825f4ca9dd3481d6c0ee6709fa8 upstream.
If dev_set_name() fails, we leak nvmem->wp_gpio as the cleanup does not put this. While a minimal fix for this would be to add the gpiod_put() call, we can do better if we split device_register(), and use the tested nvmem_release() cleanup code by initialising the device early, and putting the device.
This results in a slightly larger fix, but results in clear code.
Note: this patch depends on "nvmem: core: initialise nvmem->id early" and "nvmem: core: remove nvmem_config wp_gpio".
Fixes: 5544e90c8126 ("nvmem: core: add error handling for dev_set_name") Cc: stable@vger.kernel.org Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter error27@gmail.com Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk [Srini: Fixed subject line and error code handing with wp_gpio while applying.] Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20230127104015.23839-6-srinivas.kandagatla@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvmem/core.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 608f3ad2e2e4..ac77a019aed7 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -772,14 +772,18 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
nvmem->id = rval;
+ nvmem->dev.type = &nvmem_provider_type; + nvmem->dev.bus = &nvmem_bus_type; + nvmem->dev.parent = config->dev; + + device_initialize(&nvmem->dev); + if (!config->ignore_wp) nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp", GPIOD_OUT_HIGH); if (IS_ERR(nvmem->wp_gpio)) { - ida_free(&nvmem_ida, nvmem->id); rval = PTR_ERR(nvmem->wp_gpio); - kfree(nvmem); - return ERR_PTR(rval); + goto err_put_device; }
kref_init(&nvmem->refcnt); @@ -791,9 +795,6 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->stride = config->stride ?: 1; nvmem->word_size = config->word_size ?: 1; nvmem->size = config->size; - nvmem->dev.type = &nvmem_provider_type; - nvmem->dev.bus = &nvmem_bus_type; - nvmem->dev.parent = config->dev; nvmem->root_only = config->root_only; nvmem->priv = config->priv; nvmem->type = config->type; @@ -821,11 +822,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) break; }
- if (rval) { - ida_free(&nvmem_ida, nvmem->id); - kfree(nvmem); - return ERR_PTR(rval); - } + if (rval) + goto err_put_device;
nvmem->read_only = device_property_present(config->dev, "read-only") || config->read_only || !nvmem->reg_write; @@ -836,7 +834,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
- rval = device_register(&nvmem->dev); + rval = device_add(&nvmem->dev); if (rval) goto err_put_device;
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
commit ab3428cfd9aa2f3463ee4b2909b5bb2193bd0c4a upstream.
The i.MX6 CPU frequency driver sometimes fails to register at boot time due to nvmem_cell_read_u32() sporadically returning -ENOENT.
This happens because there is a window where __nvmem_device_get() in of_nvmem_cell_get() is able to return the nvmem device, but as cells have been setup, nvmem_find_cell_entry_by_node() returns NULL.
The occurs because the nvmem core registration code violates one of the fundamental principles of kernel programming: do not publish data structures before their setup is complete.
Fix this by making nvmem core code conform with this principle.
Fixes: eace75cfdcf7 ("nvmem: Add a simple NVMEM framework for nvmem providers") Cc: stable@vger.kernel.org Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20230127104015.23839-7-srinivas.kandagatla@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvmem/core.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
--- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -832,22 +832,16 @@ struct nvmem_device *nvmem_register(cons nvmem->dev.groups = nvmem_dev_groups; #endif
- dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); - - rval = device_add(&nvmem->dev); - if (rval) - goto err_put_device; - if (nvmem->nkeepout) { rval = nvmem_validate_keepouts(nvmem); if (rval) - goto err_device_del; + goto err_put_device; }
if (config->compat) { rval = nvmem_sysfs_setup_compat(nvmem, config); if (rval) - goto err_device_del; + goto err_put_device; }
if (config->cells) { @@ -864,6 +858,12 @@ struct nvmem_device *nvmem_register(cons if (rval) goto err_remove_cells;
+ dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); + + rval = device_add(&nvmem->dev); + if (rval) + goto err_remove_cells; + blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
return nvmem; @@ -873,8 +873,6 @@ err_remove_cells: err_teardown_compat: if (config->compat) nvmem_sysfs_remove_compat(nvmem, config); -err_device_del: - device_del(&nvmem->dev); err_put_device: put_device(&nvmem->dev);
From: Michael Walle michael@walle.cc
commit edcf2fb660526b5ed29f93bd17328a2b4835c8b2 upstream.
In of_nvmem_cell_get(), of_get_next_parent() is used on cell_np. This will decrement the refcount on cell_np, but cell_np is still used later in the code. Use of_get_parent() instead and of_node_put() in the appropriate places.
Fixes: 69aba7948cbe ("nvmem: Add a simple NVMEM framework for consumers") Fixes: 7ae6478b304b ("nvmem: core: rework nvmem cell instance creation") Cc: stable@vger.kernel.org Signed-off-by: Michael Walle michael@walle.cc Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20230127104015.23839-8-srinivas.kandagatla@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvmem/core.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
--- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -1237,16 +1237,21 @@ struct nvmem_cell *of_nvmem_cell_get(str if (!cell_np) return ERR_PTR(-ENOENT);
- nvmem_np = of_get_next_parent(cell_np); - if (!nvmem_np) + nvmem_np = of_get_parent(cell_np); + if (!nvmem_np) { + of_node_put(cell_np); return ERR_PTR(-EINVAL); + }
nvmem = __nvmem_device_get(nvmem_np, device_match_of_node); of_node_put(nvmem_np); - if (IS_ERR(nvmem)) + if (IS_ERR(nvmem)) { + of_node_put(cell_np); return ERR_CAST(nvmem); + }
cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np); + of_node_put(cell_np); if (!cell_entry) { __nvmem_device_put(nvmem); return ERR_PTR(-ENOENT);
From: Michael Walle michael@walle.cc
commit db3546d58b5a0fa581d9c9f2bdc2856fa6c5e43e upstream.
nvmem_add_cells() could return an error after some cells are already added to the provider. In this case, the added cells are not removed. Remove any registered cells if nvmem_add_cells() fails.
Fixes: fa72d847d68d7 ("nvmem: check the return value of nvmem_add_cells()") Cc: stable@vger.kernel.org Signed-off-by: Michael Walle michael@walle.cc Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20230127104015.23839-9-srinivas.kandagatla@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvmem/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -847,7 +847,7 @@ struct nvmem_device *nvmem_register(cons if (config->cells) { rval = nvmem_add_cells(nvmem, config->cells, config->ncells); if (rval) - goto err_teardown_compat; + goto err_remove_cells; }
rval = nvmem_add_cells_from_table(nvmem); @@ -870,7 +870,6 @@ struct nvmem_device *nvmem_register(cons
err_remove_cells: nvmem_device_remove_all_cells(nvmem); -err_teardown_compat: if (config->compat) nvmem_sysfs_remove_compat(nvmem, config); err_put_device:
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
commit 0c4862b1c1465e473bc961a02765490578bf5c20 upstream.
Dan Carpenter points out that the return code was not set in commit 60c8b4aebd8e ("nvmem: core: fix cleanup after dev_set_name()"), but this is not the only issue - we also need to zero wp_gpio to prevent gpiod_put() being called on an error value.
Fixes: 560181d3ace6 ("nvmem: core: fix cleanup after dev_set_name()") Cc: stable@vger.kernel.org Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter error27@gmail.com Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20230127104015.23839-10-srinivas.kandagatla@linaro... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvmem/core.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -783,6 +783,7 @@ struct nvmem_device *nvmem_register(cons GPIOD_OUT_HIGH); if (IS_ERR(nvmem->wp_gpio)) { rval = PTR_ERR(nvmem->wp_gpio); + nvmem->wp_gpio = NULL; goto err_put_device; }
From: Johan Hovold johan+linaro@kernel.org
commit c7b98de745cffdceefc077ad5cf9cda032ef8959 upstream.
Drop the confused runtime-suspend type check which effectively broke runtime PM if the DP child node happens to be parsed before the USB child node during probe (e.g. due to order of child nodes in the devicetree).
Instead use the new driver data USB PHY pointer to access the USB configuration and resources.
Fixes: 52e013d0bffa ("phy: qcom-qmp: Add support for DP in USB3+DP combo phy") Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Johan Hovold johan+linaro@kernel.org Link: https://lore.kernel.org/r/20221114081346.5116-6-johan+linaro@kernel.org Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Stephen Boyd swboyd@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -2296,15 +2296,11 @@ static void qmp_combo_disable_autonomous static int __maybe_unused qmp_combo_runtime_suspend(struct device *dev) { struct qcom_qmp *qmp = dev_get_drvdata(dev); - struct qmp_phy *qphy = qmp->phys[0]; + struct qmp_phy *qphy = qmp->usb_phy; const struct qmp_phy_cfg *cfg = qphy->cfg;
dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qphy->mode);
- /* Supported only for USB3 PHY and luckily USB3 is the first phy */ - if (cfg->type != PHY_TYPE_USB3) - return 0; - if (!qmp->init_count) { dev_vdbg(dev, "PHY not initialized, bailing out\n"); return 0; @@ -2321,16 +2317,12 @@ static int __maybe_unused qmp_combo_runt static int __maybe_unused qmp_combo_runtime_resume(struct device *dev) { struct qcom_qmp *qmp = dev_get_drvdata(dev); - struct qmp_phy *qphy = qmp->phys[0]; + struct qmp_phy *qphy = qmp->usb_phy; const struct qmp_phy_cfg *cfg = qphy->cfg; int ret = 0;
dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qphy->mode);
- /* Supported only for USB3 PHY and luckily USB3 is the first phy */ - if (cfg->type != PHY_TYPE_USB3) - return 0; - if (!qmp->init_count) { dev_vdbg(dev, "PHY not initialized, bailing out\n"); return 0;
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
commit 31352811e13dc2313f101b890fd4b1ce760b5fe7 upstream.
__dma_rx_complete() is called from two places: - Through the DMA completion callback dma_rx_complete() - From serial8250_rx_dma_flush() after IIR_RLSI or IIR_RX_TIMEOUT The former does not hold port's lock during __dma_rx_complete() which allows these two to race and potentially insert the same data twice.
Extend port's lock coverage in dma_rx_complete() to prevent the race and check if the DMA Rx is still pending completion before calling into __dma_rx_complete().
Reported-by: Gilles BULOZ gilles.buloz@kontron.com Tested-by: Gilles BULOZ gilles.buloz@kontron.com Fixes: 9ee4b83e51f7 ("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/20230130114841.25749-2-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_dma.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
--- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c @@ -57,6 +57,18 @@ static void __dma_rx_complete(void *para tty_flip_buffer_push(tty_port); }
+static void dma_rx_complete(void *param) +{ + struct uart_8250_port *p = param; + struct uart_8250_dma *dma = p->dma; + unsigned long flags; + + spin_lock_irqsave(&p->port.lock, flags); + if (dma->rx_running) + __dma_rx_complete(p); + spin_unlock_irqrestore(&p->port.lock, flags); +} + int serial8250_tx_dma(struct uart_8250_port *p) { struct uart_8250_dma *dma = p->dma; @@ -130,7 +142,7 @@ int serial8250_rx_dma(struct uart_8250_p return -EBUSY;
dma->rx_running = 1; - desc->callback = __dma_rx_complete; + desc->callback = dma_rx_complete; desc->callback_param = p;
dma->rx_cookie = dmaengine_submit(desc);
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
commit 57e9af7831dcf211c5c689c2a6f209f4abdf0bce upstream.
As DMA Rx can be completed from two places, it is possible that DMA Rx completes before DMA completion callback had a chance to complete it. Once the previous DMA Rx has been completed, a new one can be started on the next UART interrupt. The following race is possible (uart_unlock_and_check_sysrq_irqrestore() replaced with spin_unlock_irqrestore() for simplicity/clarity):
CPU0 CPU1 dma_rx_complete() serial8250_handle_irq() spin_lock_irqsave(&port->lock) handle_rx_dma() serial8250_rx_dma_flush() __dma_rx_complete() dma->rx_running = 0 // Complete DMA Rx spin_unlock_irqrestore(&port->lock)
serial8250_handle_irq() spin_lock_irqsave(&port->lock) handle_rx_dma() serial8250_rx_dma() dma->rx_running = 1 // Setup a new DMA Rx spin_unlock_irqrestore(&port->lock)
spin_lock_irqsave(&port->lock) // sees dma->rx_running = 1 __dma_rx_complete() dma->rx_running = 0 // Incorrectly complete // running DMA Rx
This race seems somewhat theoretical to occur for real but handle it correctly regardless. Check what is the DMA status before complething anything in __dma_rx_complete().
Reported-by: Gilles BULOZ gilles.buloz@kontron.com Tested-by: Gilles BULOZ gilles.buloz@kontron.com Fixes: 9ee4b83e51f7 ("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/20230130114841.25749-3-ilpo.jarvinen@linux.intel.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/8250/8250_dma.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
--- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c @@ -44,15 +44,23 @@ static void __dma_rx_complete(void *para struct uart_8250_dma *dma = p->dma; struct tty_port *tty_port = &p->port.state->port; struct dma_tx_state state; + enum dma_status dma_status; int count;
- dma->rx_running = 0; - dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); + /* + * New DMA Rx can be started during the completion handler before it + * could acquire port's lock and it might still be ongoing. Don't to + * anything in such case. + */ + dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); + if (dma_status == DMA_IN_PROGRESS) + return;
count = dma->rx_size - state.residue;
tty_insert_flip_string(tty_port, dma->rx_buf, count); p->port.icount.rx += count; + dma->rx_running = 0;
tty_flip_buffer_push(tty_port); }
From: Arnd Bergmann arnd@arndb.de
commit abce209d18fd26e865b2406cc68819289db973f9 upstream.
Using the serio subsystem now requires the code to be reachable:
x86_64-linux-ld: drivers/platform/x86/amd/pmc.o: in function `amd_pmc_suspend_handler': pmc.c:(.text+0x86c): undefined reference to `serio_bus'
Add the usual dependency: as other users of serio use 'select' rather than 'depends on', use the same here.
Fixes: 8e60615e8932 ("platform/x86/amd: pmc: Disable IRQ1 wakeup for RN/CZN") Signed-off-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20230127093950.2368575-1-arnd@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/amd/Kconfig | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/platform/x86/amd/Kconfig +++ b/drivers/platform/x86/amd/Kconfig @@ -8,6 +8,7 @@ source "drivers/platform/x86/amd/pmf/Kco config AMD_PMC tristate "AMD SoC PMC driver" depends on ACPI && PCI && RTC_CLASS + select SERIO help The driver provides support for AMD Power Management Controller primarily responsible for S2Idle transactions that are driven from
From: Peter Ujfalusi peter.ujfalusi@linux.intel.com
commit fb4293600cc651cfe4d48ec489f1d175adf6e2f8 upstream.
If the swidget is NULL we skip the preparing of the widget and jump to handle the sink path of the widget. If the prepare fails in this case we would undo the prepare but the swidget is NULL (we skipped the prepare for the widget).
To avoid NULL pointer dereference in this case we must check swidget against NULL pointer once again.
Fixes: 0ad84b11f2f8 ("ASoC: SOF: sof-audio: skip prepare/unprepare if swidget is NULL") Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter error27@gmail.com Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20230120102125.30653-1-peter.ujfalusi@linux.intel.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/sof/sof-audio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -327,7 +327,8 @@ sink_prepare: p->walking = false; if (ret < 0) { /* unprepare the source widget */ - if (widget_ops[widget->id].ipc_unprepare && swidget->prepared) { + if (widget_ops[widget->id].ipc_unprepare && + swidget && swidget->prepared) { widget_ops[widget->id].ipc_unprepare(swidget); swidget->prepared = false; }
From: Andreas Kemnade andreas@kemnade.info
commit bffb7d9d1a3dbd09e083b88aefd093b3b10abbfb upstream.
VAC needs to be wired up to produce proper measurements, without this change only near zero values are reported.
Reported-by: kernel test robot lkp@intel.com Reported-by: Julia Lawall julia.lawall@lip6.fr Fixes: 1696f36482e7 ("iio: twl6030-gpadc: TWL6030, TWL6032 GPADC driver") Signed-off-by: Andreas Kemnade andreas@kemnade.info Link: https://lore.kernel.org/r/20221217221305.671117-1-andreas@kemnade.info Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/adc/twl6030-gpadc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/adc/twl6030-gpadc.c +++ b/drivers/iio/adc/twl6030-gpadc.c @@ -952,7 +952,7 @@ static int twl6030_gpadc_probe(struct pl }
ret = twl_i2c_write_u8(TWL6030_MODULE_ID0, - VBAT_MEAS | BB_MEAS | BB_MEAS, + VBAT_MEAS | BB_MEAS | VAC_MEAS, TWL6030_MISC1); if (ret < 0) { dev_err(dev, "failed to wire up inputs\n");
From: Michael Ellerman mpe@ellerman.id.au
commit 98d0219e043e09013e883eacde3b93e0b2bf944d upstream.
If a relocatable kernel is loaded at an address that is not 2MB aligned and told not to relocate to zero, the kernel can crash due to mark_rodata_ro() incorrectly changing some read-write data to read-only.
Scenarios where the misalignment can occur are when the kernel is loaded by kdump or using the RELOCATABLE_TEST config option.
Example crash with the kernel loaded at 5MB:
Run /sbin/init as init process BUG: Unable to handle kernel data access on write at 0xc000000000452000 Faulting instruction address: 0xc0000000005b6730 Oops: Kernel access of bad area, sig: 11 [#1] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries CPU: 1 PID: 1 Comm: init Not tainted 6.2.0-rc1-00011-g349188be4841 #166 Hardware name: IBM pSeries (emulated by qemu) POWER9 (raw) 0x4e1202 0xf000005 of:SLOF,git-5b4c5a hv:linux,kvm pSeries NIP: c0000000005b6730 LR: c000000000ae9ab8 CTR: 0000000000000380 REGS: c000000004503250 TRAP: 0300 Not tainted (6.2.0-rc1-00011-g349188be4841) MSR: 8000000000009033 <SF,EE,ME,IR,DR,RI,LE> CR: 44288480 XER: 00000000 CFAR: c0000000005b66ec DAR: c000000000452000 DSISR: 0a000000 IRQMASK: 0 ... NIP memset+0x68/0x104 LR zero_user_segments.constprop.0+0xa8/0xf0 Call Trace: ext4_mpage_readpages+0x7f8/0x830 ext4_readahead+0x48/0x60 read_pages+0xb8/0x380 page_cache_ra_unbounded+0x19c/0x250 filemap_fault+0x58c/0xae0 __do_fault+0x60/0x100 __handle_mm_fault+0x1230/0x1a40 handle_mm_fault+0x120/0x300 ___do_page_fault+0x20c/0xa80 do_page_fault+0x30/0xc0 data_access_common_virt+0x210/0x220
This happens because mark_rodata_ro() tries to change permissions on the range _stext..__end_rodata, but _stext sits in the middle of the 2MB page from 4MB to 6MB:
radix-mmu: Mapped 0x0000000000000000-0x0000000000200000 with 2.00 MiB pages (exec) radix-mmu: Mapped 0x0000000000200000-0x0000000000400000 with 2.00 MiB pages radix-mmu: Mapped 0x0000000000400000-0x0000000002400000 with 2.00 MiB pages (exec)
The logic that changes the permissions assumes the linear mapping was split correctly at boot, so it marks the entire 2MB page read-only. That leads to the write fault above.
To fix it, the boot time mapping logic needs to consider that if the kernel is running at a non-zero address then _stext is a boundary where it must split the mapping.
That leads to the mapping being split correctly, allowing the rodata permission change to take happen correctly, with no spillover:
radix-mmu: Mapped 0x0000000000000000-0x0000000000200000 with 2.00 MiB pages (exec) radix-mmu: Mapped 0x0000000000200000-0x0000000000400000 with 2.00 MiB pages radix-mmu: Mapped 0x0000000000400000-0x0000000000500000 with 64.0 KiB pages radix-mmu: Mapped 0x0000000000500000-0x0000000000600000 with 64.0 KiB pages (exec) radix-mmu: Mapped 0x0000000000600000-0x0000000002400000 with 2.00 MiB pages (exec)
If the kernel is loaded at a 2MB aligned address, the mapping continues to use 2MB pages as before:
radix-mmu: Mapped 0x0000000000000000-0x0000000000200000 with 2.00 MiB pages (exec) radix-mmu: Mapped 0x0000000000200000-0x0000000000400000 with 2.00 MiB pages radix-mmu: Mapped 0x0000000000400000-0x0000000002c00000 with 2.00 MiB pages (exec) radix-mmu: Mapped 0x0000000002c00000-0x0000000100000000 with 2.00 MiB pages
Fixes: c55d7b5e6426 ("powerpc: Remove STRICT_KERNEL_RWX incompatibility with RELOCATABLE") Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20230110124753.1325426-1-mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/mm/book3s64/radix_pgtable.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -262,6 +262,17 @@ print_mapping(unsigned long start, unsig static unsigned long next_boundary(unsigned long addr, unsigned long end) { #ifdef CONFIG_STRICT_KERNEL_RWX + unsigned long stext_phys; + + stext_phys = __pa_symbol(_stext); + + // Relocatable kernel running at non-zero real address + if (stext_phys != 0) { + // Start of relocated kernel text is a rodata boundary + if (addr < stext_phys) + return stext_phys; + } + if (addr < __pa_symbol(__srwx_boundary)) return __pa_symbol(__srwx_boundary); #endif
From: Nicholas Piggin npiggin@gmail.com
commit bc88ef663265676419555df2dc469a471c0add31 upstream.
When PMI interrupts are soft-masked, local_irq_save() will clear the PMI mask bit, allowing PMIs in and causing a race condition. This causes a deadlock in native_hpte_insert via hash_preload, which depends on PMIs being disabled since commit 8b91cee5eadd ("powerpc/64s/hash: Make hash faults work in NMI context"). native_hpte_insert calls local_irq_save(). It's possible the lpar hash code is also affected when tracing is enabled because __trace_hcall_entry() calls local_irq_save().
Fix this by making arch_local_irq_save() _or_ the IRQS_DISABLED bit into the mask.
This was found with the stress_hpt option with a kbuild workload running together with `perf record -g`.
Fixes: f442d004806e ("powerpc/64s: Add support to mask perf interrupts and replay them") Fixes: 8b91cee5eadd ("powerpc/64s/hash: Make hash faults work in NMI context") Signed-off-by: Nicholas Piggin npiggin@gmail.com [mpe: Just take the fix without the new warning] Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20230121095352.2823517-1-npiggin@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/include/asm/hw_irq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index 77fa88c2aed0..0b7d01d408ac 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -192,7 +192,7 @@ static inline void arch_local_irq_enable(void)
static inline unsigned long arch_local_irq_save(void) { - return irq_soft_mask_set_return(IRQS_DISABLED); + return irq_soft_mask_or_return(IRQS_DISABLED); }
static inline bool arch_irqs_disabled_flags(unsigned long flags)
From: Michael Ellerman mpe@ellerman.id.au
commit ad53db4acb415976761d7302f5b02e97f2bd097e upstream.
The recent commit 76d588dddc45 ("powerpc/imc-pmu: Fix use of mutex in IRQs disabled section") fixed warnings (and possible deadlocks) in the IMC PMU driver by converting the locking to use spinlocks.
It also converted the init-time nest_init_lock to a spinlock, even though it's not used at runtime in IRQ disabled sections or while holding other spinlocks.
This leads to warnings such as:
BUG: sleeping function called from invalid context at include/linux/percpu-rwsem.h:49 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1, name: swapper/0 preempt_count: 1, expected: 0 CPU: 7 PID: 1 Comm: swapper/0 Not tainted 6.2.0-rc2-14719-gf12cd06109f4-dirty #1 Hardware name: Mambo,Simulated-System POWER9 0x4e1203 opal:v6.6.6 PowerNV Call Trace: dump_stack_lvl+0x74/0xa8 (unreliable) __might_resched+0x178/0x1a0 __cpuhp_setup_state+0x64/0x1e0 init_imc_pmu+0xe48/0x1250 opal_imc_counters_probe+0x30c/0x6a0 platform_probe+0x78/0x110 really_probe+0x104/0x420 __driver_probe_device+0xb0/0x170 driver_probe_device+0x58/0x180 __driver_attach+0xd8/0x250 bus_for_each_dev+0xb4/0x140 driver_attach+0x34/0x50 bus_add_driver+0x1e8/0x2d0 driver_register+0xb4/0x1c0 __platform_driver_register+0x38/0x50 opal_imc_driver_init+0x2c/0x40 do_one_initcall+0x80/0x360 kernel_init_freeable+0x310/0x3b8 kernel_init+0x30/0x1a0 ret_from_kernel_thread+0x5c/0x64
Fix it by converting nest_init_lock back to a mutex, so that we can call sleeping functions while holding it. There is no interaction between nest_init_lock and the runtime spinlocks used by the actual PMU routines.
Fixes: 76d588dddc45 ("powerpc/imc-pmu: Fix use of mutex in IRQs disabled section") Tested-by: Kajol Jainkjain@linux.ibm.com Reviewed-by: Kajol Jainkjain@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20230130014401.540543-1-mpe@ellerman.id.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/perf/imc-pmu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
--- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -22,7 +22,7 @@ * Used to avoid races in counting the nest-pmu units during hotplug * register and unregister */ -static DEFINE_SPINLOCK(nest_init_lock); +static DEFINE_MUTEX(nest_init_lock); static DEFINE_PER_CPU(struct imc_pmu_ref *, local_nest_imc_refc); static struct imc_pmu **per_nest_pmu_arr; static cpumask_t nest_imc_cpumask; @@ -1629,7 +1629,7 @@ static void imc_common_mem_free(struct i static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr) { if (pmu_ptr->domain == IMC_DOMAIN_NEST) { - spin_lock(&nest_init_lock); + mutex_lock(&nest_init_lock); if (nest_pmus == 1) { cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE); kfree(nest_imc_refc); @@ -1639,7 +1639,7 @@ static void imc_common_cpuhp_mem_free(st
if (nest_pmus > 0) nest_pmus--; - spin_unlock(&nest_init_lock); + mutex_unlock(&nest_init_lock); }
/* Free core_imc memory */ @@ -1796,11 +1796,11 @@ int init_imc_pmu(struct device_node *par * rest. To handle the cpuhotplug callback unregister, we track * the number of nest pmus in "nest_pmus". */ - spin_lock(&nest_init_lock); + mutex_lock(&nest_init_lock); if (nest_pmus == 0) { ret = init_nest_pmu_ref(); if (ret) { - spin_unlock(&nest_init_lock); + mutex_unlock(&nest_init_lock); kfree(per_nest_pmu_arr); per_nest_pmu_arr = NULL; goto err_free_mem; @@ -1808,7 +1808,7 @@ int init_imc_pmu(struct device_node *par /* Register for cpu hotplug notification. */ ret = nest_pmu_cpumask_init(); if (ret) { - spin_unlock(&nest_init_lock); + mutex_unlock(&nest_init_lock); kfree(nest_imc_refc); kfree(per_nest_pmu_arr); per_nest_pmu_arr = NULL; @@ -1816,7 +1816,7 @@ int init_imc_pmu(struct device_node *par } } nest_pmus++; - spin_unlock(&nest_init_lock); + mutex_unlock(&nest_init_lock); break; case IMC_DOMAIN_CORE: ret = core_imc_pmu_cpumask_init();
From: Abdun Nihaal abdun.nihaal@gmail.com
commit 019d22eb0eb707fc099e6e8fad9b3933236a06d0 upstream.
The data_size and valid_size fields of non resident attributes should be less than the its alloc_size field, but this is not checked in ntfs_read_mft function.
Syzbot reports a allocation order warning due to a large unchecked value of data_size getting assigned to inode->i_size which is then passed to kcalloc.
Add sanity check for ensuring that the data_size and valid_size fields are not larger than alloc_size field.
Link: https://syzkaller.appspot.com/bug?extid=fa4648a5446460b7b963 Reported-and-tested-by: syzbot+fa4648a5446460b7b963@syzkaller.appspotmail.com Fixes: (82cae269cfa95) fs/ntfs3: Add initialization of super block Signed-off-by: Abdun Nihaal abdun.nihaal@gmail.com Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ntfs3/inode.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -132,6 +132,13 @@ next_attr: if (le16_to_cpu(attr->name_off) + attr->name_len > asize) goto out;
+ if (attr->non_res) { + t64 = le64_to_cpu(attr->nres.alloc_size); + if (le64_to_cpu(attr->nres.data_size) > t64 || + le64_to_cpu(attr->nres.valid_size) > t64) + goto out; + } + switch (attr->type) { case ATTR_STD: if (attr->non_res ||
From: Kees Cook keescook@chromium.org
commit cf8aa9bf97cadf85745506c6a3e244b22c268d63 upstream.
The "buf" flexible array needs to be the memcpy() destination to avoid false positive run-time warning from the recent FORTIFY_SOURCE hardening:
memcpy: detected field-spanning write (size 93) of single field "&fh->fb" at fs/overlayfs/export.c:799 (size 21)
Reported-by: syzbot+9d14351a171d0d1c7955@syzkaller.appspotmail.com Link: https://lore.kernel.org/all/000000000000763a6c05e95a5985@google.com/ Signed-off-by: Kees Cook keescook@chromium.org Reviewed-by: Gustavo A. R. Silva gustavoars@kernel.org Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/overlayfs/export.c | 2 +- fs/overlayfs/overlayfs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
--- a/fs/overlayfs/export.c +++ b/fs/overlayfs/export.c @@ -796,7 +796,7 @@ static struct ovl_fh *ovl_fid_to_fh(stru return ERR_PTR(-ENOMEM);
/* Copy unaligned inner fh into aligned buffer */ - memcpy(&fh->fb, fid, buflen - OVL_FH_WIRE_OFFSET); + memcpy(fh->buf, fid, buflen - OVL_FH_WIRE_OFFSET); return fh; }
--- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -108,7 +108,7 @@ struct ovl_fh { u8 padding[3]; /* make sure fb.fid is 32bit aligned */ union { struct ovl_fb fb; - u8 buf[0]; + DECLARE_FLEX_ARRAY(u8, buf); }; } __packed;
From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
commit 92b4cf5b48955a4bdd15fe4e2067db8ebd87f04c upstream.
syzbot is reporting lockdep warning at f2fs_handle_error() [1], for spin_lock(&sbi->error_lock) is called before spin_lock_init() is called. For safe locking in error handling, move initialization of locks (and obvious structures) in f2fs_fill_super() to immediately after memory allocation.
Link: https://syzkaller.appspot.com/bug?extid=40642be9b7e0bb28e0df [1] Reported-by: syzbot syzbot+40642be9b7e0bb28e0df@syzkaller.appspotmail.com Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Tested-by: syzbot syzbot+40642be9b7e0bb28e0df@syzkaller.appspotmail.com Reviewed-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/super.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-)
--- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -4095,6 +4095,24 @@ try_onemore:
sbi->sb = sb;
+ /* initialize locks within allocated memory */ + init_f2fs_rwsem(&sbi->gc_lock); + mutex_init(&sbi->writepages); + init_f2fs_rwsem(&sbi->cp_global_sem); + init_f2fs_rwsem(&sbi->node_write); + init_f2fs_rwsem(&sbi->node_change); + spin_lock_init(&sbi->stat_lock); + init_f2fs_rwsem(&sbi->cp_rwsem); + init_f2fs_rwsem(&sbi->quota_sem); + init_waitqueue_head(&sbi->cp_wait); + spin_lock_init(&sbi->error_lock); + + for (i = 0; i < NR_INODE_TYPE; i++) { + INIT_LIST_HEAD(&sbi->inode_list[i]); + spin_lock_init(&sbi->inode_lock[i]); + } + mutex_init(&sbi->flush_lock); + /* Load the checksum driver */ sbi->s_chksum_driver = crypto_alloc_shash("crc32", 0, 0); if (IS_ERR(sbi->s_chksum_driver)) { @@ -4118,6 +4136,8 @@ try_onemore: sb->s_fs_info = sbi; sbi->raw_super = raw_super;
+ memcpy(sbi->errors, raw_super->s_errors, MAX_F2FS_ERRORS); + /* precompute checksum seed for metadata */ if (f2fs_sb_has_inode_chksum(sbi)) sbi->s_chksum_seed = f2fs_chksum(sbi, ~0, raw_super->uuid, @@ -4174,26 +4194,14 @@ try_onemore:
/* init f2fs-specific super block info */ sbi->valid_super_block = valid_super_block; - init_f2fs_rwsem(&sbi->gc_lock); - mutex_init(&sbi->writepages); - init_f2fs_rwsem(&sbi->cp_global_sem); - init_f2fs_rwsem(&sbi->node_write); - init_f2fs_rwsem(&sbi->node_change);
/* disallow all the data/node/meta page writes */ set_sbi_flag(sbi, SBI_POR_DOING); - spin_lock_init(&sbi->stat_lock);
err = f2fs_init_write_merge_io(sbi); if (err) goto free_bio_info;
- spin_lock_init(&sbi->error_lock); - memcpy(sbi->errors, raw_super->s_errors, MAX_F2FS_ERRORS); - - init_f2fs_rwsem(&sbi->cp_rwsem); - init_f2fs_rwsem(&sbi->quota_sem); - init_waitqueue_head(&sbi->cp_wait); init_sb_info(sbi);
err = f2fs_init_iostat(sbi); @@ -4271,12 +4279,6 @@ try_onemore: limit_reserve_root(sbi); adjust_unusable_cap_perc(sbi);
- for (i = 0; i < NR_INODE_TYPE; i++) { - INIT_LIST_HEAD(&sbi->inode_list[i]); - spin_lock_init(&sbi->inode_lock[i]); - } - mutex_init(&sbi->flush_lock); - f2fs_init_extent_cache_info(sbi);
f2fs_init_ino_entry_info(sbi);
From: Dongliang Mu dzm91@hust.edu.cn
commit b76449ee75e21acfe9fa4c653d8598f191ed7d68 upstream.
The current error handling code in ufx_usb_probe have many unmatching issues, e.g., missing ufx_free_usb_list, destroy_modedb label should only include framebuffer_release, fb_dealloc_cmap only matches fb_alloc_cmap.
My local syzkaller reports a memory leak bug:
memory leak in ufx_usb_probe
BUG: memory leak unreferenced object 0xffff88802f879580 (size 128): comm "kworker/0:7", pid 17416, jiffies 4295067474 (age 46.710s) hex dump (first 32 bytes): 80 21 7c 2e 80 88 ff ff 18 d0 d0 0c 80 88 ff ff .!|............. 00 d0 d0 0c 80 88 ff ff e0 ff ff ff 0f 00 00 00 ................ backtrace: [<ffffffff814c99a0>] kmalloc_trace+0x20/0x90 mm/slab_common.c:1045 [<ffffffff824d219c>] kmalloc include/linux/slab.h:553 [inline] [<ffffffff824d219c>] kzalloc include/linux/slab.h:689 [inline] [<ffffffff824d219c>] ufx_alloc_urb_list drivers/video/fbdev/smscufx.c:1873 [inline] [<ffffffff824d219c>] ufx_usb_probe+0x11c/0x15a0 drivers/video/fbdev/smscufx.c:1655 [<ffffffff82d17927>] usb_probe_interface+0x177/0x370 drivers/usb/core/driver.c:396 [<ffffffff82712f0d>] call_driver_probe drivers/base/dd.c:560 [inline] [<ffffffff82712f0d>] really_probe+0x12d/0x390 drivers/base/dd.c:639 [<ffffffff8271322f>] __driver_probe_device+0xbf/0x140 drivers/base/dd.c:778 [<ffffffff827132da>] driver_probe_device+0x2a/0x120 drivers/base/dd.c:808 [<ffffffff82713c27>] __device_attach_driver+0xf7/0x150 drivers/base/dd.c:936 [<ffffffff82710137>] bus_for_each_drv+0xb7/0x100 drivers/base/bus.c:427 [<ffffffff827136b5>] __device_attach+0x105/0x2d0 drivers/base/dd.c:1008 [<ffffffff82711d36>] bus_probe_device+0xc6/0xe0 drivers/base/bus.c:487 [<ffffffff8270e242>] device_add+0x642/0xdc0 drivers/base/core.c:3517 [<ffffffff82d14d5f>] usb_set_configuration+0x8ef/0xb80 drivers/usb/core/message.c:2170 [<ffffffff82d2576c>] usb_generic_driver_probe+0x8c/0xc0 drivers/usb/core/generic.c:238 [<ffffffff82d16ffc>] usb_probe_device+0x5c/0x140 drivers/usb/core/driver.c:293 [<ffffffff82712f0d>] call_driver_probe drivers/base/dd.c:560 [inline] [<ffffffff82712f0d>] really_probe+0x12d/0x390 drivers/base/dd.c:639 [<ffffffff8271322f>] __driver_probe_device+0xbf/0x140 drivers/base/dd.c:778
Fix this bug by rewriting the error handling code in ufx_usb_probe.
Reported-by: syzkaller syzkaller@googlegroups.com Tested-by: Dongliang Mu dzm91@hust.edu.cn Signed-off-by: Dongliang Mu dzm91@hust.edu.cn Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/video/fbdev/smscufx.c | 46 ++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 15 deletions(-)
--- a/drivers/video/fbdev/smscufx.c +++ b/drivers/video/fbdev/smscufx.c @@ -1622,7 +1622,7 @@ static int ufx_usb_probe(struct usb_inte struct usb_device *usbdev; struct ufx_data *dev; struct fb_info *info; - int retval; + int retval = -ENOMEM; u32 id_rev, fpga_rev;
/* usb initialization */ @@ -1654,15 +1654,17 @@ static int ufx_usb_probe(struct usb_inte
if (!ufx_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) { dev_err(dev->gdev, "ufx_alloc_urb_list failed\n"); - goto e_nomem; + goto put_ref; }
/* We don't register a new USB class. Our client interface is fbdev */
/* allocates framebuffer driver structure, not framebuffer memory */ info = framebuffer_alloc(0, &usbdev->dev); - if (!info) - goto e_nomem; + if (!info) { + dev_err(dev->gdev, "framebuffer_alloc failed\n"); + goto free_urb_list; + }
dev->info = info; info->par = dev; @@ -1705,22 +1707,34 @@ static int ufx_usb_probe(struct usb_inte check_warn_goto_error(retval, "unable to find common mode for display and adapter");
retval = ufx_reg_set_bits(dev, 0x4000, 0x00000001); - check_warn_goto_error(retval, "error %d enabling graphics engine", retval); + if (retval < 0) { + dev_err(dev->gdev, "error %d enabling graphics engine", retval); + goto setup_modes; + }
/* ready to begin using device */ atomic_set(&dev->usb_active, 1);
dev_dbg(dev->gdev, "checking var"); retval = ufx_ops_check_var(&info->var, info); - check_warn_goto_error(retval, "error %d ufx_ops_check_var", retval); + if (retval < 0) { + dev_err(dev->gdev, "error %d ufx_ops_check_var", retval); + goto reset_active; + }
dev_dbg(dev->gdev, "setting par"); retval = ufx_ops_set_par(info); - check_warn_goto_error(retval, "error %d ufx_ops_set_par", retval); + if (retval < 0) { + dev_err(dev->gdev, "error %d ufx_ops_set_par", retval); + goto reset_active; + }
dev_dbg(dev->gdev, "registering framebuffer"); retval = register_framebuffer(info); - check_warn_goto_error(retval, "error %d register_framebuffer", retval); + if (retval < 0) { + dev_err(dev->gdev, "error %d register_framebuffer", retval); + goto reset_active; + }
dev_info(dev->gdev, "SMSC UDX USB device /dev/fb%d attached. %dx%d resolution." " Using %dK framebuffer memory\n", info->node, @@ -1728,21 +1742,23 @@ static int ufx_usb_probe(struct usb_inte
return 0;
-error: - fb_dealloc_cmap(&info->cmap); -destroy_modedb: +reset_active: + atomic_set(&dev->usb_active, 0); +setup_modes: fb_destroy_modedb(info->monspecs.modedb); vfree(info->screen_base); fb_destroy_modelist(&info->modelist); +error: + fb_dealloc_cmap(&info->cmap); +destroy_modedb: framebuffer_release(info); +free_urb_list: + if (dev->urbs.count > 0) + ufx_free_urb_list(dev); put_ref: kref_put(&dev->kref, ufx_free); /* ref for framebuffer */ kref_put(&dev->kref, ufx_free); /* last ref from kref_init */ return retval; - -e_nomem: - retval = -ENOMEM; - goto put_ref; }
static void ufx_usb_disconnect(struct usb_interface *interface)
From: Chao Yu chao@kernel.org
commit d3b7b4afd6b2c344eabf9cc26b8bfa903c164c7c upstream.
syzbot found a f2fs bug:
BUG: KASAN: slab-out-of-bounds in data_blkaddr fs/f2fs/f2fs.h:2891 [inline] BUG: KASAN: slab-out-of-bounds in is_alive fs/f2fs/gc.c:1117 [inline] BUG: KASAN: slab-out-of-bounds in gc_data_segment fs/f2fs/gc.c:1520 [inline] BUG: KASAN: slab-out-of-bounds in do_garbage_collect+0x386a/0x3df0 fs/f2fs/gc.c:1734 Read of size 4 at addr ffff888076557568 by task kworker/u4:3/52
CPU: 1 PID: 52 Comm: kworker/u4:3 Not tainted 6.1.0-rc4-syzkaller-00362-gfef7fd48922d #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 Workqueue: writeback wb_workfn (flush-7:0) Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:284 [inline] print_report+0x15e/0x45d mm/kasan/report.c:395 kasan_report+0xbb/0x1f0 mm/kasan/report.c:495 data_blkaddr fs/f2fs/f2fs.h:2891 [inline] is_alive fs/f2fs/gc.c:1117 [inline] gc_data_segment fs/f2fs/gc.c:1520 [inline] do_garbage_collect+0x386a/0x3df0 fs/f2fs/gc.c:1734 f2fs_gc+0x88c/0x20a0 fs/f2fs/gc.c:1831 f2fs_balance_fs+0x544/0x6b0 fs/f2fs/segment.c:410 f2fs_write_inode+0x57e/0xe20 fs/f2fs/inode.c:753 write_inode fs/fs-writeback.c:1440 [inline] __writeback_single_inode+0xcfc/0x1440 fs/fs-writeback.c:1652 writeback_sb_inodes+0x54d/0xf90 fs/fs-writeback.c:1870 wb_writeback+0x2c5/0xd70 fs/fs-writeback.c:2044 wb_do_writeback fs/fs-writeback.c:2187 [inline] wb_workfn+0x2dc/0x12f0 fs/fs-writeback.c:2227 process_one_work+0x9bf/0x1710 kernel/workqueue.c:2289 worker_thread+0x665/0x1080 kernel/workqueue.c:2436 kthread+0x2e4/0x3a0 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:306
The root cause is that we forgot to do sanity check on .i_extra_isize in below path, result in accessing invalid address later, fix it. - gc_data_segment - is_alive - data_blkaddr - offset_in_addr
Reported-by: syzbot+f8f3dfa4abc489e768a1@syzkaller.appspotmail.com Link: https://lore.kernel.org/linux-f2fs-devel/0000000000003cb3c405ed5c17f9@google... Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/gc.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
--- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1078,7 +1078,7 @@ static bool is_alive(struct f2fs_sb_info { struct page *node_page; nid_t nid; - unsigned int ofs_in_node, max_addrs; + unsigned int ofs_in_node, max_addrs, base; block_t source_blkaddr;
nid = le32_to_cpu(sum->nid); @@ -1104,11 +1104,17 @@ static bool is_alive(struct f2fs_sb_info return false; }
- max_addrs = IS_INODE(node_page) ? DEF_ADDRS_PER_INODE : - DEF_ADDRS_PER_BLOCK; - if (ofs_in_node >= max_addrs) { - f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u", - ofs_in_node, dni->ino, dni->nid, max_addrs); + if (IS_INODE(node_page)) { + base = offset_in_addr(F2FS_INODE(node_page)); + max_addrs = DEF_ADDRS_PER_INODE; + } else { + base = 0; + max_addrs = DEF_ADDRS_PER_BLOCK; + } + + if (base + ofs_in_node >= max_addrs) { + f2fs_err(sbi, "Inconsistent blkaddr offset: base:%u, ofs_in_node:%u, max:%u, ino:%u, nid:%u", + base, ofs_in_node, max_addrs, dni->ino, dni->nid); f2fs_put_page(node_page, 1); return false; }
From: Minsuk Kang linuxlovemin@yonsei.ac.kr
commit 4920ab131b2dbae7464b72bdcac465d070254209 upstream.
This patch fixes slab-out-of-bounds reads in brcmfmac that occur in brcmf_construct_chaninfo() and brcmf_enable_bw40_2g() when the count value of channel specifications provided by the device is greater than the length of 'list->element[]', decided by the size of the 'list' allocated with kzalloc(). The patch adds checks that make the functions free the buffer and return -EINVAL if that is the case. Note that the negative return is handled by the caller, brcmf_setup_wiphybands() or brcmf_cfg80211_attach().
Found by a modified version of syzkaller.
Crash Report from brcmf_construct_chaninfo(): ================================================================== BUG: KASAN: slab-out-of-bounds in brcmf_setup_wiphybands+0x1238/0x1430 Read of size 4 at addr ffff888115f24600 by task kworker/0:2/1896
CPU: 0 PID: 1896 Comm: kworker/0:2 Tainted: G W O 5.14.0+ #132 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 Workqueue: usb_hub_wq hub_event Call Trace: dump_stack_lvl+0x57/0x7d print_address_description.constprop.0.cold+0x93/0x334 kasan_report.cold+0x83/0xdf brcmf_setup_wiphybands+0x1238/0x1430 brcmf_cfg80211_attach+0x2118/0x3fd0 brcmf_attach+0x389/0xd40 brcmf_usb_probe+0x12de/0x1690 usb_probe_interface+0x25f/0x710 really_probe+0x1be/0xa90 __driver_probe_device+0x2ab/0x460 driver_probe_device+0x49/0x120 __device_attach_driver+0x18a/0x250 bus_for_each_drv+0x123/0x1a0 __device_attach+0x207/0x330 bus_probe_device+0x1a2/0x260 device_add+0xa61/0x1ce0 usb_set_configuration+0x984/0x1770 usb_generic_driver_probe+0x69/0x90 usb_probe_device+0x9c/0x220 really_probe+0x1be/0xa90 __driver_probe_device+0x2ab/0x460 driver_probe_device+0x49/0x120 __device_attach_driver+0x18a/0x250 bus_for_each_drv+0x123/0x1a0 __device_attach+0x207/0x330 bus_probe_device+0x1a2/0x260 device_add+0xa61/0x1ce0 usb_new_device.cold+0x463/0xf66 hub_event+0x10d5/0x3330 process_one_work+0x873/0x13e0 worker_thread+0x8b/0xd10 kthread+0x379/0x450 ret_from_fork+0x1f/0x30
Allocated by task 1896: kasan_save_stack+0x1b/0x40 __kasan_kmalloc+0x7c/0x90 kmem_cache_alloc_trace+0x19e/0x330 brcmf_setup_wiphybands+0x290/0x1430 brcmf_cfg80211_attach+0x2118/0x3fd0 brcmf_attach+0x389/0xd40 brcmf_usb_probe+0x12de/0x1690 usb_probe_interface+0x25f/0x710 really_probe+0x1be/0xa90 __driver_probe_device+0x2ab/0x460 driver_probe_device+0x49/0x120 __device_attach_driver+0x18a/0x250 bus_for_each_drv+0x123/0x1a0 __device_attach+0x207/0x330 bus_probe_device+0x1a2/0x260 device_add+0xa61/0x1ce0 usb_set_configuration+0x984/0x1770 usb_generic_driver_probe+0x69/0x90 usb_probe_device+0x9c/0x220 really_probe+0x1be/0xa90 __driver_probe_device+0x2ab/0x460 driver_probe_device+0x49/0x120 __device_attach_driver+0x18a/0x250 bus_for_each_drv+0x123/0x1a0 __device_attach+0x207/0x330 bus_probe_device+0x1a2/0x260 device_add+0xa61/0x1ce0 usb_new_device.cold+0x463/0xf66 hub_event+0x10d5/0x3330 process_one_work+0x873/0x13e0 worker_thread+0x8b/0xd10 kthread+0x379/0x450 ret_from_fork+0x1f/0x30
The buggy address belongs to the object at ffff888115f24000 which belongs to the cache kmalloc-2k of size 2048 The buggy address is located 1536 bytes inside of 2048-byte region [ffff888115f24000, ffff888115f24800)
Memory state around the buggy address: ffff888115f24500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff888115f24580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff888115f24600: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
^ ffff888115f24680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff888115f24700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ==================================================================
Crash Report from brcmf_enable_bw40_2g(): ================================================================== BUG: KASAN: slab-out-of-bounds in brcmf_cfg80211_attach+0x3d11/0x3fd0 Read of size 4 at addr ffff888103787600 by task kworker/0:2/1896
CPU: 0 PID: 1896 Comm: kworker/0:2 Tainted: G W O 5.14.0+ #132 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 Workqueue: usb_hub_wq hub_event Call Trace: dump_stack_lvl+0x57/0x7d print_address_description.constprop.0.cold+0x93/0x334 kasan_report.cold+0x83/0xdf brcmf_cfg80211_attach+0x3d11/0x3fd0 brcmf_attach+0x389/0xd40 brcmf_usb_probe+0x12de/0x1690 usb_probe_interface+0x25f/0x710 really_probe+0x1be/0xa90 __driver_probe_device+0x2ab/0x460 driver_probe_device+0x49/0x120 __device_attach_driver+0x18a/0x250 bus_for_each_drv+0x123/0x1a0 __device_attach+0x207/0x330 bus_probe_device+0x1a2/0x260 device_add+0xa61/0x1ce0 usb_set_configuration+0x984/0x1770 usb_generic_driver_probe+0x69/0x90 usb_probe_device+0x9c/0x220 really_probe+0x1be/0xa90 __driver_probe_device+0x2ab/0x460 driver_probe_device+0x49/0x120 __device_attach_driver+0x18a/0x250 bus_for_each_drv+0x123/0x1a0 __device_attach+0x207/0x330 bus_probe_device+0x1a2/0x260 device_add+0xa61/0x1ce0 usb_new_device.cold+0x463/0xf66 hub_event+0x10d5/0x3330 process_one_work+0x873/0x13e0 worker_thread+0x8b/0xd10 kthread+0x379/0x450 ret_from_fork+0x1f/0x30
Allocated by task 1896: kasan_save_stack+0x1b/0x40 __kasan_kmalloc+0x7c/0x90 kmem_cache_alloc_trace+0x19e/0x330 brcmf_cfg80211_attach+0x3302/0x3fd0 brcmf_attach+0x389/0xd40 brcmf_usb_probe+0x12de/0x1690 usb_probe_interface+0x25f/0x710 really_probe+0x1be/0xa90 __driver_probe_device+0x2ab/0x460 driver_probe_device+0x49/0x120 __device_attach_driver+0x18a/0x250 bus_for_each_drv+0x123/0x1a0 __device_attach+0x207/0x330 bus_probe_device+0x1a2/0x260 device_add+0xa61/0x1ce0 usb_set_configuration+0x984/0x1770 usb_generic_driver_probe+0x69/0x90 usb_probe_device+0x9c/0x220 really_probe+0x1be/0xa90 __driver_probe_device+0x2ab/0x460 driver_probe_device+0x49/0x120 __device_attach_driver+0x18a/0x250 bus_for_each_drv+0x123/0x1a0 __device_attach+0x207/0x330 bus_probe_device+0x1a2/0x260 device_add+0xa61/0x1ce0 usb_new_device.cold+0x463/0xf66 hub_event+0x10d5/0x3330 process_one_work+0x873/0x13e0 worker_thread+0x8b/0xd10 kthread+0x379/0x450 ret_from_fork+0x1f/0x30
The buggy address belongs to the object at ffff888103787000 which belongs to the cache kmalloc-2k of size 2048 The buggy address is located 1536 bytes inside of 2048-byte region [ffff888103787000, ffff888103787800)
Memory state around the buggy address: ffff888103787500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff888103787580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff888103787600: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
^ ffff888103787680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff888103787700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ==================================================================
Reported-by: Dokyung Song dokyungs@yonsei.ac.kr Reported-by: Jisoo Jang jisoo.jang@yonsei.ac.kr Reported-by: Minsuk Kang linuxlovemin@yonsei.ac.kr Reviewed-by: Arend van Spriel arend.vanspriel@broadcom.com Signed-off-by: Minsuk Kang linuxlovemin@yonsei.ac.kr Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20221116142952.518241-1-linuxlovemin@yonsei.ac.kr Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 17 ++++++++++++ 1 file changed, 17 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -91,6 +91,9 @@ #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
+#define BRCMF_MAX_CHANSPEC_LIST \ + (BRCMF_DCMD_MEDLEN / sizeof(__le32) - 1) + static bool check_vif_up(struct brcmf_cfg80211_vif *vif) { if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) { @@ -6556,6 +6559,13 @@ static int brcmf_construct_chaninfo(stru band->channels[i].flags = IEEE80211_CHAN_DISABLED;
total = le32_to_cpu(list->count); + if (total > BRCMF_MAX_CHANSPEC_LIST) { + bphy_err(drvr, "Invalid count of channel Spec. (%u)\n", + total); + err = -EINVAL; + goto fail_pbuf; + } + for (i = 0; i < total; i++) { ch.chspec = (u16)le32_to_cpu(list->element[i]); cfg->d11inf.decchspec(&ch); @@ -6701,6 +6711,13 @@ static int brcmf_enable_bw40_2g(struct b band = cfg_to_wiphy(cfg)->bands[NL80211_BAND_2GHZ]; list = (struct brcmf_chanspec_list *)pbuf; num_chan = le32_to_cpu(list->count); + if (num_chan > BRCMF_MAX_CHANSPEC_LIST) { + bphy_err(drvr, "Invalid count of channel Spec. (%u)\n", + num_chan); + kfree(pbuf); + return -EINVAL; + } + for (i = 0; i < num_chan; i++) { ch.chspec = (u16)le32_to_cpu(list->element[i]); cfg->d11inf.decchspec(&ch);
From: Andreas Gruenbacher agruenba@redhat.com
commit 7db354444ad8429e660b0f8145d425285d4f90ff upstream.
In each of the two functions, add an inode variable that points to &ip->i_inode and use that throughout the rest of the function.
Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/gfs2/glops.c | 41 +++++++++++++++++++++-------------------- fs/gfs2/super.c | 27 ++++++++++++++------------- 2 files changed, 35 insertions(+), 33 deletions(-)
--- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -397,38 +397,39 @@ static int gfs2_dinode_in(struct gfs2_in struct timespec64 atime; u16 height, depth; umode_t mode = be32_to_cpu(str->di_mode); - bool is_new = ip->i_inode.i_state & I_NEW; + struct inode *inode = &ip->i_inode; + bool is_new = inode->i_state & I_NEW;
if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) goto corrupt; - if (unlikely(!is_new && inode_wrong_type(&ip->i_inode, mode))) + if (unlikely(!is_new && inode_wrong_type(inode, mode))) goto corrupt; ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); - ip->i_inode.i_mode = mode; + inode->i_mode = mode; if (is_new) { - ip->i_inode.i_rdev = 0; + inode->i_rdev = 0; switch (mode & S_IFMT) { case S_IFBLK: case S_IFCHR: - ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), - be32_to_cpu(str->di_minor)); + inode->i_rdev = MKDEV(be32_to_cpu(str->di_major), + be32_to_cpu(str->di_minor)); break; } }
- i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid)); - i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid)); - set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink)); - i_size_write(&ip->i_inode, be64_to_cpu(str->di_size)); - gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); + i_uid_write(inode, be32_to_cpu(str->di_uid)); + i_gid_write(inode, be32_to_cpu(str->di_gid)); + set_nlink(inode, be32_to_cpu(str->di_nlink)); + i_size_write(inode, be64_to_cpu(str->di_size)); + gfs2_set_inode_blocks(inode, be64_to_cpu(str->di_blocks)); atime.tv_sec = be64_to_cpu(str->di_atime); atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); - if (timespec64_compare(&ip->i_inode.i_atime, &atime) < 0) - ip->i_inode.i_atime = atime; - ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); - ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); - ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); - ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); + if (timespec64_compare(&inode->i_atime, &atime) < 0) + inode->i_atime = atime; + inode->i_mtime.tv_sec = be64_to_cpu(str->di_mtime); + inode->i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); + inode->i_ctime.tv_sec = be64_to_cpu(str->di_ctime); + inode->i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec);
ip->i_goal = be64_to_cpu(str->di_goal_meta); ip->i_generation = be64_to_cpu(str->di_generation); @@ -436,7 +437,7 @@ static int gfs2_dinode_in(struct gfs2_in ip->i_diskflags = be32_to_cpu(str->di_flags); ip->i_eattr = be64_to_cpu(str->di_eattr); /* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */ - gfs2_set_inode_flags(&ip->i_inode); + gfs2_set_inode_flags(inode); height = be16_to_cpu(str->di_height); if (unlikely(height > GFS2_MAX_META_HEIGHT)) goto corrupt; @@ -448,8 +449,8 @@ static int gfs2_dinode_in(struct gfs2_in ip->i_depth = (u8)depth; ip->i_entries = be32_to_cpu(str->di_entries);
- if (S_ISREG(ip->i_inode.i_mode)) - gfs2_set_aops(&ip->i_inode); + if (S_ISREG(inode->i_mode)) + gfs2_set_aops(inode);
return 0; corrupt: --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -379,6 +379,7 @@ out:
void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) { + const struct inode *inode = &ip->i_inode; struct gfs2_dinode *str = buf;
str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); @@ -386,15 +387,15 @@ void gfs2_dinode_out(const struct gfs2_i str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); - str->di_mode = cpu_to_be32(ip->i_inode.i_mode); - str->di_uid = cpu_to_be32(i_uid_read(&ip->i_inode)); - str->di_gid = cpu_to_be32(i_gid_read(&ip->i_inode)); - str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); - str->di_size = cpu_to_be64(i_size_read(&ip->i_inode)); - str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); - str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); - str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); - str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); + str->di_mode = cpu_to_be32(inode->i_mode); + str->di_uid = cpu_to_be32(i_uid_read(inode)); + str->di_gid = cpu_to_be32(i_gid_read(inode)); + str->di_nlink = cpu_to_be32(inode->i_nlink); + str->di_size = cpu_to_be64(i_size_read(inode)); + str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(inode)); + str->di_atime = cpu_to_be64(inode->i_atime.tv_sec); + str->di_mtime = cpu_to_be64(inode->i_mtime.tv_sec); + str->di_ctime = cpu_to_be64(inode->i_ctime.tv_sec);
str->di_goal_meta = cpu_to_be64(ip->i_goal); str->di_goal_data = cpu_to_be64(ip->i_goal); @@ -402,16 +403,16 @@ void gfs2_dinode_out(const struct gfs2_i
str->di_flags = cpu_to_be32(ip->i_diskflags); str->di_height = cpu_to_be16(ip->i_height); - str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && + str->di_payload_format = cpu_to_be32(S_ISDIR(inode->i_mode) && !(ip->i_diskflags & GFS2_DIF_EXHASH) ? GFS2_FORMAT_DE : 0); str->di_depth = cpu_to_be16(ip->i_depth); str->di_entries = cpu_to_be32(ip->i_entries);
str->di_eattr = cpu_to_be64(ip->i_eattr); - str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); - str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); - str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); + str->di_atime_nsec = cpu_to_be32(inode->i_atime.tv_nsec); + str->di_mtime_nsec = cpu_to_be32(inode->i_mtime.tv_nsec); + str->di_ctime_nsec = cpu_to_be32(inode->i_ctime.tv_nsec); }
/**
From: Andreas Gruenbacher agruenba@redhat.com
commit 70376c7ff31221f1d21db5611d8209e677781d3a upstream.
Check if the inode size of stuffed (inline) inodes is within the allowed range when reading inodes from disk (gfs2_dinode_in()). This prevents us from on-disk corruption.
The two checks in stuffed_readpage() and gfs2_unstuffer_page() that just truncate inline data to the maximum allowed size don't actually make sense, and they can be removed now as well.
Reported-by: syzbot+7bb81dfa9cda07d9cd9d@syzkaller.appspotmail.com Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/gfs2/aops.c | 2 -- fs/gfs2/bmap.c | 3 --- fs/gfs2/glops.c | 3 +++ 3 files changed, 3 insertions(+), 5 deletions(-)
--- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -427,8 +427,6 @@ static int stuffed_readpage(struct gfs2_ return error;
kaddr = kmap_atomic(page); - if (dsize > gfs2_max_stuffed_size(ip)) - dsize = gfs2_max_stuffed_size(ip); memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize); memset(kaddr + dsize, 0, PAGE_SIZE - dsize); kunmap_atomic(kaddr); --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -61,9 +61,6 @@ static int gfs2_unstuffer_page(struct gf void *kaddr = kmap(page); u64 dsize = i_size_read(inode);
- if (dsize > gfs2_max_stuffed_size(ip)) - dsize = gfs2_max_stuffed_size(ip); - memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize); memset(kaddr + dsize, 0, PAGE_SIZE - dsize); kunmap(page); --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -449,6 +449,9 @@ static int gfs2_dinode_in(struct gfs2_in ip->i_depth = (u8)depth; ip->i_entries = be32_to_cpu(str->di_entries);
+ if (gfs2_is_stuffed(ip) && inode->i_size > gfs2_max_stuffed_size(ip)) + goto corrupt; + if (S_ISREG(inode->i_mode)) gfs2_set_aops(inode);
From: Hao Sun sunhao.th@gmail.com
commit d3178e8a434b58678d99257c0387810a24042fb6 upstream.
The verifier skips invalid kfunc call in check_kfunc_call(), which would be captured in fixup_kfunc_call() if such insn is not eliminated by dead code elimination. However, this can lead to the following warning in backtrack_insn(), also see [1]:
------------[ cut here ]------------ verifier backtracking bug WARNING: CPU: 6 PID: 8646 at kernel/bpf/verifier.c:2756 backtrack_insn kernel/bpf/verifier.c:2756 __mark_chain_precision kernel/bpf/verifier.c:3065 mark_chain_precision kernel/bpf/verifier.c:3165 adjust_reg_min_max_vals kernel/bpf/verifier.c:10715 check_alu_op kernel/bpf/verifier.c:10928 do_check kernel/bpf/verifier.c:13821 [inline] do_check_common kernel/bpf/verifier.c:16289 [...]
So make backtracking conservative with this by returning ENOTSUPP.
[1] https://lore.kernel.org/bpf/CACkBjsaXNceR8ZjkLG=dT3P=4A8SBsg0Z5h5PWLryF5=ghK...
Reported-by: syzbot+4da3ff23081bafe74fc2@syzkaller.appspotmail.com Signed-off-by: Hao Sun sunhao.th@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/bpf/20230104014709.9375-1-sunhao.th@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/bpf/verifier.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2664,6 +2664,12 @@ static int backtrack_insn(struct bpf_ver if (opcode == BPF_CALL) { if (insn->src_reg == BPF_PSEUDO_CALL) return -ENOTSUPP; + /* kfunc with imm==0 is invalid and fixup_kfunc_call will + * catch this error later. Make backtracking conservative + * with ENOTSUPP. + */ + if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL && insn->imm == 0) + return -ENOTSUPP; /* regular helper call sets R0 */ *reg_mask &= ~1; if (*reg_mask & 0x3f) {
On Tue, Feb 07, 2023 at 01:54:14PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.1.11 release. There are 208 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Feb 2023 12:55:54 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.11-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y and the diffstat can be found below.
On our RISC-V hardware this looks good, no issues noticed. Tested-by: Conor Dooley conor.dooley@microchip.com
Thanks, Conor.
On Tue, 7 Feb 2023 at 18:29, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 6.1.11 release. There are 208 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Feb 2023 12:55:54 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.11-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. Following build regressions noticed while building selftests/vm/hugetlb-madvise.c with kselftest-merge configs.
Reported-by: Linux Kernel Functional Testing lkft@linaro.org
Build errors: ---------- hugetlb-madvise.c:242:13: warning: implicit declaration of function 'fallocate'; did you mean 'alloca'? [-Wimplicit-function-declaration] 242 | if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) { | ^~~~~~~~~ | alloca hugetlb-madvise.c:289:27: error: 'FALLOC_FL_PUNCH_HOLE' undeclared (first use in this function) 289 | if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, | ^~~~~~~~~~~~~~~~~~~~ hugetlb-madvise.c:289:27: note: each undeclared identifier is reported only once for each function it appears in hugetlb-madvise.c:289:50: error: 'FALLOC_FL_KEEP_SIZE' undeclared (first use in this function) 289 | if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, | ^~~~~~~~~~~~~~~~~~~ make[3]: *** [../lib.mk:145: /home/tuxbuild/.cache/tuxmake/builds/1/build/kselftest/vm/hugetlb-madvise] Error 1
Build log: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc/-/jobs/3728198... https://storage.tuxsuite.com/public/linaro/lkft/builds/2LPeQeCIu0YEfltwqAFCv...
-- Linaro LKFT https://lkft.linaro.org
On Tue, Feb 07, 2023 at 10:35:19PM +0530, Naresh Kamboju wrote:
On Tue, 7 Feb 2023 at 18:29, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 6.1.11 release. There are 208 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Feb 2023 12:55:54 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.11-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. Following build regressions noticed while building selftests/vm/hugetlb-madvise.c with kselftest-merge configs.
Reported-by: Linux Kernel Functional Testing lkft@linaro.org
Build errors:
hugetlb-madvise.c:242:13: warning: implicit declaration of function 'fallocate'; did you mean 'alloca'? [-Wimplicit-function-declaration] 242 | if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) { | ^~~~~~~~~ | alloca hugetlb-madvise.c:289:27: error: 'FALLOC_FL_PUNCH_HOLE' undeclared (first use in this function) 289 | if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, | ^~~~~~~~~~~~~~~~~~~~ hugetlb-madvise.c:289:27: note: each undeclared identifier is reported only once for each function it appears in hugetlb-madvise.c:289:50: error: 'FALLOC_FL_KEEP_SIZE' undeclared (first use in this function) 289 | if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, | ^~~~~~~~~~~~~~~~~~~ make[3]: *** [../lib.mk:145: /home/tuxbuild/.cache/tuxmake/builds/1/build/kselftest/vm/hugetlb-madvise] Error 1
Build log: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc/-/jobs/3728198... https://storage.tuxsuite.com/public/linaro/lkft/builds/2LPeQeCIu0YEfltwqAFCv...
I think we should drop the patch "[PATCH 6.1 012/208] selftests/vm: remove __USE_GNU in hugetlb-madvise.c" from this merge.
That patch fixes commit 62f33fa22800 ("selftests/vm: use memfd for hugetlb-madvise test"), but that's only in 6.2-rc1 and it's not in 6.1.
I don't really know why it got picked for 6.1 stable backport, because the original patch doesn't contain "CC: stable".
Thanks,
On Tue, Feb 07, 2023 at 12:26:33PM -0500, Peter Xu wrote:
On Tue, Feb 07, 2023 at 10:35:19PM +0530, Naresh Kamboju wrote:
On Tue, 7 Feb 2023 at 18:29, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 6.1.11 release. There are 208 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Feb 2023 12:55:54 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.11-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. Following build regressions noticed while building selftests/vm/hugetlb-madvise.c with kselftest-merge configs.
Reported-by: Linux Kernel Functional Testing lkft@linaro.org
Build errors:
hugetlb-madvise.c:242:13: warning: implicit declaration of function 'fallocate'; did you mean 'alloca'? [-Wimplicit-function-declaration] 242 | if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) { | ^~~~~~~~~ | alloca hugetlb-madvise.c:289:27: error: 'FALLOC_FL_PUNCH_HOLE' undeclared (first use in this function) 289 | if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, | ^~~~~~~~~~~~~~~~~~~~ hugetlb-madvise.c:289:27: note: each undeclared identifier is reported only once for each function it appears in hugetlb-madvise.c:289:50: error: 'FALLOC_FL_KEEP_SIZE' undeclared (first use in this function) 289 | if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, | ^~~~~~~~~~~~~~~~~~~ make[3]: *** [../lib.mk:145: /home/tuxbuild/.cache/tuxmake/builds/1/build/kselftest/vm/hugetlb-madvise] Error 1
Build log: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc/-/jobs/3728198... https://storage.tuxsuite.com/public/linaro/lkft/builds/2LPeQeCIu0YEfltwqAFCv...
I think we should drop the patch "[PATCH 6.1 012/208] selftests/vm: remove __USE_GNU in hugetlb-madvise.c" from this merge.
That patch fixes commit 62f33fa22800 ("selftests/vm: use memfd for hugetlb-madvise test"), but that's only in 6.2-rc1 and it's not in 6.1.
I don't really know why it got picked for 6.1 stable backport, because the original patch doesn't contain "CC: stable".
Now dropped, thanks!
greg k-h
On 2/7/23 05:54, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.1.11 release. There are 208 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Feb 2023 12:55:54 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.11-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Tested-by: Shuah Khan skhan@linuxfoundation.org
thanks, -- Shuah
On 2/7/2023 4:54 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.1.11 release. There are 208 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Feb 2023 12:55:54 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.11-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y and the diffstat can be found below.
thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Tested-by: Florian Fainelli f.fainelli@gmail.com
On Tue, Feb 07, 2023 at 01:54:14PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.1.11 release. There are 208 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.
Successfully cross-compiled for arm64 (bcm2711_defconfig, GCC 10.2.0) and powerpc (ps3_defconfig, GCC 12.2.0).
Tested-by: Bagas Sanjaya bagasdotme@gmail.com
On Tue, Feb 07, 2023 at 01:54:14PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.1.11 release. There are 208 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Feb 2023 12:55:54 +0000. Anything received after that time might be too late.
Build results: total: 155 pass: 155 fail: 0 Qemu test results: total: 503 pass: 503 fail: 0
Tested-by: Guenter Roeck linux@roeck-us.net
Guenter
On 2/7/23 4:54 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.1.11 release. There are 208 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Feb 2023 12:55:54 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.11-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y and the diffstat can be found below.
thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Tested-by: Ron Economos re@w6rz.net
On Tue, Feb 07, 2023 at 01:54:14PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.1.11 release. There are 208 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Feb 2023 12:55:54 +0000. Anything received after that time might be too late.
Hi Greg,
6.1.11-rc1 tested.
Run tested on: - Allwinner H6 (Tanix TX6) - Intel Alder Lake x86_64 (nuc12 i7-1260P)
In addition - build tested for: - Allwinner A64 - Allwinner H3 - Allwinner H5 - NXP iMX6 - NXP iMX8 - Qualcomm Dragonboard - Rockchip RK3288 - Rockchip RK3328 - Rockchip RK3399pro - Samsung Exynos
Tested-by: Rudi Heitbaum rudi@heitbaum.com -- Rudi
This is the start of the stable review cycle for the 6.1.11 release. There are 208 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Feb 2023 12:55:54 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.11-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my x86_64 and ARM64 test systems. No errors or regressions.
Tested-by: Allen Pais apais@linux.microsoft.com
Thanks.
On Tue, Feb 07, 2023 at 01:54:14PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.1.11 release. There are 208 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Feb 2023 12:55:54 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.11-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y and the diffstat can be found below.
thanks,
greg k-h
Tested rc1 against the Fedora build system (aarch64, armv7, ppc64le, s390x, x86_64), and boot tested x86_64. No regressions noted.
Tested-by: Justin M. Forbes jforbes@fedoraproject.org
linux-stable-mirror@lists.linaro.org